From c784e46c8445635afd81bd4089fc5e87271a8f3b Mon Sep 17 00:00:00 2001 From: Ralf Schlatterbeck Date: Wed, 19 May 2021 13:54:51 +0200 Subject: auxdisplay: Add I2C gpio expander example The hd44780 displays are often used with pcf8574 based I/O expanders. Add example to documentation. Suggested-by: Geert Uytterhoeven Signed-off-by: Ralf Schlatterbeck [Added Suggested-by tag] Signed-off-by: Miguel Ojeda --- .../bindings/auxdisplay/hit,hd44780.yaml | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml index 9222b06e93a0..fde07e4b119d 100644 --- a/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml +++ b/Documentation/devicetree/bindings/auxdisplay/hit,hd44780.yaml @@ -12,7 +12,10 @@ maintainers: description: The Hitachi HD44780 Character LCD Controller is commonly used on character LCDs that can display one or more lines of text. It exposes an M6800 bus - interface, which can be used in either 4-bit or 8-bit mode. + interface, which can be used in either 4-bit or 8-bit mode. By using a + GPIO expander it is possible to use the driver with one of the popular I2C + expander boards based on the PCF8574 available for these displays. For + an example see below. properties: compatible: @@ -94,3 +97,29 @@ examples: display-height-chars = <2>; display-width-chars = <16>; }; + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pcf8574: pcf8574@27 { + compatible = "nxp,pcf8574"; + reg = <0x27>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + hd44780 { + compatible = "hit,hd44780"; + display-height-chars = <2>; + display-width-chars = <16>; + data-gpios = <&pcf8574 4 0>, + <&pcf8574 5 0>, + <&pcf8574 6 0>, + <&pcf8574 7 0>; + enable-gpios = <&pcf8574 2 0>; + rs-gpios = <&pcf8574 0 0>; + rw-gpios = <&pcf8574 1 0>; + backlight-gpios = <&pcf8574 3 0>; + }; -- cgit v1.2.3-70-g09d2 From 53bb4a9dda0b51c161b2573641c586f7d5d7e189 Mon Sep 17 00:00:00 2001 From: Pu Lehui Date: Fri, 14 May 2021 14:44:38 +0800 Subject: firewire: net: remove unused variable 'guid' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC reports the following warning with W=1: drivers/firewire/net.c:493:9: warning: variable ‘guid’ set but not used [-Wunused-but-set-variable] 493 | __be64 guid; | ^~~~ This variable is not used anymore since commit 6752c8db8e0c ("firewire net, ipv4 arp: Extend hardware address and remove driver-level packet inspection."). Remove it to fix the warning. Signed-off-by: Pu Lehui Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 715e491dfbc3..4c3fd2eed1da 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -488,9 +488,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, struct sk_buff *skb, u16 source_node_id, bool is_broadcast, u16 ether_type) { - struct fwnet_device *dev; int status; - __be64 guid; switch (ether_type) { case ETH_P_ARP: @@ -503,7 +501,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, goto err; } - dev = netdev_priv(net); /* Write metadata, and then pass to the receive level */ skb->dev = net; skb->ip_summed = CHECKSUM_NONE; @@ -512,7 +509,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, * Parse the encapsulation header. This actually does the job of * converting to an ethernet-like pseudo frame header. */ - guid = cpu_to_be64(dev->card->guid); if (dev_hard_header(skb, net, ether_type, is_broadcast ? net->broadcast : net->dev_addr, NULL, skb->len) >= 0) { -- cgit v1.2.3-70-g09d2 From 54b3bd99f094b3b919de4078f60d722e62a767e3 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 13 Jun 2021 15:27:43 +0200 Subject: firewire: nosy: switch from 'pci_' to 'dma_' API The wrappers in include/linux/pci-dma-compat.h should go away. The patch has been generated with the coccinelle script below and has been hand modified to replace GFP_ with a correct flag. It has been compile tested. When memory is allocated in 'add_card()', GFP_KERNEL can be used because this flag is already used a few lines above and no lock is taken in the between. While at it, also remove some useless casting. @@ @@ - PCI_DMA_BIDIRECTIONAL + DMA_BIDIRECTIONAL @@ @@ - PCI_DMA_TODEVICE + DMA_TO_DEVICE @@ @@ - PCI_DMA_FROMDEVICE + DMA_FROM_DEVICE @@ @@ - PCI_DMA_NONE + DMA_NONE @@ expression e1, e2, e3; @@ - pci_alloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3; @@ - pci_zalloc_consistent(e1, e2, e3) + dma_alloc_coherent(&e1->dev, e2, e3, GFP_) @@ expression e1, e2, e3, e4; @@ - pci_free_consistent(e1, e2, e3, e4) + dma_free_coherent(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_single(e1, e2, e3, e4) + dma_map_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_single(e1, e2, e3, e4) + dma_unmap_single(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4, e5; @@ - pci_map_page(e1, e2, e3, e4, e5) + dma_map_page(&e1->dev, e2, e3, e4, e5) @@ expression e1, e2, e3, e4; @@ - pci_unmap_page(e1, e2, e3, e4) + dma_unmap_page(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_map_sg(e1, e2, e3, e4) + dma_map_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_unmap_sg(e1, e2, e3, e4) + dma_unmap_sg(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_cpu(e1, e2, e3, e4) + dma_sync_single_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_single_for_device(e1, e2, e3, e4) + dma_sync_single_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_cpu(e1, e2, e3, e4) + dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4) @@ expression e1, e2, e3, e4; @@ - pci_dma_sync_sg_for_device(e1, e2, e3, e4) + dma_sync_sg_for_device(&e1->dev, e2, e3, e4) @@ expression e1, e2; @@ - pci_dma_mapping_error(e1, e2) + dma_mapping_error(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_dma_mask(e1, e2) + dma_set_mask(&e1->dev, e2) @@ expression e1, e2; @@ - pci_set_consistent_dma_mask(e1, e2) + dma_set_coherent_mask(&e1->dev, e2) Signed-off-by: Christophe JAILLET Signed-off-by: Stefan Richter --- drivers/firewire/nosy.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index 88ed971e32c0..b0d671db178a 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -511,12 +511,12 @@ remove_card(struct pci_dev *dev) wake_up_interruptible(&client->buffer.wait); spin_unlock_irq(&lynx->client_list_lock); - pci_free_consistent(lynx->pci_device, sizeof(struct pcl), - lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); - pci_free_consistent(lynx->pci_device, sizeof(struct pcl), - lynx->rcv_pcl, lynx->rcv_pcl_bus); - pci_free_consistent(lynx->pci_device, PAGE_SIZE, - lynx->rcv_buffer, lynx->rcv_buffer_bus); + dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), + lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); + dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), + lynx->rcv_pcl, lynx->rcv_pcl_bus); + dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, lynx->rcv_buffer, + lynx->rcv_buffer_bus); iounmap(lynx->registers); pci_disable_device(dev); @@ -532,7 +532,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) u32 p, end; int ret, i; - if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { + if (dma_set_mask(&dev->dev, DMA_BIT_MASK(32))) { dev_err(&dev->dev, "DMA address limits not supported for PCILynx hardware\n"); return -ENXIO; @@ -564,12 +564,16 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) goto fail_deallocate_lynx; } - lynx->rcv_start_pcl = pci_alloc_consistent(lynx->pci_device, - sizeof(struct pcl), &lynx->rcv_start_pcl_bus); - lynx->rcv_pcl = pci_alloc_consistent(lynx->pci_device, - sizeof(struct pcl), &lynx->rcv_pcl_bus); - lynx->rcv_buffer = pci_alloc_consistent(lynx->pci_device, - RCV_BUFFER_SIZE, &lynx->rcv_buffer_bus); + lynx->rcv_start_pcl = dma_alloc_coherent(&lynx->pci_device->dev, + sizeof(struct pcl), + &lynx->rcv_start_pcl_bus, + GFP_KERNEL); + lynx->rcv_pcl = dma_alloc_coherent(&lynx->pci_device->dev, + sizeof(struct pcl), + &lynx->rcv_pcl_bus, GFP_KERNEL); + lynx->rcv_buffer = dma_alloc_coherent(&lynx->pci_device->dev, + RCV_BUFFER_SIZE, + &lynx->rcv_buffer_bus, GFP_KERNEL); if (lynx->rcv_start_pcl == NULL || lynx->rcv_pcl == NULL || lynx->rcv_buffer == NULL) { @@ -667,14 +671,15 @@ fail_free_irq: fail_deallocate_buffers: if (lynx->rcv_start_pcl) - pci_free_consistent(lynx->pci_device, sizeof(struct pcl), - lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus); + dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), + lynx->rcv_start_pcl, + lynx->rcv_start_pcl_bus); if (lynx->rcv_pcl) - pci_free_consistent(lynx->pci_device, sizeof(struct pcl), - lynx->rcv_pcl, lynx->rcv_pcl_bus); + dma_free_coherent(&lynx->pci_device->dev, sizeof(struct pcl), + lynx->rcv_pcl, lynx->rcv_pcl_bus); if (lynx->rcv_buffer) - pci_free_consistent(lynx->pci_device, PAGE_SIZE, - lynx->rcv_buffer, lynx->rcv_buffer_bus); + dma_free_coherent(&lynx->pci_device->dev, PAGE_SIZE, + lynx->rcv_buffer, lynx->rcv_buffer_bus); iounmap(lynx->registers); fail_deallocate_lynx: -- cgit v1.2.3-70-g09d2 From 7ebaa41047738d46fca6376b3f1765ef69c463c5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 30 Jun 2021 16:50:42 +0200 Subject: pinctrl: renesas: rcar: Avoid changing PUDn when disabling bias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When disabling pin bias, there is no need to touch the LSI pin pull-up/down control register (PUDn), which selects between pull-up and pull-down. Just disabling the pull-up/down function through the LSI pin pull-enable register (PUENn) is sufficient. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/071ec644de2555da593a4531ef5d3e4d79cf997d.1625064076.git.geert+renesas@glider.be --- drivers/pinctrl/renesas/pinctrl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index bb488af29862..85cb78cfcfa6 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -898,17 +898,17 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, if (reg->puen) { enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit); - if (bias != PIN_CONFIG_BIAS_DISABLE) + if (bias != PIN_CONFIG_BIAS_DISABLE) { enable |= BIT(bit); - if (reg->pud) { - updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); - if (bias == PIN_CONFIG_BIAS_PULL_UP) - updown |= BIT(bit); + if (reg->pud) { + updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); + if (bias == PIN_CONFIG_BIAS_PULL_UP) + updown |= BIT(bit); - sh_pfc_write(pfc, reg->pud, updown); + sh_pfc_write(pfc, reg->pud, updown); + } } - sh_pfc_write(pfc, reg->puen, enable); } else { enable = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); -- cgit v1.2.3-70-g09d2 From e9d66bdbc5abecaf705bf5a2f4f6279b9e313b0c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 30 Jun 2021 16:50:43 +0200 Subject: pinctrl: renesas: r8a77995: Add bias pinconf support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement support for pull-up (most pins, excl. DU_DOTCLKIN0) and pull-down (most pins, excl. JTAG) handling for the R-Car D3 SoC, using some parts from the common R-Car bias handling, which requires making rcar_pin_to_bias_reg() public. R-Car D3 needs special handling for the NFRE# (GP_3_0) and NFWE# (GP_3_1) pins. Unlike all other pins, they are controlled by different bits in the LSI pin pull-up/down control register (PUD2) than in the LSI pin pull-enable register (PUEN2). Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/04aad2b0bf82a32fb08e5e21e4ac1fb03452724f.1625064076.git.geert+renesas@glider.be --- drivers/pinctrl/renesas/pfc-r8a77995.c | 320 ++++++++++++++++++++++++++++++++- drivers/pinctrl/renesas/pinctrl.c | 2 +- drivers/pinctrl/renesas/sh_pfc.h | 3 + 3 files changed, 316 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/renesas/pfc-r8a77995.c b/drivers/pinctrl/renesas/pfc-r8a77995.c index b479f87a3b23..c56e1e4c13b3 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77995.c +++ b/drivers/pinctrl/renesas/pfc-r8a77995.c @@ -14,16 +14,27 @@ #include #include +#include "core.h" #include "sh_pfc.h" -#define CPU_ALL_GP(fn, sfx) \ - PORT_GP_9(0, fn, sfx), \ - PORT_GP_32(1, fn, sfx), \ - PORT_GP_32(2, fn, sfx), \ - PORT_GP_CFG_10(3, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \ - PORT_GP_32(4, fn, sfx), \ - PORT_GP_21(5, fn, sfx), \ - PORT_GP_14(6, fn, sfx) +#define CPU_ALL_GP(fn, sfx) \ + PORT_GP_CFG_9(0, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_32(1, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_32(2, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_10(3, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE | SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_32(4, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_21(5, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PORT_GP_CFG_14(6, fn, sfx, SH_PFC_PIN_CFG_PULL_UP_DOWN) + +#define CPU_ALL_NOGP(fn) \ + PIN_NOGP_CFG(DU_DOTCLKIN0, "DU_DOTCLKIN0", fn, SH_PFC_PIN_CFG_PULL_DOWN), \ + PIN_NOGP_CFG(FSCLKST_N, "FSCLKST#", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(MLB_REF, "MLB_REF", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT#", fn, SH_PFC_PIN_CFG_PULL_UP_DOWN), \ + PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TRST_N, "TRST#", fn, SH_PFC_PIN_CFG_PULL_UP) /* * F_() : just information @@ -930,8 +941,17 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_GPSR(IP13_7_4, TPU0TO3_A), }; +/* + * Pins not associated with a GPIO port. + */ +enum { + GP_ASSIGN_LAST(), + NOGP_ALL(), +}; + static const struct sh_pfc_pin pinmux_pins[] = { PINMUX_GPIO_GP_ALL(), + PINMUX_NOGP_ALL(), }; /* - AUDIO CLOCK ------------------------------------------------------------- */ @@ -2834,6 +2854,214 @@ static int r8a77995_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *po return bit; } +static const struct pinmux_bias_reg pinmux_bias_regs[] = { + { PINMUX_BIAS_REG("PUEN0", 0xe6060400, "PUD0", 0xe6060440) { + [ 0] = RCAR_GP_PIN(1, 9), /* DU_DG1 */ + [ 1] = RCAR_GP_PIN(1, 8), /* DU_DG0 */ + [ 2] = RCAR_GP_PIN(1, 7), /* DU_DB7 */ + [ 3] = RCAR_GP_PIN(1, 6), /* DU_DB6 */ + [ 4] = RCAR_GP_PIN(1, 5), /* DU_DB5 */ + [ 5] = RCAR_GP_PIN(1, 4), /* DU_DB4 */ + [ 6] = RCAR_GP_PIN(1, 3), /* DU_DB3 */ + [ 7] = RCAR_GP_PIN(1, 2), /* DU_DB2 */ + [ 8] = RCAR_GP_PIN(1, 1), /* DU_DB1 */ + [ 9] = RCAR_GP_PIN(1, 0), /* DU_DB0 */ + [10] = PIN_MLB_REF, /* MLB_REF */ + [11] = RCAR_GP_PIN(0, 8), /* MLB_SIG */ + [12] = RCAR_GP_PIN(0, 7), /* MLB_DAT */ + [13] = RCAR_GP_PIN(0, 6), /* MLB_CLK */ + [14] = RCAR_GP_PIN(0, 5), /* MSIOF2_RXD */ + [15] = RCAR_GP_PIN(0, 4), /* MSIOF2_TXD */ + [16] = RCAR_GP_PIN(0, 3), /* MSIOF2_SCK */ + [17] = RCAR_GP_PIN(0, 2), /* IRQ0_A */ + [18] = RCAR_GP_PIN(0, 1), /* USB0_OVC */ + [19] = RCAR_GP_PIN(0, 0), /* USB0_PWEN */ + [20] = PIN_PRESETOUT_N, /* PRESETOUT# */ + [21] = PIN_DU_DOTCLKIN0, /* DU_DOTCLKIN0 */ + [22] = PIN_FSCLKST_N, /* FSCLKST# */ + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = PIN_TDI, /* TDI */ + [29] = PIN_TMS, /* TMS */ + [30] = PIN_TCK, /* TCK */ + [31] = PIN_TRST_N, /* TRST# */ + } }, + { PINMUX_BIAS_REG("PUEN1", 0xe6060404, "PUD1", 0xe6060444) { + [ 0] = RCAR_GP_PIN(2, 9), /* VI4_DATA8 */ + [ 1] = RCAR_GP_PIN(2, 8), /* VI4_DATA7 */ + [ 2] = RCAR_GP_PIN(2, 7), /* VI4_DATA6 */ + [ 3] = RCAR_GP_PIN(2, 6), /* VI4_DATA5 */ + [ 4] = RCAR_GP_PIN(2, 5), /* VI4_DATA4 */ + [ 5] = RCAR_GP_PIN(2, 4), /* VI4_DATA3 */ + [ 6] = RCAR_GP_PIN(2, 3), /* VI4_DATA2 */ + [ 7] = RCAR_GP_PIN(2, 2), /* VI4_DATA1 */ + [ 8] = RCAR_GP_PIN(2, 1), /* VI4_DATA0 */ + [ 9] = RCAR_GP_PIN(2, 0), /* VI4_CLK */ + [10] = RCAR_GP_PIN(1, 31), /* QPOLB */ + [11] = RCAR_GP_PIN(1, 30), /* QPOLA */ + [12] = RCAR_GP_PIN(1, 29), /* DU_CDE */ + [13] = RCAR_GP_PIN(1, 28), /* DU_DISP/CDE */ + [14] = RCAR_GP_PIN(1, 27), /* DU_DISP */ + [15] = RCAR_GP_PIN(1, 26), /* DU_VSYNC */ + [16] = RCAR_GP_PIN(1, 25), /* DU_HSYNC */ + [17] = RCAR_GP_PIN(1, 24), /* DU_DOTCLKOUT0 */ + [18] = RCAR_GP_PIN(1, 23), /* DU_DR7 */ + [19] = RCAR_GP_PIN(1, 22), /* DU_DR6 */ + [20] = RCAR_GP_PIN(1, 21), /* DU_DR5 */ + [21] = RCAR_GP_PIN(1, 20), /* DU_DR4 */ + [22] = RCAR_GP_PIN(1, 19), /* DU_DR3 */ + [23] = RCAR_GP_PIN(1, 18), /* DU_DR2 */ + [24] = RCAR_GP_PIN(1, 17), /* DU_DR1 */ + [25] = RCAR_GP_PIN(1, 16), /* DU_DR0 */ + [26] = RCAR_GP_PIN(1, 15), /* DU_DG7 */ + [27] = RCAR_GP_PIN(1, 14), /* DU_DG6 */ + [28] = RCAR_GP_PIN(1, 13), /* DU_DG5 */ + [29] = RCAR_GP_PIN(1, 12), /* DU_DG4 */ + [30] = RCAR_GP_PIN(1, 11), /* DU_DG3 */ + [31] = RCAR_GP_PIN(1, 10), /* DU_DG2 */ + } }, + { PINMUX_BIAS_REG("PUEN2", 0xe6060408, "PUD2", 0xe6060448) { + [ 0] = RCAR_GP_PIN(3, 8), /* NFDATA6 */ + [ 1] = RCAR_GP_PIN(3, 7), /* NFDATA5 */ + [ 2] = RCAR_GP_PIN(3, 6), /* NFDATA4 */ + [ 3] = RCAR_GP_PIN(3, 5), /* NFDATA3 */ + [ 4] = RCAR_GP_PIN(3, 4), /* NFDATA2 */ + [ 5] = RCAR_GP_PIN(3, 3), /* NFDATA1 */ + [ 6] = RCAR_GP_PIN(3, 2), /* NFDATA0 */ + [ 7] = RCAR_GP_PIN(3, 1), /* NFWE# (PUEN) / NFRE# (PUD) */ + [ 8] = RCAR_GP_PIN(3, 0), /* NFRE# (PUEN) / NFWE# (PUD) */ + [ 9] = RCAR_GP_PIN(4, 0), /* NFRB# */ + [10] = RCAR_GP_PIN(2, 31), /* NFCE# */ + [11] = RCAR_GP_PIN(2, 30), /* NFCLE */ + [12] = RCAR_GP_PIN(2, 29), /* NFALE */ + [13] = RCAR_GP_PIN(2, 28), /* VI4_CLKENB */ + [14] = RCAR_GP_PIN(2, 27), /* VI4_FIELD */ + [15] = RCAR_GP_PIN(2, 26), /* VI4_HSYNC# */ + [16] = RCAR_GP_PIN(2, 25), /* VI4_VSYNC# */ + [17] = RCAR_GP_PIN(2, 24), /* VI4_DATA23 */ + [18] = RCAR_GP_PIN(2, 23), /* VI4_DATA22 */ + [19] = RCAR_GP_PIN(2, 22), /* VI4_DATA21 */ + [20] = RCAR_GP_PIN(2, 21), /* VI4_DATA20 */ + [21] = RCAR_GP_PIN(2, 20), /* VI4_DATA19 */ + [22] = RCAR_GP_PIN(2, 19), /* VI4_DATA18 */ + [23] = RCAR_GP_PIN(2, 18), /* VI4_DATA17 */ + [24] = RCAR_GP_PIN(2, 17), /* VI4_DATA16 */ + [25] = RCAR_GP_PIN(2, 16), /* VI4_DATA15 */ + [26] = RCAR_GP_PIN(2, 15), /* VI4_DATA14 */ + [27] = RCAR_GP_PIN(2, 14), /* VI4_DATA13 */ + [28] = RCAR_GP_PIN(2, 13), /* VI4_DATA12 */ + [29] = RCAR_GP_PIN(2, 12), /* VI4_DATA11 */ + [30] = RCAR_GP_PIN(2, 11), /* VI4_DATA10 */ + [31] = RCAR_GP_PIN(2, 10), /* VI4_DATA9 */ + } }, + { PINMUX_BIAS_REG("PUEN3", 0xe606040c, "PUD3", 0xe606044c) { + [ 0] = RCAR_GP_PIN(4, 31), /* CAN0_RX_A */ + [ 1] = RCAR_GP_PIN(5, 2), /* CAN_CLK */ + [ 2] = RCAR_GP_PIN(5, 1), /* TPU0TO1_A */ + [ 3] = RCAR_GP_PIN(5, 0), /* TPU0TO0_A */ + [ 4] = RCAR_GP_PIN(4, 27), /* TX2 */ + [ 5] = RCAR_GP_PIN(4, 26), /* RX2 */ + [ 6] = RCAR_GP_PIN(4, 25), /* SCK2 */ + [ 7] = RCAR_GP_PIN(4, 24), /* TX1_A */ + [ 8] = RCAR_GP_PIN(4, 23), /* RX1_A */ + [ 9] = RCAR_GP_PIN(4, 22), /* SCK1_A */ + [10] = RCAR_GP_PIN(4, 21), /* TX0_A */ + [11] = RCAR_GP_PIN(4, 20), /* RX0_A */ + [12] = RCAR_GP_PIN(4, 19), /* SCK0_A */ + [13] = RCAR_GP_PIN(4, 18), /* MSIOF1_RXD */ + [14] = RCAR_GP_PIN(4, 17), /* MSIOF1_TXD */ + [15] = RCAR_GP_PIN(4, 16), /* MSIOF1_SCK */ + [16] = RCAR_GP_PIN(4, 15), /* MSIOF0_RXD */ + [17] = RCAR_GP_PIN(4, 14), /* MSIOF0_TXD */ + [18] = RCAR_GP_PIN(4, 13), /* MSIOF0_SYNC */ + [19] = RCAR_GP_PIN(4, 12), /* MSIOF0_SCK */ + [20] = RCAR_GP_PIN(4, 11), /* SDA1 */ + [21] = RCAR_GP_PIN(4, 10), /* SCL1 */ + [22] = RCAR_GP_PIN(4, 9), /* SDA0 */ + [23] = RCAR_GP_PIN(4, 8), /* SCL0 */ + [24] = RCAR_GP_PIN(4, 7), /* SSI_WS4_A */ + [25] = RCAR_GP_PIN(4, 6), /* SSI_SDATA4_A */ + [26] = RCAR_GP_PIN(4, 5), /* SSI_SCK4_A */ + [27] = RCAR_GP_PIN(4, 4), /* SSI_WS34 */ + [28] = RCAR_GP_PIN(4, 3), /* SSI_SDATA3 */ + [29] = RCAR_GP_PIN(4, 2), /* SSI_SCK34 */ + [30] = RCAR_GP_PIN(4, 1), /* AUDIO_CLKA */ + [31] = RCAR_GP_PIN(3, 9), /* NFDATA7 */ + } }, + { PINMUX_BIAS_REG("PUEN4", 0xe6060410, "PUD4", 0xe6060450) { + [ 0] = RCAR_GP_PIN(6, 10), /* QSPI1_IO3 */ + [ 1] = RCAR_GP_PIN(6, 9), /* QSPI1_IO2 */ + [ 2] = RCAR_GP_PIN(6, 8), /* QSPI1_MISO_IO1 */ + [ 3] = RCAR_GP_PIN(6, 7), /* QSPI1_MOSI_IO0 */ + [ 4] = RCAR_GP_PIN(6, 6), /* QSPI1_SPCLK */ + [ 5] = RCAR_GP_PIN(6, 5), /* QSPI0_SSL */ + [ 6] = RCAR_GP_PIN(6, 4), /* QSPI0_IO3 */ + [ 7] = RCAR_GP_PIN(6, 3), /* QSPI0_IO2 */ + [ 8] = RCAR_GP_PIN(6, 2), /* QSPI0_MISO_IO1 */ + [ 9] = RCAR_GP_PIN(6, 1), /* QSPI0_MOSI_IO0 */ + [10] = RCAR_GP_PIN(6, 0), /* QSPI0_SPCLK */ + [11] = RCAR_GP_PIN(5, 20), /* AVB0_LINK */ + [12] = RCAR_GP_PIN(5, 19), /* AVB0_PHY_INT */ + [13] = RCAR_GP_PIN(5, 18), /* AVB0_MAGIC */ + [14] = RCAR_GP_PIN(5, 17), /* AVB0_MDC */ + [15] = RCAR_GP_PIN(5, 16), /* AVB0_MDIO */ + [16] = RCAR_GP_PIN(5, 15), /* AVB0_TXCREFCLK */ + [17] = RCAR_GP_PIN(5, 14), /* AVB0_TD3 */ + [18] = RCAR_GP_PIN(5, 13), /* AVB0_TD2 */ + [19] = RCAR_GP_PIN(5, 12), /* AVB0_TD1 */ + [20] = RCAR_GP_PIN(5, 11), /* AVB0_TD0 */ + [21] = RCAR_GP_PIN(5, 10), /* AVB0_TXC */ + [22] = RCAR_GP_PIN(5, 9), /* AVB0_TX_CTL */ + [23] = RCAR_GP_PIN(5, 8), /* AVB0_RD3 */ + [24] = RCAR_GP_PIN(5, 7), /* AVB0_RD2 */ + [25] = RCAR_GP_PIN(5, 6), /* AVB0_RD1 */ + [26] = RCAR_GP_PIN(5, 5), /* AVB0_RD0 */ + [27] = RCAR_GP_PIN(5, 4), /* AVB0_RXC */ + [28] = RCAR_GP_PIN(5, 3), /* AVB0_RX_CTL */ + [29] = RCAR_GP_PIN(4, 30), /* CAN1_TX_A */ + [30] = RCAR_GP_PIN(4, 29), /* CAN1_RX_A */ + [31] = RCAR_GP_PIN(4, 28), /* CAN0_TX_A */ + } }, + { PINMUX_BIAS_REG("PUEN5", 0xe6060414, "PUD4", 0xe6060454) { + [ 0] = SH_PFC_PIN_NONE, + [ 1] = SH_PFC_PIN_NONE, + [ 2] = SH_PFC_PIN_NONE, + [ 3] = SH_PFC_PIN_NONE, + [ 4] = SH_PFC_PIN_NONE, + [ 5] = SH_PFC_PIN_NONE, + [ 6] = SH_PFC_PIN_NONE, + [ 7] = SH_PFC_PIN_NONE, + [ 8] = SH_PFC_PIN_NONE, + [ 9] = SH_PFC_PIN_NONE, + [10] = SH_PFC_PIN_NONE, + [11] = SH_PFC_PIN_NONE, + [12] = SH_PFC_PIN_NONE, + [13] = SH_PFC_PIN_NONE, + [14] = SH_PFC_PIN_NONE, + [15] = SH_PFC_PIN_NONE, + [16] = SH_PFC_PIN_NONE, + [17] = SH_PFC_PIN_NONE, + [18] = SH_PFC_PIN_NONE, + [19] = SH_PFC_PIN_NONE, + [20] = SH_PFC_PIN_NONE, + [21] = SH_PFC_PIN_NONE, + [22] = SH_PFC_PIN_NONE, + [23] = SH_PFC_PIN_NONE, + [24] = SH_PFC_PIN_NONE, + [25] = SH_PFC_PIN_NONE, + [26] = SH_PFC_PIN_NONE, + [27] = SH_PFC_PIN_NONE, + [28] = SH_PFC_PIN_NONE, + [29] = RCAR_GP_PIN(6, 13), /* RPC_INT# */ + [30] = RCAR_GP_PIN(6, 12), /* RPC_RESET# */ + [31] = RCAR_GP_PIN(6, 11), /* QSPI1_SSL */ + } }, + { /* sentinel */ } +}; + enum ioctrl_regs { TDSELCTRL, }; @@ -2843,8 +3071,83 @@ static const struct pinmux_ioctrl_reg pinmux_ioctrl_regs[] = { { /* sentinel */ }, }; +static const struct pinmux_bias_reg * +r8a77995_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, + unsigned int *puen_bit, unsigned int *pud_bit) +{ + const struct pinmux_bias_reg *reg; + unsigned int bit; + + reg = rcar_pin_to_bias_reg(pfc, pin, &bit); + if (!reg) + return reg; + + *puen_bit = bit; + + /* NFWE# and NFRE# use different bit positions in PUD2 */ + switch (pin) { + case RCAR_GP_PIN(3, 0): /* NFRE# */ + *pud_bit = 7; + break; + + case RCAR_GP_PIN(3, 1): /* NFWE# */ + *pud_bit = 8; + break; + + default: + *pud_bit = bit; + break; + } + + return reg; +} + +static unsigned int r8a77995_pinmux_get_bias(struct sh_pfc *pfc, + unsigned int pin) +{ + const struct pinmux_bias_reg *reg; + unsigned int puen_bit, pud_bit; + + reg = r8a77995_pin_to_bias_reg(pfc, pin, &puen_bit, &pud_bit); + if (!reg) + return PIN_CONFIG_BIAS_DISABLE; + + if (!(sh_pfc_read(pfc, reg->puen) & BIT(puen_bit))) + return PIN_CONFIG_BIAS_DISABLE; + else if (sh_pfc_read(pfc, reg->pud) & BIT(pud_bit)) + return PIN_CONFIG_BIAS_PULL_UP; + else + return PIN_CONFIG_BIAS_PULL_DOWN; +} + +static void r8a77995_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, + unsigned int bias) +{ + const struct pinmux_bias_reg *reg; + unsigned int puen_bit, pud_bit; + u32 enable, updown; + + reg = r8a77995_pin_to_bias_reg(pfc, pin, &puen_bit, &pud_bit); + if (!reg) + return; + + enable = sh_pfc_read(pfc, reg->puen) & ~BIT(puen_bit); + if (bias != PIN_CONFIG_BIAS_DISABLE) { + enable |= BIT(puen_bit); + + updown = sh_pfc_read(pfc, reg->pud) & ~BIT(pud_bit); + if (bias == PIN_CONFIG_BIAS_PULL_UP) + updown |= BIT(pud_bit); + + sh_pfc_write(pfc, reg->pud, updown); + } + sh_pfc_write(pfc, reg->puen, enable); +} + static const struct sh_pfc_soc_operations r8a77995_pinmux_ops = { .pin_to_pocctrl = r8a77995_pin_to_pocctrl, + .get_bias = r8a77995_pinmux_get_bias, + .set_bias = r8a77995_pinmux_set_bias, }; const struct sh_pfc_soc_info r8a77995_pinmux_info = { @@ -2862,6 +3165,7 @@ const struct sh_pfc_soc_info r8a77995_pinmux_info = { .nr_functions = ARRAY_SIZE(pinmux_functions), .cfg_regs = pinmux_config_regs, + .bias_regs = pinmux_bias_regs, .ioctrl_regs = pinmux_ioctrl_regs, .pinmux_data = pinmux_data, diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c index 85cb78cfcfa6..f3eecb20c086 100644 --- a/drivers/pinctrl/renesas/pinctrl.c +++ b/drivers/pinctrl/renesas/pinctrl.c @@ -841,7 +841,7 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) return pinctrl_enable(pmx->pctl); } -static const struct pinmux_bias_reg * +const struct pinmux_bias_reg * rcar_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, unsigned int *bit) { diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index 320898861c4b..bf9822ef7e8c 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -781,6 +781,9 @@ extern const struct sh_pfc_soc_info shx3_pinmux_info; /* * Bias helpers */ +const struct pinmux_bias_reg * +rcar_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, + unsigned int *bit); unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin); void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); -- cgit v1.2.3-70-g09d2 From 40bb0e3e270a33b03a39cdd77bf03fc18dfe2fab Mon Sep 17 00:00:00 2001 From: Vaibhav Gupta Date: Thu, 2 Apr 2020 21:20:58 +0530 Subject: gpio: ml-ioh: Convert to dev_pm_ops Convert the legacy callback .suspend() and .resume() to the generic ones. While at it, replace ifdeffery by __maybe_unused attribute. Signed-off-by: Vaibhav Gupta Signed-off-by: Andy Shevchenko --- drivers/gpio/gpio-ml-ioh.c | 49 +++++++++++----------------------------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index 53d4abefa6ff..efa9acdc320a 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c @@ -155,11 +155,10 @@ static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) return 0; } -#ifdef CONFIG_PM /* * Save register configuration and disable interrupts. */ -static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) +static void __maybe_unused ioh_gpio_save_reg_conf(struct ioh_gpio *chip) { int i; @@ -185,7 +184,7 @@ static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) /* * This function restores the register configuration of the GPIO device. */ -static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) +static void __maybe_unused ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) { int i; @@ -207,7 +206,6 @@ static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) &chip->reg->ioh_sel_reg[i]); } } -#endif static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) { @@ -522,47 +520,23 @@ static void ioh_gpio_remove(struct pci_dev *pdev) kfree(chip); } -#ifdef CONFIG_PM -static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused ioh_gpio_suspend(struct device *dev) { - s32 ret; - struct ioh_gpio *chip = pci_get_drvdata(pdev); + struct ioh_gpio *chip = dev_get_drvdata(dev); unsigned long flags; spin_lock_irqsave(&chip->spinlock, flags); ioh_gpio_save_reg_conf(chip); spin_unlock_irqrestore(&chip->spinlock, flags); - ret = pci_save_state(pdev); - if (ret) { - dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); - return ret; - } - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_wake(pdev, PCI_D0, 1); - if (ret) - dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); - return 0; } -static int ioh_gpio_resume(struct pci_dev *pdev) +static int __maybe_unused ioh_gpio_resume(struct device *dev) { - s32 ret; - struct ioh_gpio *chip = pci_get_drvdata(pdev); + struct ioh_gpio *chip = dev_get_drvdata(dev); unsigned long flags; - ret = pci_enable_wake(pdev, PCI_D0, 0); - - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); - return ret; - } - pci_restore_state(pdev); - spin_lock_irqsave(&chip->spinlock, flags); iowrite32(0x01, &chip->reg->srst); iowrite32(0x00, &chip->reg->srst); @@ -571,10 +545,8 @@ static int ioh_gpio_resume(struct pci_dev *pdev) return 0; } -#else -#define ioh_gpio_suspend NULL -#define ioh_gpio_resume NULL -#endif + +static SIMPLE_DEV_PM_OPS(ioh_gpio_pm_ops, ioh_gpio_suspend, ioh_gpio_resume); static const struct pci_device_id ioh_gpio_pcidev_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, @@ -587,8 +559,9 @@ static struct pci_driver ioh_gpio_driver = { .id_table = ioh_gpio_pcidev_id, .probe = ioh_gpio_probe, .remove = ioh_gpio_remove, - .suspend = ioh_gpio_suspend, - .resume = ioh_gpio_resume + .driver = { + .pm = &ioh_gpio_pm_ops, + }, }; module_pci_driver(ioh_gpio_driver); -- cgit v1.2.3-70-g09d2 From a1867f85e06edacd82956d3422caa2b9074f4321 Mon Sep 17 00:00:00 2001 From: Min Li Date: Fri, 18 Jun 2021 12:37:12 -0400 Subject: mfd: Add Renesas Synchronization Management Unit (SMU) support Add support for ClockMatrix(TM) and 82P33xxx families of timing and synchronization devices. The access interface can be either SPI or I2C. Currently, it will create 2 types of MFD devices, which are to be used by the corresponding rsmu character device driver and the PTP hardware clock driver, respectively. Signed-off-by: Min Li Signed-off-by: Lee Jones --- drivers/mfd/Kconfig | 28 ++ drivers/mfd/Makefile | 5 + drivers/mfd/rsmu.h | 16 + drivers/mfd/rsmu_core.c | 88 +++++ drivers/mfd/rsmu_i2c.c | 203 +++++++++++ drivers/mfd/rsmu_spi.c | 273 +++++++++++++++ include/linux/mfd/idt82p33_reg.h | 112 ++++++ include/linux/mfd/idt8a340_reg.h | 729 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/rsmu.h | 36 ++ 9 files changed, 1490 insertions(+) create mode 100644 drivers/mfd/rsmu.h create mode 100644 drivers/mfd/rsmu_core.c create mode 100644 drivers/mfd/rsmu_i2c.c create mode 100644 drivers/mfd/rsmu_spi.c create mode 100644 include/linux/mfd/idt82p33_reg.h create mode 100644 include/linux/mfd/idt8a340_reg.h create mode 100644 include/linux/mfd/rsmu.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6a3fd2d75f96..578db280dedf 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2183,5 +2183,33 @@ config MFD_INTEL_M10_BMC additional drivers must be enabled in order to use the functionality of the device. +config MFD_RSMU_I2C + tristate "Renesas Synchronization Management Unit with I2C" + depends on I2C && OF + select MFD_CORE + select REGMAP_I2C + help + Support for the Renesas Synchronization Management Unit, such as + Clockmatrix and 82P33XXX series. This option supports I2C as + the control interface. + + This driver provides common support for accessing the device. + Additional drivers must be enabled in order to use the functionality + of the device. + +config MFD_RSMU_SPI + tristate "Renesas Synchronization Management Unit with SPI" + depends on SPI && OF + select MFD_CORE + select REGMAP_SPI + help + Support for the Renesas Synchronization Management Unit, such as + Clockmatrix and 82P33XXX series. This option supports SPI as + the control interface. + + This driver provides common support for accessing the device. + Additional drivers must be enabled in order to use the functionality + of the device. + endmenu endif diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8116c19d5fd4..54e37704f74b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -272,3 +272,8 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC) += intel-m10-bmc.o obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o + +rsmu-i2c-objs := rsmu_core.o rsmu_i2c.o +rsmu-spi-objs := rsmu_core.o rsmu_spi.o +obj-$(CONFIG_MFD_RSMU_I2C) += rsmu-i2c.o +obj-$(CONFIG_MFD_RSMU_SPI) += rsmu-spi.o diff --git a/drivers/mfd/rsmu.h b/drivers/mfd/rsmu.h new file mode 100644 index 000000000000..bb88597d189f --- /dev/null +++ b/drivers/mfd/rsmu.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Renesas Synchronization Management Unit (SMU) devices. + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ + +#ifndef __RSMU_MFD_H +#define __RSMU_MFD_H + +#include + +int rsmu_core_init(struct rsmu_ddata *rsmu); +void rsmu_core_exit(struct rsmu_ddata *rsmu); + +#endif /* __RSMU_MFD_H */ diff --git a/drivers/mfd/rsmu_core.c b/drivers/mfd/rsmu_core.c new file mode 100644 index 000000000000..29437fd0bd5b --- /dev/null +++ b/drivers/mfd/rsmu_core.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Core driver for Renesas Synchronization Management Unit (SMU) devices. + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rsmu.h" + +enum { + RSMU_PHC = 0, + RSMU_CDEV = 1, + RSMU_N_DEVS = 2, +}; + +static struct mfd_cell rsmu_cm_devs[] = { + [RSMU_PHC] = { + .name = "8a3400x-phc", + }, + [RSMU_CDEV] = { + .name = "8a3400x-cdev", + }, +}; + +static struct mfd_cell rsmu_sabre_devs[] = { + [RSMU_PHC] = { + .name = "82p33x1x-phc", + }, + [RSMU_CDEV] = { + .name = "82p33x1x-cdev", + }, +}; + +static struct mfd_cell rsmu_sl_devs[] = { + [RSMU_PHC] = { + .name = "8v19n85x-phc", + }, + [RSMU_CDEV] = { + .name = "8v19n85x-cdev", + }, +}; + +int rsmu_core_init(struct rsmu_ddata *rsmu) +{ + struct mfd_cell *cells; + int ret; + + switch (rsmu->type) { + case RSMU_CM: + cells = rsmu_cm_devs; + break; + case RSMU_SABRE: + cells = rsmu_sabre_devs; + break; + case RSMU_SL: + cells = rsmu_sl_devs; + break; + default: + dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); + return -ENODEV; + } + + mutex_init(&rsmu->lock); + + ret = devm_mfd_add_devices(rsmu->dev, PLATFORM_DEVID_AUTO, cells, + RSMU_N_DEVS, NULL, 0, NULL); + if (ret < 0) + dev_err(rsmu->dev, "Failed to register sub-devices: %d\n", ret); + + return ret; +} + +void rsmu_core_exit(struct rsmu_ddata *rsmu) +{ + mutex_destroy(&rsmu->lock); +} + +MODULE_DESCRIPTION("Renesas SMU core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/rsmu_i2c.c b/drivers/mfd/rsmu_i2c.c new file mode 100644 index 000000000000..dc001c9791c1 --- /dev/null +++ b/drivers/mfd/rsmu_i2c.c @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * I2C driver for Renesas Synchronization Management Unit (SMU) devices. + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rsmu.h" + +/* + * 16-bit register address: the lower 8 bits of the register address come + * from the offset addr byte and the upper 8 bits come from the page register. + */ +#define RSMU_CM_PAGE_ADDR 0xFD +#define RSMU_CM_PAGE_WINDOW 256 + +/* + * 15-bit register address: the lower 7 bits of the register address come + * from the offset addr byte and the upper 8 bits come from the page register. + */ +#define RSMU_SABRE_PAGE_ADDR 0x7F +#define RSMU_SABRE_PAGE_WINDOW 128 + +static const struct regmap_range_cfg rsmu_cm_range_cfg[] = { + { + .range_min = 0, + .range_max = 0xD000, + .selector_reg = RSMU_CM_PAGE_ADDR, + .selector_mask = 0xFF, + .selector_shift = 0, + .window_start = 0, + .window_len = RSMU_CM_PAGE_WINDOW, + } +}; + +static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = { + { + .range_min = 0, + .range_max = 0x400, + .selector_reg = RSMU_SABRE_PAGE_ADDR, + .selector_mask = 0xFF, + .selector_shift = 0, + .window_start = 0, + .window_len = RSMU_SABRE_PAGE_WINDOW, + } +}; + +static bool rsmu_cm_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RSMU_CM_PAGE_ADDR: + return false; + default: + return true; + } +} + +static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RSMU_SABRE_PAGE_ADDR: + return false; + default: + return true; + } +} + +static const struct regmap_config rsmu_cm_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0xD000, + .ranges = rsmu_cm_range_cfg, + .num_ranges = ARRAY_SIZE(rsmu_cm_range_cfg), + .volatile_reg = rsmu_cm_volatile_reg, + .cache_type = REGCACHE_RBTREE, + .can_multi_write = true, +}; + +static const struct regmap_config rsmu_sabre_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x400, + .ranges = rsmu_sabre_range_cfg, + .num_ranges = ARRAY_SIZE(rsmu_sabre_range_cfg), + .volatile_reg = rsmu_sabre_volatile_reg, + .cache_type = REGCACHE_RBTREE, + .can_multi_write = true, +}; + +static const struct regmap_config rsmu_sl_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .max_register = 0x339, + .cache_type = REGCACHE_NONE, + .can_multi_write = true, +}; + +static int rsmu_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct regmap_config *cfg; + struct rsmu_ddata *rsmu; + int ret; + + rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL); + if (!rsmu) + return -ENOMEM; + + i2c_set_clientdata(client, rsmu); + + rsmu->dev = &client->dev; + rsmu->type = (enum rsmu_type)id->driver_data; + + switch (rsmu->type) { + case RSMU_CM: + cfg = &rsmu_cm_regmap_config; + break; + case RSMU_SABRE: + cfg = &rsmu_sabre_regmap_config; + break; + case RSMU_SL: + cfg = &rsmu_sl_regmap_config; + break; + default: + dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); + return -ENODEV; + } + rsmu->regmap = devm_regmap_init_i2c(client, cfg); + if (IS_ERR(rsmu->regmap)) { + ret = PTR_ERR(rsmu->regmap); + dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + + return rsmu_core_init(rsmu); +} + +static int rsmu_i2c_remove(struct i2c_client *client) +{ + struct rsmu_ddata *rsmu = i2c_get_clientdata(client); + + rsmu_core_exit(rsmu); + + return 0; +} + +static const struct i2c_device_id rsmu_i2c_id[] = { + { "8a34000", RSMU_CM }, + { "8a34001", RSMU_CM }, + { "82p33810", RSMU_SABRE }, + { "82p33811", RSMU_SABRE }, + { "8v19n850", RSMU_SL }, + { "8v19n851", RSMU_SL }, + {} +}; +MODULE_DEVICE_TABLE(i2c, rsmu_i2c_id); + +static const struct of_device_id rsmu_i2c_of_match[] = { + { .compatible = "idt,8a34000", .data = (void *)RSMU_CM }, + { .compatible = "idt,8a34001", .data = (void *)RSMU_CM }, + { .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE }, + { .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE }, + { .compatible = "idt,8v19n850", .data = (void *)RSMU_SL }, + { .compatible = "idt,8v19n851", .data = (void *)RSMU_SL }, + {} +}; +MODULE_DEVICE_TABLE(of, rsmu_i2c_of_match); + +static struct i2c_driver rsmu_i2c_driver = { + .driver = { + .name = "rsmu-i2c", + .of_match_table = of_match_ptr(rsmu_i2c_of_match), + }, + .probe = rsmu_i2c_probe, + .remove = rsmu_i2c_remove, + .id_table = rsmu_i2c_id, +}; + +static int __init rsmu_i2c_init(void) +{ + return i2c_add_driver(&rsmu_i2c_driver); +} +subsys_initcall(rsmu_i2c_init); + +static void __exit rsmu_i2c_exit(void) +{ + i2c_del_driver(&rsmu_i2c_driver); +} +module_exit(rsmu_i2c_exit); + +MODULE_DESCRIPTION("Renesas SMU I2C driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/rsmu_spi.c b/drivers/mfd/rsmu_spi.c new file mode 100644 index 000000000000..fec2b4ec477c --- /dev/null +++ b/drivers/mfd/rsmu_spi.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * SPI driver for Renesas Synchronization Management Unit (SMU) devices. + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rsmu.h" + +#define RSMU_CM_PAGE_ADDR 0x7C +#define RSMU_SABRE_PAGE_ADDR 0x7F +#define RSMU_HIGHER_ADDR_MASK 0xFF80 +#define RSMU_HIGHER_ADDR_SHIFT 7 +#define RSMU_LOWER_ADDR_MASK 0x7F + +static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) +{ + struct spi_device *client = to_spi_device(rsmu->dev); + struct spi_transfer xfer = {0}; + struct spi_message msg; + u8 cmd[256] = {0}; + u8 rsp[256] = {0}; + int ret; + + cmd[0] = reg | 0x80; + xfer.rx_buf = rsp; + xfer.len = bytes + 1; + xfer.tx_buf = cmd; + xfer.bits_per_word = client->bits_per_word; + xfer.speed_hz = client->max_speed_hz; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + /* + * 4-wire SPI is a shift register, so for every byte you send, + * you get one back at the same time. Example read from 0xC024, + * which has value of 0x2D + * + * MOSI: + * 7C 00 C0 #Set page register + * A4 00 #MSB is set, so this is read command + * MISO: + * XX 2D #XX is a dummy byte from sending A4 and we + * need to throw it away + */ + ret = spi_sync(client, &msg); + if (ret >= 0) + memcpy(buf, &rsp[1], xfer.len-1); + + return ret; +} + +static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) +{ + struct spi_device *client = to_spi_device(rsmu->dev); + struct spi_transfer xfer = {0}; + struct spi_message msg; + u8 cmd[256] = {0}; + + cmd[0] = reg; + memcpy(&cmd[1], buf, bytes); + + xfer.len = bytes + 1; + xfer.tx_buf = cmd; + xfer.bits_per_word = client->bits_per_word; + xfer.speed_hz = client->max_speed_hz; + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + + return spi_sync(client, &msg); +} + +/* + * 1-byte (1B) offset addressing: + * 16-bit register address: the lower 7 bits of the register address come + * from the offset addr byte and the upper 9 bits come from the page register. + */ +static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg) +{ + u8 page_reg; + u8 buf[2]; + u16 bytes; + u16 page; + int err; + + switch (rsmu->type) { + case RSMU_CM: + page_reg = RSMU_CM_PAGE_ADDR; + page = reg & RSMU_HIGHER_ADDR_MASK; + buf[0] = (u8)(page & 0xff); + buf[1] = (u8)((page >> 8) & 0xff); + bytes = 2; + break; + case RSMU_SABRE: + page_reg = RSMU_SABRE_PAGE_ADDR; + page = reg >> RSMU_HIGHER_ADDR_SHIFT; + buf[0] = (u8)(page & 0xff); + bytes = 1; + break; + default: + dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); + return -ENODEV; + } + + /* Simply return if we are on the same page */ + if (rsmu->page == page) + return 0; + + err = rsmu_write_device(rsmu, page_reg, buf, bytes); + if (err) + dev_err(rsmu->dev, "Failed to set page offset 0x%x\n", page); + else + /* Remember the last page */ + rsmu->page = page; + + return err; +} + +static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); + u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); + int err; + + err = rsmu_write_page_register(rsmu, reg); + if (err) + return err; + + err = rsmu_read_device(rsmu, addr, (u8 *)val, 1); + if (err) + dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr); + + return err; +} + +static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); + u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); + u8 data = (u8)val; + int err; + + err = rsmu_write_page_register(rsmu, reg); + if (err) + return err; + + err = rsmu_write_device(rsmu, addr, &data, 1); + if (err) + dev_err(rsmu->dev, + "Failed to write offset address 0x%x\n", addr); + + return err; +} + +static const struct regmap_config rsmu_cm_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xD000, + .reg_read = rsmu_reg_read, + .reg_write = rsmu_reg_write, + .cache_type = REGCACHE_NONE, +}; + +static const struct regmap_config rsmu_sabre_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0x400, + .reg_read = rsmu_reg_read, + .reg_write = rsmu_reg_write, + .cache_type = REGCACHE_NONE, +}; + +static int rsmu_spi_probe(struct spi_device *client) +{ + const struct spi_device_id *id = spi_get_device_id(client); + const struct regmap_config *cfg; + struct rsmu_ddata *rsmu; + int ret; + + rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL); + if (!rsmu) + return -ENOMEM; + + spi_set_drvdata(client, rsmu); + + rsmu->dev = &client->dev; + rsmu->type = (enum rsmu_type)id->driver_data; + + /* Initialize regmap */ + switch (rsmu->type) { + case RSMU_CM: + cfg = &rsmu_cm_regmap_config; + break; + case RSMU_SABRE: + cfg = &rsmu_sabre_regmap_config; + break; + default: + dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); + return -ENODEV; + } + + rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg); + if (IS_ERR(rsmu->regmap)) { + ret = PTR_ERR(rsmu->regmap); + dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret); + return ret; + } + + return rsmu_core_init(rsmu); +} + +static int rsmu_spi_remove(struct spi_device *client) +{ + struct rsmu_ddata *rsmu = spi_get_drvdata(client); + + rsmu_core_exit(rsmu); + + return 0; +} + +static const struct spi_device_id rsmu_spi_id[] = { + { "8a34000", RSMU_CM }, + { "8a34001", RSMU_CM }, + { "82p33810", RSMU_SABRE }, + { "82p33811", RSMU_SABRE }, + {} +}; +MODULE_DEVICE_TABLE(spi, rsmu_spi_id); + +static const struct of_device_id rsmu_spi_of_match[] = { + { .compatible = "idt,8a34000", .data = (void *)RSMU_CM }, + { .compatible = "idt,8a34001", .data = (void *)RSMU_CM }, + { .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE }, + { .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE }, + {} +}; +MODULE_DEVICE_TABLE(of, rsmu_spi_of_match); + +static struct spi_driver rsmu_spi_driver = { + .driver = { + .name = "rsmu-spi", + .of_match_table = of_match_ptr(rsmu_spi_of_match), + }, + .probe = rsmu_spi_probe, + .remove = rsmu_spi_remove, + .id_table = rsmu_spi_id, +}; + +static int __init rsmu_spi_init(void) +{ + return spi_register_driver(&rsmu_spi_driver); +} +subsys_initcall(rsmu_spi_init); + +static void __exit rsmu_spi_exit(void) +{ + spi_unregister_driver(&rsmu_spi_driver); +} +module_exit(rsmu_spi_exit); + +MODULE_DESCRIPTION("Renesas SMU SPI driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/idt82p33_reg.h b/include/linux/mfd/idt82p33_reg.h new file mode 100644 index 000000000000..129a6c078221 --- /dev/null +++ b/include/linux/mfd/idt82p33_reg.h @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Register Map - Based on AN888_SMUforIEEE_SynchEther_82P33xxx_RevH.pdf + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ +#ifndef HAVE_IDT82P33_REG +#define HAVE_IDT82P33_REG + +/* Register address */ +#define DPLL1_TOD_CNFG 0x134 +#define DPLL2_TOD_CNFG 0x1B4 + +#define DPLL1_TOD_STS 0x10B +#define DPLL2_TOD_STS 0x18B + +#define DPLL1_TOD_TRIGGER 0x115 +#define DPLL2_TOD_TRIGGER 0x195 + +#define DPLL1_OPERATING_MODE_CNFG 0x120 +#define DPLL2_OPERATING_MODE_CNFG 0x1A0 + +#define DPLL1_HOLDOVER_FREQ_CNFG 0x12C +#define DPLL2_HOLDOVER_FREQ_CNFG 0x1AC + +#define DPLL1_PHASE_OFFSET_CNFG 0x143 +#define DPLL2_PHASE_OFFSET_CNFG 0x1C3 + +#define DPLL1_SYNC_EDGE_CNFG 0x140 +#define DPLL2_SYNC_EDGE_CNFG 0x1C0 + +#define DPLL1_INPUT_MODE_CNFG 0x116 +#define DPLL2_INPUT_MODE_CNFG 0x196 + +#define DPLL1_OPERATING_STS 0x102 +#define DPLL2_OPERATING_STS 0x182 + +#define DPLL1_CURRENT_FREQ_STS 0x103 +#define DPLL2_CURRENT_FREQ_STS 0x183 + +#define REG_SOFT_RESET 0X381 + +#define OUT_MUX_CNFG(outn) REG_ADDR(0x6, (0xC * (outn))) + +/* Register bit definitions */ +#define SYNC_TOD BIT(1) +#define PH_OFFSET_EN BIT(7) +#define SQUELCH_ENABLE BIT(5) + +/* Bit definitions for the DPLL_MODE register */ +#define PLL_MODE_SHIFT (0) +#define PLL_MODE_MASK (0x1F) +#define COMBO_MODE_EN BIT(5) +#define COMBO_MODE_SHIFT (6) +#define COMBO_MODE_MASK (0x3) + +/* Bit definitions for DPLL_OPERATING_STS register */ +#define OPERATING_STS_MASK (0x7) +#define OPERATING_STS_SHIFT (0x0) + +/* Bit definitions for DPLL_TOD_TRIGGER register */ +#define READ_TRIGGER_MASK (0xF) +#define READ_TRIGGER_SHIFT (0x0) +#define WRITE_TRIGGER_MASK (0xF0) +#define WRITE_TRIGGER_SHIFT (0x4) + +/* Bit definitions for REG_SOFT_RESET register */ +#define SOFT_RESET_EN BIT(7) + +enum pll_mode { + PLL_MODE_MIN = 0, + PLL_MODE_AUTOMATIC = PLL_MODE_MIN, + PLL_MODE_FORCE_FREERUN = 1, + PLL_MODE_FORCE_HOLDOVER = 2, + PLL_MODE_FORCE_LOCKED = 4, + PLL_MODE_FORCE_PRE_LOCKED2 = 5, + PLL_MODE_FORCE_PRE_LOCKED = 6, + PLL_MODE_FORCE_LOST_PHASE = 7, + PLL_MODE_DCO = 10, + PLL_MODE_WPH = 18, + PLL_MODE_MAX = PLL_MODE_WPH, +}; + +enum hw_tod_trig_sel { + HW_TOD_TRIG_SEL_MIN = 0, + HW_TOD_TRIG_SEL_NO_WRITE = HW_TOD_TRIG_SEL_MIN, + HW_TOD_TRIG_SEL_NO_READ = HW_TOD_TRIG_SEL_MIN, + HW_TOD_TRIG_SEL_SYNC_SEL = 1, + HW_TOD_TRIG_SEL_IN12 = 2, + HW_TOD_TRIG_SEL_IN13 = 3, + HW_TOD_TRIG_SEL_IN14 = 4, + HW_TOD_TRIG_SEL_TOD_PPS = 5, + HW_TOD_TRIG_SEL_TIMER_INTERVAL = 6, + HW_TOD_TRIG_SEL_MSB_PHASE_OFFSET_CNFG = 7, + HW_TOD_TRIG_SEL_MSB_HOLDOVER_FREQ_CNFG = 8, + HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG = 9, + HW_TOD_RD_TRIG_SEL_LSB_TOD_STS = HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG, + WR_TRIG_SEL_MAX = HW_TOD_WR_TRIG_SEL_MSB_TOD_CNFG, +}; + +/** @brief Enumerated type listing DPLL operational modes */ +enum dpll_state { + DPLL_STATE_FREERUN = 1, + DPLL_STATE_HOLDOVER = 2, + DPLL_STATE_LOCKED = 4, + DPLL_STATE_PRELOCKED2 = 5, + DPLL_STATE_PRELOCKED = 6, + DPLL_STATE_LOSTPHASE = 7, + DPLL_STATE_MAX +}; + +#endif diff --git a/include/linux/mfd/idt8a340_reg.h b/include/linux/mfd/idt8a340_reg.h new file mode 100644 index 000000000000..92d763230bdf --- /dev/null +++ b/include/linux/mfd/idt8a340_reg.h @@ -0,0 +1,729 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Based on 5.2.0, Family Programming Guide (Sept 30, 2020) + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ +#ifndef HAVE_IDT8A340_REG +#define HAVE_IDT8A340_REG + +#define PAGE_ADDR_BASE 0x0000 +#define PAGE_ADDR 0x00fc + +#define HW_REVISION 0x8180 +#define REV_ID 0x007a + +#define HW_DPLL_0 (0x8a00) +#define HW_DPLL_1 (0x8b00) +#define HW_DPLL_2 (0x8c00) +#define HW_DPLL_3 (0x8d00) +#define HW_DPLL_4 (0x8e00) +#define HW_DPLL_5 (0x8f00) +#define HW_DPLL_6 (0x9000) +#define HW_DPLL_7 (0x9100) + +#define HW_DPLL_TOD_SW_TRIG_ADDR__0 (0x080) +#define HW_DPLL_TOD_CTRL_1 (0x089) +#define HW_DPLL_TOD_CTRL_2 (0x08A) +#define HW_DPLL_TOD_OVR__0 (0x098) +#define HW_DPLL_TOD_OUT_0__0 (0x0B0) + +#define HW_Q0_Q1_CH_SYNC_CTRL_0 (0xa740) +#define HW_Q0_Q1_CH_SYNC_CTRL_1 (0xa741) +#define HW_Q2_Q3_CH_SYNC_CTRL_0 (0xa742) +#define HW_Q2_Q3_CH_SYNC_CTRL_1 (0xa743) +#define HW_Q4_Q5_CH_SYNC_CTRL_0 (0xa744) +#define HW_Q4_Q5_CH_SYNC_CTRL_1 (0xa745) +#define HW_Q6_Q7_CH_SYNC_CTRL_0 (0xa746) +#define HW_Q6_Q7_CH_SYNC_CTRL_1 (0xa747) +#define HW_Q8_CH_SYNC_CTRL_0 (0xa748) +#define HW_Q8_CH_SYNC_CTRL_1 (0xa749) +#define HW_Q9_CH_SYNC_CTRL_0 (0xa74a) +#define HW_Q9_CH_SYNC_CTRL_1 (0xa74b) +#define HW_Q10_CH_SYNC_CTRL_0 (0xa74c) +#define HW_Q10_CH_SYNC_CTRL_1 (0xa74d) +#define HW_Q11_CH_SYNC_CTRL_0 (0xa74e) +#define HW_Q11_CH_SYNC_CTRL_1 (0xa74f) + +#define SYNC_SOURCE_DPLL0_TOD_PPS 0x14 +#define SYNC_SOURCE_DPLL1_TOD_PPS 0x15 +#define SYNC_SOURCE_DPLL2_TOD_PPS 0x16 +#define SYNC_SOURCE_DPLL3_TOD_PPS 0x17 + +#define SYNCTRL1_MASTER_SYNC_RST BIT(7) +#define SYNCTRL1_MASTER_SYNC_TRIG BIT(5) +#define SYNCTRL1_TOD_SYNC_TRIG BIT(4) +#define SYNCTRL1_FBDIV_FRAME_SYNC_TRIG BIT(3) +#define SYNCTRL1_FBDIV_SYNC_TRIG BIT(2) +#define SYNCTRL1_Q1_DIV_SYNC_TRIG BIT(1) +#define SYNCTRL1_Q0_DIV_SYNC_TRIG BIT(0) + +#define HW_Q8_CTRL_SPARE (0xa7d4) +#define HW_Q11_CTRL_SPARE (0xa7ec) + +/** + * Select FOD5 as sync_trigger for Q8 divider. + * Transition from logic zero to one + * sets trigger to sync Q8 divider. + * + * Unused when FOD4 is driving Q8 divider (normal operation). + */ +#define Q9_TO_Q8_SYNC_TRIG BIT(1) + +/** + * Enable FOD5 as driver for clock and sync for Q8 divider. + * Enable fanout buffer for FOD5. + * + * Unused when FOD4 is driving Q8 divider (normal operation). + */ +#define Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK (BIT(0) | BIT(2)) + +/** + * Select FOD6 as sync_trigger for Q11 divider. + * Transition from logic zero to one + * sets trigger to sync Q11 divider. + * + * Unused when FOD7 is driving Q11 divider (normal operation). + */ +#define Q10_TO_Q11_SYNC_TRIG BIT(1) + +/** + * Enable FOD6 as driver for clock and sync for Q11 divider. + * Enable fanout buffer for FOD6. + * + * Unused when FOD7 is driving Q11 divider (normal operation). + */ +#define Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK (BIT(0) | BIT(2)) + +#define RESET_CTRL 0xc000 +#define SM_RESET 0x0012 +#define SM_RESET_V520 0x0013 +#define SM_RESET_CMD 0x5A + +#define GENERAL_STATUS 0xc014 +#define BOOT_STATUS 0x0000 +#define HW_REV_ID 0x000A +#define BOND_ID 0x000B +#define HW_CSR_ID 0x000C +#define HW_IRQ_ID 0x000E +#define MAJ_REL 0x0010 +#define MIN_REL 0x0011 +#define HOTFIX_REL 0x0012 +#define PIPELINE_ID 0x0014 +#define BUILD_ID 0x0018 +#define JTAG_DEVICE_ID 0x001c +#define PRODUCT_ID 0x001e +#define OTP_SCSR_CONFIG_SELECT 0x0022 + +#define STATUS 0xc03c +#define DPLL0_STATUS 0x0018 +#define DPLL1_STATUS 0x0019 +#define DPLL2_STATUS 0x001a +#define DPLL3_STATUS 0x001b +#define DPLL4_STATUS 0x001c +#define DPLL5_STATUS 0x001d +#define DPLL6_STATUS 0x001e +#define DPLL7_STATUS 0x001f +#define DPLL_SYS_STATUS 0x0020 +#define DPLL_SYS_APLL_STATUS 0x0021 +#define DPLL0_FILTER_STATUS 0x0044 +#define DPLL1_FILTER_STATUS 0x004c +#define DPLL2_FILTER_STATUS 0x0054 +#define DPLL3_FILTER_STATUS 0x005c +#define DPLL4_FILTER_STATUS 0x0064 +#define DPLL5_FILTER_STATUS 0x006c +#define DPLL6_FILTER_STATUS 0x0074 +#define DPLL7_FILTER_STATUS 0x007c +#define DPLLSYS_FILTER_STATUS 0x0084 +#define USER_GPIO0_TO_7_STATUS 0x008a +#define USER_GPIO8_TO_15_STATUS 0x008b + +#define GPIO_USER_CONTROL 0xc160 +#define GPIO0_TO_7_OUT 0x0000 +#define GPIO8_TO_15_OUT 0x0001 +#define GPIO0_TO_7_OUT_V520 0x0002 +#define GPIO8_TO_15_OUT_V520 0x0003 + +#define STICKY_STATUS_CLEAR 0xc164 + +#define GPIO_TOD_NOTIFICATION_CLEAR 0xc16c + +#define ALERT_CFG 0xc188 + +#define SYS_DPLL_XO 0xc194 + +#define SYS_APLL 0xc19c + +#define INPUT_0 0xc1b0 +#define INPUT_1 0xc1c0 +#define INPUT_2 0xc1d0 +#define INPUT_3 0xc200 +#define INPUT_4 0xc210 +#define INPUT_5 0xc220 +#define INPUT_6 0xc230 +#define INPUT_7 0xc240 +#define INPUT_8 0xc250 +#define INPUT_9 0xc260 +#define INPUT_10 0xc280 +#define INPUT_11 0xc290 +#define INPUT_12 0xc2a0 +#define INPUT_13 0xc2b0 +#define INPUT_14 0xc2c0 +#define INPUT_15 0xc2d0 + +#define REF_MON_0 0xc2e0 +#define REF_MON_1 0xc2ec +#define REF_MON_2 0xc300 +#define REF_MON_3 0xc30c +#define REF_MON_4 0xc318 +#define REF_MON_5 0xc324 +#define REF_MON_6 0xc330 +#define REF_MON_7 0xc33c +#define REF_MON_8 0xc348 +#define REF_MON_9 0xc354 +#define REF_MON_10 0xc360 +#define REF_MON_11 0xc36c +#define REF_MON_12 0xc380 +#define REF_MON_13 0xc38c +#define REF_MON_14 0xc398 +#define REF_MON_15 0xc3a4 + +#define DPLL_0 0xc3b0 +#define DPLL_CTRL_REG_0 0x0002 +#define DPLL_CTRL_REG_1 0x0003 +#define DPLL_CTRL_REG_2 0x0004 +#define DPLL_TOD_SYNC_CFG 0x0031 +#define DPLL_COMBO_SLAVE_CFG_0 0x0032 +#define DPLL_COMBO_SLAVE_CFG_1 0x0033 +#define DPLL_SLAVE_REF_CFG 0x0034 +#define DPLL_REF_MODE 0x0035 +#define DPLL_PHASE_MEASUREMENT_CFG 0x0036 +#define DPLL_MODE 0x0037 +#define DPLL_MODE_V520 0x003B +#define DPLL_1 0xc400 +#define DPLL_2 0xc438 +#define DPLL_2_V520 0xc43c +#define DPLL_3 0xc480 +#define DPLL_4 0xc4b8 +#define DPLL_4_V520 0xc4bc +#define DPLL_5 0xc500 +#define DPLL_6 0xc538 +#define DPLL_6_V520 0xc53c +#define DPLL_7 0xc580 +#define SYS_DPLL 0xc5b8 +#define SYS_DPLL_V520 0xc5bc + +#define DPLL_CTRL_0 0xc600 +#define DPLL_CTRL_DPLL_MANU_REF_CFG 0x0001 +#define DPLL_CTRL_DPLL_FOD_FREQ 0x001c +#define DPLL_CTRL_COMBO_MASTER_CFG 0x003a +#define DPLL_CTRL_1 0xc63c +#define DPLL_CTRL_2 0xc680 +#define DPLL_CTRL_3 0xc6bc +#define DPLL_CTRL_4 0xc700 +#define DPLL_CTRL_5 0xc73c +#define DPLL_CTRL_6 0xc780 +#define DPLL_CTRL_7 0xc7bc +#define SYS_DPLL_CTRL 0xc800 + +#define DPLL_PHASE_0 0xc818 +/* Signed 42-bit FFO in units of 2^(-53) */ +#define DPLL_WR_PHASE 0x0000 +#define DPLL_PHASE_1 0xc81c +#define DPLL_PHASE_2 0xc820 +#define DPLL_PHASE_3 0xc824 +#define DPLL_PHASE_4 0xc828 +#define DPLL_PHASE_5 0xc82c +#define DPLL_PHASE_6 0xc830 +#define DPLL_PHASE_7 0xc834 + +#define DPLL_FREQ_0 0xc838 +/* Signed 42-bit FFO in units of 2^(-53) */ +#define DPLL_WR_FREQ 0x0000 +#define DPLL_FREQ_1 0xc840 +#define DPLL_FREQ_2 0xc848 +#define DPLL_FREQ_3 0xc850 +#define DPLL_FREQ_4 0xc858 +#define DPLL_FREQ_5 0xc860 +#define DPLL_FREQ_6 0xc868 +#define DPLL_FREQ_7 0xc870 + +#define DPLL_PHASE_PULL_IN_0 0xc880 +#define PULL_IN_OFFSET 0x0000 /* Signed 32 bit */ +#define PULL_IN_SLOPE_LIMIT 0x0004 /* Unsigned 24 bit */ +#define PULL_IN_CTRL 0x0007 +#define DPLL_PHASE_PULL_IN_1 0xc888 +#define DPLL_PHASE_PULL_IN_2 0xc890 +#define DPLL_PHASE_PULL_IN_3 0xc898 +#define DPLL_PHASE_PULL_IN_4 0xc8a0 +#define DPLL_PHASE_PULL_IN_5 0xc8a8 +#define DPLL_PHASE_PULL_IN_6 0xc8b0 +#define DPLL_PHASE_PULL_IN_7 0xc8b8 + +#define GPIO_CFG 0xc8c0 +#define GPIO_CFG_GBL 0x0000 +#define GPIO_0 0xc8c2 +#define GPIO_DCO_INC_DEC 0x0000 +#define GPIO_OUT_CTRL_0 0x0001 +#define GPIO_OUT_CTRL_1 0x0002 +#define GPIO_TOD_TRIG 0x0003 +#define GPIO_DPLL_INDICATOR 0x0004 +#define GPIO_LOS_INDICATOR 0x0005 +#define GPIO_REF_INPUT_DSQ_0 0x0006 +#define GPIO_REF_INPUT_DSQ_1 0x0007 +#define GPIO_REF_INPUT_DSQ_2 0x0008 +#define GPIO_REF_INPUT_DSQ_3 0x0009 +#define GPIO_MAN_CLK_SEL_0 0x000a +#define GPIO_MAN_CLK_SEL_1 0x000b +#define GPIO_MAN_CLK_SEL_2 0x000c +#define GPIO_SLAVE 0x000d +#define GPIO_ALERT_OUT_CFG 0x000e +#define GPIO_TOD_NOTIFICATION_CFG 0x000f +#define GPIO_CTRL 0x0010 +#define GPIO_CTRL_V520 0x0011 +#define GPIO_1 0xc8d4 +#define GPIO_2 0xc8e6 +#define GPIO_3 0xc900 +#define GPIO_4 0xc912 +#define GPIO_5 0xc924 +#define GPIO_6 0xc936 +#define GPIO_7 0xc948 +#define GPIO_8 0xc95a +#define GPIO_9 0xc980 +#define GPIO_10 0xc992 +#define GPIO_11 0xc9a4 +#define GPIO_12 0xc9b6 +#define GPIO_13 0xc9c8 +#define GPIO_14 0xc9da +#define GPIO_15 0xca00 + +#define OUT_DIV_MUX 0xca12 +#define OUTPUT_0 0xca14 +#define OUTPUT_0_V520 0xca20 +/* FOD frequency output divider value */ +#define OUT_DIV 0x0000 +#define OUT_DUTY_CYCLE_HIGH 0x0004 +#define OUT_CTRL_0 0x0008 +#define OUT_CTRL_1 0x0009 +/* Phase adjustment in FOD cycles */ +#define OUT_PHASE_ADJ 0x000c +#define OUTPUT_1 0xca24 +#define OUTPUT_1_V520 0xca30 +#define OUTPUT_2 0xca34 +#define OUTPUT_2_V520 0xca40 +#define OUTPUT_3 0xca44 +#define OUTPUT_3_V520 0xca50 +#define OUTPUT_4 0xca54 +#define OUTPUT_4_V520 0xca60 +#define OUTPUT_5 0xca64 +#define OUTPUT_5_V520 0xca80 +#define OUTPUT_6 0xca80 +#define OUTPUT_6_V520 0xca90 +#define OUTPUT_7 0xca90 +#define OUTPUT_7_V520 0xcaa0 +#define OUTPUT_8 0xcaa0 +#define OUTPUT_8_V520 0xcab0 +#define OUTPUT_9 0xcab0 +#define OUTPUT_9_V520 0xcac0 +#define OUTPUT_10 0xcac0 +#define OUTPUT_10_V520 0xcad0 +#define OUTPUT_11 0xcad0 +#define OUTPUT_11_V520 0xcae0 + +#define SERIAL 0xcae0 +#define SERIAL_V520 0xcaf0 + +#define PWM_ENCODER_0 0xcb00 +#define PWM_ENCODER_1 0xcb08 +#define PWM_ENCODER_2 0xcb10 +#define PWM_ENCODER_3 0xcb18 +#define PWM_ENCODER_4 0xcb20 +#define PWM_ENCODER_5 0xcb28 +#define PWM_ENCODER_6 0xcb30 +#define PWM_ENCODER_7 0xcb38 +#define PWM_DECODER_0 0xcb40 +#define PWM_DECODER_1 0xcb48 +#define PWM_DECODER_1_V520 0xcb4a +#define PWM_DECODER_2 0xcb50 +#define PWM_DECODER_2_V520 0xcb54 +#define PWM_DECODER_3 0xcb58 +#define PWM_DECODER_3_V520 0xcb5e +#define PWM_DECODER_4 0xcb60 +#define PWM_DECODER_4_V520 0xcb68 +#define PWM_DECODER_5 0xcb68 +#define PWM_DECODER_5_V520 0xcb80 +#define PWM_DECODER_6 0xcb70 +#define PWM_DECODER_6_V520 0xcb8a +#define PWM_DECODER_7 0xcb80 +#define PWM_DECODER_7_V520 0xcb94 +#define PWM_DECODER_8 0xcb88 +#define PWM_DECODER_8_V520 0xcb9e +#define PWM_DECODER_9 0xcb90 +#define PWM_DECODER_9_V520 0xcba8 +#define PWM_DECODER_10 0xcb98 +#define PWM_DECODER_10_V520 0xcbb2 +#define PWM_DECODER_11 0xcba0 +#define PWM_DECODER_11_V520 0xcbbc +#define PWM_DECODER_12 0xcba8 +#define PWM_DECODER_12_V520 0xcbc6 +#define PWM_DECODER_13 0xcbb0 +#define PWM_DECODER_13_V520 0xcbd0 +#define PWM_DECODER_14 0xcbb8 +#define PWM_DECODER_14_V520 0xcbda +#define PWM_DECODER_15 0xcbc0 +#define PWM_DECODER_15_V520 0xcbe4 +#define PWM_USER_DATA 0xcbc8 +#define PWM_USER_DATA_V520 0xcbf0 + +#define TOD_0 0xcbcc +#define TOD_0_V520 0xcc00 +/* Enable TOD counter, output channel sync and even-PPS mode */ +#define TOD_CFG 0x0000 +#define TOD_CFG_V520 0x0001 +#define TOD_1 0xcbce +#define TOD_1_V520 0xcc02 +#define TOD_2 0xcbd0 +#define TOD_2_V520 0xcc04 +#define TOD_3 0xcbd2 +#define TOD_3_V520 0xcc06 + +#define TOD_WRITE_0 0xcc00 +#define TOD_WRITE_0_V520 0xcc10 +/* 8-bit subns, 32-bit ns, 48-bit seconds */ +#define TOD_WRITE 0x0000 +/* Counter increments after TOD write is completed */ +#define TOD_WRITE_COUNTER 0x000c +/* TOD write trigger configuration */ +#define TOD_WRITE_SELECT_CFG_0 0x000d +/* TOD write trigger selection */ +#define TOD_WRITE_CMD 0x000f +#define TOD_WRITE_1 0xcc10 +#define TOD_WRITE_1_V520 0xcc20 +#define TOD_WRITE_2 0xcc20 +#define TOD_WRITE_2_V520 0xcc30 +#define TOD_WRITE_3 0xcc30 +#define TOD_WRITE_3_V520 0xcc40 + +#define TOD_READ_PRIMARY_0 0xcc40 +#define TOD_READ_PRIMARY_0_V520 0xcc50 +/* 8-bit subns, 32-bit ns, 48-bit seconds */ +#define TOD_READ_PRIMARY 0x0000 +/* Counter increments after TOD write is completed */ +#define TOD_READ_PRIMARY_COUNTER 0x000b +/* Read trigger configuration */ +#define TOD_READ_PRIMARY_SEL_CFG_0 0x000c +/* Read trigger selection */ +#define TOD_READ_PRIMARY_CMD 0x000e +#define TOD_READ_PRIMARY_CMD_V520 0x000f +#define TOD_READ_PRIMARY_1 0xcc50 +#define TOD_READ_PRIMARY_1_V520 0xcc60 +#define TOD_READ_PRIMARY_2 0xcc60 +#define TOD_READ_PRIMARY_2_V520 0xcc80 +#define TOD_READ_PRIMARY_3 0xcc80 +#define TOD_READ_PRIMARY_3_V520 0xcc90 + +#define TOD_READ_SECONDARY_0 0xcc90 +#define TOD_READ_SECONDARY_0_V520 0xcca0 +#define TOD_READ_SECONDARY_1 0xcca0 +#define TOD_READ_SECONDARY_1_V520 0xccb0 +#define TOD_READ_SECONDARY_2 0xccb0 +#define TOD_READ_SECONDARY_2_V520 0xccc0 +#define TOD_READ_SECONDARY_3 0xccc0 +#define TOD_READ_SECONDARY_3_V520 0xccd0 + +#define OUTPUT_TDC_CFG 0xccd0 +#define OUTPUT_TDC_CFG_V520 0xcce0 +#define OUTPUT_TDC_0 0xcd00 +#define OUTPUT_TDC_1 0xcd08 +#define OUTPUT_TDC_2 0xcd10 +#define OUTPUT_TDC_3 0xcd18 +#define INPUT_TDC 0xcd20 + +#define SCRATCH 0xcf50 +#define SCRATCH_V520 0xcf4c + +#define EEPROM 0xcf68 +#define EEPROM_V520 0xcf64 + +#define OTP 0xcf70 + +#define BYTE 0xcf80 + +/* Bit definitions for the MAJ_REL register */ +#define MAJOR_SHIFT (1) +#define MAJOR_MASK (0x7f) +#define PR_BUILD BIT(0) + +/* Bit definitions for the USER_GPIO0_TO_7_STATUS register */ +#define GPIO0_LEVEL BIT(0) +#define GPIO1_LEVEL BIT(1) +#define GPIO2_LEVEL BIT(2) +#define GPIO3_LEVEL BIT(3) +#define GPIO4_LEVEL BIT(4) +#define GPIO5_LEVEL BIT(5) +#define GPIO6_LEVEL BIT(6) +#define GPIO7_LEVEL BIT(7) + +/* Bit definitions for the USER_GPIO8_TO_15_STATUS register */ +#define GPIO8_LEVEL BIT(0) +#define GPIO9_LEVEL BIT(1) +#define GPIO10_LEVEL BIT(2) +#define GPIO11_LEVEL BIT(3) +#define GPIO12_LEVEL BIT(4) +#define GPIO13_LEVEL BIT(5) +#define GPIO14_LEVEL BIT(6) +#define GPIO15_LEVEL BIT(7) + +/* Bit definitions for the GPIO0_TO_7_OUT register */ +#define GPIO0_DRIVE_LEVEL BIT(0) +#define GPIO1_DRIVE_LEVEL BIT(1) +#define GPIO2_DRIVE_LEVEL BIT(2) +#define GPIO3_DRIVE_LEVEL BIT(3) +#define GPIO4_DRIVE_LEVEL BIT(4) +#define GPIO5_DRIVE_LEVEL BIT(5) +#define GPIO6_DRIVE_LEVEL BIT(6) +#define GPIO7_DRIVE_LEVEL BIT(7) + +/* Bit definitions for the GPIO8_TO_15_OUT register */ +#define GPIO8_DRIVE_LEVEL BIT(0) +#define GPIO9_DRIVE_LEVEL BIT(1) +#define GPIO10_DRIVE_LEVEL BIT(2) +#define GPIO11_DRIVE_LEVEL BIT(3) +#define GPIO12_DRIVE_LEVEL BIT(4) +#define GPIO13_DRIVE_LEVEL BIT(5) +#define GPIO14_DRIVE_LEVEL BIT(6) +#define GPIO15_DRIVE_LEVEL BIT(7) + +/* Bit definitions for the DPLL_TOD_SYNC_CFG register */ +#define TOD_SYNC_SOURCE_SHIFT (1) +#define TOD_SYNC_SOURCE_MASK (0x3) +#define TOD_SYNC_EN BIT(0) + +/* Bit definitions for the DPLL_MODE register */ +#define WRITE_TIMER_MODE BIT(6) +#define PLL_MODE_SHIFT (3) +#define PLL_MODE_MASK (0x7) +#define STATE_MODE_SHIFT (0) +#define STATE_MODE_MASK (0x7) + +/* Bit definitions for the GPIO_CFG_GBL register */ +#define SUPPLY_MODE_SHIFT (0) +#define SUPPLY_MODE_MASK (0x3) + +/* Bit definitions for the GPIO_DCO_INC_DEC register */ +#define INCDEC_DPLL_INDEX_SHIFT (0) +#define INCDEC_DPLL_INDEX_MASK (0x7) + +/* Bit definitions for the GPIO_OUT_CTRL_0 register */ +#define CTRL_OUT_0 BIT(0) +#define CTRL_OUT_1 BIT(1) +#define CTRL_OUT_2 BIT(2) +#define CTRL_OUT_3 BIT(3) +#define CTRL_OUT_4 BIT(4) +#define CTRL_OUT_5 BIT(5) +#define CTRL_OUT_6 BIT(6) +#define CTRL_OUT_7 BIT(7) + +/* Bit definitions for the GPIO_OUT_CTRL_1 register */ +#define CTRL_OUT_8 BIT(0) +#define CTRL_OUT_9 BIT(1) +#define CTRL_OUT_10 BIT(2) +#define CTRL_OUT_11 BIT(3) +#define CTRL_OUT_12 BIT(4) +#define CTRL_OUT_13 BIT(5) +#define CTRL_OUT_14 BIT(6) +#define CTRL_OUT_15 BIT(7) + +/* Bit definitions for the GPIO_TOD_TRIG register */ +#define TOD_TRIG_0 BIT(0) +#define TOD_TRIG_1 BIT(1) +#define TOD_TRIG_2 BIT(2) +#define TOD_TRIG_3 BIT(3) + +/* Bit definitions for the GPIO_DPLL_INDICATOR register */ +#define IND_DPLL_INDEX_SHIFT (0) +#define IND_DPLL_INDEX_MASK (0x7) + +/* Bit definitions for the GPIO_LOS_INDICATOR register */ +#define REFMON_INDEX_SHIFT (0) +#define REFMON_INDEX_MASK (0xf) +/* Active level of LOS indicator, 0=low 1=high */ +#define ACTIVE_LEVEL BIT(4) + +/* Bit definitions for the GPIO_REF_INPUT_DSQ_0 register */ +#define DSQ_INP_0 BIT(0) +#define DSQ_INP_1 BIT(1) +#define DSQ_INP_2 BIT(2) +#define DSQ_INP_3 BIT(3) +#define DSQ_INP_4 BIT(4) +#define DSQ_INP_5 BIT(5) +#define DSQ_INP_6 BIT(6) +#define DSQ_INP_7 BIT(7) + +/* Bit definitions for the GPIO_REF_INPUT_DSQ_1 register */ +#define DSQ_INP_8 BIT(0) +#define DSQ_INP_9 BIT(1) +#define DSQ_INP_10 BIT(2) +#define DSQ_INP_11 BIT(3) +#define DSQ_INP_12 BIT(4) +#define DSQ_INP_13 BIT(5) +#define DSQ_INP_14 BIT(6) +#define DSQ_INP_15 BIT(7) + +/* Bit definitions for the GPIO_REF_INPUT_DSQ_2 register */ +#define DSQ_DPLL_0 BIT(0) +#define DSQ_DPLL_1 BIT(1) +#define DSQ_DPLL_2 BIT(2) +#define DSQ_DPLL_3 BIT(3) +#define DSQ_DPLL_4 BIT(4) +#define DSQ_DPLL_5 BIT(5) +#define DSQ_DPLL_6 BIT(6) +#define DSQ_DPLL_7 BIT(7) + +/* Bit definitions for the GPIO_REF_INPUT_DSQ_3 register */ +#define DSQ_DPLL_SYS BIT(0) +#define GPIO_DSQ_LEVEL BIT(1) + +/* Bit definitions for the GPIO_TOD_NOTIFICATION_CFG register */ +#define DPLL_TOD_SHIFT (0) +#define DPLL_TOD_MASK (0x3) +#define TOD_READ_SECONDARY BIT(2) +#define GPIO_ASSERT_LEVEL BIT(3) + +/* Bit definitions for the GPIO_CTRL register */ +#define GPIO_FUNCTION_EN BIT(0) +#define GPIO_CMOS_OD_MODE BIT(1) +#define GPIO_CONTROL_DIR BIT(2) +#define GPIO_PU_PD_MODE BIT(3) +#define GPIO_FUNCTION_SHIFT (4) +#define GPIO_FUNCTION_MASK (0xf) + +/* Bit definitions for the OUT_CTRL_1 register */ +#define OUT_SYNC_DISABLE BIT(7) +#define SQUELCH_VALUE BIT(6) +#define SQUELCH_DISABLE BIT(5) +#define PAD_VDDO_SHIFT (2) +#define PAD_VDDO_MASK (0x7) +#define PAD_CMOSDRV_SHIFT (0) +#define PAD_CMOSDRV_MASK (0x3) + +/* Bit definitions for the TOD_CFG register */ +#define TOD_EVEN_PPS_MODE BIT(2) +#define TOD_OUT_SYNC_ENABLE BIT(1) +#define TOD_ENABLE BIT(0) + +/* Bit definitions for the TOD_WRITE_SELECT_CFG_0 register */ +#define WR_PWM_DECODER_INDEX_SHIFT (4) +#define WR_PWM_DECODER_INDEX_MASK (0xf) +#define WR_REF_INDEX_SHIFT (0) +#define WR_REF_INDEX_MASK (0xf) + +/* Bit definitions for the TOD_WRITE_CMD register */ +#define TOD_WRITE_SELECTION_SHIFT (0) +#define TOD_WRITE_SELECTION_MASK (0xf) +/* 4.8.7 */ +#define TOD_WRITE_TYPE_SHIFT (4) +#define TOD_WRITE_TYPE_MASK (0x3) + +/* Bit definitions for the TOD_READ_PRIMARY_SEL_CFG_0 register */ +#define RD_PWM_DECODER_INDEX_SHIFT (4) +#define RD_PWM_DECODER_INDEX_MASK (0xf) +#define RD_REF_INDEX_SHIFT (0) +#define RD_REF_INDEX_MASK (0xf) + +/* Bit definitions for the TOD_READ_PRIMARY_CMD register */ +#define TOD_READ_TRIGGER_MODE BIT(4) +#define TOD_READ_TRIGGER_SHIFT (0) +#define TOD_READ_TRIGGER_MASK (0xf) + +/* Bit definitions for the DPLL_CTRL_COMBO_MASTER_CFG register */ +#define COMBO_MASTER_HOLD BIT(0) + +/* Bit definitions for DPLL_SYS_STATUS register */ +#define DPLL_SYS_STATE_MASK (0xf) + +/* Bit definitions for SYS_APLL_STATUS register */ +#define SYS_APLL_LOSS_LOCK_LIVE_MASK BIT(0) +#define SYS_APLL_LOSS_LOCK_LIVE_LOCKED 0 +#define SYS_APLL_LOSS_LOCK_LIVE_UNLOCKED 1 + +/* Bit definitions for the DPLL0_STATUS register */ +#define DPLL_STATE_MASK (0xf) +#define DPLL_STATE_SHIFT (0x0) + +/* Values of DPLL_N.DPLL_MODE.PLL_MODE */ +enum pll_mode { + PLL_MODE_MIN = 0, + PLL_MODE_NORMAL = PLL_MODE_MIN, + PLL_MODE_WRITE_PHASE = 1, + PLL_MODE_WRITE_FREQUENCY = 2, + PLL_MODE_GPIO_INC_DEC = 3, + PLL_MODE_SYNTHESIS = 4, + PLL_MODE_PHASE_MEASUREMENT = 5, + PLL_MODE_DISABLED = 6, + PLL_MODE_MAX = PLL_MODE_DISABLED, +}; + +enum hw_tod_write_trig_sel { + HW_TOD_WR_TRIG_SEL_MIN = 0, + HW_TOD_WR_TRIG_SEL_MSB = HW_TOD_WR_TRIG_SEL_MIN, + HW_TOD_WR_TRIG_SEL_RESERVED = 1, + HW_TOD_WR_TRIG_SEL_TOD_PPS = 2, + HW_TOD_WR_TRIG_SEL_IRIGB_PPS = 3, + HW_TOD_WR_TRIG_SEL_PWM_PPS = 4, + HW_TOD_WR_TRIG_SEL_GPIO = 5, + HW_TOD_WR_TRIG_SEL_FOD_SYNC = 6, + WR_TRIG_SEL_MAX = HW_TOD_WR_TRIG_SEL_FOD_SYNC, +}; + +enum scsr_read_trig_sel { + /* CANCEL CURRENT TOD READ; MODULE BECOMES IDLE - NO TRIGGER OCCURS */ + SCSR_TOD_READ_TRIG_SEL_DISABLE = 0, + /* TRIGGER IMMEDIATELY */ + SCSR_TOD_READ_TRIG_SEL_IMMEDIATE = 1, + /* TRIGGER ON RISING EDGE OF INTERNAL TOD PPS SIGNAL */ + SCSR_TOD_READ_TRIG_SEL_TODPPS = 2, + /* TRGGER ON RISING EDGE OF SELECTED REFERENCE INPUT */ + SCSR_TOD_READ_TRIG_SEL_REFCLK = 3, + /* TRIGGER ON RISING EDGE OF SELECTED PWM DECODER 1PPS OUTPUT */ + SCSR_TOD_READ_TRIG_SEL_PWMPPS = 4, + SCSR_TOD_READ_TRIG_SEL_RESERVED = 5, + /* TRIGGER WHEN WRITE FREQUENCY EVENT OCCURS */ + SCSR_TOD_READ_TRIG_SEL_WRITEFREQUENCYEVENT = 6, + /* TRIGGER ON SELECTED GPIO */ + SCSR_TOD_READ_TRIG_SEL_GPIO = 7, + SCSR_TOD_READ_TRIG_SEL_MAX = SCSR_TOD_READ_TRIG_SEL_GPIO, +}; + +/* Values STATUS.DPLL_SYS_STATUS.DPLL_SYS_STATE */ +enum dpll_state { + DPLL_STATE_MIN = 0, + DPLL_STATE_FREERUN = DPLL_STATE_MIN, + DPLL_STATE_LOCKACQ = 1, + DPLL_STATE_LOCKREC = 2, + DPLL_STATE_LOCKED = 3, + DPLL_STATE_HOLDOVER = 4, + DPLL_STATE_OPEN_LOOP = 5, + DPLL_STATE_MAX = DPLL_STATE_OPEN_LOOP, +}; + +/* 4.8.7 only */ +enum scsr_tod_write_trig_sel { + SCSR_TOD_WR_TRIG_SEL_DISABLE = 0, + SCSR_TOD_WR_TRIG_SEL_IMMEDIATE = 1, + SCSR_TOD_WR_TRIG_SEL_REFCLK = 2, + SCSR_TOD_WR_TRIG_SEL_PWMPPS = 3, + SCSR_TOD_WR_TRIG_SEL_TODPPS = 4, + SCSR_TOD_WR_TRIG_SEL_SYNCFOD = 5, + SCSR_TOD_WR_TRIG_SEL_GPIO = 6, + SCSR_TOD_WR_TRIG_SEL_MAX = SCSR_TOD_WR_TRIG_SEL_GPIO, +}; + +/* 4.8.7 only */ +enum scsr_tod_write_type_sel { + SCSR_TOD_WR_TYPE_SEL_ABSOLUTE = 0, + SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS = 1, + SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS = 2, + SCSR_TOD_WR_TYPE_SEL_MAX = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS, +}; +#endif diff --git a/include/linux/mfd/rsmu.h b/include/linux/mfd/rsmu.h new file mode 100644 index 000000000000..6870de608233 --- /dev/null +++ b/include/linux/mfd/rsmu.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Core interface for Renesas Synchronization Management Unit (SMU) devices. + * + * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. + */ + +#ifndef __LINUX_MFD_RSMU_H +#define __LINUX_MFD_RSMU_H + +/* The supported devices are ClockMatrix, Sabre and SnowLotus */ +enum rsmu_type { + RSMU_CM = 0x34000, + RSMU_SABRE = 0x33810, + RSMU_SL = 0x19850, +}; + +/** + * + * struct rsmu_ddata - device data structure for sub devices. + * + * @dev: i2c/spi device. + * @regmap: i2c/spi bus access. + * @lock: mutex used by sub devices to make sure a series of + * bus access requests are not interrupted. + * @type: RSMU device type. + * @page: i2c/spi bus driver internal use only. + */ +struct rsmu_ddata { + struct device *dev; + struct regmap *regmap; + struct mutex lock; + enum rsmu_type type; + u16 page; +}; +#endif /* __LINUX_MFD_RSMU_H */ -- cgit v1.2.3-70-g09d2 From 07c6b5933ebf58b6132aea9f3e72a62486882bfb Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Fri, 9 Jul 2021 22:53:57 -0700 Subject: f2fs: add sysfs nodes to get GC info for each GC mode Added gc_reclaimed_segments and gc_segment_mode sysfs nodes. 1) "gc_reclaimed_segments" shows how many segments have been reclaimed by GC during a specific GC mode. 2) "gc_segment_mode" is used to control for which gc mode the "gc_reclaimed_segments" node shows. Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 14 ++++++++++++++ fs/f2fs/debug.c | 9 +++++++++ fs/f2fs/f2fs.h | 5 +++++ fs/f2fs/gc.c | 1 + fs/f2fs/sysfs.c | 28 ++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index ef4b9218ae1e..845c4be535b0 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -493,3 +493,17 @@ Contact: "Chao Yu" Description: When ATGC is on, it controls age threshold to bypass GCing young candidates whose age is not beyond the threshold, by default it was initialized as 604800 seconds (equals to 7 days). + +What: /sys/fs/f2fs//gc_reclaimed_segments +Date: July 2021 +Contact: "Daeho Jeong" +Description: Show how many segments have been reclaimed by GC during a specific + GC mode (0: GC normal, 1: GC idle CB, 2: GC idle greedy, + 3: GC idle AT, 4: GC urgent high, 5: GC urgent low) + You can re-initialize this value to "0". + +What: /sys/fs/f2fs//gc_segment_mode +Date: July 2021 +Contact: "Daeho Jeong" +Description: You can control for which gc mode the "gc_reclaimed_segments" node shows. + Refer to the description of the modes in "gc_reclaimed_segments". diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 833325038ef3..53ed1e9191f0 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -450,6 +450,15 @@ static int stat_show(struct seq_file *s, void *v) si->data_segs, si->bg_data_segs); seq_printf(s, " - node segments : %d (%d)\n", si->node_segs, si->bg_node_segs); + seq_printf(s, " - Reclaimed segs : Normal (%d), Idle CB (%d), " + "Idle Greedy (%d), Idle AT (%d), " + "Urgent High (%d), Urgent Low (%d)\n", + si->sbi->gc_reclaimed_segs[GC_NORMAL], + si->sbi->gc_reclaimed_segs[GC_IDLE_CB], + si->sbi->gc_reclaimed_segs[GC_IDLE_GREEDY], + si->sbi->gc_reclaimed_segs[GC_IDLE_AT], + si->sbi->gc_reclaimed_segs[GC_URGENT_HIGH], + si->sbi->gc_reclaimed_segs[GC_URGENT_LOW]); seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks, si->bg_data_blks + si->bg_node_blks); seq_printf(s, " - data blocks : %d (%d)\n", si->data_blks, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index ee8eb33e2c25..49d35e27db9f 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1253,6 +1253,7 @@ enum { GC_IDLE_AT, GC_URGENT_HIGH, GC_URGENT_LOW, + MAX_GC_MODE, }; enum { @@ -1733,6 +1734,10 @@ struct f2fs_sb_info { struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ + /* For reclaimed segs statistics per each GC mode */ + unsigned int gc_segment_mode; /* GC state for reclaimed segments */ + unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */ + #ifdef CONFIG_F2FS_FS_COMPRESSION struct kmem_cache *page_array_slab; /* page array entry */ unsigned int page_array_slab_size; /* default page array slab size */ diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 0e42ee5f7770..d9511827dc83 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1646,6 +1646,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, force_migrate); stat_inc_seg_count(sbi, type, gc_type); + sbi->gc_reclaimed_segs[sbi->gc_mode]++; migrated++; freed: diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 6642246206bd..15fe30d3aeb5 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -307,6 +307,14 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, return sysfs_emit(buf, "%u\n", sbi->compr_new_inode); #endif + if (!strcmp(a->attr.name, "gc_segment_mode")) + return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode); + + if (!strcmp(a->attr.name, "gc_reclaimed_segments")) { + return sysfs_emit(buf, "%u\n", + sbi->gc_reclaimed_segs[sbi->gc_segment_mode]); + } + ui = (unsigned int *)(ptr + a->offset); return sprintf(buf, "%u\n", *ui); @@ -515,6 +523,21 @@ out: return count; } + if (!strcmp(a->attr.name, "gc_segment_mode")) { + if (t < MAX_GC_MODE) + sbi->gc_segment_mode = t; + else + return -EINVAL; + return count; + } + + if (!strcmp(a->attr.name, "gc_reclaimed_segments")) { + if (t != 0) + return -EINVAL; + sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0; + return count; + } + *ui = (unsigned int)t; return count; @@ -740,6 +763,9 @@ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_cou F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs); + #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { ATTR_LIST(gc_urgent_sleep_time), @@ -812,6 +838,8 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(atgc_candidate_count), ATTR_LIST(atgc_age_weight), ATTR_LIST(atgc_age_threshold), + ATTR_LIST(gc_segment_mode), + ATTR_LIST(gc_reclaimed_segments), NULL, }; ATTRIBUTE_GROUPS(f2fs); -- cgit v1.2.3-70-g09d2 From 01f6afd0f3ccaa2d5f7fb87e7bd910dc17eef06b Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Sat, 10 Jul 2021 08:21:41 +0800 Subject: f2fs: compress: fix to set zstd compress level correctly As 5kft reported in [1]: set_compress_context() should set compress level into .i_compress_flag for zstd as well as lz4hc, otherwise, zstd compressor will still use default zstd compress level during compression, fix it. [1] https://lore.kernel.org/linux-f2fs-devel/8e29f52b-6b0d-45ec-9520-e63eb254287a@www.fastmail.com/T/#u Fixes: 3fde13f817e2 ("f2fs: compress: support compress level") Reported-by: 5kft <5kft@5kft.org> Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/f2fs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 49d35e27db9f..867f2c5d9559 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4142,7 +4142,8 @@ static inline void set_compress_context(struct inode *inode) 1 << COMPRESS_CHKSUM : 0; F2FS_I(inode)->i_cluster_size = 1 << F2FS_I(inode)->i_log_cluster_size; - if (F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 && + if ((F2FS_I(inode)->i_compress_algorithm == COMPRESS_LZ4 || + F2FS_I(inode)->i_compress_algorithm == COMPRESS_ZSTD) && F2FS_OPTION(sbi).compress_level) F2FS_I(inode)->i_compress_flag |= F2FS_OPTION(sbi).compress_level << -- cgit v1.2.3-70-g09d2 From 5417c98c12f6eeb1252130bcea3b943f5e273be7 Mon Sep 17 00:00:00 2001 From: Wang Xiaojun Date: Fri, 9 Jul 2021 16:34:53 +0800 Subject: f2fs: avoid to create an empty string as the extension_list When creating a file, we need to set the temperature based on extension_list. If the empty string is a valid extension_list, the is_extension_exist will always returns true, which affects the separation of hot and cold. Signed-off-by: Wang Xiaojun Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 15fe30d3aeb5..b1725620c07d 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -351,7 +351,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a, set = false; } - if (strlen(name) >= F2FS_EXTENSION_LEN) + if (!strlen(name) || strlen(name) >= F2FS_EXTENSION_LEN) return -EINVAL; down_write(&sbi->sb_lock); -- cgit v1.2.3-70-g09d2 From 0a65579cdd28bed3e84e1b4929c3080da4f06d79 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:32 +0800 Subject: swiotlb: Refactor swiotlb init functions Add a new function, swiotlb_init_io_tlb_mem, for the io_tlb_mem struct initialization to make the code reusable. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Acked-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index e50df8d8f87e..414db5fc8de9 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -168,9 +168,28 @@ void __init swiotlb_update_mem_attributes(void) memset(vaddr, 0, bytes); } -int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) +static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, + unsigned long nslabs, bool late_alloc) { + void *vaddr = phys_to_virt(start); unsigned long bytes = nslabs << IO_TLB_SHIFT, i; + + mem->nslabs = nslabs; + mem->start = start; + mem->end = mem->start + bytes; + mem->index = 0; + mem->late_alloc = late_alloc; + spin_lock_init(&mem->lock); + for (i = 0; i < mem->nslabs; i++) { + mem->slots[i].list = IO_TLB_SEGSIZE - io_tlb_offset(i); + mem->slots[i].orig_addr = INVALID_PHYS_ADDR; + mem->slots[i].alloc_size = 0; + } + memset(vaddr, 0, bytes); +} + +int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) +{ struct io_tlb_mem *mem; size_t alloc_size; @@ -186,16 +205,8 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) if (!mem) panic("%s: Failed to allocate %zu bytes align=0x%lx\n", __func__, alloc_size, PAGE_SIZE); - mem->nslabs = nslabs; - mem->start = __pa(tlb); - mem->end = mem->start + bytes; - mem->index = 0; - spin_lock_init(&mem->lock); - for (i = 0; i < mem->nslabs; i++) { - mem->slots[i].list = IO_TLB_SEGSIZE - io_tlb_offset(i); - mem->slots[i].orig_addr = INVALID_PHYS_ADDR; - mem->slots[i].alloc_size = 0; - } + + swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, false); io_tlb_default_mem = mem; if (verbose) @@ -282,8 +293,8 @@ swiotlb_late_init_with_default_size(size_t default_size) int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) { - unsigned long bytes = nslabs << IO_TLB_SHIFT, i; struct io_tlb_mem *mem; + unsigned long bytes = nslabs << IO_TLB_SHIFT; if (swiotlb_force == SWIOTLB_NO_FORCE) return 0; @@ -297,20 +308,9 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) if (!mem) return -ENOMEM; - mem->nslabs = nslabs; - mem->start = virt_to_phys(tlb); - mem->end = mem->start + bytes; - mem->index = 0; - mem->late_alloc = 1; - spin_lock_init(&mem->lock); - for (i = 0; i < mem->nslabs; i++) { - mem->slots[i].list = IO_TLB_SEGSIZE - io_tlb_offset(i); - mem->slots[i].orig_addr = INVALID_PHYS_ADDR; - mem->slots[i].alloc_size = 0; - } - + memset(mem, 0, sizeof(*mem)); set_memory_decrypted((unsigned long)tlb, bytes >> PAGE_SHIFT); - memset(tlb, 0, bytes); + swiotlb_init_io_tlb_mem(mem, virt_to_phys(tlb), nslabs, true); io_tlb_default_mem = mem; swiotlb_print_info(); -- cgit v1.2.3-70-g09d2 From 6e675a1c455ea7579c7eaf1a38fe64267039d6fe Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:33 +0800 Subject: swiotlb: Refactor swiotlb_create_debugfs Split the debugfs creation to make the code reusable for supporting different bounce buffer pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 414db5fc8de9..ae6a151d0a41 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -669,19 +669,26 @@ bool is_swiotlb_active(void) EXPORT_SYMBOL_GPL(is_swiotlb_active); #ifdef CONFIG_DEBUG_FS +static struct dentry *debugfs_dir; -static int __init swiotlb_create_debugfs(void) +static void swiotlb_create_debugfs_files(struct io_tlb_mem *mem) { - struct io_tlb_mem *mem = io_tlb_default_mem; - - if (!mem) - return 0; - mem->debugfs = debugfs_create_dir("swiotlb", NULL); debugfs_create_ulong("io_tlb_nslabs", 0400, mem->debugfs, &mem->nslabs); debugfs_create_ulong("io_tlb_used", 0400, mem->debugfs, &mem->used); +} + +static int __init swiotlb_create_default_debugfs(void) +{ + struct io_tlb_mem *mem = io_tlb_default_mem; + + debugfs_dir = debugfs_create_dir("swiotlb", NULL); + if (mem) { + mem->debugfs = debugfs_dir; + swiotlb_create_debugfs_files(mem); + } return 0; } -late_initcall(swiotlb_create_debugfs); +late_initcall(swiotlb_create_default_debugfs); #endif -- cgit v1.2.3-70-g09d2 From 69031f500865ee3eee19566a1b9c40a189817eaa Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:34 +0800 Subject: swiotlb: Set dev->dma_io_tlb_mem to the swiotlb pool used Always have the pointer to the swiotlb pool used in struct device. This could help simplify the code for other pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/base/core.c | 4 ++++ include/linux/device.h | 4 ++++ kernel/dma/swiotlb.c | 8 ++++---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index cadcade65825..ea5b85354526 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include /* for dma_default_coherent */ @@ -2846,6 +2847,9 @@ void device_initialize(struct device *dev) defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) dev->dma_coherent = dma_default_coherent; #endif +#ifdef CONFIG_SWIOTLB + dev->dma_io_tlb_mem = io_tlb_default_mem; +#endif } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/include/linux/device.h b/include/linux/device.h index 59940f1744c1..2a22875238a6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -423,6 +423,7 @@ struct dev_links_info { * @dma_pools: Dma pools (if dma'ble device). * @dma_mem: Internal for coherent mem override. * @cma_area: Contiguous memory area for dma allocations + * @dma_io_tlb_mem: Pointer to the swiotlb pool used. Not for driver use. * @archdata: For arch-specific additions. * @of_node: Associated device tree node. * @fwnode: Associated device node supplied by platform firmware. @@ -531,6 +532,9 @@ struct device { #ifdef CONFIG_DMA_CMA struct cma *cma_area; /* contiguous memory area for dma allocations */ +#endif +#ifdef CONFIG_SWIOTLB + struct io_tlb_mem *dma_io_tlb_mem; #endif /* arch specific additions */ struct dev_archdata archdata; diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index ae6a151d0a41..33d413beddd4 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -348,7 +348,7 @@ static unsigned int swiotlb_align_offset(struct device *dev, u64 addr) static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size, enum dma_data_direction dir) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; int index = (tlb_addr - mem->start) >> IO_TLB_SHIFT; phys_addr_t orig_addr = mem->slots[index].orig_addr; size_t alloc_size = mem->slots[index].alloc_size; @@ -429,7 +429,7 @@ static unsigned int wrap_index(struct io_tlb_mem *mem, unsigned int index) static int find_slots(struct device *dev, phys_addr_t orig_addr, size_t alloc_size) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; unsigned long boundary_mask = dma_get_seg_boundary(dev); dma_addr_t tbl_dma_addr = phys_to_dma_unencrypted(dev, mem->start) & boundary_mask; @@ -506,7 +506,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, size_t mapping_size, size_t alloc_size, enum dma_data_direction dir, unsigned long attrs) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; unsigned int offset = swiotlb_align_offset(dev, orig_addr); unsigned int i; int index; @@ -557,7 +557,7 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, size_t mapping_size, enum dma_data_direction dir, unsigned long attrs) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = hwdev->dma_io_tlb_mem; unsigned long flags; unsigned int offset = swiotlb_align_offset(hwdev, tlb_addr); int index = (tlb_addr - offset - mem->start) >> IO_TLB_SHIFT; -- cgit v1.2.3-70-g09d2 From 7fd856aa7f4261ddac62ea59d8383fef22a0690e Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:35 +0800 Subject: swiotlb: Update is_swiotlb_buffer to add a struct device argument Update is_swiotlb_buffer to add a struct device argument. This will be useful later to allow for different pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/iommu/dma-iommu.c | 12 ++++++------ drivers/xen/swiotlb-xen.c | 2 +- include/linux/swiotlb.h | 7 ++++--- kernel/dma/direct.c | 6 +++--- kernel/dma/direct.h | 6 +++--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 98ba927aee1a..4e34e8b26579 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -506,7 +506,7 @@ static void __iommu_dma_unmap_swiotlb(struct device *dev, dma_addr_t dma_addr, __iommu_dma_unmap(dev, dma_addr, size); - if (unlikely(is_swiotlb_buffer(phys))) + if (unlikely(is_swiotlb_buffer(dev, phys))) swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs); } @@ -577,7 +577,7 @@ static dma_addr_t __iommu_dma_map_swiotlb(struct device *dev, phys_addr_t phys, } iova = __iommu_dma_map(dev, phys, aligned_size, prot, dma_mask); - if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(phys)) + if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(dev, phys)) swiotlb_tbl_unmap_single(dev, phys, org_size, dir, attrs); return iova; } @@ -783,7 +783,7 @@ static void iommu_dma_sync_single_for_cpu(struct device *dev, if (!dev_is_dma_coherent(dev)) arch_sync_dma_for_cpu(phys, size, dir); - if (is_swiotlb_buffer(phys)) + if (is_swiotlb_buffer(dev, phys)) swiotlb_sync_single_for_cpu(dev, phys, size, dir); } @@ -796,7 +796,7 @@ static void iommu_dma_sync_single_for_device(struct device *dev, return; phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), dma_handle); - if (is_swiotlb_buffer(phys)) + if (is_swiotlb_buffer(dev, phys)) swiotlb_sync_single_for_device(dev, phys, size, dir); if (!dev_is_dma_coherent(dev)) @@ -817,7 +817,7 @@ static void iommu_dma_sync_sg_for_cpu(struct device *dev, if (!dev_is_dma_coherent(dev)) arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); - if (is_swiotlb_buffer(sg_phys(sg))) + if (is_swiotlb_buffer(dev, sg_phys(sg))) swiotlb_sync_single_for_cpu(dev, sg_phys(sg), sg->length, dir); } @@ -834,7 +834,7 @@ static void iommu_dma_sync_sg_for_device(struct device *dev, return; for_each_sg(sgl, sg, nelems, i) { - if (is_swiotlb_buffer(sg_phys(sg))) + if (is_swiotlb_buffer(dev, sg_phys(sg))) swiotlb_sync_single_for_device(dev, sg_phys(sg), sg->length, dir); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 24d11861ac7d..0c4fb34f11ab 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -100,7 +100,7 @@ static int is_xen_swiotlb_buffer(struct device *dev, dma_addr_t dma_addr) * in our domain. Therefore _only_ check address within our domain. */ if (pfn_valid(PFN_DOWN(paddr))) - return is_swiotlb_buffer(paddr); + return is_swiotlb_buffer(dev, paddr); return 0; } diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 216854a5e513..d1f3d95881cd 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -2,6 +2,7 @@ #ifndef __LINUX_SWIOTLB_H #define __LINUX_SWIOTLB_H +#include #include #include #include @@ -101,9 +102,9 @@ struct io_tlb_mem { }; extern struct io_tlb_mem *io_tlb_default_mem; -static inline bool is_swiotlb_buffer(phys_addr_t paddr) +static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; return mem && paddr >= mem->start && paddr < mem->end; } @@ -115,7 +116,7 @@ bool is_swiotlb_active(void); void __init swiotlb_adjust_size(unsigned long size); #else #define swiotlb_force SWIOTLB_NO_FORCE -static inline bool is_swiotlb_buffer(phys_addr_t paddr) +static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) { return false; } diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index f737e3347059..84c9feb5474a 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -343,7 +343,7 @@ void dma_direct_sync_sg_for_device(struct device *dev, for_each_sg(sgl, sg, nents, i) { phys_addr_t paddr = dma_to_phys(dev, sg_dma_address(sg)); - if (unlikely(is_swiotlb_buffer(paddr))) + if (unlikely(is_swiotlb_buffer(dev, paddr))) swiotlb_sync_single_for_device(dev, paddr, sg->length, dir); @@ -369,7 +369,7 @@ void dma_direct_sync_sg_for_cpu(struct device *dev, if (!dev_is_dma_coherent(dev)) arch_sync_dma_for_cpu(paddr, sg->length, dir); - if (unlikely(is_swiotlb_buffer(paddr))) + if (unlikely(is_swiotlb_buffer(dev, paddr))) swiotlb_sync_single_for_cpu(dev, paddr, sg->length, dir); @@ -504,7 +504,7 @@ size_t dma_direct_max_mapping_size(struct device *dev) bool dma_direct_need_sync(struct device *dev, dma_addr_t dma_addr) { return !dev_is_dma_coherent(dev) || - is_swiotlb_buffer(dma_to_phys(dev, dma_addr)); + is_swiotlb_buffer(dev, dma_to_phys(dev, dma_addr)); } /** diff --git a/kernel/dma/direct.h b/kernel/dma/direct.h index 50afc05b6f1d..13e9e7158d94 100644 --- a/kernel/dma/direct.h +++ b/kernel/dma/direct.h @@ -56,7 +56,7 @@ static inline void dma_direct_sync_single_for_device(struct device *dev, { phys_addr_t paddr = dma_to_phys(dev, addr); - if (unlikely(is_swiotlb_buffer(paddr))) + if (unlikely(is_swiotlb_buffer(dev, paddr))) swiotlb_sync_single_for_device(dev, paddr, size, dir); if (!dev_is_dma_coherent(dev)) @@ -73,7 +73,7 @@ static inline void dma_direct_sync_single_for_cpu(struct device *dev, arch_sync_dma_for_cpu_all(); } - if (unlikely(is_swiotlb_buffer(paddr))) + if (unlikely(is_swiotlb_buffer(dev, paddr))) swiotlb_sync_single_for_cpu(dev, paddr, size, dir); if (dir == DMA_FROM_DEVICE) @@ -113,7 +113,7 @@ static inline void dma_direct_unmap_page(struct device *dev, dma_addr_t addr, if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) dma_direct_sync_single_for_cpu(dev, addr, size, dir); - if (unlikely(is_swiotlb_buffer(phys))) + if (unlikely(is_swiotlb_buffer(dev, phys))) swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs); } #endif /* _KERNEL_DMA_DIRECT_H */ -- cgit v1.2.3-70-g09d2 From 6f2beb268a5d35504a636c4a3b7aaa76ec32d96c Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:36 +0800 Subject: swiotlb: Update is_swiotlb_active to add a struct device argument Update is_swiotlb_active to add a struct device argument. This will be useful later to allow for different pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- drivers/gpu/drm/i915/gem/i915_gem_internal.c | 2 +- drivers/gpu/drm/nouveau/nouveau_ttm.c | 2 +- drivers/pci/xen-pcifront.c | 2 +- include/linux/swiotlb.h | 4 ++-- kernel/dma/direct.c | 2 +- kernel/dma/swiotlb.c | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index ce6b664b10aa..89a894354263 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -42,7 +42,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) max_order = MAX_ORDER; #ifdef CONFIG_SWIOTLB - if (is_swiotlb_active()) { + if (is_swiotlb_active(obj->base.dev->dev)) { unsigned int max_segment; max_segment = swiotlb_max_segment(); diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index f4c2e46b6fe1..2ca9d9a9e5d5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -276,7 +276,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) } #if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86) - need_swiotlb = is_swiotlb_active(); + need_swiotlb = is_swiotlb_active(dev->dev); #endif ret = ttm_device_init(&drm->ttm.bdev, &nouveau_bo_driver, drm->dev->dev, diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index b7a8f3a1921f..0d56985bfe81 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -693,7 +693,7 @@ static int pcifront_connect_and_init_dma(struct pcifront_device *pdev) spin_unlock(&pcifront_dev_lock); - if (!err && !is_swiotlb_active()) { + if (!err && !is_swiotlb_active(&pdev->xdev->dev)) { err = pci_xen_swiotlb_init_late(); if (err) dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n"); diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index d1f3d95881cd..dd1c30a83058 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -112,7 +112,7 @@ static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) void __init swiotlb_exit(void); unsigned int swiotlb_max_segment(void); size_t swiotlb_max_mapping_size(struct device *dev); -bool is_swiotlb_active(void); +bool is_swiotlb_active(struct device *dev); void __init swiotlb_adjust_size(unsigned long size); #else #define swiotlb_force SWIOTLB_NO_FORCE @@ -132,7 +132,7 @@ static inline size_t swiotlb_max_mapping_size(struct device *dev) return SIZE_MAX; } -static inline bool is_swiotlb_active(void) +static inline bool is_swiotlb_active(struct device *dev) { return false; } diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 84c9feb5474a..7a88c34d0867 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -495,7 +495,7 @@ int dma_direct_supported(struct device *dev, u64 mask) size_t dma_direct_max_mapping_size(struct device *dev) { /* If SWIOTLB is active, use its maximum mapping size */ - if (is_swiotlb_active() && + if (is_swiotlb_active(dev) && (dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE)) return swiotlb_max_mapping_size(dev); return SIZE_MAX; diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 33d413beddd4..d8677d6637dd 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -662,9 +662,9 @@ size_t swiotlb_max_mapping_size(struct device *dev) return ((size_t)IO_TLB_SIZE) * IO_TLB_SEGSIZE; } -bool is_swiotlb_active(void) +bool is_swiotlb_active(struct device *dev) { - return io_tlb_default_mem != NULL; + return dev->dma_io_tlb_mem != NULL; } EXPORT_SYMBOL_GPL(is_swiotlb_active); -- cgit v1.2.3-70-g09d2 From 903cd0f315fe426c6a64c54ed389de0becb663dc Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Thu, 24 Jun 2021 23:55:20 +0800 Subject: swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and use it to determine whether to bounce the data or not. This will be useful later to allow for different pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk [v2: Includes Will's fix] --- drivers/xen/swiotlb-xen.c | 2 +- include/linux/swiotlb.h | 13 +++++++++++++ kernel/dma/direct.c | 2 +- kernel/dma/direct.h | 2 +- kernel/dma/swiotlb.c | 4 ++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 0c4fb34f11ab..785ec7e8be01 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -374,7 +374,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, if (dma_capable(dev, dev_addr, size, true) && !range_straddles_page_boundary(phys, size) && !xen_arch_need_swiotlb(dev, phys, dev_addr) && - swiotlb_force != SWIOTLB_FORCE) + !is_swiotlb_force_bounce(dev)) goto done; /* diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index dd1c30a83058..da348671b0d5 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -84,6 +84,7 @@ extern enum swiotlb_force swiotlb_force; * unmap calls. * @debugfs: The dentry to debugfs. * @late_alloc: %true if allocated using the page allocator + * @force_bounce: %true if swiotlb bouncing is forced */ struct io_tlb_mem { phys_addr_t start; @@ -94,6 +95,7 @@ struct io_tlb_mem { spinlock_t lock; struct dentry *debugfs; bool late_alloc; + bool force_bounce; struct io_tlb_slot { phys_addr_t orig_addr; size_t alloc_size; @@ -109,6 +111,13 @@ static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) return mem && paddr >= mem->start && paddr < mem->end; } +static inline bool is_swiotlb_force_bounce(struct device *dev) +{ + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; + + return mem && mem->force_bounce; +} + void __init swiotlb_exit(void); unsigned int swiotlb_max_segment(void); size_t swiotlb_max_mapping_size(struct device *dev); @@ -120,6 +129,10 @@ static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) { return false; } +static inline bool is_swiotlb_force_bounce(struct device *dev) +{ + return false; +} static inline void swiotlb_exit(void) { } diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 7a88c34d0867..a92465b4eb12 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -496,7 +496,7 @@ size_t dma_direct_max_mapping_size(struct device *dev) { /* If SWIOTLB is active, use its maximum mapping size */ if (is_swiotlb_active(dev) && - (dma_addressing_limited(dev) || swiotlb_force == SWIOTLB_FORCE)) + (dma_addressing_limited(dev) || is_swiotlb_force_bounce(dev))) return swiotlb_max_mapping_size(dev); return SIZE_MAX; } diff --git a/kernel/dma/direct.h b/kernel/dma/direct.h index 13e9e7158d94..4632b0f4f72e 100644 --- a/kernel/dma/direct.h +++ b/kernel/dma/direct.h @@ -87,7 +87,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, phys_addr_t phys = page_to_phys(page) + offset; dma_addr_t dma_addr = phys_to_dma(dev, phys); - if (unlikely(swiotlb_force == SWIOTLB_FORCE)) + if (is_swiotlb_force_bounce(dev)) return swiotlb_map(dev, phys, size, dir, attrs); if (unlikely(!dma_capable(dev, dma_addr, size, true))) { diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index d8677d6637dd..04319dd22d28 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -179,6 +179,10 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, mem->end = mem->start + bytes; mem->index = 0; mem->late_alloc = late_alloc; + + if (swiotlb_force == SWIOTLB_FORCE) + mem->force_bounce = true; + spin_lock_init(&mem->lock); for (i = 0; i < mem->nslabs; i++) { mem->slots[i].list = IO_TLB_SEGSIZE - io_tlb_offset(i); -- cgit v1.2.3-70-g09d2 From 36f7b2f3ca5f0bee00abf9ea52748ce0644a21c6 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Thu, 24 Jun 2021 23:55:21 +0800 Subject: swiotlb: Move alloc_size to swiotlb_find_slots Rename find_slots to swiotlb_find_slots and move the maintenance of alloc_size to it for better code reusability later. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 04319dd22d28..0116a630dc13 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -430,8 +430,8 @@ static unsigned int wrap_index(struct io_tlb_mem *mem, unsigned int index) * Find a suitable number of IO TLB entries size that will fit this request and * allocate a buffer from that IO TLB pool. */ -static int find_slots(struct device *dev, phys_addr_t orig_addr, - size_t alloc_size) +static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr, + size_t alloc_size) { struct io_tlb_mem *mem = dev->dma_io_tlb_mem; unsigned long boundary_mask = dma_get_seg_boundary(dev); @@ -442,6 +442,7 @@ static int find_slots(struct device *dev, phys_addr_t orig_addr, dma_get_min_align_mask(dev) & ~(IO_TLB_SIZE - 1); unsigned int nslots = nr_slots(alloc_size), stride; unsigned int index, wrap, count = 0, i; + unsigned int offset = swiotlb_align_offset(dev, orig_addr); unsigned long flags; BUG_ON(!nslots); @@ -486,8 +487,11 @@ not_found: return -1; found: - for (i = index; i < index + nslots; i++) + for (i = index; i < index + nslots; i++) { mem->slots[i].list = 0; + mem->slots[i].alloc_size = + alloc_size - (offset + ((i - index) << IO_TLB_SHIFT)); + } for (i = index - 1; io_tlb_offset(i) != IO_TLB_SEGSIZE - 1 && mem->slots[i].list; i--) @@ -528,7 +532,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, return (phys_addr_t)DMA_MAPPING_ERROR; } - index = find_slots(dev, orig_addr, alloc_size + offset); + index = swiotlb_find_slots(dev, orig_addr, alloc_size + offset); if (index == -1) { if (!(attrs & DMA_ATTR_NO_WARN)) dev_warn_ratelimited(dev, @@ -542,11 +546,8 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, * This is needed when we sync the memory. Then we sync the buffer if * needed. */ - for (i = 0; i < nr_slots(alloc_size + offset); i++) { + for (i = 0; i < nr_slots(alloc_size + offset); i++) mem->slots[index + i].orig_addr = slot_addr(orig_addr, i); - mem->slots[index + i].alloc_size = - alloc_size - (i << IO_TLB_SHIFT); - } tlb_addr = slot_addr(mem->start, index) + offset; if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) && (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)) -- cgit v1.2.3-70-g09d2 From 70347877231eeb505a27abe80af7ae3d3a281519 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:39 +0800 Subject: swiotlb: Refactor swiotlb_tbl_unmap_single Add a new function, swiotlb_release_slots, to make the code reusable for supporting different bounce buffer pools. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 0116a630dc13..23b6df3a6ab7 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -555,27 +555,15 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, return tlb_addr; } -/* - * tlb_addr is the physical address of the bounce buffer to unmap. - */ -void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, - size_t mapping_size, enum dma_data_direction dir, - unsigned long attrs) +static void swiotlb_release_slots(struct device *dev, phys_addr_t tlb_addr) { - struct io_tlb_mem *mem = hwdev->dma_io_tlb_mem; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; unsigned long flags; - unsigned int offset = swiotlb_align_offset(hwdev, tlb_addr); + unsigned int offset = swiotlb_align_offset(dev, tlb_addr); int index = (tlb_addr - offset - mem->start) >> IO_TLB_SHIFT; int nslots = nr_slots(mem->slots[index].alloc_size + offset); int count, i; - /* - * First, sync the memory before unmapping the entry - */ - if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) && - (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) - swiotlb_bounce(hwdev, tlb_addr, mapping_size, DMA_FROM_DEVICE); - /* * Return the buffer to the free list by setting the corresponding * entries to indicate the number of contiguous entries available. @@ -610,6 +598,23 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr, spin_unlock_irqrestore(&mem->lock, flags); } +/* + * tlb_addr is the physical address of the bounce buffer to unmap. + */ +void swiotlb_tbl_unmap_single(struct device *dev, phys_addr_t tlb_addr, + size_t mapping_size, enum dma_data_direction dir, + unsigned long attrs) +{ + /* + * First, sync the memory before unmapping the entry + */ + if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) && + (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) + swiotlb_bounce(dev, tlb_addr, mapping_size, DMA_FROM_DEVICE); + + swiotlb_release_slots(dev, tlb_addr); +} + void swiotlb_sync_single_for_device(struct device *dev, phys_addr_t tlb_addr, size_t size, enum dma_data_direction dir) { -- cgit v1.2.3-70-g09d2 From f4111e39a52aa5d5136d890bbd1aa87c1c8fe3bc Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:40 +0800 Subject: swiotlb: Add restricted DMA alloc/free support Add the functions, swiotlb_{alloc,free} and is_swiotlb_for_alloc to support the memory allocation from restricted DMA pool. The restricted DMA pool is preferred if available. Note that since coherent allocation needs remapping, one must set up another device coherent pool by shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic coherent allocation. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Acked-by: Stefano Stabellini Signed-off-by: Konrad Rzeszutek Wilk --- include/linux/swiotlb.h | 26 ++++++++++++++++++++++++++ kernel/dma/direct.c | 49 +++++++++++++++++++++++++++++++++++++------------ kernel/dma/swiotlb.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 14 deletions(-) diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index da348671b0d5..3b9454d1e498 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -85,6 +85,7 @@ extern enum swiotlb_force swiotlb_force; * @debugfs: The dentry to debugfs. * @late_alloc: %true if allocated using the page allocator * @force_bounce: %true if swiotlb bouncing is forced + * @for_alloc: %true if the pool is used for memory allocation */ struct io_tlb_mem { phys_addr_t start; @@ -96,6 +97,7 @@ struct io_tlb_mem { struct dentry *debugfs; bool late_alloc; bool force_bounce; + bool for_alloc; struct io_tlb_slot { phys_addr_t orig_addr; size_t alloc_size; @@ -158,4 +160,28 @@ static inline void swiotlb_adjust_size(unsigned long size) extern void swiotlb_print_info(void); extern void swiotlb_set_max_segment(unsigned int); +#ifdef CONFIG_DMA_RESTRICTED_POOL +struct page *swiotlb_alloc(struct device *dev, size_t size); +bool swiotlb_free(struct device *dev, struct page *page, size_t size); + +static inline bool is_swiotlb_for_alloc(struct device *dev) +{ + return dev->dma_io_tlb_mem->for_alloc; +} +#else +static inline struct page *swiotlb_alloc(struct device *dev, size_t size) +{ + return NULL; +} +static inline bool swiotlb_free(struct device *dev, struct page *page, + size_t size) +{ + return false; +} +static inline bool is_swiotlb_for_alloc(struct device *dev) +{ + return false; +} +#endif /* CONFIG_DMA_RESTRICTED_POOL */ + #endif /* __LINUX_SWIOTLB_H */ diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index a92465b4eb12..2de33e5d302b 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -75,6 +75,15 @@ static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size) min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit); } +static void __dma_direct_free_pages(struct device *dev, struct page *page, + size_t size) +{ + if (IS_ENABLED(CONFIG_DMA_RESTRICTED_POOL) && + swiotlb_free(dev, page, size)) + return; + dma_free_contiguous(dev, page, size); +} + static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, gfp_t gfp) { @@ -86,6 +95,16 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, &phys_limit); + if (IS_ENABLED(CONFIG_DMA_RESTRICTED_POOL) && + is_swiotlb_for_alloc(dev)) { + page = swiotlb_alloc(dev, size); + if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { + __dma_direct_free_pages(dev, page, size); + return NULL; + } + return page; + } + page = dma_alloc_contiguous(dev, size, gfp); if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { dma_free_contiguous(dev, page, size); @@ -142,7 +161,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, gfp |= __GFP_NOWARN; if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) && - !force_dma_unencrypted(dev)) { + !force_dma_unencrypted(dev) && !is_swiotlb_for_alloc(dev)) { page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO); if (!page) return NULL; @@ -155,18 +174,23 @@ void *dma_direct_alloc(struct device *dev, size_t size, } if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) && - !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && - !dev_is_dma_coherent(dev)) + !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) && + !is_swiotlb_for_alloc(dev)) return arch_dma_alloc(dev, size, dma_handle, gfp, attrs); /* * Remapping or decrypting memory may block. If either is required and * we can't block, allocate the memory from the atomic pools. + * If restricted DMA (i.e., is_swiotlb_for_alloc) is required, one must + * set up another device coherent pool by shared-dma-pool and use + * dma_alloc_from_dev_coherent instead. */ if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) && !gfpflags_allow_blocking(gfp) && (force_dma_unencrypted(dev) || - (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev)))) + (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && + !dev_is_dma_coherent(dev))) && + !is_swiotlb_for_alloc(dev)) return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp); /* we always manually zero the memory once we are done */ @@ -237,7 +261,7 @@ out_encrypt_pages: return NULL; } out_free_pages: - dma_free_contiguous(dev, page, size); + __dma_direct_free_pages(dev, page, size); return NULL; } @@ -247,15 +271,15 @@ void dma_direct_free(struct device *dev, size_t size, unsigned int page_order = get_order(size); if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) && - !force_dma_unencrypted(dev)) { + !force_dma_unencrypted(dev) && !is_swiotlb_for_alloc(dev)) { /* cpu_addr is a struct page cookie, not a kernel address */ dma_free_contiguous(dev, cpu_addr, size); return; } if (!IS_ENABLED(CONFIG_ARCH_HAS_DMA_SET_UNCACHED) && - !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && - !dev_is_dma_coherent(dev)) { + !IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && !dev_is_dma_coherent(dev) && + !is_swiotlb_for_alloc(dev)) { arch_dma_free(dev, size, cpu_addr, dma_addr, attrs); return; } @@ -273,7 +297,7 @@ void dma_direct_free(struct device *dev, size_t size, else if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED)) arch_dma_clear_uncached(cpu_addr, size); - dma_free_contiguous(dev, dma_direct_to_page(dev, dma_addr), size); + __dma_direct_free_pages(dev, dma_direct_to_page(dev, dma_addr), size); } struct page *dma_direct_alloc_pages(struct device *dev, size_t size, @@ -283,7 +307,8 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, void *ret; if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) && - force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp)) + force_dma_unencrypted(dev) && !gfpflags_allow_blocking(gfp) && + !is_swiotlb_for_alloc(dev)) return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp); page = __dma_direct_alloc_pages(dev, size, gfp); @@ -310,7 +335,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, *dma_handle = phys_to_dma_direct(dev, page_to_phys(page)); return page; out_free_pages: - dma_free_contiguous(dev, page, size); + __dma_direct_free_pages(dev, page, size); return NULL; } @@ -329,7 +354,7 @@ void dma_direct_free_pages(struct device *dev, size_t size, if (force_dma_unencrypted(dev)) set_memory_encrypted((unsigned long)vaddr, 1 << page_order); - dma_free_contiguous(dev, page, size); + __dma_direct_free_pages(dev, page, size); } #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \ diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 23b6df3a6ab7..44fc3d10f017 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -462,8 +462,9 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr, index = wrap = wrap_index(mem, ALIGN(mem->index, stride)); do { - if ((slot_addr(tbl_dma_addr, index) & iotlb_align_mask) != - (orig_addr & iotlb_align_mask)) { + if (orig_addr && + (slot_addr(tbl_dma_addr, index) & iotlb_align_mask) != + (orig_addr & iotlb_align_mask)) { index = wrap_index(mem, index + 1); continue; } @@ -702,3 +703,36 @@ static int __init swiotlb_create_default_debugfs(void) late_initcall(swiotlb_create_default_debugfs); #endif + +#ifdef CONFIG_DMA_RESTRICTED_POOL +struct page *swiotlb_alloc(struct device *dev, size_t size) +{ + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; + phys_addr_t tlb_addr; + int index; + + if (!mem) + return NULL; + + index = swiotlb_find_slots(dev, 0, size); + if (index == -1) + return NULL; + + tlb_addr = slot_addr(mem->start, index); + + return pfn_to_page(PFN_DOWN(tlb_addr)); +} + +bool swiotlb_free(struct device *dev, struct page *page, size_t size) +{ + phys_addr_t tlb_addr = page_to_phys(page); + + if (!is_swiotlb_buffer(dev, tlb_addr)) + return false; + + swiotlb_release_slots(dev, tlb_addr); + + return true; +} + +#endif /* CONFIG_DMA_RESTRICTED_POOL */ -- cgit v1.2.3-70-g09d2 From 0b84e4f8b793eb4045fd64f6f514165a7974cd16 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:41 +0800 Subject: swiotlb: Add restricted DMA pool initialization Add the initialization function to create restricted DMA pools from matching reserved-memory nodes. Regardless of swiotlb setting, the restricted DMA pool is preferred if available. The restricted DMA pools provide a basic level of protection against the DMA overwriting buffer contents at unexpected times. However, to protect against general data leakage and system memory corruption, the system needs to provide a way to lock down the memory access, e.g., MPU. Signed-off-by: Claire Chang Reviewed-by: Christoph Hellwig Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- include/linux/swiotlb.h | 3 +- kernel/dma/Kconfig | 14 +++++++++ kernel/dma/swiotlb.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 3b9454d1e498..39284ff2a6cd 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -73,7 +73,8 @@ extern enum swiotlb_force swiotlb_force; * range check to see if the memory was in fact allocated by this * API. * @nslabs: The number of IO TLB blocks (in groups of 64) between @start and - * @end. This is command line adjustable via setup_io_tlb_npages. + * @end. For default swiotlb, this is command line adjustable via + * setup_io_tlb_npages. * @used: The number of used IO TLB block. * @list: The free list describing the number of free entries available * from each index. diff --git a/kernel/dma/Kconfig b/kernel/dma/Kconfig index 77b405508743..3e961dc39634 100644 --- a/kernel/dma/Kconfig +++ b/kernel/dma/Kconfig @@ -80,6 +80,20 @@ config SWIOTLB bool select NEED_DMA_MAP_STATE +config DMA_RESTRICTED_POOL + bool "DMA Restricted Pool" + depends on OF && OF_RESERVED_MEM + select SWIOTLB + help + This enables support for restricted DMA pools which provide a level of + DMA memory protection on systems with limited hardware protection + capabilities, such as those lacking an IOMMU. + + For more information see + + and . + If unsure, say "n". + # # Should be selected if we can mmap non-coherent mappings to userspace. # The only thing that is really required is a way to set an uncached bit diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 44fc3d10f017..0ffbaae9fba2 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -39,6 +39,13 @@ #ifdef CONFIG_DEBUG_FS #include #endif +#ifdef CONFIG_DMA_RESTRICTED_POOL +#include +#include +#include +#include +#include +#endif #include #include @@ -735,4 +742,73 @@ bool swiotlb_free(struct device *dev, struct page *page, size_t size) return true; } +static int rmem_swiotlb_device_init(struct reserved_mem *rmem, + struct device *dev) +{ + struct io_tlb_mem *mem = rmem->priv; + unsigned long nslabs = rmem->size >> IO_TLB_SHIFT; + + /* + * Since multiple devices can share the same pool, the private data, + * io_tlb_mem struct, will be initialized by the first device attached + * to it. + */ + if (!mem) { + mem = kzalloc(struct_size(mem, slots, nslabs), GFP_KERNEL); + if (!mem) + return -ENOMEM; + + set_memory_decrypted((unsigned long)phys_to_virt(rmem->base), + rmem->size >> PAGE_SHIFT); + swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false); + mem->force_bounce = true; + mem->for_alloc = true; + + rmem->priv = mem; + + if (IS_ENABLED(CONFIG_DEBUG_FS)) { + mem->debugfs = + debugfs_create_dir(rmem->name, debugfs_dir); + swiotlb_create_debugfs_files(mem); + } + } + + dev->dma_io_tlb_mem = mem; + + return 0; +} + +static void rmem_swiotlb_device_release(struct reserved_mem *rmem, + struct device *dev) +{ + dev->dma_io_tlb_mem = io_tlb_default_mem; +} + +static const struct reserved_mem_ops rmem_swiotlb_ops = { + .device_init = rmem_swiotlb_device_init, + .device_release = rmem_swiotlb_device_release, +}; + +static int __init rmem_swiotlb_setup(struct reserved_mem *rmem) +{ + unsigned long node = rmem->fdt_node; + + if (of_get_flat_dt_prop(node, "reusable", NULL) || + of_get_flat_dt_prop(node, "linux,cma-default", NULL) || + of_get_flat_dt_prop(node, "linux,dma-default", NULL) || + of_get_flat_dt_prop(node, "no-map", NULL)) + return -EINVAL; + + if (PageHighMem(pfn_to_page(PHYS_PFN(rmem->base)))) { + pr_err("Restricted DMA pool must be accessible within the linear mapping."); + return -EINVAL; + } + + rmem->ops = &rmem_swiotlb_ops; + pr_info("Reserved memory: created restricted DMA pool at %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + return 0; +} + +RESERVEDMEM_OF_DECLARE(dma, "restricted-dma-pool", rmem_swiotlb_setup); #endif /* CONFIG_DMA_RESTRICTED_POOL */ -- cgit v1.2.3-70-g09d2 From b12fe999545cf3fd89e1a178ee4e541a9331da82 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:42 +0800 Subject: dt-bindings: of: Add restricted DMA pool Introduce the new compatible string, restricted-dma-pool, for restricted DMA. One can specify the address and length of the restricted DMA memory region by restricted-dma-pool in the reserved-memory node. Signed-off-by: Claire Chang Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- .../bindings/reserved-memory/reserved-memory.txt | 36 ++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt index e8d3096d922c..39b5f4c5a511 100644 --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt @@ -51,6 +51,23 @@ compatible (optional) - standard definition used as a shared pool of DMA buffers for a set of devices. It can be used by an operating system to instantiate the necessary pool management subsystem if necessary. + - restricted-dma-pool: This indicates a region of memory meant to be + used as a pool of restricted DMA buffers for a set of devices. The + memory region would be the only region accessible to those devices. + When using this, the no-map and reusable properties must not be set, + so the operating system can create a virtual mapping that will be used + for synchronization. The main purpose for restricted DMA is to + mitigate the lack of DMA access control on systems without an IOMMU, + which could result in the DMA accessing the system memory at + unexpected times and/or unexpected addresses, possibly leading to data + leakage or corruption. The feature on its own provides a basic level + of protection against the DMA overwriting buffer contents at + unexpected times. However, to protect against general data leakage and + system memory corruption, the system needs to provide way to lock down + the memory access, e.g., MPU. Note that since coherent allocation + needs remapping, one must set up another device coherent pool by + shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic + coherent allocation. - vendor specific string in the form ,[-] no-map (optional) - empty property - Indicates the operating system must not create a virtual mapping @@ -85,10 +102,11 @@ memory-region-names (optional) - a list of names, one for each corresponding Example ------- -This example defines 3 contiguous regions are defined for Linux kernel: +This example defines 4 contiguous regions for Linux kernel: one default of all device drivers (named linux,cma@72000000 and 64MiB in size), -one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and -one for multimedia processing (named multimedia-memory@77000000, 64MiB). +one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), +one for multimedia processing (named multimedia-memory@77000000, 64MiB), and +one for restricted dma pool (named restricted_dma_reserved@0x50000000, 64MiB). / { #address-cells = <1>; @@ -120,6 +138,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB). compatible = "acme,multimedia-memory"; reg = <0x77000000 0x4000000>; }; + + restricted_dma_reserved: restricted_dma_reserved { + compatible = "restricted-dma-pool"; + reg = <0x50000000 0x4000000>; + }; }; /* ... */ @@ -138,4 +161,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB). memory-region = <&multimedia_reserved>; /* ... */ }; + + pcie_device: pcie_device@0,0 { + reg = <0x83010000 0x0 0x00000000 0x0 0x00100000 + 0x83010000 0x0 0x00100000 0x0 0x00100000>; + memory-region = <&restricted_dma_reserved>; + /* ... */ + }; }; -- cgit v1.2.3-70-g09d2 From fec9b625095f7308e52a6922619cd4abaa9534a8 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Sat, 19 Jun 2021 11:40:43 +0800 Subject: of: Add plumbing for restricted DMA pool If a device is not behind an IOMMU, we look up the device node and set up the restricted DMA when the restricted-dma-pool is presented. Signed-off-by: Claire Chang Tested-by: Stefano Stabellini Tested-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- drivers/of/address.c | 33 +++++++++++++++++++++++++++++++++ drivers/of/device.c | 3 +++ drivers/of/of_private.h | 6 ++++++ 3 files changed, 42 insertions(+) diff --git a/drivers/of/address.c b/drivers/of/address.c index 94f017d808c4..973257434398 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -995,6 +996,38 @@ out: of_node_put(node); return ret; } + +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) +{ + struct device_node *node, *of_node = dev->of_node; + int count, i; + + count = of_property_count_elems_of_size(of_node, "memory-region", + sizeof(u32)); + /* + * If dev->of_node doesn't exist or doesn't contain memory-region, try + * the OF node having DMA configuration. + */ + if (count <= 0) { + of_node = np; + count = of_property_count_elems_of_size( + of_node, "memory-region", sizeof(u32)); + } + + for (i = 0; i < count; i++) { + node = of_parse_phandle(of_node, "memory-region", i); + /* + * There might be multiple memory regions, but only one + * restricted-dma-pool region is allowed. + */ + if (of_device_is_compatible(node, "restricted-dma-pool") && + of_device_is_available(node)) + return of_reserved_mem_device_init_by_idx(dev, of_node, + i); + } + + return 0; +} #endif /* CONFIG_HAS_DMA */ /** diff --git a/drivers/of/device.c b/drivers/of/device.c index c5a9473a5fb1..2defdca418ec 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -165,6 +165,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, arch_setup_dma_ops(dev, dma_start, size, iommu, coherent); + if (!iommu) + return of_dma_set_restricted_buffer(dev, np); + return 0; } EXPORT_SYMBOL_GPL(of_dma_configure_id); diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 631489f7f8c0..376462798f7e 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -163,12 +163,18 @@ struct bus_dma_region; #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA) int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map); +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np); #else static inline int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) { return -ENODEV; } +static inline int of_dma_set_restricted_buffer(struct device *dev, + struct device_node *np) +{ + return -ENODEV; +} #endif void fdt_init_reserved_mem(void); -- cgit v1.2.3-70-g09d2 From 09a4a79d42ced8ca7fc250b05e45ac1cb23a9c52 Mon Sep 17 00:00:00 2001 From: Claire Chang Date: Thu, 1 Jul 2021 11:31:30 +0800 Subject: swiotlb: fix implicit debugfs declarations Factor out the debugfs bits from rmem_swiotlb_device_init() into a separate rmem_swiotlb_debugfs_init() to fix the implicit debugfs declarations. Fixes: 461021875c50 ("swiotlb: Add restricted DMA pool initialization") Reported-by: kernel test robot Signed-off-by: Claire Chang Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 0ffbaae9fba2..b7f76bca89bf 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -712,6 +712,21 @@ late_initcall(swiotlb_create_default_debugfs); #endif #ifdef CONFIG_DMA_RESTRICTED_POOL + +#ifdef CONFIG_DEBUG_FS +static void rmem_swiotlb_debugfs_init(struct reserved_mem *rmem) +{ + struct io_tlb_mem *mem = rmem->priv; + + mem->debugfs = debugfs_create_dir(rmem->name, debugfs_dir); + swiotlb_create_debugfs_files(mem); +} +#else +static void rmem_swiotlb_debugfs_init(struct reserved_mem *rmem) +{ +} +#endif + struct page *swiotlb_alloc(struct device *dev, size_t size) { struct io_tlb_mem *mem = dev->dma_io_tlb_mem; @@ -766,11 +781,7 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem, rmem->priv = mem; - if (IS_ENABLED(CONFIG_DEBUG_FS)) { - mem->debugfs = - debugfs_create_dir(rmem->name, debugfs_dir); - swiotlb_create_debugfs_files(mem); - } + rmem_swiotlb_debugfs_init(rmem); } dev->dma_io_tlb_mem = mem; -- cgit v1.2.3-70-g09d2 From 868c9ddc182bc6728bb380cbfb3170734f72c599 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Wed, 7 Jul 2021 14:12:54 +0900 Subject: swiotlb: add overflow checks to swiotlb_bounce This is a follow-up on 5f89468e2f06 ("swiotlb: manipulate orig_addr when tlb_addr has offset") which fixed unaligned dma mappings, making sure the following overflows are caught: - offset of the start of the slot within the device bigger than requested address' offset, in other words if the base address given in swiotlb_tbl_map_single to create the mapping (orig_addr) was after the requested address for the sync (tlb_offset) in the same block: |------------------------------------------| block <----------------------------> mapped part of the block ^ orig_addr ^ invalid tlb_addr for sync - if the resulting offset was bigger than the allocation size this one could happen if the mapping was not until the end. e.g. |------------------------------------------| block <---------------------> mapped part of the block ^ ^ orig_addr invalid tlb_addr Both should never happen so print a warning and bail out without trying to adjust the sizes/offsets: the first one could try to sync from orig_addr to whatever is left of the requested size, but the later really has nothing to sync there... Signed-off-by: Dominique Martinet Cc: Konrad Rzeszutek Wilk Reviewed-by: Bumyong Lee Cc: Christoph Hellwig Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index b7f76bca89bf..f1a9ae7fad8f 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -365,13 +365,27 @@ static void swiotlb_bounce(struct device *dev, phys_addr_t tlb_addr, size_t size size_t alloc_size = mem->slots[index].alloc_size; unsigned long pfn = PFN_DOWN(orig_addr); unsigned char *vaddr = phys_to_virt(tlb_addr); - unsigned int tlb_offset; + unsigned int tlb_offset, orig_addr_offset; if (orig_addr == INVALID_PHYS_ADDR) return; - tlb_offset = (tlb_addr & (IO_TLB_SIZE - 1)) - - swiotlb_align_offset(dev, orig_addr); + tlb_offset = tlb_addr & (IO_TLB_SIZE - 1); + orig_addr_offset = swiotlb_align_offset(dev, orig_addr); + if (tlb_offset < orig_addr_offset) { + dev_WARN_ONCE(dev, 1, + "Access before mapping start detected. orig offset %u, requested offset %u.\n", + orig_addr_offset, tlb_offset); + return; + } + + tlb_offset -= orig_addr_offset; + if (tlb_offset > alloc_size) { + dev_WARN_ONCE(dev, 1, + "Buffer overflow detected. Allocation size: %zu. Mapping size: %zu+%u.\n", + alloc_size, size, tlb_offset); + return; + } orig_addr += tlb_offset; alloc_size -= tlb_offset; -- cgit v1.2.3-70-g09d2 From fe364a7d95c24e07e9b3f2ab917f01d6d8330bba Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 12 Jul 2021 14:39:40 +0300 Subject: dmaengine: dw: Program xBAR hardware for Elkhart Lake Intel Elkhart Lake PSE DMA implementation is integrated with crossbar IP in order to serve more hardware than there are DMA request lines available. Due to this, program xBAR hardware to make flexible support of PSE peripheral. The Device-to-Device has not been tested and it's not supported by DMA Engine, but it's left in the code for the sake of documenting hardware features. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210712113940.42753-1-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw/idma32.c | 138 ++++++++++++++++++++++++++++++++++- drivers/dma/dw/internal.h | 16 ++++ drivers/dma/dw/pci.c | 6 +- drivers/dma/dw/platform.c | 6 +- include/linux/platform_data/dma-dw.h | 3 + 5 files changed, 160 insertions(+), 9 deletions(-) diff --git a/drivers/dma/dw/idma32.c b/drivers/dma/dw/idma32.c index 3ce44de25d33..58f4078d83fe 100644 --- a/drivers/dma/dw/idma32.c +++ b/drivers/dma/dw/idma32.c @@ -1,15 +1,144 @@ // SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2013,2018 Intel Corporation +// Copyright (C) 2013,2018,2020-2021 Intel Corporation #include #include #include +#include +#include #include #include #include "internal.h" -static void idma32_initialize_chan(struct dw_dma_chan *dwc) +#define DMA_CTL_CH(x) (0x1000 + (x) * 4) +#define DMA_SRC_ADDR_FILLIN(x) (0x1100 + (x) * 4) +#define DMA_DST_ADDR_FILLIN(x) (0x1200 + (x) * 4) +#define DMA_XBAR_SEL(x) (0x1300 + (x) * 4) +#define DMA_REGACCESS_CHID_CFG (0x1400) + +#define CTL_CH_TRANSFER_MODE_MASK GENMASK(1, 0) +#define CTL_CH_TRANSFER_MODE_S2S 0 +#define CTL_CH_TRANSFER_MODE_S2D 1 +#define CTL_CH_TRANSFER_MODE_D2S 2 +#define CTL_CH_TRANSFER_MODE_D2D 3 +#define CTL_CH_RD_RS_MASK GENMASK(4, 3) +#define CTL_CH_WR_RS_MASK GENMASK(6, 5) +#define CTL_CH_RD_NON_SNOOP_BIT BIT(8) +#define CTL_CH_WR_NON_SNOOP_BIT BIT(9) + +#define XBAR_SEL_DEVID_MASK GENMASK(15, 0) +#define XBAR_SEL_RX_TX_BIT BIT(16) +#define XBAR_SEL_RX_TX_SHIFT 16 + +#define REGACCESS_CHID_MASK GENMASK(2, 0) + +static unsigned int idma32_get_slave_devfn(struct dw_dma_chan *dwc) +{ + struct device *slave = dwc->chan.slave; + + if (!slave || !dev_is_pci(slave)) + return 0; + + return to_pci_dev(slave)->devfn; +} + +static void idma32_initialize_chan_xbar(struct dw_dma_chan *dwc) +{ + struct dw_dma *dw = to_dw_dma(dwc->chan.device); + void __iomem *misc = __dw_regs(dw); + u32 cfghi = 0, cfglo = 0; + u8 dst_id, src_id; + u32 value; + + /* DMA Channel ID Configuration register must be programmed first */ + value = readl(misc + DMA_REGACCESS_CHID_CFG); + + value &= ~REGACCESS_CHID_MASK; + value |= dwc->chan.chan_id; + + writel(value, misc + DMA_REGACCESS_CHID_CFG); + + /* Configure channel attributes */ + value = readl(misc + DMA_CTL_CH(dwc->chan.chan_id)); + + value &= ~(CTL_CH_RD_NON_SNOOP_BIT | CTL_CH_WR_NON_SNOOP_BIT); + value &= ~(CTL_CH_RD_RS_MASK | CTL_CH_WR_RS_MASK); + value &= ~CTL_CH_TRANSFER_MODE_MASK; + + switch (dwc->direction) { + case DMA_MEM_TO_DEV: + value |= CTL_CH_TRANSFER_MODE_D2S; + value |= CTL_CH_WR_NON_SNOOP_BIT; + break; + case DMA_DEV_TO_MEM: + value |= CTL_CH_TRANSFER_MODE_S2D; + value |= CTL_CH_RD_NON_SNOOP_BIT; + break; + default: + /* + * Memory-to-Memory and Device-to-Device are ignored for now. + * + * For Memory-to-Memory transfers we would need to set mode + * and disable snooping on both sides. + */ + return; + } + + writel(value, misc + DMA_CTL_CH(dwc->chan.chan_id)); + + /* Configure crossbar selection */ + value = readl(misc + DMA_XBAR_SEL(dwc->chan.chan_id)); + + /* DEVFN selection */ + value &= ~XBAR_SEL_DEVID_MASK; + value |= idma32_get_slave_devfn(dwc); + + switch (dwc->direction) { + case DMA_MEM_TO_DEV: + value |= XBAR_SEL_RX_TX_BIT; + break; + case DMA_DEV_TO_MEM: + value &= ~XBAR_SEL_RX_TX_BIT; + break; + default: + /* Memory-to-Memory and Device-to-Device are ignored for now */ + return; + } + + writel(value, misc + DMA_XBAR_SEL(dwc->chan.chan_id)); + + /* Configure DMA channel low and high registers */ + switch (dwc->direction) { + case DMA_MEM_TO_DEV: + dst_id = dwc->chan.chan_id; + src_id = dwc->dws.src_id; + break; + case DMA_DEV_TO_MEM: + dst_id = dwc->dws.dst_id; + src_id = dwc->chan.chan_id; + break; + default: + /* Memory-to-Memory and Device-to-Device are ignored for now */ + return; + } + + /* Set default burst alignment */ + cfglo |= IDMA32C_CFGL_DST_BURST_ALIGN | IDMA32C_CFGL_SRC_BURST_ALIGN; + + /* Low 4 bits of the request lines */ + cfghi |= IDMA32C_CFGH_DST_PER(dst_id & 0xf); + cfghi |= IDMA32C_CFGH_SRC_PER(src_id & 0xf); + + /* Request line extension (2 bits) */ + cfghi |= IDMA32C_CFGH_DST_PER_EXT(dst_id >> 4 & 0x3); + cfghi |= IDMA32C_CFGH_SRC_PER_EXT(src_id >> 4 & 0x3); + + channel_writel(dwc, CFG_LO, cfglo); + channel_writel(dwc, CFG_HI, cfghi); +} + +static void idma32_initialize_chan_generic(struct dw_dma_chan *dwc) { u32 cfghi = 0; u32 cfglo = 0; @@ -134,7 +263,10 @@ int idma32_dma_probe(struct dw_dma_chip *chip) return -ENOMEM; /* Channel operations */ - dw->initialize_chan = idma32_initialize_chan; + if (chip->pdata->quirks & DW_DMA_QUIRK_XBAR_PRESENT) + dw->initialize_chan = idma32_initialize_chan_xbar; + else + dw->initialize_chan = idma32_initialize_chan_generic; dw->suspend_chan = idma32_suspend_chan; dw->resume_chan = idma32_resume_chan; dw->prepare_ctllo = idma32_prepare_ctllo; diff --git a/drivers/dma/dw/internal.h b/drivers/dma/dw/internal.h index 2e1c52eefdeb..563ce73488db 100644 --- a/drivers/dma/dw/internal.h +++ b/drivers/dma/dw/internal.h @@ -74,4 +74,20 @@ static __maybe_unused const struct dw_dma_chip_pdata idma32_chip_pdata = { .remove = idma32_dma_remove, }; +static const struct dw_dma_platform_data xbar_pdata = { + .nr_channels = 8, + .chan_allocation_order = CHAN_ALLOCATION_ASCENDING, + .chan_priority = CHAN_PRIORITY_ASCENDING, + .block_size = 131071, + .nr_masters = 1, + .data_width = {4}, + .quirks = DW_DMA_QUIRK_XBAR_PRESENT, +}; + +static __maybe_unused const struct dw_dma_chip_pdata xbar_chip_pdata = { + .pdata = &xbar_pdata, + .probe = idma32_dma_probe, + .remove = idma32_dma_remove, +}; + #endif /* _DMA_DW_INTERNAL_H */ diff --git a/drivers/dma/dw/pci.c b/drivers/dma/dw/pci.c index 1142aa6f8c4a..26a3f926da02 100644 --- a/drivers/dma/dw/pci.c +++ b/drivers/dma/dw/pci.c @@ -120,9 +120,9 @@ static const struct pci_device_id dw_pci_id_table[] = { { PCI_VDEVICE(INTEL, 0x22c0), (kernel_ulong_t)&dw_dma_chip_pdata }, /* Elkhart Lake iDMA 32-bit (PSE DMA) */ - { PCI_VDEVICE(INTEL, 0x4bb4), (kernel_ulong_t)&idma32_chip_pdata }, - { PCI_VDEVICE(INTEL, 0x4bb5), (kernel_ulong_t)&idma32_chip_pdata }, - { PCI_VDEVICE(INTEL, 0x4bb6), (kernel_ulong_t)&idma32_chip_pdata }, + { PCI_VDEVICE(INTEL, 0x4bb4), (kernel_ulong_t)&xbar_chip_pdata }, + { PCI_VDEVICE(INTEL, 0x4bb5), (kernel_ulong_t)&xbar_chip_pdata }, + { PCI_VDEVICE(INTEL, 0x4bb6), (kernel_ulong_t)&xbar_chip_pdata }, /* Haswell */ { PCI_VDEVICE(INTEL, 0x9c60), (kernel_ulong_t)&dw_dma_chip_pdata }, diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index 0585d749d935..246118955877 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c @@ -149,9 +149,9 @@ static const struct acpi_device_id dw_dma_acpi_id_table[] = { { "808622C0", (kernel_ulong_t)&dw_dma_chip_pdata }, /* Elkhart Lake iDMA 32-bit (PSE DMA) */ - { "80864BB4", (kernel_ulong_t)&idma32_chip_pdata }, - { "80864BB5", (kernel_ulong_t)&idma32_chip_pdata }, - { "80864BB6", (kernel_ulong_t)&idma32_chip_pdata }, + { "80864BB4", (kernel_ulong_t)&xbar_chip_pdata }, + { "80864BB5", (kernel_ulong_t)&xbar_chip_pdata }, + { "80864BB6", (kernel_ulong_t)&xbar_chip_pdata }, { } }; diff --git a/include/linux/platform_data/dma-dw.h b/include/linux/platform_data/dma-dw.h index b34a094b2258..b11b0c8bc5da 100644 --- a/include/linux/platform_data/dma-dw.h +++ b/include/linux/platform_data/dma-dw.h @@ -52,6 +52,7 @@ struct dw_dma_slave { * @max_burst: Maximum value of burst transaction size supported by hardware * per channel (in units of CTL.SRC_TR_WIDTH/CTL.DST_TR_WIDTH). * @protctl: Protection control signals setting per channel. + * @quirks: Optional platform quirks. */ struct dw_dma_platform_data { unsigned int nr_channels; @@ -71,6 +72,8 @@ struct dw_dma_platform_data { #define CHAN_PROTCTL_CACHEABLE BIT(2) #define CHAN_PROTCTL_MASK GENMASK(2, 0) unsigned char protctl; +#define DW_DMA_QUIRK_XBAR_PRESENT BIT(0) + unsigned int quirks; }; #endif /* _PLATFORM_DATA_DMA_DW_H */ -- cgit v1.2.3-70-g09d2 From 53b50458110d829c8fc45e7803a335a515698fd8 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 8 Jul 2021 07:08:26 +0200 Subject: dmaengine: idxd: Simplify code and axe the use of a deprecated API The wrappers in include/linux/pci-dma-compat.h should go away. Replace 'pci_set_dma_mask/pci_set_consistent_dma_mask' by an equivalent and less verbose 'dma_set_mask_and_coherent()' call. Even if the code may look different, it should have exactly the same run-time behavior. If pci_set_dma_mask(64) fails and pci_set_dma_mask(32) succeeds, then pci_set_consistent_dma_mask(64) will also fail. Signed-off-by: Christophe JAILLET Acked-by: Dave Jiang Link: https://lore.kernel.org/r/70c8a3bc67e41c5fefb526ecd64c5174c1e2dc76.1625720835.git.christophe.jaillet@wanadoo.fr Signed-off-by: Vinod Koul --- drivers/dma/idxd/init.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index c8ae41d36040..de300ba38b14 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -637,15 +637,9 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } dev_dbg(dev, "Set DMA masks\n"); - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (rc) - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (rc) - goto err; - - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - if (rc) - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (rc) goto err; -- cgit v1.2.3-70-g09d2 From 0dcfe41e9a4ca759ccc87a48e3bb9cc3b08ff1e8 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 4 Jun 2021 17:06:21 -0700 Subject: dmanegine: idxd: cleanup all device related bits after disabling device The previous state cleanup patch only performed wq state cleanups. This does not go far enough as when device is disabled or reset, the state for groups and engines must also be cleaned up. Add additional state cleanup beyond wq cleanup. Tie those cleanups directly to device disable and reset, and wq disable and reset. Fixes: da32b28c95a7 ("dmaengine: idxd: cleanup workqueue config after disabling") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162285154108.2096632.5572805472362321307.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 88 ++++++++++++++++++++++++++++++++++------------- drivers/dma/idxd/idxd.h | 6 ++-- drivers/dma/idxd/irq.c | 4 +-- drivers/dma/idxd/sysfs.c | 22 +++--------- 4 files changed, 74 insertions(+), 46 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 420b93fe5feb..928c2c8817f0 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -15,6 +15,8 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, u32 *status); +static void idxd_device_wqs_clear_state(struct idxd_device *idxd); +static void idxd_wq_disable_cleanup(struct idxd_wq *wq); /* Interrupt control bits */ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id) @@ -234,7 +236,7 @@ int idxd_wq_enable(struct idxd_wq *wq) return 0; } -int idxd_wq_disable(struct idxd_wq *wq) +int idxd_wq_disable(struct idxd_wq *wq, bool reset_config) { struct idxd_device *idxd = wq->idxd; struct device *dev = &idxd->pdev->dev; @@ -255,6 +257,8 @@ int idxd_wq_disable(struct idxd_wq *wq) return -ENXIO; } + if (reset_config) + idxd_wq_disable_cleanup(wq); wq->state = IDXD_WQ_DISABLED; dev_dbg(dev, "WQ %d disabled\n", wq->id); return 0; @@ -289,6 +293,7 @@ void idxd_wq_reset(struct idxd_wq *wq) operand = BIT(wq->id % 16) | ((wq->id / 16) << 16); idxd_cmd_exec(idxd, IDXD_CMD_RESET_WQ, operand, NULL); + idxd_wq_disable_cleanup(wq); wq->state = IDXD_WQ_DISABLED; } @@ -337,7 +342,7 @@ int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid) unsigned int offset; unsigned long flags; - rc = idxd_wq_disable(wq); + rc = idxd_wq_disable(wq, false); if (rc < 0) return rc; @@ -364,7 +369,7 @@ int idxd_wq_disable_pasid(struct idxd_wq *wq) unsigned int offset; unsigned long flags; - rc = idxd_wq_disable(wq); + rc = idxd_wq_disable(wq, false); if (rc < 0) return rc; @@ -383,11 +388,11 @@ int idxd_wq_disable_pasid(struct idxd_wq *wq) return 0; } -void idxd_wq_disable_cleanup(struct idxd_wq *wq) +static void idxd_wq_disable_cleanup(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; - lockdep_assert_held(&idxd->dev_lock); + lockdep_assert_held(&wq->wq_lock); memset(wq->wqcfg, 0, idxd->wqcfg_size); wq->type = IDXD_WQT_NONE; wq->size = 0; @@ -548,22 +553,6 @@ int idxd_device_enable(struct idxd_device *idxd) return 0; } -void idxd_device_wqs_clear_state(struct idxd_device *idxd) -{ - int i; - - lockdep_assert_held(&idxd->dev_lock); - - for (i = 0; i < idxd->max_wqs; i++) { - struct idxd_wq *wq = idxd->wqs[i]; - - if (wq->state == IDXD_WQ_ENABLED) { - idxd_wq_disable_cleanup(wq); - wq->state = IDXD_WQ_DISABLED; - } - } -} - int idxd_device_disable(struct idxd_device *idxd) { struct device *dev = &idxd->pdev->dev; @@ -585,7 +574,7 @@ int idxd_device_disable(struct idxd_device *idxd) } spin_lock_irqsave(&idxd->dev_lock, flags); - idxd_device_wqs_clear_state(idxd); + idxd_device_clear_state(idxd); idxd->state = IDXD_DEV_CONF_READY; spin_unlock_irqrestore(&idxd->dev_lock, flags); return 0; @@ -597,7 +586,7 @@ void idxd_device_reset(struct idxd_device *idxd) idxd_cmd_exec(idxd, IDXD_CMD_RESET_DEVICE, 0, NULL); spin_lock_irqsave(&idxd->dev_lock, flags); - idxd_device_wqs_clear_state(idxd); + idxd_device_clear_state(idxd); idxd->state = IDXD_DEV_CONF_READY; spin_unlock_irqrestore(&idxd->dev_lock, flags); } @@ -685,6 +674,59 @@ int idxd_device_release_int_handle(struct idxd_device *idxd, int handle, } /* Device configuration bits */ +static void idxd_engines_clear_state(struct idxd_device *idxd) +{ + struct idxd_engine *engine; + int i; + + lockdep_assert_held(&idxd->dev_lock); + for (i = 0; i < idxd->max_engines; i++) { + engine = idxd->engines[i]; + engine->group = NULL; + } +} + +static void idxd_groups_clear_state(struct idxd_device *idxd) +{ + struct idxd_group *group; + int i; + + lockdep_assert_held(&idxd->dev_lock); + for (i = 0; i < idxd->max_groups; i++) { + group = idxd->groups[i]; + memset(&group->grpcfg, 0, sizeof(group->grpcfg)); + group->num_engines = 0; + group->num_wqs = 0; + group->use_token_limit = false; + group->tokens_allowed = 0; + group->tokens_reserved = 0; + group->tc_a = -1; + group->tc_b = -1; + } +} + +static void idxd_device_wqs_clear_state(struct idxd_device *idxd) +{ + int i; + + lockdep_assert_held(&idxd->dev_lock); + for (i = 0; i < idxd->max_wqs; i++) { + struct idxd_wq *wq = idxd->wqs[i]; + + if (wq->state == IDXD_WQ_ENABLED) { + idxd_wq_disable_cleanup(wq); + wq->state = IDXD_WQ_DISABLED; + } + } +} + +void idxd_device_clear_state(struct idxd_device *idxd) +{ + idxd_groups_clear_state(idxd); + idxd_engines_clear_state(idxd); + idxd_device_wqs_clear_state(idxd); +} + void idxd_msix_perm_setup(struct idxd_device *idxd) { union msix_perm mperm; diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 26482c7d4c3a..1f0991dec679 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -420,9 +420,8 @@ int idxd_device_init_reset(struct idxd_device *idxd); int idxd_device_enable(struct idxd_device *idxd); int idxd_device_disable(struct idxd_device *idxd); void idxd_device_reset(struct idxd_device *idxd); -void idxd_device_cleanup(struct idxd_device *idxd); +void idxd_device_clear_state(struct idxd_device *idxd); int idxd_device_config(struct idxd_device *idxd); -void idxd_device_wqs_clear_state(struct idxd_device *idxd); void idxd_device_drain_pasid(struct idxd_device *idxd, int pasid); int idxd_device_load_config(struct idxd_device *idxd); int idxd_device_request_int_handle(struct idxd_device *idxd, int idx, int *handle, @@ -435,12 +434,11 @@ void idxd_wqs_unmap_portal(struct idxd_device *idxd); int idxd_wq_alloc_resources(struct idxd_wq *wq); void idxd_wq_free_resources(struct idxd_wq *wq); int idxd_wq_enable(struct idxd_wq *wq); -int idxd_wq_disable(struct idxd_wq *wq); +int idxd_wq_disable(struct idxd_wq *wq, bool reset_config); void idxd_wq_drain(struct idxd_wq *wq); void idxd_wq_reset(struct idxd_wq *wq); int idxd_wq_map_portal(struct idxd_wq *wq); void idxd_wq_unmap_portal(struct idxd_wq *wq); -void idxd_wq_disable_cleanup(struct idxd_wq *wq); int idxd_wq_set_pasid(struct idxd_wq *wq, int pasid); int idxd_wq_disable_pasid(struct idxd_wq *wq); void idxd_wq_quiesce(struct idxd_wq *wq); diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index ae68e1e5487a..7a2cf0512501 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -59,7 +59,7 @@ static void idxd_device_reinit(struct work_struct *work) return; out: - idxd_device_wqs_clear_state(idxd); + idxd_device_clear_state(idxd); } static void idxd_device_fault_work(struct work_struct *work) @@ -192,7 +192,7 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) spin_lock_bh(&idxd->dev_lock); idxd_wqs_quiesce(idxd); idxd_wqs_unmap_portal(idxd); - idxd_device_wqs_clear_state(idxd); + idxd_device_clear_state(idxd); dev_err(&idxd->pdev->dev, "idxd halted, need %s.\n", gensts.reset_type == IDXD_DEVICE_RESET_FLR ? diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 0460d58e3941..71cd73fefec6 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -129,7 +129,7 @@ static int enable_wq(struct idxd_wq *wq) rc = idxd_wq_map_portal(wq); if (rc < 0) { dev_warn(dev, "wq portal mapping failed: %d\n", rc); - rc = idxd_wq_disable(wq); + rc = idxd_wq_disable(wq, false); if (rc < 0) dev_warn(dev, "IDXD wq disable failed\n"); mutex_unlock(&wq->wq_lock); @@ -262,8 +262,6 @@ static void disable_wq(struct idxd_wq *wq) static int idxd_config_bus_remove(struct device *dev) { - int rc; - dev_dbg(dev, "%s called for %s\n", __func__, dev_name(dev)); /* disable workqueue here */ @@ -288,22 +286,12 @@ static int idxd_config_bus_remove(struct device *dev) } idxd_unregister_dma_device(idxd); - rc = idxd_device_disable(idxd); - if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) { - for (i = 0; i < idxd->max_wqs; i++) { - struct idxd_wq *wq = idxd->wqs[i]; - - mutex_lock(&wq->wq_lock); - idxd_wq_disable_cleanup(wq); - mutex_unlock(&wq->wq_lock); - } - } + idxd_device_disable(idxd); + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) + idxd_device_reset(idxd); module_put(THIS_MODULE); - if (rc < 0) - dev_warn(dev, "Device disable failed\n"); - else - dev_info(dev, "Device %s disabled\n", dev_name(dev)); + dev_info(dev, "Device %s disabled\n", dev_name(dev)); } return 0; -- cgit v1.2.3-70-g09d2 From e753a64bee753136087dfd70b37fdd199e942ea9 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 3 Jun 2021 14:57:35 -0700 Subject: dmaengine: idxd: Add wq occupancy information to sysfs attribute Add occupancy information to wq sysfs attribute. Attribute will show wq occupancy data if "WQ Occupancy Support" field in WQCAP is 1. It displays the number of entries currently in this WQ. This is provided as an estimate and should not be relied on to determine whether there is space in the WQ. The data is to provide information to user apps for flow control. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162275745546.1857062.8765615879420582018.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- Documentation/ABI/stable/sysfs-driver-dma-idxd | 7 +++++++ drivers/dma/idxd/registers.h | 3 +++ drivers/dma/idxd/sysfs.c | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/Documentation/ABI/stable/sysfs-driver-dma-idxd b/Documentation/ABI/stable/sysfs-driver-dma-idxd index d431e2d00472..adb0c93e8dfc 100644 --- a/Documentation/ABI/stable/sysfs-driver-dma-idxd +++ b/Documentation/ABI/stable/sysfs-driver-dma-idxd @@ -211,6 +211,13 @@ Contact: dmaengine@vger.kernel.org Description: Indicate whether ATS disable is turned on for the workqueue. 0 indicates ATS is on, and 1 indicates ATS is off for the workqueue. +What: /sys/bus/dsa/devices/wq./occupancy +Date May 25, 2021 +KernelVersion: 5.14.0 +Contact: dmaengine@vger.kernel.org +Description: Show the current number of entries in this WQ if WQ Occupancy + Support bit WQ capabilities is 1. + What: /sys/bus/dsa/devices/engine./group_id Date: Oct 25, 2019 KernelVersion: 5.6.0 diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h index c970c3f025f0..7343a8f48819 100644 --- a/drivers/dma/idxd/registers.h +++ b/drivers/dma/idxd/registers.h @@ -349,6 +349,9 @@ union wqcfg { } __packed; #define WQCFG_PASID_IDX 2 +#define WQCFG_OCCUP_IDX 6 + +#define WQCFG_OCCUP_MASK 0xffff /* * This macro calculates the offset into the WQCFG register diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 71cd73fefec6..a193de32536d 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -1246,6 +1246,24 @@ static ssize_t wq_ats_disable_store(struct device *dev, struct device_attribute static struct device_attribute dev_attr_wq_ats_disable = __ATTR(ats_disable, 0644, wq_ats_disable_show, wq_ats_disable_store); +static ssize_t wq_occupancy_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct idxd_wq *wq = confdev_to_wq(dev); + struct idxd_device *idxd = wq->idxd; + u32 occup, offset; + + if (!idxd->hw.wq_cap.occupancy) + return -EOPNOTSUPP; + + offset = WQCFG_OFFSET(idxd, wq->id, WQCFG_OCCUP_IDX); + occup = ioread32(idxd->reg_base + offset) & WQCFG_OCCUP_MASK; + + return sysfs_emit(buf, "%u\n", occup); +} + +static struct device_attribute dev_attr_wq_occupancy = + __ATTR(occupancy, 0444, wq_occupancy_show, NULL); + static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_clients.attr, &dev_attr_wq_state.attr, @@ -1261,6 +1279,7 @@ static struct attribute *idxd_wq_attributes[] = { &dev_attr_wq_max_transfer_size.attr, &dev_attr_wq_max_batch_size.attr, &dev_attr_wq_ats_disable.attr, + &dev_attr_wq_occupancy.attr, NULL, }; -- cgit v1.2.3-70-g09d2 From 53499d1fc11267e078557fc68ce943c1eb3b7a37 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 3 Jun 2021 11:01:37 -0700 Subject: dmaengine: idxd: have command status always set The cached command status is only set when the write back status is is passed in. Move the variable set outside of the check so it is always set. Fixes: 0d5c10b4c84d ("dmaengine: idxd: add work queue drain support") Reported-by: Ramesh Thomas Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162274329740.1822314.3443875665504707588.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 928c2c8817f0..c8cf1de72176 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -486,6 +486,7 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, union idxd_command_reg cmd; DECLARE_COMPLETION_ONSTACK(done); unsigned long flags; + u32 stat; if (idxd_device_is_halted(idxd)) { dev_warn(&idxd->pdev->dev, "Device is HALTED!\n"); @@ -518,11 +519,11 @@ static void idxd_cmd_exec(struct idxd_device *idxd, int cmd_code, u32 operand, */ spin_unlock_irqrestore(&idxd->cmd_lock, flags); wait_for_completion(&done); + stat = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET); spin_lock_irqsave(&idxd->cmd_lock, flags); - if (status) { - *status = ioread32(idxd->reg_base + IDXD_CMDSTS_OFFSET); - idxd->cmd_status = *status & GENMASK(7, 0); - } + if (status) + *status = stat; + idxd->cmd_status = stat & GENMASK(7, 0); __clear_bit(IDXD_FLAG_CMD_RUNNING, &idxd->flags); /* Wake up other pending commands */ -- cgit v1.2.3-70-g09d2 From ac24a2dc06cd773895d2fba0378c2538b8176565 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 24 Jun 2021 12:08:21 -0700 Subject: dmaengine: idxd: add missing percpu ref put on failure When enqcmds() fails, exit path is missing a percpu_ref_put(). This can cause failure on shutdown path when the driver is attempting to quiesce the wq. Add missing percpu_ref_put() call on the error exit path. Fixes: 93a40a6d7428 ("dmaengine: idxd: add percpu_ref to descriptor submission path") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162456170168.1121236.7240941044089212312.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/submit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index 19afb62abaff..b0f1ddf75d31 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -118,8 +118,10 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) * device is not accepting descriptor at all. */ rc = enqcmds(portal, desc->hw); - if (rc < 0) + if (rc < 0) { + percpu_ref_put(&wq->wq_active); return rc; + } } percpu_ref_put(&wq->wq_active); -- cgit v1.2.3-70-g09d2 From 6cfd9e62e3297993f9f9d2d15f3acb14a0e8abbf Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 24 Jun 2021 13:39:33 -0700 Subject: dmaengine: idxd: assign MSIX vectors to each WQ rather than roundrobin IOPS increased when changing MSIX vector to per WQ from roundrobin. Allows descriptor to be completed by the submitter improves caching locality. Suggested-by: Konstantin Ananyev Signed-off-by: Dave Jiang Acked-by: Konstantin Ananyev Link: https://lore.kernel.org/r/162456717326.1130457.15258077196523268356.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 2 -- drivers/dma/idxd/submit.c | 36 ++++++++---------------------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 1f0991dec679..edfa81f0fe18 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -153,7 +153,6 @@ struct idxd_wq { enum idxd_wq_state state; unsigned long flags; union wqcfg *wqcfg; - u32 vec_ptr; /* interrupt steering */ struct dsa_hw_desc **hw_descs; int num_descs; union { @@ -290,7 +289,6 @@ struct idxd_desc { struct list_head list; int id; int cpu; - unsigned int vector; struct idxd_wq *wq; }; diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index b0f1ddf75d31..425eeea9577b 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -22,22 +22,13 @@ static struct idxd_desc *__get_desc(struct idxd_wq *wq, int idx, int cpu) desc->hw->pasid = idxd->pasid; /* - * Descriptor completion vectors are 1...N for MSIX. We will round - * robin through the N vectors. + * On host, MSIX vecotr 0 is used for misc interrupt. Therefore when we match + * vector 1:1 to the WQ id, we need to add 1 */ - wq->vec_ptr = (wq->vec_ptr % idxd->num_wq_irqs) + 1; - if (!idxd->int_handles) { - desc->hw->int_handle = wq->vec_ptr; - } else { - desc->vector = wq->vec_ptr; - /* - * int_handles are only for descriptor completion. However for device - * MSIX enumeration, vec 0 is used for misc interrupts. Therefore even - * though we are rotating through 1...N for descriptor interrupts, we - * need to acqurie the int_handles from 0..N-1. - */ - desc->hw->int_handle = idxd->int_handles[desc->vector - 1]; - } + if (!idxd->int_handles) + desc->hw->int_handle = wq->id + 1; + else + desc->hw->int_handle = idxd->int_handles[wq->id]; return desc; } @@ -130,19 +121,8 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) * Pending the descriptor to the lockless list for the irq_entry * that we designated the descriptor to. */ - if (desc->hw->flags & IDXD_OP_FLAG_RCI) { - int vec; - - /* - * If the driver is on host kernel, it would be the value - * assigned to interrupt handle, which is index for MSIX - * vector. If it's guest then can't use the int_handle since - * that is the index to IMS for the entire device. The guest - * device local index will be used. - */ - vec = !idxd->int_handles ? desc->hw->int_handle : desc->vector; - llist_add(&desc->llnode, &idxd->irq_entries[vec].pending_llist); - } + if (desc->hw->flags & IDXD_OP_FLAG_RCI) + llist_add(&desc->llnode, &idxd->irq_entries[wq->id + 1].pending_llist); return 0; } -- cgit v1.2.3-70-g09d2 From b2296eeac91555bd13f774efa7ab7d4b12fb71ef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 25 Jun 2021 10:38:10 +0200 Subject: dmaengine: idxd: depends on !UML Now that UML has PCI support, this driver must depend also on !UML since it pokes at X86_64 architecture internals that don't exist on ARCH=um. Reported-by: kernel test robot Signed-off-by: Johannes Berg Acked-by: Dave Jiang Acked-By: Anton Ivanov Link: https://lore.kernel.org/r/20210625103810.fe877ae0aef4.If240438e3f50ae226f3f755fc46ea498c6858393@changeid Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 39b5b46e880f..f450e4231db7 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -279,7 +279,7 @@ config INTEL_IDMA64 config INTEL_IDXD tristate "Intel Data Accelerators support" - depends on PCI && X86_64 + depends on PCI && X86_64 && !UML depends on PCI_MSI depends on SBITMAP select DMA_ENGINE -- cgit v1.2.3-70-g09d2 From 05f3485cad759b2d63c5625caef334de4c2cb57d Mon Sep 17 00:00:00 2001 From: Alex Bee Date: Thu, 27 May 2021 17:44:44 +0200 Subject: dt-bindings: mfd: syscon: add Rockchip RK3036/RK3228 qos compatibles Document Rockchip RK3036/RK3228 qos compatibles Signed-off-by: Alex Bee Reviewed-by: Heiko Stuebner Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/syscon.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index f14ae6da0068..ad1121620e15 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -45,7 +45,9 @@ properties: - microchip,sparx5-cpu-syscon - mstar,msc313-pmsleep - rockchip,px30-qos + - rockchip,rk3036-qos - rockchip,rk3066-qos + - rockchip,rk3228-qos - rockchip,rk3288-qos - rockchip,rk3399-qos - samsung,exynos3-sysreg -- cgit v1.2.3-70-g09d2 From f861d1d77a17e66b90be11c2575f6631879cebb1 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Thu, 24 Jun 2021 19:47:18 +0800 Subject: dt-bindings: mfd: syscon: Add rk3568 QoS register compatible Document rk3568 compatible for QoS registers. Signed-off-by: Liang Chen Acked-by: Rob Herring Acked-by: Heiko Stuebner Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/syscon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index ad1121620e15..abe3fd817e0b 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -50,6 +50,7 @@ properties: - rockchip,rk3228-qos - rockchip,rk3288-qos - rockchip,rk3399-qos + - rockchip,rk3568-qos - samsung,exynos3-sysreg - samsung,exynos4-sysreg - samsung,exynos5-sysreg -- cgit v1.2.3-70-g09d2 From 4faee8b65ec32346f8096e64c5fa1d5a73121742 Mon Sep 17 00:00:00 2001 From: Zou Wei Date: Tue, 4 May 2021 10:22:57 +0800 Subject: dmaengine: sprd: Add missing MODULE_DEVICE_TABLE This patch adds missing MODULE_DEVICE_TABLE definition which generates correct modalias for automatic loading of this driver when it is built as an external module. Reported-by: Hulk Robot Signed-off-by: Zou Wei Reviewed-by: Baolin Wang Link: https://lore.kernel.org/r/1620094977-70146-1-git-send-email-zou_wei@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/sprd-dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 0ef5ca81ba4d..4357d2395e6b 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -1265,6 +1265,7 @@ static const struct of_device_id sprd_dma_match[] = { { .compatible = "sprd,sc9860-dma", }, {}, }; +MODULE_DEVICE_TABLE(of, sprd_dma_match); static int __maybe_unused sprd_dma_runtime_suspend(struct device *dev) { -- cgit v1.2.3-70-g09d2 From e6c65d354fae36e5a3ccd9dca6cec05ea2e4473a Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Sun, 20 Jun 2021 13:28:43 +0800 Subject: docs/zh_CN: create new translations for zh_CN/dev-tools/testing-overview Create new translations for dev-tools/testing-overview.rst and link it to dev-tools/index.rst with TODOList modifications. Signed-off-by: Hu Haowen Reviewed-by: Wu XiangCheng Reviewed-by: Yanteng Si Signed-off-by: Wu XiangCheng Link: https://lore.kernel.org/r/20210620052841.GA22083@bobwxc.top Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/dev-tools/index.rst | 5 + .../zh_CN/dev-tools/testing-overview.rst | 108 +++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 Documentation/translations/zh_CN/dev-tools/testing-overview.rst diff --git a/Documentation/translations/zh_CN/dev-tools/index.rst b/Documentation/translations/zh_CN/dev-tools/index.rst index e6c99f2f543f..0f770b8664e9 100644 --- a/Documentation/translations/zh_CN/dev-tools/index.rst +++ b/Documentation/translations/zh_CN/dev-tools/index.rst @@ -11,6 +11,9 @@ 目前这些文档已经整理在一起,不需要再花费额外的精力。 欢迎任何补丁。 +有关测试专用工具的简要概述,参见 +Documentation/translations/zh_CN/dev-tools/testing-overview.rst + .. class:: toc-title 目录 @@ -18,6 +21,7 @@ .. toctree:: :maxdepth: 2 + testing-overview gcov kasan @@ -29,6 +33,7 @@ Todolist: - ubsan - kmemleak - kcsan + - kfence - gdb-kernel-debugging - kgdb - kselftest diff --git a/Documentation/translations/zh_CN/dev-tools/testing-overview.rst b/Documentation/translations/zh_CN/dev-tools/testing-overview.rst new file mode 100644 index 000000000000..8206d5b477e2 --- /dev/null +++ b/Documentation/translations/zh_CN/dev-tools/testing-overview.rst @@ -0,0 +1,108 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/dev-tools/testing-overview.rst +:Translator: 胡皓文 Hu Haowen + +============ +内核测试指南 +============ + +有许多不同的工具可以用于测试Linux内核,因此了解什么时候使用它们可能 +很困难。本文档粗略概述了它们之间的区别,并阐释了它们是怎样糅合在一起 +的。 + +编写和运行测试 +============== + +大多数内核测试都是用kselftest或KUnit框架之一编写的。它们都让运行测试 +更加简化,并为编写新测试提供帮助。 + +如果你想验证内核的行为——尤其是内核的特定部分——那你就要使用kUnit或 +kselftest。 + +KUnit和kselftest的区别 +---------------------- + +.. note:: + 由于本文段中部分术语尚无较好的对应中文释义,可能导致与原文含义 + 存在些许差异,因此建议读者结合原文 + (Documentation/dev-tools/testing-overview.rst)辅助阅读。 + 如对部分翻译有异议或有更好的翻译意见,欢迎联系译者进行修订。 + +KUnit(Documentation/dev-tools/kunit/index.rst)是用于“白箱”测 +试的一个完整的内核内部系统:因为测试代码是内核的一部分,所以它能够访 +问用户空间不能访问到的内部结构和功能。 + +因此,KUnit测试最好针对内核中较小的、自包含的部分,以便能够独立地测 +试。“单元”测试的概念亦是如此。 + +比如,一个KUnit测试可能测试一个单独的内核功能(甚至通过一个函数测试 +一个单一的代码路径,例如一个错误处理案例),而不是整个地测试一个特性。 + +这也使得KUnit测试构建和运行非常地快,从而能够作为开发流程的一部分被 +频繁地运行。 + +有关更详细的介绍,请参阅KUnit测试代码风格指南 +Documentation/dev-tools/kunit/style.rst + +kselftest(Documentation/dev-tools/kselftest.rst),相对来说,大量用 +于用户空间,并且通常测试用户空间的脚本或程序。 + +这使得编写复杂的测试,或者需要操作更多全局系统状态的测试更加容易(诸 +如生成进程之类)。然而,从kselftest直接调用内核函数是不行的。这也就 +意味着只有通过某种方式(如系统调用、驱动设备、文件系统等)导出到了用 +户空间的内核功能才能使用kselftest来测试。为此,有些测试包含了一个伴 +生的内核模块用于导出更多的信息和功能。不过,对于基本上或者完全在内核 +中运行的测试,KUnit可能是更佳工具。 + +kselftest也因此非常适合于全部功能的测试,因为这些功能会将接口暴露到 +用户空间,从而能够被测试,而不是展现实现细节。“system”测试和 +“end-to-end”测试亦是如此。 + +比如,一个新的系统调用应该伴随有新的kselftest测试。 + +代码覆盖率工具 +============== + +支持两种不同代码之间的覆盖率测量工具。它们可以用来验证一项测试执行的 +确切函数或代码行。这有助于决定内核被测试了多少,或用来查找合适的测试 +中没有覆盖到的极端情况。 + +Documentation/translations/zh_CN/dev-tools/gcov.rst 是GCC的覆盖率测试工具,能用于获取内核的全局或每个模块的 +覆盖率。与KCOV不同的是,这个工具不记录每个任务的覆盖率。覆盖率数据可 +以通过debugfs读取,并通过常规的gcov工具进行解释。 + +Documentation/dev-tools/kcov.rst 是能够构建在内核之中,用于在每个任务的层面捕捉覆盖率的一 +个功能。因此,它对于模糊测试和关于代码执行期间信息的其它情况非常有用, +比如在一个单一系统调用里使用它就很有用。 + +动态分析工具 +============ + +内核也支持许多动态分析工具,用以检测正在运行的内核中出现的多种类型的 +问题。这些工具通常每个去寻找一类不同的缺陷,比如非法内存访问,数据竞 +争等并发问题,或整型溢出等其他未定义行为。 + +如下所示: + +* kmemleak检测可能的内存泄漏。参阅 + Documentation/dev-tools/kmemleak.rst +* KASAN检测非法内存访问,如数组越界和释放后重用(UAF)。参阅 + Documentation/dev-tools/kasan.rst +* UBSAN检测C标准中未定义的行为,如整型溢出。参阅 + Documentation/dev-tools/ubsan.rst +* KCSAN检测数据竞争。参阅 Documentation/dev-tools/kcsan.rst +* KFENCE是一个低开销的内存问题检测器,比KASAN更快且能被用于批量构建。 + 参阅 Documentation/dev-tools/kfence.rst +* lockdep是一个锁定正确性检测器。参阅 + Documentation/locking/lockdep-design.rst +* 除此以外,在内核中还有一些其它的调试工具,大多数能在 + lib/Kconfig.debug 中找到。 + +这些工具倾向于对内核进行整体测试,并且不像kselftest和KUnit一样“传递”。 +它们可以通过在启用这些工具时运行内核测试以与kselftest或KUnit结合起来: +之后你就能确保这些错误在测试过程中都不会发生了。 + +一些工具与KUnit和kselftest集成,并且在检测到问题时会自动打断测试。 -- cgit v1.2.3-70-g09d2 From c767ef4519b3716d74a78e0bafad250b0c6e1783 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 9 Jul 2021 11:01:43 +0800 Subject: docs/zh_CN: add core api genericirq translation translate Documentation/core-api/genericirq.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Wu XiangCheng Link: https://lore.kernel.org/r/20210709030143.548940-1-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/core-api/genericirq.rst | 409 +++++++++++++++++++++ .../translations/zh_CN/core-api/index.rst | 2 +- 2 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/core-api/genericirq.rst diff --git a/Documentation/translations/zh_CN/core-api/genericirq.rst b/Documentation/translations/zh_CN/core-api/genericirq.rst new file mode 100644 index 000000000000..05ccb954c18d --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/genericirq.rst @@ -0,0 +1,409 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/genericirq.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 吴想成 Wu XiangCheng + +.. include:: + +.. _cn_core-api_genericirq: + +================ +Linux通用IRQ处理 +================ + +:版权: |copy| 2005-2010: Thomas Gleixner +:版权: |copy| 2005-2006: Ingo Molnar + +简介 +==== + +通用中断处理层是为了给设备驱动程序提供一个完整的中断处理抽象(层)。它能够处 +理所有不同类型的中断控制器硬件。设备驱动程序使用通用API函数来请求、启用、禁 +用和释放中断。驱动程序不需要知道任何关于硬件处理中断的细节,所以它们可以在不同的 +平台上使用而不需要修改代码。 + +本文档提供给那些希望在通用IRQ处理层的帮助下实现基于其架构的中断子系统的开发 +者。 + +理论依据 +======== + +Linux中中断处理的原始实现使用__do_IRQ()超级处理程序,它能够处理每种类型的 +中断逻辑。 + +最初,Russell King确定了不同类型的处理程序,以便为Linux 2.5/2.6中的ARM中 +断处理程序实现建立一个相当通用的集合。他区分了以下几种类型: + +- 电平触发型 + +- 边沿触发型 + +- 简单型 + +在实现过程中,我们发现了另一种类型: + +- 响应EOI(end of interrupt)型 + +在SMP的__do_IRQ()超级处理程序中,还需定义一种类型: + +-  每cpu型(针对CPU SMP) + +这种高层IRQ处理程序的拆分实现使我们能够为每个特定的中断类型优化中断处理的流 +程。这减少了该特定代码路径的复杂性,并允许对特定类型进行优化处理。 + +最初的通用IRQ实现使用hw_interrupt_type结构体及其 ``->ack`` ``->end`` 等回 +调来区分超级处理程序中的流控制。这导致了流逻辑和低级硬件逻辑的混合,也导致了 +不必要的代码重复:例如i386中的 ``ioapic_level_irq`` 和 ``ioapic_edge_irq`` , +这两个IRQ类型共享许多低级的细节,但有不同的流处理。 + +一个更自然的抽象是“irq流”和“芯片细节”的干净分离。 + +分析一些架构的IRQ子系统的实现可以发现,他们中的大多数可以使用一套通用的“irq +流”方法,只需要添加芯片级的特定代码。这种分离对于那些需要IRQ流本身而不需要芯 +片细节的特定(子)架构也很有价值——以提供了一个更透明的IRQ子系统设计。 + +每个中断描述符都被分配给它自己的高层流程处理程序,这通常是一个通用的实现。(这 +种高层次的流程处理程序的实现也使得提供解复用处理程序变得简单,这可以在各种架 +构的嵌入式平台上找到。) + +这种分离使得通用中断处理层更加灵活和可扩展。例如,一个(子)架构可以使用通用 +的IRQ流实现“电平触发型”中断,并添加一个(子)架构特定的“边沿型”实现。 + +为了使向新模型的过渡更容易,并防止破坏现有实现,__do_IRQ()超级处理程序仍然 +可用。这导致了一种暂时的双重性。随着时间的推移,新的模型应该在越来越多的架构中 +被使用,因为它能使IRQ子系统更小更干净。它已经被废弃三年了,即将被删除。 + +已知的缺陷和假设 +================ + +没有(但愿如此)。 + +抽象层 +====== + +中断代码中主要有三个抽象层次: + +1. 高级别的驱动API + +2. 高级别的IRQ流处理器 + +3. 芯片级的硬件封装 + +中断控制流 +---------- + +每个中断都由一个中断描述符结构体irq_desc来描述。中断是由一个“无符号整型”的数值来 +引用的,它在描述符结构体数组中选择相应的中断描述符结构体。描述符结构体包含状态 +信息和指向中断流方法和中断芯片结构的指针,这些都是分配给这个中断的。 + +每当中断触发时,低级架构代码通过调用desc->handle_irq()调用到通用中断代码中。 +这个高层IRQ处理函数只使用由分配的芯片描述符结构体引用的desc->irq_data.chip +基元。 + +高级驱动程序API +--------------- + +高层驱动API由以下函数组成: + +- request_irq() + +- request_threaded_irq() + +- free_irq() + +- disable_irq() + +- enable_irq() + +- disable_irq_nosync() (SMP only) + +- synchronize_irq() (SMP only) + +- irq_set_irq_type() + +- irq_set_irq_wake() + +- irq_set_handler_data() + +- irq_set_chip() + +- irq_set_chip_data() + +详见自动生成的函数文档。 + +.. note:: + + 由于文档构建流程所限,中文文档中并没有引入自动生成的函数文档,所以请读者直接 + 阅读源码注释。 + +电平触发型IRQ流处理程序 +----------------------- + +通用层提供了一套预定义的irq-flow方法: + +- handle_level_irq() + +- handle_edge_irq() + +- handle_fasteoi_irq() + +- handle_simple_irq() + +- handle_percpu_irq() + +- handle_edge_eoi_irq() + +- handle_bad_irq() + +中断流处理程序(无论是预定义的还是架构特定的)由架构在启动期间或设备初始化期间分配给 +特定中断。 + +默认流实现 +~~~~~~~~~~ + +辅助函数 +^^^^^^^^ + +辅助函数调用芯片基元,并被默认流实现所使用。以下是实现的辅助函数(简化摘录):: + + default_enable(struct irq_data *data) + { + desc->irq_data.chip->irq_unmask(data); + } + + default_disable(struct irq_data *data) + { + if (!delay_disable(data)) + desc->irq_data.chip->irq_mask(data); + } + + default_ack(struct irq_data *data) + { + chip->irq_ack(data); + } + + default_mask_ack(struct irq_data *data) + { + if (chip->irq_mask_ack) { + chip->irq_mask_ack(data); + } else { + chip->irq_mask(data); + chip->irq_ack(data); + } + } + + noop(struct irq_data *data)) + { + } + + + +默认流处理程序的实现 +~~~~~~~~~~~~~~~~~~~~ + +电平触发型IRQ流处理器 +^^^^^^^^^^^^^^^^^^^^^ + +handle_level_irq为电平触发型的中断提供了一个通用实现。 + +实现的控制流如下(简化摘录):: + + desc->irq_data.chip->irq_mask_ack(); + handle_irq_event(desc->action); + desc->irq_data.chip->irq_unmask(); + + +默认的需回应IRQ流处理器 +^^^^^^^^^^^^^^^^^^^^^^^ + +handle_fasteoi_irq为中断提供了一个通用的实现,它只需要在处理程序的末端有一个EOI。 + +实现的控制流如下(简化摘录):: + + handle_irq_event(desc->action); + desc->irq_data.chip->irq_eoi(); + + +默认的边沿触发型IRQ流处理器 +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +handle_edge_irq为边沿触发型的中断提供了一个通用的实现。 + +实现的控制流如下(简化摘录):: + + if (desc->status & running) { + desc->irq_data.chip->irq_mask_ack(); + desc->status |= pending | masked; + return; + } + desc->irq_data.chip->irq_ack(); + desc->status |= running; + do { + if (desc->status & masked) + desc->irq_data.chip->irq_unmask(); + desc->status &= ~pending; + handle_irq_event(desc->action); + } while (status & pending); + desc->status &= ~running; + + +默认的简单型IRQ流处理器 +^^^^^^^^^^^^^^^^^^^^^^^ + +handle_simple_irq提供了一个简单型中断的通用实现。 + +.. note:: + + 简单型的流处理程序不调用任何处理程序/芯片基元。 + +实现的控制流程如下(简化摘录):: + + handle_irq_event(desc->action); + + +默认的每CPU型流处理程序 +^^^^^^^^^^^^^^^^^^^^^^^ + +handle_percpu_irq为每CPU型中断提供一个通用的实现。 + +每个CPU中断只在SMP上可用,该处理程序提供了一个没有锁的简化版本。 + +以下是控制流的实现(简化摘录):: + + if (desc->irq_data.chip->irq_ack) + desc->irq_data.chip->irq_ack(); + handle_irq_event(desc->action); + if (desc->irq_data.chip->irq_eoi) + desc->irq_data.chip->irq_eoi(); + + +EOI边沿型IRQ流处理器 +^^^^^^^^^^^^^^^^^^^^ + +handle_edge_eoi_irq提供了一个异常的边沿触发型处理程序,它只用于拯救powerpc/cell +上的一个严重失控的irq控制器。 + +坏的IRQ流处理器 +^^^^^^^^^^^^^^^ + +handle_bad_irq用于处理没有真正分配处理程序的假中断。 + +特殊性和优化 +~~~~~~~~~~~~ + +通用函数是为“干净”的架构和芯片设计的,它们没有平台特定的IRQ处理特殊性。如果一 +个架构需要在“流”的层面上实现特殊性,那么它可以通过覆盖高层的IRQ-流处理程序来实 +现。 + +延迟中断禁用 +~~~~~~~~~~~~ + +每个中断可选择的功能是由Russell King在ARM中断实现中引入的,当调用disable_irq() +时,不会在硬件层面上屏蔽中断。中断保持启用状态,而在中断事件发生时在流处理器中被 +屏蔽。这可以防止在硬件上丢失边沿中断,因为硬件上不存储边沿中断事件,而中断在硬件 +级被禁用。当一个中断在IRQ_DISABLED标志被设置时到达,那么该中断在硬件层面被屏蔽, +IRQ_PENDING位被设置。当中断被enable_irq()重新启用时,将检查挂起位,如果它被设置, +中断将通过硬件或软件重发机制重新发送。(当你想使用延迟中断禁用功能,而你的硬件又不 +能重新触发中断时,有必要启用CONFIG_HARDIRQS_SW_RESEND。) 延迟中断禁止功能是不可 +配置的。 + +芯片级硬件封装 +-------------- + +芯片级硬件描述符结构体 :c:type:`irq_chip` 包含了所有与芯片直接相关的功能,这些功 +能可以被irq流实现所利用。 + +- ``irq_ack`` + +- ``irq_mask_ack`` - 可选的,建议使用的性能 + +- ``irq_mask`` + +- ``irq_unmask`` + +- ``irq_eoi`` - 可选的,EOI流处理程序需要 + +- ``irq_retrigger`` - 可选的 + +- ``irq_set_type`` - 可选的 + +- ``irq_set_wake`` - 可选的 + +这些基元的意思是严格意义上的:ack是指ACK,masking是指对IRQ线的屏蔽,等等。这取决 +于流处理器如何使用这些基本的低级功能单元。 + +__do_IRQ入口点 +============== + +最初的实现__do_IRQ()是所有类型中断的替代入口点。它已经不存在了。 + +这个处理程序被证明不适合所有的中断硬件,因此被重新实现了边沿/级别/简单/超高速中断 +的拆分功能。这不仅是一个功能优化。它也缩短了中断的代码路径。 + +在SMP上的锁 +=========== + +芯片寄存器的锁定是由定义芯片基元的架构决定的。每个寄存器的结构通过desc->lock,由 +通用层保护。 + +通用中断芯片 +============ + +为了避免复制相同的IRQ芯片实现,核心提供了一个可配置的通用中断芯片实现。开发者在自 +己实现相同的功能之前,应该仔细检查通用芯片是否符合他们的需求,并以稍微不同的方式实 +现相同的功能。 + +该API在以下内核代码中: + +kernel/irq/generic-chip.c + +结构体 +====== + +本章包含自动生成的结构体文档,这些结构体在通用IRQ层中使用。 + +该API在以下内核代码中: + +include/linux/irq.h + +include/linux/interrupt.h + +提供的通用函数 +============== + +这一章包含了自动生成的内核API函数的文档,这些函数被导出。 + +该API在以下内核代码中: + +kernel/irq/manage.c + +kernel/irq/chip.c + +提供的内部函数 +============== + +本章包含自动生成的内部函数的文档。 + +该API在以下内核代码中: + +kernel/irq/irqdesc.c + +kernel/irq/handle.c + +kernel/irq/chip.c + +鸣谢 +==== + +感谢以下人士对本文档作出的贡献: + +1. Thomas Gleixner tglx@linutronix.de + +2. Ingo Molnar mingo@elte.hu diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index b4bde9396339..71a212a2a9db 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -80,13 +80,13 @@ Todolist: :maxdepth: 1 cachetlb + genericirq Todolist: cpu_hotplug memory-hotplug - genericirq protection-keys -- cgit v1.2.3-70-g09d2 From 153c43a84c7f092b21d9624ffd819552cd5c915b Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Fri, 25 Jun 2021 23:54:37 +0200 Subject: Documentation: arm: marvell: Add few missing models and documentation files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár Link: https://lore.kernel.org/r/20210625215437.2156-1-pali@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/arm/marvell.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/arm/marvell.rst b/Documentation/arm/marvell.rst index db2246493d18..85169bc3f538 100644 --- a/Documentation/arm/marvell.rst +++ b/Documentation/arm/marvell.rst @@ -58,11 +58,19 @@ Kirkwood family - Product Brief : https://web.archive.org/web/20120616201621/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6180-003_ver1.pdf - Hardware Spec : https://web.archive.org/web/20130730091654/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6180_OpenSource.pdf - Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + - 88F6280 + + - Product Brief : https://web.archive.org/web/20130730091058/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6280_SoC_PB-001.pdf - 88F6281 - Product Brief : https://web.archive.org/web/20120131133709/http://www.marvell.com/embedded-processors/kirkwood/assets/88F6281-004_ver1.pdf - Hardware Spec : https://web.archive.org/web/20120620073511/http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf - Functional Spec: https://web.archive.org/web/20130730091033/http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf + - 88F6321 + - 88F6322 + - 88F6323 + + - Product Brief : https://web.archive.org/web/20120616201639/http://www.marvell.com/embedded-processors/kirkwood/assets/88f632x_pb.pdf Homepage: https://web.archive.org/web/20160513194943/http://www.marvell.com/embedded-processors/kirkwood/ Core: @@ -89,6 +97,10 @@ Discovery family - MV76100 + - Product Brief : https://web.archive.org/web/20140722064429/http://www.marvell.com/embedded-processors/discovery-innovation/assets/MV76100-002_WEB.pdf + - Hardware Spec : https://web.archive.org/web/20140722064425/http://www.marvell.com/embedded-processors/discovery-innovation/assets/HW_MV76100_OpenSource.pdf + - Functional Spec: https://web.archive.org/web/20111110081125/http://www.marvell.com/embedded-processors/discovery-innovation/assets/FS_MV76100_78100_78200_OpenSource.pdf + Not supported by the Linux kernel. Core: @@ -124,17 +136,23 @@ EBU Armada family Armada 38x Flavors: - 88F6810 Armada 380 + - 88F6811 Armada 381 + - 88F6821 Armada 382 + - 88F6W21 Armada 383 - 88F6820 Armada 385 - 88F6828 Armada 388 - Product infos: https://web.archive.org/web/20181006144616/http://www.marvell.com/embedded-processors/armada-38x/ - Functional Spec: https://web.archive.org/web/20200420191927/https://www.marvell.com/content/dam/marvell/en/public-collateral/embedded-processors/marvell-embedded-processors-armada-38x-functional-specifications-2015-11.pdf + - Hardware Spec: https://web.archive.org/web/20180713105318/https://www.marvell.com/docs/embedded-processors/assets/marvell-embedded-processors-armada-38x-hardware-specifications-2017-03.pdf + - Design guide: https://web.archive.org/web/20180712231737/https://www.marvell.com/docs/embedded-processors/assets/marvell-embedded-processors-armada-38x-hardware-design-guide-2017-08.pdf Core: ARM Cortex-A9 Armada 39x Flavors: - 88F6920 Armada 390 + - 88F6925 Armada 395 - 88F6928 Armada 398 - Product infos: https://web.archive.org/web/20181020222559/http://www.marvell.com/embedded-processors/armada-39x/ -- cgit v1.2.3-70-g09d2 From f1285c68e12558b147979b96f4efcbc2eb0c48cd Mon Sep 17 00:00:00 2001 From: Cengiz Can Date: Tue, 29 Jun 2021 17:15:09 +0300 Subject: Documentation: sysrq: convert to third person Two parts of the sysrq documentation have sentences written from a first person's point of view. Documentation is generally written from a third person's view in a formal way. Convert those senteces to be less personal and generic. Signed-off-by: Cengiz Can Link: https://lore.kernel.org/r/20210629141508.52229-1-cengiz@kernel.wtf Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/sysrq.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guide/sysrq.rst index 60ce5f5ebab6..0a178ef0111d 100644 --- a/Documentation/admin-guide/sysrq.rst +++ b/Documentation/admin-guide/sysrq.rst @@ -72,7 +72,7 @@ On PowerPC On other If you know of the key combos for other architectures, please - let me know so I can add them to this section. + submit a patch to be included in this section. On all Write a character to /proc/sysrq-trigger. e.g.:: @@ -205,10 +205,12 @@ frozen (probably root) filesystem via the FIFREEZE ioctl. Sometimes SysRq seems to get 'stuck' after using it, what can I do? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -That happens to me, also. I've found that tapping shift, alt, and control -on both sides of the keyboard, and hitting an invalid sysrq sequence again -will fix the problem. (i.e., something like :kbd:`alt-sysrq-z`). Switching to -another virtual console (:kbd:`ALT+Fn`) and then back again should also help. +When this happens, try tapping shift, alt and control on both sides of the +keyboard, and hitting an invalid sysrq sequence again. (i.e., something like +:kbd:`alt-sysrq-z`). + +Switching to another virtual console (:kbd:`ALT+Fn`) and then back again +should also help. I hit SysRq, but nothing seems to happen, what's wrong? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3-70-g09d2 From 341968c617ca7726b444fdb23e5b2efb0881c5db Mon Sep 17 00:00:00 2001 From: Hu Jialun Date: Sun, 4 Jul 2021 00:48:34 +0800 Subject: docs/zh_CN: Remove the Microsoft rhetoric Update Chinese translation on par with original English coding-style.rst Related commit b7592e5b82db19b72a34b471f3296ad3f651c8b9 Signed-off-by: Hu Jialun Reviewed-by: Hu Haowen Link: https://lore.kernel.org/r/20210703164834.460447-1-hujialun@comp.nus.edu.sg Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/process/coding-style.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/translations/zh_CN/process/coding-style.rst b/Documentation/translations/zh_CN/process/coding-style.rst index b8c484a84d10..638d714bec83 100644 --- a/Documentation/translations/zh_CN/process/coding-style.rst +++ b/Documentation/translations/zh_CN/process/coding-style.rst @@ -268,8 +268,7 @@ C 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字 ``count_active_users()`` 或者类似的名字,你不应该叫它 ``cntuser()`` 。 在函数名中包含函数类型 (所谓的匈牙利命名法) 是脑子出了问题——编译器知道那些类 -型而且能够检查那些类型,这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题 -的程序。 +型而且能够检查那些类型,这样做只能把程序员弄糊涂了。 本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计 数器,它应该被称为 ``i`` 。叫它 ``loop_counter`` 并无益处,如果它没有被误解的 -- cgit v1.2.3-70-g09d2 From f8c6a07c25ce7ff99f6d7e19352e495af6af1d69 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 9 Jul 2021 11:00:34 +0800 Subject: docs/core-api: Modify document layout Modify the layout of the document and remove unnecessary symbols. Signed-off-by: Yanteng Si Reviewed-by: Wu XiangCheng Link: https://lore.kernel.org/r/f151bbc0d1ff6cf24611a698c76b90181f005f8d.1625798719.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/core-api/cpu_hotplug.rst | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Documentation/core-api/cpu_hotplug.rst b/Documentation/core-api/cpu_hotplug.rst index a2c96bec5ee8..0c872cbea7d5 100644 --- a/Documentation/core-api/cpu_hotplug.rst +++ b/Documentation/core-api/cpu_hotplug.rst @@ -91,9 +91,10 @@ Never use anything other than ``cpumask_t`` to represent bitmap of CPUs. Using CPU hotplug ================= + The kernel option *CONFIG_HOTPLUG_CPU* needs to be enabled. It is currently available on multiple architectures including ARM, MIPS, PowerPC and X86. The -configuration is done via the sysfs interface: :: +configuration is done via the sysfs interface:: $ ls -lh /sys/devices/system/cpu total 0 @@ -113,14 +114,14 @@ configuration is done via the sysfs interface: :: The files *offline*, *online*, *possible*, *present* represent the CPU masks. Each CPU folder contains an *online* file which controls the logical on (1) and -off (0) state. To logically shutdown CPU4: :: +off (0) state. To logically shutdown CPU4:: $ echo 0 > /sys/devices/system/cpu/cpu4/online smpboot: CPU 4 is now offline Once the CPU is shutdown, it will be removed from */proc/interrupts*, */proc/cpuinfo* and should also not be shown visible by the *top* command. To -bring CPU4 back online: :: +bring CPU4 back online:: $ echo 1 > /sys/devices/system/cpu/cpu4/online smpboot: Booting Node 0 Processor 4 APIC 0x1 @@ -142,6 +143,7 @@ The CPU hotplug coordination The offline case ---------------- + Once a CPU has been logically shutdown the teardown callbacks of registered hotplug states will be invoked, starting with ``CPUHP_ONLINE`` and terminating at state ``CPUHP_OFFLINE``. This includes: @@ -158,9 +160,10 @@ at state ``CPUHP_OFFLINE``. This includes: Using the hotplug API --------------------- + It is possible to receive notifications once a CPU is offline or onlined. This might be important to certain drivers which need to perform some kind of setup -or clean up functions based on the number of available CPUs: :: +or clean up functions based on the number of available CPUs:: #include @@ -186,9 +189,10 @@ During the removal of a hotplug state the teardown callback will be invoked. Multiple instances ~~~~~~~~~~~~~~~~~~ + If a driver has multiple instances and each instance needs to perform the callback independently then it is likely that a ''multi-state'' should be used. -First a multi-state state needs to be registered: :: +First a multi-state state needs to be registered:: ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "X/Y:online, Y_online, Y_prepare_down); @@ -197,7 +201,7 @@ First a multi-state state needs to be registered: :: The ``cpuhp_setup_state_multi()`` behaves similar to ``cpuhp_setup_state()`` except it prepares the callbacks for a multi state and does not invoke the callbacks. This is a one time setup. -Once a new instance is allocated, you need to register this new instance: :: +Once a new instance is allocated, you need to register this new instance:: ret = cpuhp_state_add_instance(Y_hp_online, &d->node); @@ -206,7 +210,8 @@ This function will add this instance to your previously allocated (*Y_online*) on all online CPUs. The *node* element is a ``struct hlist_node`` member of your per-instance data structure. -On removal of the instance: :: +On removal of the instance:: + cpuhp_state_remove_instance(Y_hp_online, &d->node) should be invoked which will invoke the teardown callback on all online @@ -214,6 +219,7 @@ CPUs. Manual setup ~~~~~~~~~~~~ + Usually it is handy to invoke setup and teardown callbacks on registration or removal of a state because usually the operation needs to performed once a CPU goes online (offline) and during initial setup (shutdown) of the driver. However @@ -226,6 +232,7 @@ hotplug operations. The ordering of the events -------------------------- + The hotplug states are defined in ``include/linux/cpuhotplug.h``: * The states *CPUHP_OFFLINE* … *CPUHP_AP_OFFLINE* are invoked before the @@ -248,13 +255,14 @@ another hotplug event. Testing of hotplug states ========================= + One way to verify whether a custom state is working as expected or not is to shutdown a CPU and then put it online again. It is also possible to put the CPU to certain state (for instance *CPUHP_AP_ONLINE*) and then go back to *CPUHP_ONLINE*. This would simulate an error one state after *CPUHP_AP_ONLINE* which would lead to rollback to the online state. -All registered states are enumerated in ``/sys/devices/system/cpu/hotplug/states``: :: +All registered states are enumerated in ``/sys/devices/system/cpu/hotplug/states`` :: $ tail /sys/devices/system/cpu/hotplug/states 138: mm/vmscan:online @@ -268,7 +276,7 @@ All registered states are enumerated in ``/sys/devices/system/cpu/hotplug/states 168: sched:active 169: online -To rollback CPU4 to ``lib/percpu_cnt:online`` and back online just issue: :: +To rollback CPU4 to ``lib/percpu_cnt:online`` and back online just issue:: $ cat /sys/devices/system/cpu/cpu4/hotplug/state 169 @@ -276,14 +284,14 @@ To rollback CPU4 to ``lib/percpu_cnt:online`` and back online just issue: :: $ cat /sys/devices/system/cpu/cpu4/hotplug/state 140 -It is important to note that the teardown callbac of state 140 have been -invoked. And now get back online: :: +It is important to note that the teardown callback of state 140 have been +invoked. And now get back online:: $ echo 169 > /sys/devices/system/cpu/cpu4/hotplug/target $ cat /sys/devices/system/cpu/cpu4/hotplug/state 169 -With trace events enabled, the individual steps are visible, too: :: +With trace events enabled, the individual steps are visible, too:: # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | @@ -318,6 +326,7 @@ trace. Architecture's requirements =========================== + The following functions and configurations are required: ``CONFIG_HOTPLUG_CPU`` @@ -339,11 +348,12 @@ The following functions and configurations are required: User Space Notification ======================= -After CPU successfully onlined or offline udev events are sent. A udev rule like: :: + +After CPU successfully onlined or offline udev events are sent. A udev rule like:: SUBSYSTEM=="cpu", DRIVERS=="processor", DEVPATH=="/devices/system/cpu/*", RUN+="the_hotplug_receiver.sh" -will receive all events. A script like: :: +will receive all events. A script like:: #!/bin/sh -- cgit v1.2.3-70-g09d2 From d4229805df852d5b6508ea7e186c974446147634 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 9 Jul 2021 11:00:35 +0800 Subject: docs/zh_CN: add core api cpu_hotplug translation Translate Documentation/core-api/cpu_hotplug.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Wu XiangCheng Link: https://lore.kernel.org/r/5c2273563e64ccbbaf1e7ff043d2ab467879c421.1625798719.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/core-api/cpu_hotplug.rst | 348 +++++++++++++++++++++ .../translations/zh_CN/core-api/index.rst | 2 +- 2 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/core-api/cpu_hotplug.rst diff --git a/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst new file mode 100644 index 000000000000..85a264287426 --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/cpu_hotplug.rst @@ -0,0 +1,348 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/cpu_hotplug.rst +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 吴想成 Wu XiangCheng + +.. _cn_core_api_cpu_hotplug: + +================= +内核中的CPU热拔插 +================= + +:时间: 2016年12月 +:作者: Sebastian Andrzej Siewior , + Rusty Russell , + Srivatsa Vaddagiri , + Ashok Raj , + Joel Schopp + +简介 +==== + +现代系统架构的演进已经在处理器中引入了先进的错误报告和纠正能力。有一些OEM也支 +持可热拔插的NUMA(Non Uniform Memory Access,非统一内存访问)硬件,其中物理 +节点的插入和移除需要支持CPU热插拔。 + +这样的进步要求内核可用的CPU被移除,要么是出于配置的原因,要么是出于RAS的目的, +以保持一个不需要的CPU不在系统执行路径。因此需要在Linux内核中支持CPU热拔插。 + +CPU热拔插支持的一个更新颖的用途是它在SMP的暂停恢复支持中的应用。双核和超线程支 +持使得即使是笔记本电脑也能运行不支持这些方法的SMP内核。 + + +命令行开关 +========== + +``maxcpus=n`` + 限制启动时的CPU为 *n* 个。例如,如果你有四个CPU,使用 ``maxcpus=2`` 将只能启 + 动两个。你可以选择稍后让其他CPU上线。 + +``nr_cpus=n`` + 限制内核将支持的CPU总量。如果这里提供的数量低于实际可用的CPU数量,那么其他CPU + 以后就不能上线了。 + +``additional_cpus=n`` + 使用它来限制可热插拔的CPU。该选项设置 + ``cpu_possible_mask = cpu_present_mask + additional_cpus`` + + 这个选项只限于IA64架构。 + +``possible_cpus=n`` + 这个选项设置 ``cpu_possible_mask`` 中的 ``possible_cpus`` 位。 + + 这个选项只限于X86和S390架构。 + +``cpu0_hotplug`` + 允许关闭CPU0。 + + 这个选项只限于X86架构。 + +CPU位图 +======= + +``cpu_possible_mask`` + 系统中可能可用CPU的位图。这是用来为per_cpu变量分配一些启动时的内存,这些变量 + 不会随着CPU的可用或移除而增加/减少。一旦在启动时的发现阶段被设置,该映射就是静态 + 的,也就是说,任何时候都不会增加或删除任何位。根据你的系统需求提前准确地调整它 + 可以节省一些启动时的内存。 + +``cpu_online_mask`` + 当前在线的所有CPU的位图。在一个CPU可用于内核调度并准备接收设备的中断后,它被 + 设置在 ``__cpu_up()`` 中。当使用 ``__cpu_disable()`` 关闭一个CPU时,它被清 + 空,在此之前,所有的操作系统服务包括中断都被迁移到另一个目标CPU。 + +``cpu_present_mask`` + 系统中当前存在的CPU的位图。它们并非全部在线。当物理热拔插被相关的子系统 + (如ACPI)处理时,可以改变和添加新的位或从位图中删除,这取决于事件是 + hot-add/hot-remove。目前还没有定死规定。典型的用法是在启动时启动拓扑结构,这时 + 热插拔被禁用。 + +你真的不需要操作任何系统的CPU映射。在大多数情况下,它们应该是只读的。当设置每个 +CPU资源时,几乎总是使用 ``cpu_possible_mask`` 或 ``for_each_possible_cpu()`` +来进行迭代。宏 ``for_each_cpu()`` 可以用来迭代一个自定义的CPU掩码。 + +不要使用 ``cpumask_t`` 以外的任何东西来表示CPU的位图。 + + +使用CPU热拔插 +============= + +内核选项 *CONFIG_HOTPLUG_CPU* 需要被启用。它目前可用于多种架构,包括ARM、MIPS、 +PowerPC和X86。配置是通过sysfs接口完成的:: + + $ ls -lh /sys/devices/system/cpu + total 0 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu0 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu1 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu2 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu3 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu4 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu5 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu6 + drwxr-xr-x 9 root root 0 Dec 21 16:33 cpu7 + drwxr-xr-x 2 root root 0 Dec 21 16:33 hotplug + -r--r--r-- 1 root root 4.0K Dec 21 16:33 offline + -r--r--r-- 1 root root 4.0K Dec 21 16:33 online + -r--r--r-- 1 root root 4.0K Dec 21 16:33 possible + -r--r--r-- 1 root root 4.0K Dec 21 16:33 present + +文件 *offline* 、 *online* 、*possible* 、*present* 代表CPU掩码。每个CPU文件 +夹包含一个 *online* 文件,控制逻辑上的开(1)和关(0)状态。要在逻辑上关闭CPU4:: + + $ echo 0 > /sys/devices/system/cpu/cpu4/online + smpboot: CPU 4 is now offline + +一旦CPU被关闭,它将从 */proc/interrupts* 、*/proc/cpuinfo* 中被删除,也不应该 +被 *top* 命令显示出来。要让CPU4重新上线:: + + $ echo 1 > /sys/devices/system/cpu/cpu4/online + smpboot: Booting Node 0 Processor 4 APIC 0x1 + +CPU又可以使用了。这应该对所有的CPU都有效。CPU0通常比较特殊,被排除在CPU热拔插之外。 +在X86上,内核选项 *CONFIG_BOOTPARAM_HOTPLUG_CPU0* 必须被启用,以便能够关闭CPU0。 +或者,可以使用内核命令选项 *cpu0_hotplug* 。CPU0的一些已知的依赖性: + +* 从休眠/暂停中恢复。如果CPU0处于离线状态,休眠/暂停将失败。 +* PIC中断。如果检测到PIC中断,CPU0就不能被移除。 + +如果你发现CPU0上有任何依赖性,请告知Fenghua Yu 。 + +CPU的热拔插协作 +=============== + +下线情况 +-------- + +一旦CPU被逻辑关闭,注册的热插拔状态的清除回调将被调用,从 ``CPUHP_ONLINE`` 开始,在 +``CPUHP_OFFLINE`` 状态结束。这包括: + +* 如果任务因暂停操作而被冻结,那么 *cpuhp_tasks_frozen* 将被设置为true。 + +* 所有进程都会从这个将要离线的CPU迁移到新的CPU上。新的CPU是从每个进程的当前cpuset中 + 选择的,它可能是所有在线CPU的一个子集。 + +* 所有针对这个CPU的中断都被迁移到新的CPU上。 + +* 计时器也会被迁移到新的CPU上。 + +* 一旦所有的服务被迁移,内核会调用一个特定的例程 ``__cpu_disable()`` 来进行特定的清 + 理。 + +使用热插拔API +------------- + +一旦一个CPU下线或上线,就有可能收到通知。这对某些需要根据可用CPU数量执行某种设置或清 +理功能的驱动程序来说可能很重要:: + + #include + + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "X/Y:online", + Y_online, Y_prepare_down); + +*X* 是子系统, *Y* 是特定的驱动程序。 *Y_online* 回调将在所有在线CPU的注册过程中被调用。 +如果在线回调期间发生错误, *Y_prepare_down* 回调将在所有之前调用过在线回调的CPU上调 +用。注册完成后,一旦有CPU上线, *Y_online* 回调将被调用,当CPU关闭时, *Y_prepare_down* +将被调用。所有之前在 *Y_online* 中分配的资源都应该在 *Y_prepare_down* 中释放。如果在 +注册过程中发生错误,返回值 *ret* 为负值。否则会返回一个正值,其中包含动态分配状态 +( *CPUHP_AP_ONLINE_DYN* )的分配热拔插。对于预定义的状态,它将返回0。 + +该回调可以通过调用 ``cpuhp_remove_state()`` 来删除。如果是动态分配的状态 +( *CPUHP_AP_ONLINE_DYN* ),则使用返回的状态。在移除热插拔状态的过程中,将调用拆解回调。 + +多个实例 +~~~~~~~~ + +如果一个驱动程序有多个实例,并且每个实例都需要独立执行回调,那么很可能应该使用 +``multi-state`` 。首先需要注册一个多状态的状态:: + + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "X/Y:online, + Y_online, Y_prepare_down); + Y_hp_online = ret; + +``cpuhp_setup_state_multi()`` 的行为与 ``cpuhp_setup_state()`` 类似,只是它 +为多状态准备了回调,但不调用回调。这是一个一次性的设置。 +一旦分配了一个新的实例,你需要注册这个新实例:: + + ret = cpuhp_state_add_instance(Y_hp_online, &d->node); + +这个函数将把这个实例添加到你先前分配的 ``Y_hp_online`` 状态,并在所有在线的 +CPU上调用先前注册的回调( ``Y_online`` )。 *node* 元素是你的每个实例数据结构 +中的一个 ``struct hlist_node`` 成员。 + +在移除该实例时:: + + cpuhp_state_remove_instance(Y_hp_online, &d->node) + +应该被调用,这将在所有在线CPU上调用拆分回调。 + +手动设置 +~~~~~~~~ + +通常情况下,在注册或移除状态时调用setup和teamdown回调是很方便的,因为通常在CPU上线 +(下线)和驱动的初始设置(关闭)时需要执行该操作。然而,每个注册和删除功能也有一个 +_nocalls的后缀,如果不希望调用回调,则不调用所提供的回调。在手动设置(或关闭)期间, +应该使用 ``get_online_cpus()`` 和 ``put_online_cpus()`` 函数来抑制CPU热插拔操作。 + + +事件的顺序 +---------- + +热插拔状态被定义在 ``include/linux/cpuhotplug.h``: + +* ``CPUHP_OFFLINE`` ... ``CPUHP_AP_OFFLINE`` 状态是在CPU启动前调用的。 + +* ``CPUHP_AP_OFFLINE`` ... ``CPUHP_AP_ONLINE`` 状态是在CPU被启动后被调用的。 + 中断是关闭的,调度程序还没有在这个CPU上活动。从 ``CPUHP_AP_OFFLINE`` 开始, + 回调被调用到目标CPU上。 + +* ``CPUHP_AP_ONLINE_DYN`` 和 ``CPUHP_AP_ONLINE_DYN_END`` 之间的状态被保留 + 给动态分配。 + +* 这些状态在CPU关闭时以相反的顺序调用,从 ``CPUHP_ONLINE`` 开始,在 ``CPUHP_OFFLINE`` + 停止。这里的回调是在将被关闭的CPU上调用的,直到 ``CPUHP_AP_OFFLINE`` 。 + +通过 ``CPUHP_AP_ONLINE_DYN`` 动态分配的状态通常已经足够了。然而,如果在启动或关闭 +期间需要更早的调用,那么应该获得一个显式状态。如果热拔插事件需要相对于另一个热拔插事 +件的特定排序,也可能需要一个显式状态。 + +测试热拔插状态 +============== + +验证自定义状态是否按预期工作的一个方法是关闭一个CPU,然后再把它上线。也可以把CPU放到某 +些状态(例如 ``CPUHP_AP_ONLINE`` ),然后再回到 ``CPUHP_ONLINE`` 。这将模拟在 +``CPUHP_AP_ONLINE`` 之后的一个状态出现错误,从而导致回滚到在线状态。 + +所有注册的状态都被列举在 ``/sys/devices/system/cpu/hotplug/states`` :: + + $ tail /sys/devices/system/cpu/hotplug/states + 138: mm/vmscan:online + 139: mm/vmstat:online + 140: lib/percpu_cnt:online + 141: acpi/cpu-drv:online + 142: base/cacheinfo:online + 143: virtio/net:online + 144: x86/mce:online + 145: printk:online + 168: sched:active + 169: online + +要将CPU4回滚到 ``lib/percpu_cnt:online`` ,再回到在线状态,只需发出:: + + $ cat /sys/devices/system/cpu/cpu4/hotplug/state + 169 + $ echo 140 > /sys/devices/system/cpu/cpu4/hotplug/target + $ cat /sys/devices/system/cpu/cpu4/hotplug/state + 140 + +需要注意的是,状态140的清除回调已经被调用。现在重新上线:: + + $ echo 169 > /sys/devices/system/cpu/cpu4/hotplug/target + $ cat /sys/devices/system/cpu/cpu4/hotplug/state + 169 + +启用追踪事件后,单个步骤也是可见的:: + + # TASK-PID CPU# TIMESTAMP FUNCTION + # | | | | | + bash-394 [001] 22.976: cpuhp_enter: cpu: 0004 target: 140 step: 169 (cpuhp_kick_ap_work) + cpuhp/4-31 [004] 22.977: cpuhp_enter: cpu: 0004 target: 140 step: 168 (sched_cpu_deactivate) + cpuhp/4-31 [004] 22.990: cpuhp_exit: cpu: 0004 state: 168 step: 168 ret: 0 + cpuhp/4-31 [004] 22.991: cpuhp_enter: cpu: 0004 target: 140 step: 144 (mce_cpu_pre_down) + cpuhp/4-31 [004] 22.992: cpuhp_exit: cpu: 0004 state: 144 step: 144 ret: 0 + cpuhp/4-31 [004] 22.993: cpuhp_multi_enter: cpu: 0004 target: 140 step: 143 (virtnet_cpu_down_prep) + cpuhp/4-31 [004] 22.994: cpuhp_exit: cpu: 0004 state: 143 step: 143 ret: 0 + cpuhp/4-31 [004] 22.995: cpuhp_enter: cpu: 0004 target: 140 step: 142 (cacheinfo_cpu_pre_down) + cpuhp/4-31 [004] 22.996: cpuhp_exit: cpu: 0004 state: 142 step: 142 ret: 0 + bash-394 [001] 22.997: cpuhp_exit: cpu: 0004 state: 140 step: 169 ret: 0 + bash-394 [005] 95.540: cpuhp_enter: cpu: 0004 target: 169 step: 140 (cpuhp_kick_ap_work) + cpuhp/4-31 [004] 95.541: cpuhp_enter: cpu: 0004 target: 169 step: 141 (acpi_soft_cpu_online) + cpuhp/4-31 [004] 95.542: cpuhp_exit: cpu: 0004 state: 141 step: 141 ret: 0 + cpuhp/4-31 [004] 95.543: cpuhp_enter: cpu: 0004 target: 169 step: 142 (cacheinfo_cpu_online) + cpuhp/4-31 [004] 95.544: cpuhp_exit: cpu: 0004 state: 142 step: 142 ret: 0 + cpuhp/4-31 [004] 95.545: cpuhp_multi_enter: cpu: 0004 target: 169 step: 143 (virtnet_cpu_online) + cpuhp/4-31 [004] 95.546: cpuhp_exit: cpu: 0004 state: 143 step: 143 ret: 0 + cpuhp/4-31 [004] 95.547: cpuhp_enter: cpu: 0004 target: 169 step: 144 (mce_cpu_online) + cpuhp/4-31 [004] 95.548: cpuhp_exit: cpu: 0004 state: 144 step: 144 ret: 0 + cpuhp/4-31 [004] 95.549: cpuhp_enter: cpu: 0004 target: 169 step: 145 (console_cpu_notify) + cpuhp/4-31 [004] 95.550: cpuhp_exit: cpu: 0004 state: 145 step: 145 ret: 0 + cpuhp/4-31 [004] 95.551: cpuhp_enter: cpu: 0004 target: 169 step: 168 (sched_cpu_activate) + cpuhp/4-31 [004] 95.552: cpuhp_exit: cpu: 0004 state: 168 step: 168 ret: 0 + bash-394 [005] 95.553: cpuhp_exit: cpu: 0004 state: 169 step: 140 ret: 0 + +可以看到,CPU4一直下降到时间戳22.996,然后又上升到95.552。所有被调用的回调, +包括它们的返回代码都可以在跟踪中看到。 + +架构的要求 +========== + +需要具备以下功能和配置: + +``CONFIG_HOTPLUG_CPU`` + 这个配置项需要在Kconfig中启用 + +``__cpu_up()`` + 调出一个cpu的架构接口 + +``__cpu_disable()`` + 关闭CPU的架构接口,在此程序返回后,内核不能再处理任何中断。这包括定时器的关闭。 + +``__cpu_die()`` + 这实际上是为了确保CPU的死亡。实际上,看看其他架构中实现CPU热拔插的一些示例代 + 码。对于那个特定的架构,处理器被从 ``idle()`` 循环中拿下来。 ``__cpu_die()`` + 通常会等待一些per_cpu状态的设置,以确保处理器的死亡例程被调用来保持活跃。 + +用户空间通知 +============ + +在CPU成功上线或下线后,udev事件被发送。一个udev规则,比如:: + + SUBSYSTEM=="cpu", DRIVERS=="processor", DEVPATH=="/devices/system/cpu/*", RUN+="the_hotplug_receiver.sh" + +将接收所有事件。一个像这样的脚本:: + + #!/bin/sh + + if [ "${ACTION}" = "offline" ] + then + echo "CPU ${DEVPATH##*/} offline" + + elif [ "${ACTION}" = "online" ] + then + echo "CPU ${DEVPATH##*/} online" + + fi + +可以进一步处理该事件。 + +内核内联文档参考 +================ + +该API在以下内核代码中: + +include/linux/cpuhotplug.h diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index 71a212a2a9db..67252125ddee 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -80,12 +80,12 @@ Todolist: :maxdepth: 1 cachetlb + cpu_hotplug genericirq Todolist: - cpu_hotplug memory-hotplug protection-keys -- cgit v1.2.3-70-g09d2 From 620127548a691b00d18442338922434ff7e37467 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 9 Jul 2021 11:02:42 +0800 Subject: docs/zh_CN: add core api memory_hotplug translation Translate Documentation/core-api/memory_hotplug.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/55a74c9fe5627edff36fa01940eae943f0861f8e.1625797729.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/core-api/index.rst | 3 + .../translations/zh_CN/core-api/memory-hotplug.rst | 126 +++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 Documentation/translations/zh_CN/core-api/memory-hotplug.rst diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index 67252125ddee..cd25d42dfb2c 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -82,11 +82,14 @@ Todolist: cachetlb cpu_hotplug genericirq + memory-hotplug Todolist: memory-hotplug + cpu_hotplug + genericirq protection-keys diff --git a/Documentation/translations/zh_CN/core-api/memory-hotplug.rst b/Documentation/translations/zh_CN/core-api/memory-hotplug.rst new file mode 100644 index 000000000000..161f4d2c18cc --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/memory-hotplug.rst @@ -0,0 +1,126 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/memory_hotplug.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 吴想成 Wu XiangCheng + +.. _cn_core-api_memory-hotplug: + +========== +内存热插拔 +========== + +内存热拔插事件通知器 +==================== + +热插拔事件被发送到一个通知队列中。 + +在 ``include/linux/memory.h`` 中定义了六种类型的通知: + +MEM_GOING_ONLINE + 在新内存可用之前生成,以便能够为子系统处理内存做准备。页面分配器仍然无法从新 + 的内存中进行分配。 + +MEM_CANCEL_ONLINE + 如果MEM_GOING_ONLINE失败,则生成。 + +MEM_ONLINE + 当内存成功上线时产生。回调可以从新的内存中分配页面。 + +MEM_GOING_OFFLINE + 在开始对内存进行下线处理时生成。从内存中的分配不再可能,但是一些要下线的内存 + 仍然在使用。回调可以用来释放一个子系统在指定内存块中已知的内存。 + +MEM_CANCEL_OFFLINE + 如果MEM_GOING_OFFLINE失败,则生成。来自我们试图离线的内存块中的内存又可以使 + 用了。 + +MEM_OFFLINE + 在内存下线完成后生成。 + +可以通过调用如下函数来注册一个回调程序: + + hotplug_memory_notifier(callback_func, priority) + +优先级数值较高的回调函数在数值较低的回调函数之前被调用。 + +一个回调函数必须有以下原型:: + + int callback_func( + struct notifier_block *self, unsigned long action, void *arg); + +回调函数的第一个参数(self)是指向回调函数本身的通知器链块的一个指针。第二个参 +数(action)是上述的事件类型之一。第三个参数(arg)传递一个指向 +memory_notify结构体的指针:: + + struct memory_notify { + unsigned long start_pfn; + unsigned long nr_pages; + int status_change_nid_normal; + int status_change_nid_high; + int status_change_nid; + } + +- start_pfn是在线/离线内存的start_pfn。 + +- nr_pages是在线/离线内存的页数。 + +- status_change_nid_normal是当nodemask的N_NORMAL_MEMORY被设置/清除时设置节 + 点id,如果是-1,则nodemask状态不改变。 + +- status_change_nid_high是当nodemask的N_HIGH_MEMORY被设置/清除时设置的节点 + id,如果这个值为-1,那么nodemask状态不会改变。 + +- status_change_nid是当nodemask的N_MEMORY被(将)设置/清除时设置的节点id。这 + 意味着一个新的(没上线的)节点通过联机获得新的内存,而一个节点失去了所有的内 + 存。如果这个值为-1,那么nodemask的状态就不会改变。 + + 如果 status_changed_nid* >= 0,回调应该在必要时为节点创建/丢弃结构体。 + +回调程序应返回 ``include/linux/notifier.h`` 中定义的NOTIFY_DONE, NOTIFY_OK, +NOTIFY_BAD, NOTIFY_STOP中的一个值。 + +NOTIFY_DONE和NOTIFY_OK对进一步处理没有影响。 + +NOTIFY_BAD是作为对MEM_GOING_ONLINE、MEM_GOING_OFFLINE、MEM_ONLINE或MEM_OFFLINE +动作的回应,用于取消热插拔。它停止对通知队列的进一步处理。 + +NOTIFY_STOP停止对通知队列的进一步处理。 + +内部锁 +====== + +当添加/删除使用内存块设备(即普通RAM)的内存时,device_hotplug_lock应该被保持 +为: + +- 针对在线/离线请求进行同步(例如,通过sysfs)。这样一来,内存块设备只有在内存 + 被完全添加后才能被用户空间访问(.online/.state属性)。而在删除内存时,我们知 + 道没有人在临界区。 + +- 与CPU热拔插或类似操作同步(例如ACPI和PPC相关操作) + +特别是,在添加内存和用户空间试图以比预期更快的速度上线该内存时,有可能出现锁反转, +使用device_hotplug_lock可以避免此情况: + +- device_online()将首先接受device_lock(),然后是mem_hotplug_lock。 + +- add_memory_resource()将首先使用mem_hotplug_lock,然后是device_lock()(在创 + 建设备时,在bus_add_device()期间)。 + +由于在使用device_lock()之前,设备对用户空间是可见的,这可能导致锁的反转。 + +内存的上线/下线应该通过device_online()/device_offline()完成————确保它与通过 +sysfs进行的操作正确同步。建议持有device_hotplug_lock(例如,保护online_type)。 + +当添加/删除/上线/下线内存或者添加/删除异构或设备内存时,我们应该始终持有写模式的 +mem_hotplug_lock,以序列化内存热插拔(例如访问全局/区域变量)。 + +此外,mem_hotplug_lock(与device_hotplug_lock相反)在读取模式下允许一个相当 +有效的get_online_mems/put_online_mems实现,所以访问内存的代码可以防止该内存 +消失。 -- cgit v1.2.3-70-g09d2 From 4b3abe1fde4799ed92c378e545271ca7a7828a41 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 9 Jul 2021 11:02:43 +0800 Subject: docs/zh_CN: add core api protection keys translation Translate Documentation/core-api/protection-keys.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/abdcd4f157062a529cfc50754689d2df26070592.1625797729.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/core-api/index.rst | 2 +- .../zh_CN/core-api/protection-keys.rst | 99 ++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/core-api/protection-keys.rst diff --git a/Documentation/translations/zh_CN/core-api/index.rst b/Documentation/translations/zh_CN/core-api/index.rst index cd25d42dfb2c..d5e947d8b6f1 100644 --- a/Documentation/translations/zh_CN/core-api/index.rst +++ b/Documentation/translations/zh_CN/core-api/index.rst @@ -83,6 +83,7 @@ Todolist: cpu_hotplug genericirq memory-hotplug + protection-keys Todolist: @@ -90,7 +91,6 @@ Todolist: memory-hotplug cpu_hotplug genericirq - protection-keys 内存管理 diff --git a/Documentation/translations/zh_CN/core-api/protection-keys.rst b/Documentation/translations/zh_CN/core-api/protection-keys.rst new file mode 100644 index 000000000000..d07830050153 --- /dev/null +++ b/Documentation/translations/zh_CN/core-api/protection-keys.rst @@ -0,0 +1,99 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/core-api/protection-keys.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 吴想成 Wu XiangCheng + +.. _cn_core-api_protection-keys: + +============ +内存保护密钥 +============ + +用户空间的内存保护密钥(Memory Protection Keys for Userspace,PKU,亦 +即PKEYs)是英特尔Skylake(及以后)“可扩展处理器”服务器CPU上的一项功能。 +它将在未来的非服务器英特尔处理器和未来的AMD处理器中可用。 + +对于任何希望测试或使用该功能的人来说,它在亚马逊的EC2 C5实例中是可用的, +并且已知可以在那里使用Ubuntu 17.04镜像运行。 + +内存保护密钥提供了一种机制来执行基于页面的保护,但在应用程序改变保护域 +时不需要修改页表。它的工作原理是在每个页表项中为“保护密钥”分配4个以 +前被忽略的位,从而提供16个可能的密钥。 + +还有一个新的用户可访问寄存器(PKRU),为每个密钥提供两个单独的位(访 +问禁止和写入禁止)。作为一个CPU寄存器,PKRU在本质上是线程本地的,可能 +会给每个线程提供一套不同于其他线程的保护措施。 + +有两条新指令(RDPKRU/WRPKRU)用于读取和写入新的寄存器。该功能仅在64位 +模式下可用,尽管物理地址扩展页表中理论上有空间。这些权限只在数据访问上 +强制执行,对指令获取没有影响。 + + +系统调用 +======== + +有3个系统调用可以直接与pkeys进行交互:: + + int pkey_alloc(unsigned long flags, unsigned long init_access_rights) + int pkey_free(int pkey); + int pkey_mprotect(unsigned long start, size_t len, + unsigned long prot, int pkey); + +在使用一个pkey之前,必须先用pkey_alloc()分配它。一个应用程序直接调用 +WRPKRU指令,以改变一个密钥覆盖的内存的访问权限。在这个例子中,WRPKRU +被一个叫做pkey_set()的C函数所封装:: + + int real_prot = PROT_READ|PROT_WRITE; + pkey = pkey_alloc(0, PKEY_DISABLE_WRITE); + ptr = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + ret = pkey_mprotect(ptr, PAGE_SIZE, real_prot, pkey); + ... application runs here + +现在,如果应用程序需要更新'ptr'处的数据,它可以获得访问权,进行更新, +然后取消其写访问权:: + + pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE + *ptr = foo; // assign something + pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again + +现在,当它释放内存时,它也将释放pkey,因为它不再被使用了:: + + munmap(ptr, PAGE_SIZE); + pkey_free(pkey); + +.. note:: pkey_set()是RDPKRU和WRPKRU指令的一个封装器。在tools/testing/selftests/x86/protection_keys.c中可以找到一个实现实例。 + tools/testing/selftests/x86/protection_keys.c. + +行为 +==== + +内核试图使保护密钥与普通的mprotect()的行为一致。例如,如果你这样做:: + + mprotect(ptr, size, PROT_NONE); + something(ptr); + +这样做的时候,你可以期待保护密钥的相同效果:: + + pkey = pkey_alloc(0, PKEY_DISABLE_WRITE | PKEY_DISABLE_READ); + pkey_mprotect(ptr, size, PROT_READ|PROT_WRITE, pkey); + something(ptr); + +无论something()是否是对'ptr'的直接访问,这都应该为真。 +如:: + + *ptr = foo; + +或者当内核代表应用程序进行访问时,比如read():: + + read(fd, ptr, 1); + +在这两种情况下,内核都会发送一个SIGSEGV,但当违反保护密钥时,si_code +将被设置为SEGV_PKERR,而当违反普通的mprotect()权限时,则是SEGV_ACCERR。 -- cgit v1.2.3-70-g09d2 From 350ec9bc618c042940ef7743e53f308f214de23a Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:45 +0200 Subject: RDMA/rtrs: Add error messages for failed operations. It could help debugging in case of error happens. Link: https://lore.kernel.org/r/20210712060750.16494-2-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index 61919ebd92b2..870b21f551a4 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -316,6 +316,7 @@ void rtrs_send_hb_ack(struct rtrs_sess *sess) err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm, 0, NULL); if (err) { + rtrs_err(sess, "send HB ACK failed, errno: %d\n", err); sess->hb_err_handler(usr_con); return; } @@ -333,6 +334,7 @@ static void hb_work(struct work_struct *work) usr_con = sess->con[0]; if (sess->hb_missed_cnt > sess->hb_missed_max) { + rtrs_err(sess, "HB missed max reached.\n"); sess->hb_err_handler(usr_con); return; } @@ -348,6 +350,7 @@ static void hb_work(struct work_struct *work) err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm, 0, NULL); if (err) { + rtrs_err(sess, "HB send failed, errno: %d\n", err); sess->hb_err_handler(usr_con); return; } -- cgit v1.2.3-70-g09d2 From a10431eff136ef15e1f9955efe369744b1294db1 Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:46 +0200 Subject: RDMA/rtrs: move wr_cnt from rtrs_srv_con to rtrs_con We need to track also the wr used for heatbeat. This is a preparation for that, will be used in later patch. The io_cnt in rtrs_clt is removed, use wr_cnt instead. Link: https://lore.kernel.org/r/20210712060750.16494-3-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 7 ++++--- drivers/infiniband/ulp/rtrs/rtrs-clt.h | 1 - drivers/infiniband/ulp/rtrs/rtrs-pri.h | 1 + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 6 +++--- drivers/infiniband/ulp/rtrs/rtrs-srv.h | 1 - 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index f2c40e50f25e..5cb00ea08919 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -478,7 +478,7 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = atomic_inc_return(&con->io_cnt) % sess->queue_depth ? + flags = atomic_inc_return(&con->c.wr_cnt) % sess->queue_depth ? 0 : IB_SEND_SIGNALED; ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr, @@ -1043,7 +1043,7 @@ static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = atomic_inc_return(&con->io_cnt) % sess->queue_depth ? + flags = atomic_inc_return(&con->c.wr_cnt) % sess->queue_depth ? 0 : IB_SEND_SIGNALED; ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr, @@ -1601,7 +1601,8 @@ static int create_con(struct rtrs_clt_sess *sess, unsigned int cid) con->cpu = (cid ? cid - 1 : 0) % nr_cpu_ids; con->c.cid = cid; con->c.sess = &sess->s; - atomic_set(&con->io_cnt, 0); + /* Align with srv, init as 1 */ + atomic_set(&con->c.wr_cnt, 1); mutex_init(&con->con_mutex); sess->s.con[cid] = &con->c; diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h index e276a2dfcf7c..3c3ff094588c 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h @@ -74,7 +74,6 @@ struct rtrs_clt_con { u32 queue_num; unsigned int cpu; struct mutex con_mutex; - atomic_t io_cnt; int cm_err; }; diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index 36f184a3b676..a44a4fb1b515 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -96,6 +96,7 @@ struct rtrs_con { struct rdma_cm_id *cm_id; unsigned int cid; int nr_cqe; + atomic_t wr_cnt; }; struct rtrs_sess { diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 3df290086169..31b846ca0c5e 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -269,7 +269,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id) * From time to time we have to post signaled sends, * or send queue will fill up and only QP reset can help. */ - flags = (atomic_inc_return(&id->con->wr_cnt) % srv->queue_depth) ? + flags = (atomic_inc_return(&id->con->c.wr_cnt) % srv->queue_depth) ? 0 : IB_SEND_SIGNALED; if (need_inval) { @@ -396,7 +396,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = (atomic_inc_return(&con->wr_cnt) % srv->queue_depth) ? + flags = (atomic_inc_return(&con->c.wr_cnt) % srv->queue_depth) ? 0 : IB_SEND_SIGNALED; imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval); imm_wr.wr.next = NULL; @@ -1648,7 +1648,7 @@ static int create_con(struct rtrs_srv_sess *sess, con->c.cm_id = cm_id; con->c.sess = &sess->s; con->c.cid = cid; - atomic_set(&con->wr_cnt, 1); + atomic_set(&con->c.wr_cnt, 1); wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr; if (con->c.cid == 0) { diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.h b/drivers/infiniband/ulp/rtrs/rtrs-srv.h index f8da2e3f0bda..6785c3b6363e 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.h @@ -42,7 +42,6 @@ struct rtrs_srv_stats { struct rtrs_srv_con { struct rtrs_con c; - atomic_t wr_cnt; atomic_t sq_wr_avail; struct list_head rsp_wr_wait_list; spinlock_t rsp_wr_wait_lock; -- cgit v1.2.3-70-g09d2 From e2d98504c697f9c8e45b815062f8893b10808d8e Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:47 +0200 Subject: RDMA/rtrs: Enable the same selective signal for heartbeat and IO On idle session, because we do not do signal for heartbeat, it will overflow the send queue after sometime. To avoid that, we need to enable the signal for heartbeat. To do that, add a new member signal_interval in rtrs_path, which will set min of queue_depth and SERVICE_CON_QUEUE_DEPTH, and track it for both heartbeat and IO, so the sq queue full accounting is correct. Fixes: b38041d50add ("RDMA/rtrs: Do not signal for heatbeat") Link: https://lore.kernel.org/r/20210712060750.16494-4-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 7 +++++-- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 1 + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 11 ++++++----- drivers/infiniband/ulp/rtrs/rtrs.c | 7 ++++++- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 5cb00ea08919..f023676e05e4 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -478,7 +478,7 @@ static int rtrs_post_send_rdma(struct rtrs_clt_con *con, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = atomic_inc_return(&con->c.wr_cnt) % sess->queue_depth ? + flags = atomic_inc_return(&con->c.wr_cnt) % sess->s.signal_interval ? 0 : IB_SEND_SIGNALED; ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr, @@ -680,6 +680,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc) case IB_WC_RDMA_WRITE: /* * post_send() RDMA write completions of IO reqs (read/write) + * and hb. */ break; @@ -1043,7 +1044,7 @@ static int rtrs_post_rdma_write_sg(struct rtrs_clt_con *con, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = atomic_inc_return(&con->c.wr_cnt) % sess->queue_depth ? + flags = atomic_inc_return(&con->c.wr_cnt) % sess->s.signal_interval ? 0 : IB_SEND_SIGNALED; ib_dma_sync_single_for_device(sess->s.dev->ib_dev, req->iu->dma_addr, @@ -1849,6 +1850,8 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, return -ENOMEM; } sess->queue_depth = queue_depth; + sess->s.signal_interval = min_not_zero(queue_depth, + (unsigned short) SERVICE_CON_QUEUE_DEPTH); sess->max_hdr_size = le32_to_cpu(msg->max_hdr_size); sess->max_io_size = le32_to_cpu(msg->max_io_size); sess->flags = le32_to_cpu(msg->flags); diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index a44a4fb1b515..b88a4944cb30 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -109,6 +109,7 @@ struct rtrs_sess { unsigned int con_num; unsigned int irq_con_num; unsigned int recon_cnt; + unsigned int signal_interval; struct rtrs_ib_dev *dev; int dev_ref; struct ib_cqe *hb_cqe; diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 31b846ca0c5e..44ed15f38896 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -201,7 +201,6 @@ static int rdma_write_sg(struct rtrs_srv_op *id) struct rtrs_srv_sess *sess = to_srv_sess(s); dma_addr_t dma_addr = sess->dma_addr[id->msg_id]; struct rtrs_srv_mr *srv_mr; - struct rtrs_srv *srv = sess->srv; struct ib_send_wr inv_wr; struct ib_rdma_wr imm_wr; struct ib_rdma_wr *wr = NULL; @@ -269,7 +268,7 @@ static int rdma_write_sg(struct rtrs_srv_op *id) * From time to time we have to post signaled sends, * or send queue will fill up and only QP reset can help. */ - flags = (atomic_inc_return(&id->con->c.wr_cnt) % srv->queue_depth) ? + flags = (atomic_inc_return(&id->con->c.wr_cnt) % s->signal_interval) ? 0 : IB_SEND_SIGNALED; if (need_inval) { @@ -347,7 +346,6 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, struct ib_send_wr inv_wr, *wr = NULL; struct ib_rdma_wr imm_wr; struct ib_reg_wr rwr; - struct rtrs_srv *srv = sess->srv; struct rtrs_srv_mr *srv_mr; bool need_inval = false; enum ib_send_flags flags; @@ -396,7 +394,7 @@ static int send_io_resp_imm(struct rtrs_srv_con *con, struct rtrs_srv_op *id, * From time to time we have to post signalled sends, * or send queue will fill up and only QP reset can help. */ - flags = (atomic_inc_return(&con->c.wr_cnt) % srv->queue_depth) ? + flags = (atomic_inc_return(&con->c.wr_cnt) % s->signal_interval) ? 0 : IB_SEND_SIGNALED; imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval); imm_wr.wr.next = NULL; @@ -1268,8 +1266,9 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc) case IB_WC_SEND: /* * post_send() RDMA write completions of IO reqs (read/write) + * and hb. */ - atomic_add(srv->queue_depth, &con->sq_wr_avail); + atomic_add(s->signal_interval, &con->sq_wr_avail); if (unlikely(!list_empty_careful(&con->rsp_wr_wait_list))) rtrs_rdma_process_wr_wait_list(con); @@ -1659,6 +1658,8 @@ static int create_con(struct rtrs_srv_sess *sess, max_send_wr = min_t(int, wr_limit, SERVICE_CON_QUEUE_DEPTH * 2 + 2); max_recv_wr = max_send_wr; + s->signal_interval = min_not_zero(srv->queue_depth, + (size_t)SERVICE_CON_QUEUE_DEPTH); } else { /* when always_invlaidate enalbed, we need linv+rinv+mr+imm */ if (always_invalidate) diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index 870b21f551a4..7f2dfb9d11fc 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -187,10 +187,15 @@ int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, struct ib_send_wr *head) { struct ib_rdma_wr wr; + struct rtrs_sess *sess = con->sess; + enum ib_send_flags sflags; + + sflags = (atomic_inc_return(&con->wr_cnt) % sess->signal_interval) ? + 0 : IB_SEND_SIGNALED; wr = (struct ib_rdma_wr) { .wr.wr_cqe = cqe, - .wr.send_flags = flags, + .wr.send_flags = sflags, .wr.opcode = IB_WR_RDMA_WRITE_WITH_IMM, .wr.ex.imm_data = cpu_to_be32(imm_data), }; -- cgit v1.2.3-70-g09d2 From 6ea9b773390d70c6c6c363f0428d1a4cbec3757a Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:48 +0200 Subject: RDMA/rtrs: Make rtrs_post_rdma_write_imm_empty static It's only used in rtrs.c, so no need to export. Link: https://lore.kernel.org/r/20210712060750.16494-5-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs-pri.h | 3 --- drivers/infiniband/ulp/rtrs/rtrs.c | 9 +++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index b88a4944cb30..76581ebaed1d 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -311,9 +311,6 @@ int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu, struct ib_send_wr *tail); int rtrs_post_recv_empty(struct rtrs_con *con, struct ib_cqe *cqe); -int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, - u32 imm_data, enum ib_send_flags flags, - struct ib_send_wr *head); int rtrs_cq_qp_create(struct rtrs_sess *sess, struct rtrs_con *con, u32 max_send_sge, int cq_vector, int nr_cqe, diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index 7f2dfb9d11fc..528d6a57c9b6 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -182,9 +182,11 @@ int rtrs_iu_post_rdma_write_imm(struct rtrs_con *con, struct rtrs_iu *iu, } EXPORT_SYMBOL_GPL(rtrs_iu_post_rdma_write_imm); -int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, - u32 imm_data, enum ib_send_flags flags, - struct ib_send_wr *head) +static int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, + struct ib_cqe *cqe, + u32 imm_data, + enum ib_send_flags flags, + struct ib_send_wr *head) { struct ib_rdma_wr wr; struct rtrs_sess *sess = con->sess; @@ -202,7 +204,6 @@ int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, return rtrs_post_send(con->qp, head, &wr.wr, NULL); } -EXPORT_SYMBOL_GPL(rtrs_post_rdma_write_imm_empty); static void qp_event_handler(struct ib_event *ev, void *ctx) { -- cgit v1.2.3-70-g09d2 From 99fac8bf6d5ecf1029147b71ef2a49c4ff912047 Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:49 +0200 Subject: RDMA/rtrs: Remove unused flags parameter flags is not used, so remove it from rtrs_post_rdma_write_imm_empty. Link: https://lore.kernel.org/r/20210712060750.16494-6-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index 528d6a57c9b6..b56dc5b82db0 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -185,7 +185,6 @@ EXPORT_SYMBOL_GPL(rtrs_iu_post_rdma_write_imm); static int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct ib_cqe *cqe, u32 imm_data, - enum ib_send_flags flags, struct ib_send_wr *head) { struct ib_rdma_wr wr; @@ -320,7 +319,7 @@ void rtrs_send_hb_ack(struct rtrs_sess *sess) imm = rtrs_to_imm(RTRS_HB_ACK_IMM, 0); err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm, - 0, NULL); + NULL); if (err) { rtrs_err(sess, "send HB ACK failed, errno: %d\n", err); sess->hb_err_handler(usr_con); @@ -354,7 +353,7 @@ static void hb_work(struct work_struct *work) imm = rtrs_to_imm(RTRS_HB_MSG_IMM, 0); err = rtrs_post_rdma_write_imm_empty(usr_con, sess->hb_cqe, imm, - 0, NULL); + NULL); if (err) { rtrs_err(sess, "HB send failed, errno: %d\n", err); sess->hb_err_handler(usr_con); -- cgit v1.2.3-70-g09d2 From cfcdbd9dd7632a9bb1e308a029f5fa65008333af Mon Sep 17 00:00:00 2001 From: Jack Wang Date: Mon, 12 Jul 2021 08:07:50 +0200 Subject: RDMA/rtrs: Move sq_wr_avail to rtrs_con In order to account HB for sq_wr_avail properly, move sq_wr_avail from rtrs_srv_con to rtrs_con. Although rtrs-clt do not care sq_wr_avail, but still init it to max_send_wr. Fixes: b38041d50add ("RDMA/rtrs: Do not signal for heatbeat") Link: https://lore.kernel.org/r/20210712060750.16494-7-jinpu.wang@ionos.com Signed-off-by: Jack Wang Reviewed-by: Aleksei Marov Reviewed-by: Gioh Kim Reviewed-by: Md Haris Iqbal Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/rtrs/rtrs-clt.c | 1 + drivers/infiniband/ulp/rtrs/rtrs-pri.h | 1 + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 8 ++++---- drivers/infiniband/ulp/rtrs/rtrs-srv.h | 1 - drivers/infiniband/ulp/rtrs/rtrs.c | 1 + 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index f023676e05e4..ece3205531b8 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -1680,6 +1680,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con) sess->queue_depth * 3 + 1); max_send_sge = 2; } + atomic_set(&con->c.sq_wr_avail, max_send_wr); cq_num = max_send_wr + max_recv_wr; /* alloc iu to recv new rkey reply when server reports flags set */ if (sess->flags & RTRS_MSG_NEW_RKEY_F || con->c.cid == 0) { diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index 76581ebaed1d..d12ddfa50747 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -97,6 +97,7 @@ struct rtrs_con { unsigned int cid; int nr_cqe; atomic_t wr_cnt; + atomic_t sq_wr_avail; }; struct rtrs_sess { diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 44ed15f38896..cd9a4ccf4c28 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -507,11 +507,11 @@ bool rtrs_srv_resp_rdma(struct rtrs_srv_op *id, int status) ib_update_fast_reg_key(mr->mr, ib_inc_rkey(mr->mr->rkey)); } if (unlikely(atomic_sub_return(1, - &con->sq_wr_avail) < 0)) { + &con->c.sq_wr_avail) < 0)) { rtrs_err(s, "IB send queue full: sess=%s cid=%d\n", kobject_name(&sess->kobj), con->c.cid); - atomic_add(1, &con->sq_wr_avail); + atomic_add(1, &con->c.sq_wr_avail); spin_lock(&con->rsp_wr_wait_lock); list_add_tail(&id->wait_list, &con->rsp_wr_wait_list); spin_unlock(&con->rsp_wr_wait_lock); @@ -1268,7 +1268,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc) * post_send() RDMA write completions of IO reqs (read/write) * and hb. */ - atomic_add(s->signal_interval, &con->sq_wr_avail); + atomic_add(s->signal_interval, &con->c.sq_wr_avail); if (unlikely(!list_empty_careful(&con->rsp_wr_wait_list))) rtrs_rdma_process_wr_wait_list(con); @@ -1680,7 +1680,7 @@ static int create_con(struct rtrs_srv_sess *sess, */ } cq_num = max_send_wr + max_recv_wr; - atomic_set(&con->sq_wr_avail, max_send_wr); + atomic_set(&con->c.sq_wr_avail, max_send_wr); cq_vector = rtrs_srv_get_next_cq_vector(sess); /* TODO: SOFTIRQ can be faster, but be careful with softirq context */ diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.h b/drivers/infiniband/ulp/rtrs/rtrs-srv.h index 6785c3b6363e..e81774f5acd3 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.h @@ -42,7 +42,6 @@ struct rtrs_srv_stats { struct rtrs_srv_con { struct rtrs_con c; - atomic_t sq_wr_avail; struct list_head rsp_wr_wait_list; spinlock_t rsp_wr_wait_lock; }; diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index b56dc5b82db0..ca542e477d38 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -191,6 +191,7 @@ static int rtrs_post_rdma_write_imm_empty(struct rtrs_con *con, struct rtrs_sess *sess = con->sess; enum ib_send_flags sflags; + atomic_dec_if_positive(&con->sq_wr_avail); sflags = (atomic_inc_return(&con->wr_cnt) % sess->signal_interval) ? 0 : IB_SEND_SIGNALED; -- cgit v1.2.3-70-g09d2 From 1ec50dd12a434794249a5d3c6e0a392d89c15ee6 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Mon, 21 Jun 2021 23:14:21 -0700 Subject: RDMA/siw: Remove kmap() kmap() is being deprecated and will break uses of device dax after PKS protection is introduced.[1] These uses of kmap() in the SIW driver are thread local. Therefore kmap_local_page() is sufficient to use and will work with pgmap protected pages when those are implemnted. There is one more use of kmap() in this driver which is split into its own patch because kmap_local_page() has strict ordering rules and the use of the kmap_mask over multiple segments must be handled carefully. Therefore, that conversion is handled in a stand alone patch. Use kmap_local_page() instead of kmap() in the 'easy' cases. [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/ Link: https://lore.kernel.org/r/20210622061422.2633501-4-ira.weiny@intel.com Signed-off-by: Ira Weiny Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/siw/siw_qp_tx.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index 7989c4043db4..db68a10d12cd 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -76,7 +76,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) if (unlikely(!p)) return -EFAULT; - buffer = kmap(p); + buffer = kmap_local_page(p); if (likely(PAGE_SIZE - off >= bytes)) { memcpy(paddr, buffer + off, bytes); @@ -84,7 +84,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) unsigned long part = bytes - (PAGE_SIZE - off); memcpy(paddr, buffer + off, part); - kunmap(p); + kunmap_local(buffer); if (!mem->is_pbl) p = siw_get_upage(mem->umem, @@ -96,10 +96,10 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr) if (unlikely(!p)) return -EFAULT; - buffer = kmap(p); + buffer = kmap_local_page(p); memcpy(paddr + part, buffer, bytes - part); } - kunmap(p); + kunmap_local(buffer); } } return (int)bytes; @@ -485,6 +485,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) while (sge_len) { size_t plen = min((int)PAGE_SIZE - fp_off, sge_len); + void *kaddr; if (!is_kva) { struct page *p; @@ -517,10 +518,11 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) iov[seg].iov_base, plen); } else if (do_crc) { + kaddr = kmap_local_page(p); crypto_shash_update(c_tx->mpa_crc_hd, - kmap(p) + fp_off, + kaddr + fp_off, plen); - kunmap(p); + kunmap_local(kaddr); } } else { u64 va = sge->laddr + sge_off; -- cgit v1.2.3-70-g09d2 From 9d649d594f3965cbd162121259b2f84928b907a1 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Thu, 24 Jun 2021 10:48:14 -0700 Subject: RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() kmap() is being deprecated and will break uses of device dax after PKS protection is introduced.[1] The use of kmap() in siw_tx_hdt() is all thread local therefore kmap_local_page() is a sufficient replacement and will work with pgmap protected pages when those are implemented. siw_tx_hdt() tracks pages used in a page_array. It uses that array to unmap pages which were mapped on function exit. Not all entries in the array are mapped and this is tracked in kmap_mask. kunmap_local() takes a mapped address rather than a page. Alter siw_unmap_pages() to take the iov array to reuse the iov_base address of each mapping. Use PAGE_MASK to get the proper address for kunmap_local(). kmap_local_page() mappings are tracked in a stack and must be unmapped in the opposite order they were mapped in. Because segments are mapped into the page array in increasing index order, modify siw_unmap_pages() to unmap pages in decreasing order. Use kmap_local_page() instead of kmap() to map pages in the page_array. [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/ Link: https://lore.kernel.org/r/20210624174814.2822896-1-ira.weiny@intel.com Signed-off-by: Ira Weiny Reviewed-by: Bernard Metzler Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/siw/siw_qp_tx.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index db68a10d12cd..1f4e60257700 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s, struct page **page, #define MAX_TRAILER (MPA_CRC_SIZE + 4) -static void siw_unmap_pages(struct page **pp, unsigned long kmap_mask) +static void siw_unmap_pages(struct kvec *iov, unsigned long kmap_mask, int len) { - while (kmap_mask) { - if (kmap_mask & BIT(0)) - kunmap(*pp); - pp++; - kmap_mask >>= 1; + int i; + + /* + * Work backwards through the array to honor the kmap_local_page() + * ordering requirements. + */ + for (i = (len-1); i >= 0; i--) { + if (kmap_mask & BIT(i)) { + unsigned long addr = (unsigned long)iov[i].iov_base; + + kunmap_local((void *)(addr & PAGE_MASK)); + } } } @@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) p = siw_get_upage(mem->umem, sge->laddr + sge_off); if (unlikely(!p)) { - siw_unmap_pages(page_array, kmap_mask); + siw_unmap_pages(iov, kmap_mask, seg); wqe->processed -= c_tx->bytes_unsent; rv = -EFAULT; goto done_crc; @@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) page_array[seg] = p; if (!c_tx->use_sendpage) { - iov[seg].iov_base = kmap(p) + fp_off; - iov[seg].iov_len = plen; + void *kaddr = kmap_local_page(p); /* Remember for later kunmap() */ kmap_mask |= BIT(seg); + iov[seg].iov_base = kaddr + fp_off; + iov[seg].iov_len = plen; if (do_crc) crypto_shash_update( @@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) if (++seg > (int)MAX_ARRAY) { siw_dbg_qp(tx_qp(c_tx), "to many fragments\n"); - siw_unmap_pages(page_array, kmap_mask); + siw_unmap_pages(iov, kmap_mask, seg-1); wqe->processed -= c_tx->bytes_unsent; rv = -EMSGSIZE; goto done_crc; @@ -593,7 +601,7 @@ sge_done: } else { rv = kernel_sendmsg(s, &msg, iov, seg + 1, hdr_len + data_len + trl_len); - siw_unmap_pages(page_array, kmap_mask); + siw_unmap_pages(iov, kmap_mask, seg); } if (rv < (int)hdr_len) { /* Not even complete hdr pushed or negative rv */ -- cgit v1.2.3-70-g09d2 From cdbdb7724740f62d11519679e11cf673cd9d6c8f Mon Sep 17 00:00:00 2001 From: Xiao Yang Date: Fri, 2 Jul 2021 20:30:24 +0800 Subject: RDMA/rxe: Remove the repeated 'mr->umem = umem' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop duplicated code Link: https://lore.kernel.org/r/20210702123024.37025-1-ice_yangxiao@163.com Signed-off-by: Xiao Yang Reviewed-by: Håkon Bugge Reviewed-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_mr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 6aabcb4de235..487cefc015b8 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -122,7 +122,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, goto err1; } - mr->umem = umem; num_buf = ib_umem_num_pages(umem); rxe_mr_init(access, mr); -- cgit v1.2.3-70-g09d2 From 916071185b178b052e0ca8bcdf269161b6848da9 Mon Sep 17 00:00:00 2001 From: Weihang Li Date: Thu, 8 Jul 2021 18:59:18 +0800 Subject: MAINTAINERS: Update maintainers of HiSilicon RoCE Lijun has moved to work in other technical areas, and Wenpeng will maintain this modules instead of him. Link: https://lore.kernel.org/r/1625741958-51363-1-git-send-email-liweihang@huawei.com Signed-off-by: Weihang Li Signed-off-by: Jason Gunthorpe --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..5b772ea29b0c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8394,7 +8394,7 @@ F: drivers/crypto/hisilicon/sgl.c F: drivers/crypto/hisilicon/zip/ HISILICON ROCE DRIVER -M: Lijun Ou +M: Wenpeng Liang M: Weihang Li L: linux-rdma@vger.kernel.org S: Maintained -- cgit v1.2.3-70-g09d2 From 8c1b4316c3faa38cb66bde200a8f2942fa6728b6 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Mon, 12 Jul 2021 13:59:23 +0300 Subject: RDMA/efa: Split hardware stats to device and port stats The hardware stats API distinguishes between device and port statistics, split the EFA stats accordingly instead of always dumping everything. Link: https://lore.kernel.org/r/20210712105923.17389-1-galpress@amazon.com Reviewed-by: Firas JahJah Reviewed-by: Yossi Leybovich Signed-off-by: Gal Pressman Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/efa/efa_verbs.c | 118 ++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index be6d3ff0f1be..b4cfb656ddd5 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* - * Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include @@ -30,7 +30,21 @@ struct efa_user_mmap_entry { u8 mmap_flag; }; -#define EFA_DEFINE_STATS(op) \ +#define EFA_DEFINE_DEVICE_STATS(op) \ + op(EFA_SUBMITTED_CMDS, "submitted_cmds") \ + op(EFA_COMPLETED_CMDS, "completed_cmds") \ + op(EFA_CMDS_ERR, "cmds_err") \ + op(EFA_NO_COMPLETION_CMDS, "no_completion_cmds") \ + op(EFA_KEEP_ALIVE_RCVD, "keep_alive_rcvd") \ + op(EFA_ALLOC_PD_ERR, "alloc_pd_err") \ + op(EFA_CREATE_QP_ERR, "create_qp_err") \ + op(EFA_CREATE_CQ_ERR, "create_cq_err") \ + op(EFA_REG_MR_ERR, "reg_mr_err") \ + op(EFA_ALLOC_UCONTEXT_ERR, "alloc_ucontext_err") \ + op(EFA_CREATE_AH_ERR, "create_ah_err") \ + op(EFA_MMAP_ERR, "mmap_err") + +#define EFA_DEFINE_PORT_STATS(op) \ op(EFA_TX_BYTES, "tx_bytes") \ op(EFA_TX_PKTS, "tx_pkts") \ op(EFA_RX_BYTES, "rx_bytes") \ @@ -44,28 +58,24 @@ struct efa_user_mmap_entry { op(EFA_RDMA_READ_BYTES, "rdma_read_bytes") \ op(EFA_RDMA_READ_WR_ERR, "rdma_read_wr_err") \ op(EFA_RDMA_READ_RESP_BYTES, "rdma_read_resp_bytes") \ - op(EFA_SUBMITTED_CMDS, "submitted_cmds") \ - op(EFA_COMPLETED_CMDS, "completed_cmds") \ - op(EFA_CMDS_ERR, "cmds_err") \ - op(EFA_NO_COMPLETION_CMDS, "no_completion_cmds") \ - op(EFA_KEEP_ALIVE_RCVD, "keep_alive_rcvd") \ - op(EFA_ALLOC_PD_ERR, "alloc_pd_err") \ - op(EFA_CREATE_QP_ERR, "create_qp_err") \ - op(EFA_CREATE_CQ_ERR, "create_cq_err") \ - op(EFA_REG_MR_ERR, "reg_mr_err") \ - op(EFA_ALLOC_UCONTEXT_ERR, "alloc_ucontext_err") \ - op(EFA_CREATE_AH_ERR, "create_ah_err") \ - op(EFA_MMAP_ERR, "mmap_err") #define EFA_STATS_ENUM(ename, name) ename, #define EFA_STATS_STR(ename, name) [ename] = name, -enum efa_hw_stats { - EFA_DEFINE_STATS(EFA_STATS_ENUM) +enum efa_hw_device_stats { + EFA_DEFINE_DEVICE_STATS(EFA_STATS_ENUM) +}; + +static const char *const efa_device_stats_names[] = { + EFA_DEFINE_DEVICE_STATS(EFA_STATS_STR) +}; + +enum efa_hw_port_stats { + EFA_DEFINE_PORT_STATS(EFA_STATS_ENUM) }; -static const char *const efa_stats_names[] = { - EFA_DEFINE_STATS(EFA_STATS_STR) +static const char *const efa_port_stats_names[] = { + EFA_DEFINE_PORT_STATS(EFA_STATS_STR) }; #define EFA_CHUNK_PAYLOAD_SHIFT 12 @@ -1904,33 +1914,53 @@ int efa_destroy_ah(struct ib_ah *ibah, u32 flags) return 0; } -struct rdma_hw_stats *efa_alloc_hw_port_stats(struct ib_device *ibdev, u32 port_num) +struct rdma_hw_stats *efa_alloc_hw_port_stats(struct ib_device *ibdev, + u32 port_num) { - return rdma_alloc_hw_stats_struct(efa_stats_names, - ARRAY_SIZE(efa_stats_names), + return rdma_alloc_hw_stats_struct(efa_port_stats_names, + ARRAY_SIZE(efa_port_stats_names), RDMA_HW_STATS_DEFAULT_LIFESPAN); } struct rdma_hw_stats *efa_alloc_hw_device_stats(struct ib_device *ibdev) { - /* - * It is probably a bug that efa reports its port stats as device - * stats - */ - return efa_alloc_hw_port_stats(ibdev, 0); + return rdma_alloc_hw_stats_struct(efa_device_stats_names, + ARRAY_SIZE(efa_device_stats_names), + RDMA_HW_STATS_DEFAULT_LIFESPAN); } -int efa_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, - u32 port_num, int index) +static int efa_fill_device_stats(struct efa_dev *dev, + struct rdma_hw_stats *stats) +{ + struct efa_com_stats_admin *as = &dev->edev.aq.stats; + struct efa_stats *s = &dev->stats; + + stats->value[EFA_SUBMITTED_CMDS] = atomic64_read(&as->submitted_cmd); + stats->value[EFA_COMPLETED_CMDS] = atomic64_read(&as->completed_cmd); + stats->value[EFA_CMDS_ERR] = atomic64_read(&as->cmd_err); + stats->value[EFA_NO_COMPLETION_CMDS] = atomic64_read(&as->no_completion); + + stats->value[EFA_KEEP_ALIVE_RCVD] = atomic64_read(&s->keep_alive_rcvd); + stats->value[EFA_ALLOC_PD_ERR] = atomic64_read(&s->alloc_pd_err); + stats->value[EFA_CREATE_QP_ERR] = atomic64_read(&s->create_qp_err); + stats->value[EFA_CREATE_CQ_ERR] = atomic64_read(&s->create_cq_err); + stats->value[EFA_REG_MR_ERR] = atomic64_read(&s->reg_mr_err); + stats->value[EFA_ALLOC_UCONTEXT_ERR] = + atomic64_read(&s->alloc_ucontext_err); + stats->value[EFA_CREATE_AH_ERR] = atomic64_read(&s->create_ah_err); + stats->value[EFA_MMAP_ERR] = atomic64_read(&s->mmap_err); + + return ARRAY_SIZE(efa_device_stats_names); +} + +static int efa_fill_port_stats(struct efa_dev *dev, struct rdma_hw_stats *stats, + u32 port_num) { struct efa_com_get_stats_params params = {}; union efa_com_get_stats_result result; - struct efa_dev *dev = to_edev(ibdev); struct efa_com_rdma_read_stats *rrs; struct efa_com_messages_stats *ms; struct efa_com_basic_stats *bs; - struct efa_com_stats_admin *as; - struct efa_stats *s; int err; params.scope = EFA_ADMIN_GET_STATS_SCOPE_ALL; @@ -1969,24 +1999,16 @@ int efa_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, stats->value[EFA_RDMA_READ_WR_ERR] = rrs->read_wr_err; stats->value[EFA_RDMA_READ_RESP_BYTES] = rrs->read_resp_bytes; - as = &dev->edev.aq.stats; - stats->value[EFA_SUBMITTED_CMDS] = atomic64_read(&as->submitted_cmd); - stats->value[EFA_COMPLETED_CMDS] = atomic64_read(&as->completed_cmd); - stats->value[EFA_CMDS_ERR] = atomic64_read(&as->cmd_err); - stats->value[EFA_NO_COMPLETION_CMDS] = atomic64_read(&as->no_completion); - - s = &dev->stats; - stats->value[EFA_KEEP_ALIVE_RCVD] = atomic64_read(&s->keep_alive_rcvd); - stats->value[EFA_ALLOC_PD_ERR] = atomic64_read(&s->alloc_pd_err); - stats->value[EFA_CREATE_QP_ERR] = atomic64_read(&s->create_qp_err); - stats->value[EFA_CREATE_CQ_ERR] = atomic64_read(&s->create_cq_err); - stats->value[EFA_REG_MR_ERR] = atomic64_read(&s->reg_mr_err); - stats->value[EFA_ALLOC_UCONTEXT_ERR] = - atomic64_read(&s->alloc_ucontext_err); - stats->value[EFA_CREATE_AH_ERR] = atomic64_read(&s->create_ah_err); - stats->value[EFA_MMAP_ERR] = atomic64_read(&s->mmap_err); + return ARRAY_SIZE(efa_port_stats_names); +} - return ARRAY_SIZE(efa_stats_names); +int efa_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats, + u32 port_num, int index) +{ + if (port_num) + return efa_fill_port_stats(to_edev(ibdev), stats, port_num); + else + return efa_fill_device_stats(to_edev(ibdev), stats); } enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev, -- cgit v1.2.3-70-g09d2 From f4abaa9eebde334045ed6ac4e564d050f1df3013 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 29 Jun 2021 11:25:50 -0700 Subject: HID: input: do not report stylus battery state as "full" The power supply states of discharging, charging, full, etc, represent state of charging, not the capacity level of the battery (for which we have a separate property). Current HID usage tables to not allow for expressing charging state of the batteries found in generic styli, so we should simply assume that the battery is discharging even if current capacity is at 100% when battery strength reporting is done via HID interface. In fact, we were doing just that before commit 581c4484769e. This change helps UIs to not mis-represent fully charged batteries in styli as being charging/topping-off. Fixes: 581c4484769e ("HID: input: map digitizer battery usage") Reported-by: Kenneth Albanowski Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 4286a51f7f16..4b5ebeacd283 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -419,8 +419,6 @@ static int hidinput_get_battery_property(struct power_supply *psy, if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - else if (dev->battery_capacity == 100) - val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; -- cgit v1.2.3-70-g09d2 From d4b9f10a0eb64c623217eb5938d913974afbe9d2 Mon Sep 17 00:00:00 2001 From: José Expósito Date: Wed, 7 Jul 2021 17:58:21 +0200 Subject: HID: magicmouse: enable high-resolution scroll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Magic Mouse, generations 1 and 2, doesn't have a physical scroll wheel, instead, the REL_WHEEL and REL_HWHEEL events are emulated when sliding a finger on the surface of the mouse. However, the smooth movement of the finger is transformed into a step based scroll on the screen, leading to a suboptimal user experience. Emulate high-resolution scroll by sending REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES events so the scroll on the screen is closer to the finger movement. Signed-off-by: José Expósito Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 8bcaee4ccae0..e95f46dab4ad 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -68,6 +68,9 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie #define TOUCH_STATE_START 0x30 #define TOUCH_STATE_DRAG 0x40 +/* Number of high-resolution events for each low-resolution detent. */ +#define SCROLL_HR_STEPS 10 +#define SCROLL_HR_MULT (120 / SCROLL_HR_STEPS) #define SCROLL_ACCEL_DEFAULT 7 /* Touch surface information. Dimension is in hundredths of a mm, min and max @@ -126,6 +129,8 @@ struct magicmouse_sc { short y; short scroll_x; short scroll_y; + short scroll_x_hr; + short scroll_y_hr; u8 size; } touches[16]; int tracking_ids[16]; @@ -248,12 +253,18 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda unsigned long now = jiffies; int step_x = msc->touches[id].scroll_x - x; int step_y = msc->touches[id].scroll_y - y; + int step_hr = ((64 - (int)scroll_speed) * msc->scroll_accel) / + SCROLL_HR_STEPS; + int step_x_hr = msc->touches[id].scroll_x_hr - x; + int step_y_hr = msc->touches[id].scroll_y_hr - y; /* Calculate and apply the scroll motion. */ switch (state) { case TOUCH_STATE_START: msc->touches[id].scroll_x = x; msc->touches[id].scroll_y = y; + msc->touches[id].scroll_x_hr = x; + msc->touches[id].scroll_y_hr = y; /* Reset acceleration after half a second. */ if (scroll_acceleration && time_before(now, @@ -280,6 +291,24 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda msc->scroll_jiffies = now; input_report_rel(input, REL_WHEEL, step_y); } + + step_x_hr /= step_hr; + if (step_x_hr != 0) { + msc->touches[id].scroll_x_hr -= step_x_hr * + step_hr; + input_report_rel(input, + REL_HWHEEL_HI_RES, + -step_x_hr * SCROLL_HR_MULT); + } + + step_y_hr /= step_hr; + if (step_y_hr != 0) { + msc->touches[id].scroll_y_hr -= step_y_hr * + step_hr; + input_report_rel(input, + REL_WHEEL_HI_RES, + step_y_hr * SCROLL_HR_MULT); + } break; } } @@ -481,6 +510,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd if (emulate_scroll_wheel) { __set_bit(REL_WHEEL, input->relbit); __set_bit(REL_HWHEEL, input->relbit); + __set_bit(REL_WHEEL_HI_RES, input->relbit); + __set_bit(REL_HWHEEL_HI_RES, input->relbit); } } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) { /* setting the device name to ensure the same driver settings -- cgit v1.2.3-70-g09d2 From 9d60648c607a2bfeef5e563e49de5d2e1b7a639a Mon Sep 17 00:00:00 2001 From: José Expósito Date: Wed, 7 Jul 2021 17:58:22 +0200 Subject: HID: magicmouse: high-resolution scroll threshold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to avoid triggering involuntary high-resolution scroll events due to tiny touch movement deltas, add a movement threshold. The value chosen for the threshold, about 1.5 ~ 2 mm, is similar to the threshold used on touchpads by libinput (see libinput evdev-mt-touchpad-gestures.c) to try to keep the scroll experience consistent. Signed-off-by: José Expósito Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index e95f46dab4ad..686788ebf3e1 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -71,6 +71,7 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie /* Number of high-resolution events for each low-resolution detent. */ #define SCROLL_HR_STEPS 10 #define SCROLL_HR_MULT (120 / SCROLL_HR_STEPS) +#define SCROLL_HR_THRESHOLD 90 /* units */ #define SCROLL_ACCEL_DEFAULT 7 /* Touch surface information. Dimension is in hundredths of a mm, min and max @@ -132,6 +133,8 @@ struct magicmouse_sc { short scroll_x_hr; short scroll_y_hr; u8 size; + bool scroll_x_active; + bool scroll_y_active; } touches[16]; int tracking_ids[16]; @@ -265,6 +268,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda msc->touches[id].scroll_y = y; msc->touches[id].scroll_x_hr = x; msc->touches[id].scroll_y_hr = y; + msc->touches[id].scroll_x_active = false; + msc->touches[id].scroll_y_active = false; /* Reset acceleration after half a second. */ if (scroll_acceleration && time_before(now, @@ -292,8 +297,16 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda input_report_rel(input, REL_WHEEL, step_y); } + if (!msc->touches[id].scroll_x_active && + abs(step_x_hr) > SCROLL_HR_THRESHOLD) { + msc->touches[id].scroll_x_active = true; + msc->touches[id].scroll_x_hr = x; + step_x_hr = 0; + } + step_x_hr /= step_hr; - if (step_x_hr != 0) { + if (step_x_hr != 0 && + msc->touches[id].scroll_x_active) { msc->touches[id].scroll_x_hr -= step_x_hr * step_hr; input_report_rel(input, @@ -301,8 +314,16 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda -step_x_hr * SCROLL_HR_MULT); } + if (!msc->touches[id].scroll_y_active && + abs(step_y_hr) > SCROLL_HR_THRESHOLD) { + msc->touches[id].scroll_y_active = true; + msc->touches[id].scroll_y_hr = y; + step_y_hr = 0; + } + step_y_hr /= step_hr; - if (step_y_hr != 0) { + if (step_y_hr != 0 && + msc->touches[id].scroll_y_active) { msc->touches[id].scroll_y_hr -= step_y_hr * step_hr; input_report_rel(input, -- cgit v1.2.3-70-g09d2 From 18eeef46d3593e3bc3d6a8f7a6f94ace356578ff Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Fri, 25 Jun 2021 08:18:36 -0700 Subject: HID: i2c-hid: goodix: Tie the reset line to true state of the regulator The regulator for the touchscreen could be: * A dedicated regulator just for the touchscreen. * A regulator shared with something else in the system. * An always-on regulator. How we want the "reset" line to behave depends a bit on which of those three cases we're in. Currently the code is written with the assumption that it has a dedicated regulator, but that's not really guaranteed to be the case. The problem we run into is that if we leave the touchscreen powered on (because someone else is requesting the regulator or it's an always-on regulator) and we assert reset then we apparently burn an extra 67 mW of power. That's not great. Let's instead tie the control of the reset line to the true state of the regulator as reported by regulator notifiers. If we have an always-on regulator our notifier will never be called. If we have a shared regulator then our notifier will be called when the touchscreen is truly turned on or truly turned off. Using notifiers like this nicely handles all the cases without resorting to hacks like pretending that there is no "reset" GPIO if we have an always-on regulator. NOTE: if the regulator is on a shared line it's still possible that things could be a little off. Specifically, this case is not handled even after this patch: 1. Suspend goodix (send "sleep", goodix stops requesting regulator on) 2. Other regulator user turns off (regulator fully turns off). 3. Goodix driver gets notified and asserts reset. 4. Other regulator user turns on. 5. Goodix driver gets notified and deasserts reset. 6. Nobody resumes goodix. With that set of steps we'll have reset deasserted but we will have lost the results of the I2C_HID_PWR_SLEEP from the suspend path. That means we might be in higher power than we could be even if the goodix driver thinks things are suspended. Presumably, however, we're still in better shape than if we were asserting "reset" the whole time. If somehow the above situation is actually affecting someone and we want to do better we can deal with it when we have a real use case. Signed-off-by: Douglas Anderson Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-of-goodix.c | 92 ++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 13 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c index ee0225982a82..31a4c229fdb7 100644 --- a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c +++ b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c @@ -26,28 +26,29 @@ struct i2c_hid_of_goodix { struct i2chid_ops ops; struct regulator *vdd; + struct notifier_block nb; + struct mutex regulator_mutex; struct gpio_desc *reset_gpio; const struct goodix_i2c_hid_timing_data *timings; }; -static int goodix_i2c_hid_power_up(struct i2chid_ops *ops) +static void goodix_i2c_hid_deassert_reset(struct i2c_hid_of_goodix *ihid_goodix, + bool regulator_just_turned_on) { - struct i2c_hid_of_goodix *ihid_goodix = - container_of(ops, struct i2c_hid_of_goodix, ops); - int ret; - - ret = regulator_enable(ihid_goodix->vdd); - if (ret) - return ret; - - if (ihid_goodix->timings->post_power_delay_ms) + if (regulator_just_turned_on && ihid_goodix->timings->post_power_delay_ms) msleep(ihid_goodix->timings->post_power_delay_ms); gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 0); if (ihid_goodix->timings->post_gpio_reset_delay_ms) msleep(ihid_goodix->timings->post_gpio_reset_delay_ms); +} - return 0; +static int goodix_i2c_hid_power_up(struct i2chid_ops *ops) +{ + struct i2c_hid_of_goodix *ihid_goodix = + container_of(ops, struct i2c_hid_of_goodix, ops); + + return regulator_enable(ihid_goodix->vdd); } static void goodix_i2c_hid_power_down(struct i2chid_ops *ops) @@ -55,20 +56,54 @@ static void goodix_i2c_hid_power_down(struct i2chid_ops *ops) struct i2c_hid_of_goodix *ihid_goodix = container_of(ops, struct i2c_hid_of_goodix, ops); - gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); regulator_disable(ihid_goodix->vdd); } +static int ihid_goodix_vdd_notify(struct notifier_block *nb, + unsigned long event, + void *ignored) +{ + struct i2c_hid_of_goodix *ihid_goodix = + container_of(nb, struct i2c_hid_of_goodix, nb); + int ret = NOTIFY_OK; + + mutex_lock(&ihid_goodix->regulator_mutex); + + switch (event) { + case REGULATOR_EVENT_PRE_DISABLE: + gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); + break; + + case REGULATOR_EVENT_ENABLE: + goodix_i2c_hid_deassert_reset(ihid_goodix, true); + break; + + case REGULATOR_EVENT_ABORT_DISABLE: + goodix_i2c_hid_deassert_reset(ihid_goodix, false); + break; + + default: + ret = NOTIFY_DONE; + break; + } + + mutex_unlock(&ihid_goodix->regulator_mutex); + + return ret; +} + static int i2c_hid_of_goodix_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_hid_of_goodix *ihid_goodix; - + int ret; ihid_goodix = devm_kzalloc(&client->dev, sizeof(*ihid_goodix), GFP_KERNEL); if (!ihid_goodix) return -ENOMEM; + mutex_init(&ihid_goodix->regulator_mutex); + ihid_goodix->ops.power_up = goodix_i2c_hid_power_up; ihid_goodix->ops.power_down = goodix_i2c_hid_power_down; @@ -84,6 +119,37 @@ static int i2c_hid_of_goodix_probe(struct i2c_client *client, ihid_goodix->timings = device_get_match_data(&client->dev); + /* + * We need to control the "reset" line in lockstep with the regulator + * actually turning on an off instead of just when we make the request. + * This matters if the regulator is shared with another consumer. + * - If the regulator is off then we must assert reset. The reset + * line is active low and on some boards it could cause a current + * leak if left high. + * - If the regulator is on then we don't want reset asserted for very + * long. Holding the controller in reset apparently draws extra + * power. + */ + mutex_lock(&ihid_goodix->regulator_mutex); + ihid_goodix->nb.notifier_call = ihid_goodix_vdd_notify; + ret = regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb); + if (ret) { + mutex_unlock(&ihid_goodix->regulator_mutex); + return dev_err_probe(&client->dev, ret, + "regulator notifier request failed\n"); + } + + /* + * If someone else is holding the regulator on (or the regulator is + * an always-on one) we might never be told to deassert reset. Do it + * now. Here we'll assume that someone else might have _just + * barely_ turned the regulator on so we'll do the full + * "post_power_delay" just in case. + */ + if (ihid_goodix->reset_gpio && regulator_is_enabled(ihid_goodix->vdd)) + goodix_i2c_hid_deassert_reset(ihid_goodix, true); + mutex_unlock(&ihid_goodix->regulator_mutex); + return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001); } -- cgit v1.2.3-70-g09d2 From b13c1fff66cc255c0a9d48561d05f0f7e8ffd385 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Tue, 13 Jul 2021 17:47:13 +0800 Subject: clk: rockchip: add dt-binding clkid for hclk_sfc on rk3036 Add dt-binding for hclk_sfc on rk3036 Signed-off-by: Chris Morgan Signed-off-by: Jon Lin Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20210713094718.1709-1-jon.lin@rock-chips.com Signed-off-by: Heiko Stuebner --- include/dt-bindings/clock/rk3036-cru.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/clock/rk3036-cru.h b/include/dt-bindings/clock/rk3036-cru.h index 35a5a01f9697..a96a9870ad59 100644 --- a/include/dt-bindings/clock/rk3036-cru.h +++ b/include/dt-bindings/clock/rk3036-cru.h @@ -81,6 +81,7 @@ #define HCLK_OTG0 449 #define HCLK_OTG1 450 #define HCLK_NANDC 453 +#define HCLK_SFC 454 #define HCLK_SDMMC 456 #define HCLK_SDIO 457 #define HCLK_EMMC 459 -- cgit v1.2.3-70-g09d2 From 0be3df186f870cbde56b223c1ad7892109c9c440 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Tue, 13 Jul 2021 17:44:50 +0800 Subject: clk: rockchip: rk3036: fix up the sclk_sfc parent error Choose the correct pll Signed-off-by: Elaine Zhang Signed-off-by: Jon Lin Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20210713094456.23288-5-jon.lin@rock-chips.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 614845cc5b4a..c38ad4ec8746 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -121,6 +121,7 @@ PNAME(mux_pll_src_3plls_p) = { "apll", "dpll", "gpll" }; PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" }; PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" }; +PNAME(mux_pll_src_dmyapll_dpll_gpll_xin24_p) = { "dummy_apll", "dpll", "gpll", "xin24m" }; PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" }; PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; @@ -340,7 +341,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS, RK2928_CLKGATE_CON(10), 4, GFLAGS), - COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_dmyapll_dpll_gpll_xin24_p, 0, RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS, RK2928_CLKGATE_CON(10), 5, GFLAGS), -- cgit v1.2.3-70-g09d2 From d61eb8a1f5184f32ddc5ac03c930cff8e9a6fae9 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Tue, 13 Jul 2021 17:47:14 +0800 Subject: clk: rockchip: Add support for hclk_sfc on rk3036 Add support for the bus clock for the serial flash controller on the rk3036. Taken from the Rockchip BSP kernel but not tested on real hardware (as I lack a 3036 based SoC to test). Signed-off-by: Chris Morgan Signed-off-by: Jon Lin Acked-by: Stephen Boyd Link: https://lore.kernel.org/r/20210713094718.1709-2-jon.lin@rock-chips.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3036.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index c38ad4ec8746..d644bc155ec6 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -404,7 +404,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), - GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), + GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), /* pclk_peri gates */ -- cgit v1.2.3-70-g09d2 From ff44b90b325dcd585cdba6ded6c9c52ea8ddead0 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Mon, 28 Jun 2021 19:14:40 +0000 Subject: dt_bindings: mtd: partitions: redboot: convert to YAML Converts mtd/partitions/redboot-fis.txt to YAML. Signed-off-by: Corentin Labbe Reviewed-by: Linus Walleij Reviewed-by: Rob Herring Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210628191440.2823024-1-clabbe@baylibre.com --- .../bindings/mtd/partitions/redboot-fis.txt | 27 -------------- .../bindings/mtd/partitions/redboot-fis.yaml | 42 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 27 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt create mode 100644 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml diff --git a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt deleted file mode 100644 index fd0ebe4e3415..000000000000 --- a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt +++ /dev/null @@ -1,27 +0,0 @@ -RedBoot FLASH Image System (FIS) Partitions -=========================================== - -The FLASH Image System (FIS) directory is a flash description -format closely associated with the RedBoot boot loader. - -It uses one single flash eraseblock in the flash to store an index of -all images in the flash. - -This block size will vary depending on flash but is typically -32 KB in size. - -Required properties: -- compatible : (required) must be "redboot-fis" -- fis-index-block : (required) a index to the eraseblock containing - the FIS directory on this device. On a flash memory with 32KB - eraseblocks, 0 means the first eraseblock at 0x00000000, 1 means the - second eraseblock at 0x00008000 and so on. - -Example: - -flash@0 { - partitions { - compatible = "redboot-fis"; - fis-index-block = <0>; - }; -}; diff --git a/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml new file mode 100644 index 000000000000..fee8d81b5276 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mtd/partitions/redboot-fis.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RedBoot FLASH Image System (FIS) Partitions + +description: The FLASH Image System (FIS) directory is a flash description + format closely associated with the RedBoot boot loader. + It uses one single flash eraseblock in the flash to store an index of + all images in the flash. + This block size will vary depending on flash but is typically + 32 KB in size. + +maintainers: + - Linus Walleij + +properties: + compatible: + const: redboot-fis + + fis-index-block: + $ref: /schemas/types.yaml#/definitions/uint32 + description: a index to the eraseblock containing the FIS directory on this + device. On a flash memory with 32KB eraseblocks, 0 means the first + eraseblock at 0x00000000, 1 means the second eraseblock at 0x00008000 and so on. + +required: + - compatible + - fis-index-block + +additionalProperties: false + +examples: + - | + flash { + partitions { + compatible = "redboot-fis"; + fis-index-block = <0>; + }; + }; -- cgit v1.2.3-70-g09d2 From 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 10 Jun 2021 16:39:45 +0200 Subject: dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation "PAGESIZE / 512" is the number of ECC chunks. "ECC_BYTES" is the number of bytes needed to store a single ECC code. "2" is the space reserved by the bad block marker. "2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal than the total number of OOB bytes, otherwise it won't fit. Fix the equation by substituting s/>=/<=/. Suggested-by: Ryan J. Barnett Signed-off-by: Miquel Raynal Acked-by: Rob Herring Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal@bootlin.com --- Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index 44919d48d241..c459f169a904 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -122,7 +122,7 @@ on various other factors also like; so the device should have enough free bytes available its OOB/Spare area to accommodate ECC for entire page. In general following expression helps in determining if given device can accommodate ECC syndrome: - "2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE" + "2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE" where OOBSIZE number of bytes in OOB/spare area PAGESIZE number of bytes in main-area of device page -- cgit v1.2.3-70-g09d2 From 1a57b13e6017d2af575f4f42e848aa0b64d4bcf1 Mon Sep 17 00:00:00 2001 From: Stefan Riedmueller Date: Fri, 25 Jun 2021 14:38:21 +0200 Subject: mtd: rawnand: nand_bbt: Skip bad blocks when searching for the BBT in NAND The blocks containing the bad block table can become bad as well. So make sure to skip any blocks that are marked bad when searching for the bad block table. Otherwise in very rare cases where two BBT blocks wear out it might happen that an obsolete BBT is used instead of a newer available version. This only applies to drivers which make use of a bad block marker in flash. Other drivers won't be able to identify bad BBT blocks and thus can't skip these. Signed-off-by: Stefan Riedmueller Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210625123821.207458-1-s.riedmueller@phytec.de --- drivers/mtd/nand/raw/nand_bbt.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index dced32a126d9..b7ad030225f8 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -447,6 +447,35 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, return 0; } +/* Check if a potential BBT block is marked as bad */ +static int bbt_block_checkbad(struct nand_chip *this, struct nand_bbt_descr *td, + loff_t offs, uint8_t *buf) +{ + struct nand_bbt_descr *bd = this->badblock_pattern; + + /* + * No need to check for a bad BBT block if the BBM area overlaps with + * the bad block table marker area in OOB since writing a BBM here + * invalidates the bad block table marker anyway. + */ + if (!(td->options & NAND_BBT_NO_OOB) && + td->offs >= bd->offs && td->offs < bd->offs + bd->len) + return 0; + + /* + * There is no point in checking for a bad block marker if writing + * such marker is not supported + */ + if (this->bbt_options & NAND_BBT_NO_OOB_BBM || + this->options & NAND_NO_BBM_QUIRK) + return 0; + + if (scan_block_fast(this, bd, offs, buf) > 0) + return 1; + + return 0; +} + /** * create_bbt - [GENERIC] Create a bad block table by scanning the device * @this: NAND chip object @@ -560,6 +589,10 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf, int actblock = startblock + dir * block; loff_t offs = (loff_t)actblock << this->bbt_erase_shift; + /* Check if block is marked bad */ + if (bbt_block_checkbad(this, td, offs, buf)) + continue; + /* Read first page */ scan_read(this, buf, offs, mtd->writesize, td); if (!check_pattern(buf, scanlen, mtd->writesize, td)) { -- cgit v1.2.3-70-g09d2 From 7ed012969bbcdbd7aef5778a061681e6cbc4b402 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Wed, 14 Jul 2021 17:01:59 +0200 Subject: Compiler Attributes: fix __has_attribute(__no_sanitize_coverage__) for GCC 4 Fix __has_attribute(__no_sanitize_coverage__) for GCC 4 by defining __GCC4_has_attribute___no_sanitize_coverage__. Fixes: 540540d06e9d ("kcov: add __no_sanitize_coverage to fix noinstr for all architectures") Reported-by: Geert Uytterhoeven Signed-off-by: Marco Elver Signed-off-by: Miguel Ojeda --- include/linux/compiler_attributes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index 183ddd5fd072..7b1fa5c30169 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -36,6 +36,7 @@ # define __GCC4_has_attribute___nonstring__ 0 # define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) # define __GCC4_has_attribute___no_sanitize_undefined__ (__GNUC_MINOR__ >= 9) +# define __GCC4_has_attribute___no_sanitize_coverage__ 0 # define __GCC4_has_attribute___fallthrough__ 0 #endif -- cgit v1.2.3-70-g09d2 From 8363dfc845d74b980e109111b82f0a72aa92e47a Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jun 2021 21:51:57 +0200 Subject: mtd: spinand: Fix comment This is a copy paste error, checking the ECC status finishes a page read here, not a page write. Fixes: 945845b54c9c ("mtd: spinand: Instantiate a SPI-NAND on-die ECC engine") Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210629195157.567828-1-miquel.raynal@bootlin.com --- drivers/mtd/nand/spi/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 446ba8d43fbc..4af32cfcbd96 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -307,7 +307,7 @@ static int spinand_ondie_ecc_finish_io_req(struct nand_device *nand, if (req->type == NAND_PAGE_WRITE) return 0; - /* Finish a page write: check the status, report errors/bitflips */ + /* Finish a page read: check the status, report errors/bitflips */ ret = spinand_check_ecc_status(spinand, engine_conf->status); if (ret == -EBADMSG) mtd->ecc_stats.failed++; -- cgit v1.2.3-70-g09d2 From c5b9ee9c361f52cd319135b9ec7fe684d5e2e026 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 4 Jul 2021 10:47:05 +0100 Subject: mtd: rawnand: Fix a couple of spelling mistakes in Kconfig There are two spelling mistakes in the Kconfig text. Fix them. Signed-off-by: Colin Ian King Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210704094705.37175-1-colin.king@canonical.com --- drivers/mtd/nand/raw/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 630728de4b7c..67b7cb67c030 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -480,9 +480,9 @@ config MTD_NAND_RICOH select MTD_SM_COMMON help Enable support for Ricoh R5C852 xD card reader - You also need to enable ether + You also need to enable either NAND SSFDC (SmartMedia) read only translation layer' or new - expermental, readwrite + experimental, readwrite 'SmartMedia/xD new translation layer' config MTD_NAND_DISKONCHIP -- cgit v1.2.3-70-g09d2 From 333ff32d54cdefc2e479892e7f15ac91e026b57d Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Wed, 14 Jul 2021 13:02:28 +0200 Subject: auxdisplay: hd44780: Fix oops on module unloading Fixes: 718e05ed92ec ("auxdisplay: Introduce hd44780_common.[ch]") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/lkml/CAHp75VfKyqy+vM0XkP9Yb+znGOTVT4zYCRY3A3nQ7C3WNUVN0g@mail.gmail.com/ Reported-By: Andy Shevchenko Signed-off-by: Lars Poeschel Tested-by: Andy Shevchenko [added Link, Fixes, Cc stable tags, edited message] Signed-off-by: Miguel Ojeda --- drivers/auxdisplay/hd44780.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c index 2e5e7c993933..8b2a0eb3f32a 100644 --- a/drivers/auxdisplay/hd44780.c +++ b/drivers/auxdisplay/hd44780.c @@ -323,8 +323,8 @@ static int hd44780_remove(struct platform_device *pdev) { struct charlcd *lcd = platform_get_drvdata(pdev); - kfree(lcd->drvdata); charlcd_unregister(lcd); + kfree(lcd->drvdata); kfree(lcd); return 0; -- cgit v1.2.3-70-g09d2 From ac8c8fa0a8c3a7bc0a9a9cc44ab3650d98662754 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 15 Jul 2021 17:41:52 +0300 Subject: auxdisplay: charlcd: Drop unneeded initializers and switch to C99 style For structure initializers the fields are 0 (or NULL) by default, so there is no need to fill them explicitly. Besides that, much easier to read when initializers use C99 style. Hence, convert to C99 style as well. Signed-off-by: Andy Shevchenko Acked-by: Willy Tarreau Signed-off-by: Miguel Ojeda --- drivers/auxdisplay/charlcd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/auxdisplay/charlcd.c b/drivers/auxdisplay/charlcd.c index 24fd6f369ebe..304accde365c 100644 --- a/drivers/auxdisplay/charlcd.c +++ b/drivers/auxdisplay/charlcd.c @@ -637,9 +637,7 @@ static int panel_notify_sys(struct notifier_block *this, unsigned long code, } static struct notifier_block panel_notifier = { - panel_notify_sys, - NULL, - 0 + .notifier_call = panel_notify_sys, }; int charlcd_register(struct charlcd *lcd) -- cgit v1.2.3-70-g09d2 From f885afe28d20b66341a8f55b10367312c1d6b686 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 16 Jun 2021 17:15:48 +0300 Subject: auxdisplay: ks0108: Switch to use module_parport_driver() Switch to use module_parport_driver() to reduce boilerplate code. Signed-off-by: Andy Shevchenko Signed-off-by: Miguel Ojeda --- drivers/auxdisplay/ks0108.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c index 03c95ad4216c..da9abfbb6d33 100644 --- a/drivers/auxdisplay/ks0108.c +++ b/drivers/auxdisplay/ks0108.c @@ -167,19 +167,7 @@ static struct parport_driver ks0108_parport_driver = { .detach = ks0108_parport_detach, .devmodel = true, }; - -static int __init ks0108_init(void) -{ - return parport_register_driver(&ks0108_parport_driver); -} - -static void __exit ks0108_exit(void) -{ - parport_unregister_driver(&ks0108_parport_driver); -} - -module_init(ks0108_init); -module_exit(ks0108_exit); +module_parport_driver(ks0108_parport_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Miguel Ojeda "); -- cgit v1.2.3-70-g09d2 From 24ebc044c72ee6e88dc902a0041bac672f012537 Mon Sep 17 00:00:00 2001 From: Jinchao Wang Date: Sat, 26 Jun 2021 18:15:38 +0800 Subject: auxdisplay: Replace symbolic permissions with octal permissions Resolves the checkpatch warning. Signed-off-by: Jinchao Wang [edited wording] Signed-off-by: Miguel Ojeda --- drivers/auxdisplay/cfag12864b.c | 2 +- drivers/auxdisplay/ks0108.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index fd430e6866a1..6526aa51fb1d 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -33,7 +33,7 @@ */ static unsigned int cfag12864b_rate = CONFIG_CFAG12864B_RATE; -module_param(cfag12864b_rate, uint, S_IRUGO); +module_param(cfag12864b_rate, uint, 0444); MODULE_PARM_DESC(cfag12864b_rate, "Refresh rate (hertz)"); diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c index da9abfbb6d33..e871b94a1911 100644 --- a/drivers/auxdisplay/ks0108.c +++ b/drivers/auxdisplay/ks0108.c @@ -28,11 +28,11 @@ */ static unsigned int ks0108_port = CONFIG_KS0108_PORT; -module_param(ks0108_port, uint, S_IRUGO); +module_param(ks0108_port, uint, 0444); MODULE_PARM_DESC(ks0108_port, "Parallel port where the LCD is connected"); static unsigned int ks0108_delay = CONFIG_KS0108_DELAY; -module_param(ks0108_delay, uint, S_IRUGO); +module_param(ks0108_delay, uint, 0444); MODULE_PARM_DESC(ks0108_delay, "Delay between each control writing (microseconds)"); /* -- cgit v1.2.3-70-g09d2 From f949a9ebce7a18005266b859a17f10c891bb13d7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 29 Jun 2021 19:12:39 +0200 Subject: mfd: axp20x: Update AXP288 volatile ranges On Cherry Trail devices with an AXP288 PMIC the external SD-card slot used the AXP's DLDO2 as card-voltage and either DLDO3 or GPIO1LDO (GPIO1 pin in low noise LDO mode) as signal-voltage. These regulators are turned on/off and in case of the signal-voltage also have their output-voltage changed by the _PS0 and _PS3 power- management ACPI methods on the MMC-controllers ACPI fwnode as well as by the _DSM ACPI method for changing the signal voltage. The AML code implementing these methods is directly accessing the PMIC through ACPI I2C OpRegion accesses, instead of using the special PMIC OpRegion handled by drivers/acpi/pmic/intel_pmic_xpower.c . This means that the contents of the involved PMIC registers can change without the change being made through the regmap interface, so regmap should not cache the contents of these registers. Mark the regulator power on/off, the regulator voltage control and the GPIO1 control registers as volatile, to avoid regmap caching them. Specifically this fixes an issue on some models where the i915 driver toggles another LDO using the same on/off register on/off through MIPI sequences (through intel_soc_pmic_exec_mipi_pmic_seq_element()) which then writes back a cached on/off register-value where the card-voltage is off causing the external sdcard slot to stop working when the screen goes blank, or comes back on again. The regulator register-range now marked volatile also includes the buck regulator control registers. This is done on purpose these are normally not touched by the AML code, but they are updated directly by the SoC's PUNIT which means that they may also change without going through regmap. Note the AXP288 PMIC is only used on Bay- and Cherry-Trail platforms, so even though this is an ACPI specific problem there is no need to make the new volatile ranges conditional since these platforms always use ACPI. Fixes: dc91c3b6fe66 ("mfd: axp20x: Mark AXP20X_VBUS_IPSOUT_MGMT as volatile") Fixes: cd53216625a0 ("mfd: axp20x: Fix axp288 volatile ranges") Reported-and-tested-by: Clamshell Signed-off-by: Hans de Goede Reviewed-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 4145a38b3890..d0ac019850d1 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -125,12 +125,13 @@ static const struct regmap_range axp288_writeable_ranges[] = { static const struct regmap_range axp288_volatile_ranges[] = { regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON), + regmap_reg_range(AXP22X_PWR_OUT_CTRL1, AXP22X_ALDO3_V_OUT), regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT), regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL), regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), - regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), + regmap_reg_range(AXP20X_GPIO1_CTRL, AXP22X_GPIO_STATE), regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L), regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG), }; -- cgit v1.2.3-70-g09d2 From f4ab169e88d9a512f3d93b315aa04ac1e058991b Mon Sep 17 00:00:00 2001 From: Martin Hundebøll Date: Tue, 29 Jun 2021 14:12:13 +0200 Subject: mfd: intel-m10-bmc: Add N5010 variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The m10-bmc is used on the Silicom N5010 PAC too, so add it to list of m10bmc types. Signed-off-by: Martin Hundebøll Acked-by: Moritz Fischer Reviewed-by: Xu Yilun Reviewed-by: Matthew Gerlach Signed-off-by: Lee Jones --- drivers/mfd/intel-m10-bmc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/intel-m10-bmc.c b/drivers/mfd/intel-m10-bmc.c index 1a9bfb7f48cd..8db3bcf5fccc 100644 --- a/drivers/mfd/intel-m10-bmc.c +++ b/drivers/mfd/intel-m10-bmc.c @@ -15,7 +15,8 @@ enum m10bmc_type { M10_N3000, - M10_D5005 + M10_D5005, + M10_N5010, }; static struct mfd_cell m10bmc_d5005_subdevs[] = { @@ -28,6 +29,10 @@ static struct mfd_cell m10bmc_pacn3000_subdevs[] = { { .name = "n3000bmc-secure" }, }; +static struct mfd_cell m10bmc_n5010_subdevs[] = { + { .name = "n5010bmc-hwmon" }, +}; + static const struct regmap_range m10bmc_regmap_range[] = { regmap_reg_range(M10BMC_LEGACY_BUILD_VER, M10BMC_LEGACY_BUILD_VER), regmap_reg_range(M10BMC_SYS_BASE, M10BMC_SYS_END), @@ -192,6 +197,10 @@ static int intel_m10_bmc_spi_probe(struct spi_device *spi) cells = m10bmc_d5005_subdevs; n_cell = ARRAY_SIZE(m10bmc_d5005_subdevs); break; + case M10_N5010: + cells = m10bmc_n5010_subdevs; + n_cell = ARRAY_SIZE(m10bmc_n5010_subdevs); + break; default: return -ENODEV; } @@ -207,6 +216,7 @@ static int intel_m10_bmc_spi_probe(struct spi_device *spi) static const struct spi_device_id m10bmc_spi_id[] = { { "m10-n3000", M10_N3000 }, { "m10-d5005", M10_D5005 }, + { "m10-n5010", M10_N5010 }, { } }; MODULE_DEVICE_TABLE(spi, m10bmc_spi_id); -- cgit v1.2.3-70-g09d2 From 84742a98a97237146bdcc5f87c20a7d3d76e02de Mon Sep 17 00:00:00 2001 From: Fei Shao Date: Tue, 29 Jun 2021 17:43:38 +0800 Subject: mfd: mt6360: Sort regulator resources Reorder the regulator resources. Signed-off-by: Fei Shao Signed-off-by: Lee Jones --- drivers/mfd/mt6360-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c index e628953548ce..6eaa6775b888 100644 --- a/drivers/mfd/mt6360-core.c +++ b/drivers/mfd/mt6360-core.c @@ -319,18 +319,18 @@ static const struct resource mt6360_regulator_resources[] = { DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OC_EVT, "buck2_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OV_EVT, "buck2_ov_evt"), DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_UV_EVT, "buck2_uv_evt"), - DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"), - DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"), - DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"), - DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO5_OC_EVT, "ldo5_oc_evt"), + DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"), + DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO1_PGB_EVT, "ldo1_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO2_PGB_EVT, "ldo2_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO3_PGB_EVT, "ldo3_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO5_PGB_EVT, "ldo5_pgb_evt"), + DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"), + DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"), }; static const struct mfd_cell mt6360_devs[] = { -- cgit v1.2.3-70-g09d2 From 3d134e75c08bd2f19bf80ffddfbd3eab3160ef07 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Jul 2021 14:51:13 +0200 Subject: gpio: rcar: Always use local variable dev in gpio_rcar_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As we have already have a pointer to the device structure in a local variable in gpio_rcar_probe(), we can just use "dev" instead of "p->dev". Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-rcar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index e7092d5fe700..ae1ffb2b230d 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -564,9 +564,9 @@ static int gpio_rcar_probe(struct platform_device *pdev) } if (p->info.has_inen) { - pm_runtime_get_sync(p->dev); + pm_runtime_get_sync(dev); gpio_rcar_enable_inputs(p); - pm_runtime_put(p->dev); + pm_runtime_put(dev); } dev_info(dev, "driving %d GPIOs\n", npins); -- cgit v1.2.3-70-g09d2 From 0bc0602ae8275aadc7288692331589350987cef7 Mon Sep 17 00:00:00 2001 From: Anand Khoje Date: Mon, 12 Jul 2021 17:56:23 +0530 Subject: IB/core: Updating cache for subnet_prefix in config_non_roce_gid_cache() Currently, cache for subnet_prefix was getting updated by reading port attributes via ib_query_port. ib_query_port() calls ops.query_gid() to get subnet_prefix and returns it via port_attr. In ib_cache_update(), config_non_roce_gid_cache() obtains GIDs by calling ops.query_gid(). We utilize this to store subnet_prefix in cache. Link: https://lore.kernel.org/r/20210712122625.1147-2-anand.a.khoje@oracle.com Suggested-by: Jason Gunthorpe Suggested-by: Aru Kolappan Signed-off-by: Anand Khoje Signed-off-by: Haakon Bugge Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/cache.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index c9e9fc81447e..929399e103d1 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -1429,7 +1429,7 @@ int rdma_read_gid_l2_fields(const struct ib_gid_attr *attr, EXPORT_SYMBOL(rdma_read_gid_l2_fields); static int config_non_roce_gid_cache(struct ib_device *device, - u32 port, int gid_tbl_len) + u32 port, struct ib_port_attr *tprops) { struct ib_gid_attr gid_attr = {}; struct ib_gid_table *table; @@ -1441,7 +1441,7 @@ static int config_non_roce_gid_cache(struct ib_device *device, table = rdma_gid_table(device, port); mutex_lock(&table->lock); - for (i = 0; i < gid_tbl_len; ++i) { + for (i = 0; i < tprops->gid_tbl_len; ++i) { if (!device->ops.query_gid) continue; ret = device->ops.query_gid(device, port, i, &gid_attr.gid); @@ -1452,6 +1452,8 @@ static int config_non_roce_gid_cache(struct ib_device *device, goto err; } gid_attr.index = i; + tprops->subnet_prefix = + be64_to_cpu(gid_attr.gid.global.subnet_prefix); add_modify_gid(table, &gid_attr); } err: @@ -1484,7 +1486,7 @@ ib_cache_update(struct ib_device *device, u32 port, bool update_gids, if (!rdma_protocol_roce(device, port) && update_gids) { ret = config_non_roce_gid_cache(device, port, - tprops->gid_tbl_len); + tprops); if (ret) goto err; } -- cgit v1.2.3-70-g09d2 From 36721a6d4cf2a39f411e3ac04d5771d1ffef9d23 Mon Sep 17 00:00:00 2001 From: Anand Khoje Date: Mon, 12 Jul 2021 17:56:24 +0530 Subject: IB/core: Shifting initialization of device->cache_lock The lock cache_lock of struct ib_device is initialized in function ib_cache_setup_one(). This is much later than the device initialization in _ib_alloc_device(). This change shifts initialization of cache_lock in _ib_alloc_device(). Link: https://lore.kernel.org/r/20210712122625.1147-3-anand.a.khoje@oracle.com Suggested-by: Haakon Bugge Signed-off-by: Anand Khoje Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/cache.c | 2 -- drivers/infiniband/core/device.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 929399e103d1..0c98dd3dee67 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -1621,8 +1621,6 @@ int ib_cache_setup_one(struct ib_device *device) u32 p; int err; - rwlock_init(&device->cache_lock); - err = gid_table_setup_one(device); if (err) return err; diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index fa20b1824fb8..ba0ad7241772 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -607,6 +607,8 @@ struct ib_device *_ib_alloc_device(size_t size) for (i = 0; i < ARRAY_SIZE(device->cq_pools); i++) INIT_LIST_HEAD(&device->cq_pools[i]); + rwlock_init(&device->cache_lock); + device->uverbs_cmd_mask = BIT_ULL(IB_USER_VERBS_CMD_ALLOC_MW) | BIT_ULL(IB_USER_VERBS_CMD_ALLOC_PD) | -- cgit v1.2.3-70-g09d2 From 21bfee9c0c7754408b1f311bffe304caf3e62250 Mon Sep 17 00:00:00 2001 From: Anand Khoje Date: Mon, 12 Jul 2021 17:56:25 +0530 Subject: IB/core: Read subnet_prefix in ib_query_port via cache. ib_query_port() calls device->ops.query_port() to get the port attributes. The method of querying is device driver specific. The same function calls device->ops.query_gid() to get the GID and extract the subnet_prefix (gid_prefix). The GID and subnet_prefix are stored in a cache. But they do not get read from the cache if the device is an Infiniband device. The following change takes advantage of the cached subnet_prefix. Testing with RDBMS has shown a significant improvement in performance with this change. Link: https://lore.kernel.org/r/20210712122625.1147-4-anand.a.khoje@oracle.com Signed-off-by: Anand Khoje Signed-off-by: Haakon Bugge Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/device.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index ba0ad7241772..9056f48bdca6 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2052,7 +2052,6 @@ static int __ib_query_port(struct ib_device *device, u32 port_num, struct ib_port_attr *port_attr) { - union ib_gid gid = {}; int err; memset(port_attr, 0, sizeof(*port_attr)); @@ -2065,11 +2064,8 @@ static int __ib_query_port(struct ib_device *device, IB_LINK_LAYER_INFINIBAND) return 0; - err = device->ops.query_gid(device, port_num, 0, &gid); - if (err) - return err; - - port_attr->subnet_prefix = be64_to_cpu(gid.global.subnet_prefix); + ib_get_cached_subnet_prefix(device, port_num, + &port_attr->subnet_prefix); return 0; } -- cgit v1.2.3-70-g09d2 From fe87fb17c6febdf6e0f7308cdf175de617d24c72 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:33 -0500 Subject: RDMA/rxe: Move ICRC checking to a subroutine Move the code in rxe_recv() that checks the ICRC on incoming packets to a subroutine rxe_check_icrc() and move that to rxe_icrc.c. Link: https://lore.kernel.org/r/20210707040040.15434-2-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Reviewed-by: Zhu Yanjun Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_icrc.c | 38 ++++++++++++++++++++++++++++++++++++ drivers/infiniband/sw/rxe/rxe_loc.h | 2 ++ drivers/infiniband/sw/rxe/rxe_recv.c | 23 ++-------------------- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 66b2aad54bb7..d067841214be 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -67,3 +67,41 @@ u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb) rxe_opcode[pkt->opcode].length - RXE_BTH_BYTES); return crc; } + +/** + * rxe_icrc_check() - Compute ICRC for a packet and compare to the ICRC + * delivered in the packet. + * @skb: packet buffer + * @pkt: packet info + * + * Return: 0 if the values match else an error + */ +int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) +{ + __be32 *icrcp; + u32 pkt_icrc; + u32 icrc; + + icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); + pkt_icrc = be32_to_cpu(*icrcp); + + icrc = rxe_icrc_hdr(pkt, skb); + icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), + payload_size(pkt) + bth_pad(pkt)); + icrc = (__force u32)cpu_to_be32(~icrc); + + if (unlikely(icrc != pkt_icrc)) { + if (skb->protocol == htons(ETH_P_IPV6)) + pr_warn_ratelimited("bad ICRC from %pI6c\n", + &ipv6_hdr(skb)->saddr); + else if (skb->protocol == htons(ETH_P_IP)) + pr_warn_ratelimited("bad ICRC from %pI4\n", + &ip_hdr(skb)->saddr); + else + pr_warn_ratelimited("bad ICRC from unknown\n"); + + return -EINVAL; + } + + return 0; +} diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 1ddb20855dee..015777e31ec9 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -193,7 +193,9 @@ int rxe_completer(void *arg); int rxe_requester(void *arg); int rxe_responder(void *arg); +/* rxe_icrc.c */ u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb); +int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt); void rxe_resp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb); diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c index 7a49e27da23a..6a6cc1fa90e4 100644 --- a/drivers/infiniband/sw/rxe/rxe_recv.c +++ b/drivers/infiniband/sw/rxe/rxe_recv.c @@ -361,8 +361,6 @@ void rxe_rcv(struct sk_buff *skb) int err; struct rxe_pkt_info *pkt = SKB_TO_PKT(skb); struct rxe_dev *rxe = pkt->rxe; - __be32 *icrcp; - u32 calc_icrc, pack_icrc; if (unlikely(skb->len < RXE_BTH_BYTES)) goto drop; @@ -384,26 +382,9 @@ void rxe_rcv(struct sk_buff *skb) if (unlikely(err)) goto drop; - /* Verify ICRC */ - icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); - pack_icrc = be32_to_cpu(*icrcp); - - calc_icrc = rxe_icrc_hdr(pkt, skb); - calc_icrc = rxe_crc32(rxe, calc_icrc, (u8 *)payload_addr(pkt), - payload_size(pkt) + bth_pad(pkt)); - calc_icrc = (__force u32)cpu_to_be32(~calc_icrc); - if (unlikely(calc_icrc != pack_icrc)) { - if (skb->protocol == htons(ETH_P_IPV6)) - pr_warn_ratelimited("bad ICRC from %pI6c\n", - &ipv6_hdr(skb)->saddr); - else if (skb->protocol == htons(ETH_P_IP)) - pr_warn_ratelimited("bad ICRC from %pI4\n", - &ip_hdr(skb)->saddr); - else - pr_warn_ratelimited("bad ICRC from unknown\n"); - + err = rxe_icrc_check(skb, pkt); + if (unlikely(err)) goto drop; - } rxe_counter_inc(rxe, RXE_CNT_RCVD_PKTS); -- cgit v1.2.3-70-g09d2 From 36fbb03d05f2799a27bbed51564aba0354f3fee3 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:34 -0500 Subject: RDMA/rxe: Move rxe_xmit_packet to a subroutine rxe_xmit_packet() was an overlong inline subroutine. This patch moves it into rxe_net.c as an ordinary subroutine. Link: https://lore.kernel.org/r/20210707040040.15434-3-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Reviewed-by: Zhu Yanjun Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_loc.h | 45 ++----------------------------------- drivers/infiniband/sw/rxe/rxe_net.c | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 015777e31ec9..409d10f20948 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -104,6 +104,8 @@ int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb); struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, int paylen, struct rxe_pkt_info *pkt); int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc); +int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, + struct sk_buff *skb); const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num); int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid); int rxe_mcast_delete(struct rxe_dev *rxe, union ib_gid *mgid); @@ -206,47 +208,4 @@ static inline unsigned int wr_opcode_mask(int opcode, struct rxe_qp *qp) return rxe_wr_opcode_info[opcode].mask[qp->ibqp.qp_type]; } -static inline int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, - struct sk_buff *skb) -{ - int err; - int is_request = pkt->mask & RXE_REQ_MASK; - struct rxe_dev *rxe = to_rdev(qp->ibqp.device); - - if ((is_request && (qp->req.state != QP_STATE_READY)) || - (!is_request && (qp->resp.state != QP_STATE_READY))) { - pr_info("Packet dropped. QP is not in ready state\n"); - goto drop; - } - - if (pkt->mask & RXE_LOOPBACK_MASK) { - memcpy(SKB_TO_PKT(skb), pkt, sizeof(*pkt)); - rxe_loopback(skb); - err = 0; - } else { - err = rxe_send(pkt, skb); - } - - if (err) { - rxe->xmit_errors++; - rxe_counter_inc(rxe, RXE_CNT_SEND_ERR); - return err; - } - - if ((qp_type(qp) != IB_QPT_RC) && - (pkt->mask & RXE_END_MASK)) { - pkt->wqe->state = wqe_state_done; - rxe_run_task(&qp->comp.task, 1); - } - - rxe_counter_inc(rxe, RXE_CNT_SENT_PKTS); - goto done; - -drop: - kfree_skb(skb); - err = 0; -done: - return err; -} - #endif /* RXE_LOC_H */ diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index dec92928a1cd..c93a379a1b28 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -421,6 +421,49 @@ void rxe_loopback(struct sk_buff *skb) rxe_rcv(skb); } +int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, + struct sk_buff *skb) +{ + int err; + int is_request = pkt->mask & RXE_REQ_MASK; + struct rxe_dev *rxe = to_rdev(qp->ibqp.device); + + if ((is_request && (qp->req.state != QP_STATE_READY)) || + (!is_request && (qp->resp.state != QP_STATE_READY))) { + pr_info("Packet dropped. QP is not in ready state\n"); + goto drop; + } + + if (pkt->mask & RXE_LOOPBACK_MASK) { + memcpy(SKB_TO_PKT(skb), pkt, sizeof(*pkt)); + rxe_loopback(skb); + err = 0; + } else { + err = rxe_send(pkt, skb); + } + + if (err) { + rxe->xmit_errors++; + rxe_counter_inc(rxe, RXE_CNT_SEND_ERR); + return err; + } + + if ((qp_type(qp) != IB_QPT_RC) && + (pkt->mask & RXE_END_MASK)) { + pkt->wqe->state = wqe_state_done; + rxe_run_task(&qp->comp.task, 1); + } + + rxe_counter_inc(rxe, RXE_CNT_SENT_PKTS); + goto done; + +drop: + kfree_skb(skb); + err = 0; +done: + return err; +} + struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, int paylen, struct rxe_pkt_info *pkt) { -- cgit v1.2.3-70-g09d2 From 13050a0b32e3caa8160e940f0d66059ed3e4e62b Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:35 -0500 Subject: RDMA/rxe: Fixup rxe_send and rxe_loopback Fixup rxe_send() and rxe_loopback() in rxe_net.c to have the same calling sequence. This patch makes them static and have the same parameter list and return value. Link: https://lore.kernel.org/r/20210707040040.15434-4-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_loc.h | 2 -- drivers/infiniband/sw/rxe/rxe_net.c | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 409d10f20948..5fc9abea88ca 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -99,8 +99,6 @@ struct rxe_mw *rxe_lookup_mw(struct rxe_qp *qp, int access, u32 rkey); void rxe_mw_cleanup(struct rxe_pool_entry *arg); /* rxe_net.c */ -void rxe_loopback(struct sk_buff *skb); -int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb); struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, int paylen, struct rxe_pkt_info *pkt); int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index c93a379a1b28..beaaec2e5a17 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -373,7 +373,7 @@ static void rxe_skb_tx_dtor(struct sk_buff *skb) rxe_drop_ref(qp); } -int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb) +static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt) { int err; @@ -406,19 +406,23 @@ int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb) /* fix up a send packet to match the packets * received from UDP before looping them back */ -void rxe_loopback(struct sk_buff *skb) +static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt) { - struct rxe_pkt_info *pkt = SKB_TO_PKT(skb); + memcpy(SKB_TO_PKT(skb), pkt, sizeof(*pkt)); if (skb->protocol == htons(ETH_P_IP)) skb_pull(skb, sizeof(struct iphdr)); else skb_pull(skb, sizeof(struct ipv6hdr)); - if (WARN_ON(!ib_device_try_get(&pkt->rxe->ib_dev))) + if (WARN_ON(!ib_device_try_get(&pkt->rxe->ib_dev))) { kfree_skb(skb); - else - rxe_rcv(skb); + return -EIO; + } + + rxe_rcv(skb); + + return 0; } int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, @@ -434,14 +438,10 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, goto drop; } - if (pkt->mask & RXE_LOOPBACK_MASK) { - memcpy(SKB_TO_PKT(skb), pkt, sizeof(*pkt)); - rxe_loopback(skb); - err = 0; - } else { - err = rxe_send(pkt, skb); - } - + if (pkt->mask & RXE_LOOPBACK_MASK) + err = rxe_loopback(skb, pkt); + else + err = rxe_send(skb, pkt); if (err) { rxe->xmit_errors++; rxe_counter_inc(rxe, RXE_CNT_SEND_ERR); -- cgit v1.2.3-70-g09d2 From 1117f26ea7ec233318c66fdbef76ce212414a826 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:36 -0500 Subject: RDMA/rxe: Move ICRC generation to a subroutine Isolate ICRC generation into a single subroutine named rxe_generate_icrc() in rxe_icrc.c. Remove scattered crc generation code from elsewhere. Link: https://lore.kernel.org/r/20210707040040.15434-5-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_comp.c | 4 ++-- drivers/infiniband/sw/rxe/rxe_icrc.c | 13 +++++++++++++ drivers/infiniband/sw/rxe/rxe_loc.h | 10 +++++----- drivers/infiniband/sw/rxe/rxe_mr.c | 22 ++++------------------ drivers/infiniband/sw/rxe/rxe_net.c | 6 +++--- drivers/infiniband/sw/rxe/rxe_req.c | 13 ++----------- drivers/infiniband/sw/rxe/rxe_resp.c | 33 ++++++++------------------------- 7 files changed, 37 insertions(+), 64 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c index 58ad9c2644f3..d2d802c776fd 100644 --- a/drivers/infiniband/sw/rxe/rxe_comp.c +++ b/drivers/infiniband/sw/rxe/rxe_comp.c @@ -349,7 +349,7 @@ static inline enum comp_state do_read(struct rxe_qp *qp, ret = copy_data(qp->pd, IB_ACCESS_LOCAL_WRITE, &wqe->dma, payload_addr(pkt), - payload_size(pkt), RXE_TO_MR_OBJ, NULL); + payload_size(pkt), RXE_TO_MR_OBJ); if (ret) { wqe->status = IB_WC_LOC_PROT_ERR; return COMPST_ERROR; @@ -371,7 +371,7 @@ static inline enum comp_state do_atomic(struct rxe_qp *qp, ret = copy_data(qp->pd, IB_ACCESS_LOCAL_WRITE, &wqe->dma, &atomic_orig, - sizeof(u64), RXE_TO_MR_OBJ, NULL); + sizeof(u64), RXE_TO_MR_OBJ); if (ret) { wqe->status = IB_WC_LOC_PROT_ERR; return COMPST_ERROR; diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index d067841214be..08ab32eb6445 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -105,3 +105,16 @@ int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) return 0; } + +/* rxe_icrc_generate- compute ICRC for a packet. */ +void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt) +{ + __be32 *icrcp; + u32 icrc; + + icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); + icrc = rxe_icrc_hdr(pkt, skb); + icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), + payload_size(pkt) + bth_pad(pkt)); + *icrcp = (__force __be32)~icrc; +} diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 5fc9abea88ca..a832535fa35a 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -77,10 +77,9 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova, int access, struct rxe_mr *mr); int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr); int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, - enum rxe_mr_copy_dir dir, u32 *crcp); -int copy_data(struct rxe_pd *pd, int access, - struct rxe_dma_info *dma, void *addr, int length, - enum rxe_mr_copy_dir dir, u32 *crcp); + enum rxe_mr_copy_dir dir); +int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma, + void *addr, int length, enum rxe_mr_copy_dir dir); void *iova_to_vaddr(struct rxe_mr *mr, u64 iova, int length); struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, enum rxe_mr_lookup_type type); @@ -101,7 +100,7 @@ void rxe_mw_cleanup(struct rxe_pool_entry *arg); /* rxe_net.c */ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av, int paylen, struct rxe_pkt_info *pkt); -int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc); +int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb); int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, struct sk_buff *skb); const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num); @@ -196,6 +195,7 @@ int rxe_responder(void *arg); /* rxe_icrc.c */ u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb); int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt); +void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt); void rxe_resp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb); diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 487cefc015b8..1ee5bd8291e5 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -278,11 +278,10 @@ out: } /* copy data from a range (vaddr, vaddr+length-1) to or from - * a mr object starting at iova. Compute incremental value of - * crc32 if crcp is not zero. caller must hold a reference to mr + * a mr object starting at iova. */ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, - enum rxe_mr_copy_dir dir, u32 *crcp) + enum rxe_mr_copy_dir dir) { int err; int bytes; @@ -292,7 +291,6 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, int m; int i; size_t offset; - u32 crc = crcp ? (*crcp) : 0; if (length == 0) return 0; @@ -306,10 +304,6 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, memcpy(dest, src, length); - if (crcp) - *crcp = rxe_crc32(to_rdev(mr->ibmr.device), *crcp, dest, - length); - return 0; } @@ -340,10 +334,6 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, memcpy(dest, src, bytes); - if (crcp) - crc = rxe_crc32(to_rdev(mr->ibmr.device), crc, dest, - bytes); - length -= bytes; addr += bytes; @@ -358,9 +348,6 @@ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length, } } - if (crcp) - *crcp = crc; - return 0; err1: @@ -376,8 +363,7 @@ int copy_data( struct rxe_dma_info *dma, void *addr, int length, - enum rxe_mr_copy_dir dir, - u32 *crcp) + enum rxe_mr_copy_dir dir) { int bytes; struct rxe_sge *sge = &dma->sge[dma->cur_sge]; @@ -438,7 +424,7 @@ int copy_data( if (bytes > 0) { iova = sge->addr + offset; - err = rxe_mr_copy(mr, iova, addr, bytes, dir, crcp); + err = rxe_mr_copy(mr, iova, addr, bytes, dir); if (err) goto err2; diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index beaaec2e5a17..10c13dfebcbc 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -343,7 +343,7 @@ static int prepare6(struct rxe_pkt_info *pkt, struct sk_buff *skb) return 0; } -int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc) +int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb) { int err = 0; @@ -352,8 +352,6 @@ int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc) else if (skb->protocol == htons(ETH_P_IPV6)) err = prepare6(pkt, skb); - *crc = rxe_icrc_hdr(pkt, skb); - if (ether_addr_equal(skb->dev->dev_addr, rxe_get_av(pkt)->dmac)) pkt->mask |= RXE_LOOPBACK_MASK; @@ -438,6 +436,8 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, goto drop; } + rxe_icrc_generate(skb, pkt); + if (pkt->mask & RXE_LOOPBACK_MASK) err = rxe_loopback(skb, pkt); else diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index c57699cc6578..3894197a82f6 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -466,12 +466,9 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe, struct rxe_pkt_info *pkt, struct sk_buff *skb, int paylen) { - struct rxe_dev *rxe = to_rdev(qp->ibqp.device); - u32 crc = 0; - u32 *p; int err; - err = rxe_prepare(pkt, skb, &crc); + err = rxe_prepare(pkt, skb); if (err) return err; @@ -479,7 +476,6 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe, if (wqe->wr.send_flags & IB_SEND_INLINE) { u8 *tmp = &wqe->dma.inline_data[wqe->dma.sge_offset]; - crc = rxe_crc32(rxe, crc, tmp, paylen); memcpy(payload_addr(pkt), tmp, paylen); wqe->dma.resid -= paylen; @@ -487,8 +483,7 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe, } else { err = copy_data(qp->pd, 0, &wqe->dma, payload_addr(pkt), paylen, - RXE_FROM_MR_OBJ, - &crc); + RXE_FROM_MR_OBJ); if (err) return err; } @@ -496,12 +491,8 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_send_wqe *wqe, u8 *pad = payload_addr(pkt) + paylen; memset(pad, 0, bth_pad(pkt)); - crc = rxe_crc32(rxe, crc, pad, bth_pad(pkt)); } } - p = payload_addr(pkt) + paylen + bth_pad(pkt); - - *p = ~crc; return 0; } diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index 3743dc39b60c..685b8aebd627 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -536,7 +536,7 @@ static enum resp_states send_data_in(struct rxe_qp *qp, void *data_addr, int err; err = copy_data(qp->pd, IB_ACCESS_LOCAL_WRITE, &qp->resp.wqe->dma, - data_addr, data_len, RXE_TO_MR_OBJ, NULL); + data_addr, data_len, RXE_TO_MR_OBJ); if (unlikely(err)) return (err == -ENOSPC) ? RESPST_ERR_LENGTH : RESPST_ERR_MALFORMED_WQE; @@ -552,7 +552,7 @@ static enum resp_states write_data_in(struct rxe_qp *qp, int data_len = payload_size(pkt); err = rxe_mr_copy(qp->resp.mr, qp->resp.va + qp->resp.offset, - payload_addr(pkt), data_len, RXE_TO_MR_OBJ, NULL); + payload_addr(pkt), data_len, RXE_TO_MR_OBJ); if (err) { rc = RESPST_ERR_RKEY_VIOLATION; goto out; @@ -613,13 +613,10 @@ static struct sk_buff *prepare_ack_packet(struct rxe_qp *qp, int opcode, int payload, u32 psn, - u8 syndrome, - u32 *crcp) + u8 syndrome) { struct rxe_dev *rxe = to_rdev(qp->ibqp.device); struct sk_buff *skb; - u32 crc = 0; - u32 *p; int paylen; int pad; int err; @@ -651,20 +648,12 @@ static struct sk_buff *prepare_ack_packet(struct rxe_qp *qp, if (ack->mask & RXE_ATMACK_MASK) atmack_set_orig(ack, qp->resp.atomic_orig); - err = rxe_prepare(ack, skb, &crc); + err = rxe_prepare(ack, skb); if (err) { kfree_skb(skb); return NULL; } - if (crcp) { - /* CRC computation will be continued by the caller */ - *crcp = crc; - } else { - p = payload_addr(ack) + payload + bth_pad(ack); - *p = ~crc; - } - return skb; } @@ -682,8 +671,6 @@ static enum resp_states read_reply(struct rxe_qp *qp, int opcode; int err; struct resp_res *res = qp->resp.res; - u32 icrc; - u32 *p; if (!res) { /* This is the first time we process that request. Get a @@ -742,24 +729,20 @@ static enum resp_states read_reply(struct rxe_qp *qp, payload = min_t(int, res->read.resid, mtu); skb = prepare_ack_packet(qp, req_pkt, &ack_pkt, opcode, payload, - res->cur_psn, AETH_ACK_UNLIMITED, &icrc); + res->cur_psn, AETH_ACK_UNLIMITED); if (!skb) return RESPST_ERR_RNR; err = rxe_mr_copy(res->read.mr, res->read.va, payload_addr(&ack_pkt), - payload, RXE_FROM_MR_OBJ, &icrc); + payload, RXE_FROM_MR_OBJ); if (err) pr_err("Failed copying memory\n"); if (bth_pad(&ack_pkt)) { - struct rxe_dev *rxe = to_rdev(qp->ibqp.device); u8 *pad = payload_addr(&ack_pkt) + payload; memset(pad, 0, bth_pad(&ack_pkt)); - icrc = rxe_crc32(rxe, icrc, pad, bth_pad(&ack_pkt)); } - p = payload_addr(&ack_pkt) + payload + bth_pad(&ack_pkt); - *p = ~icrc; err = rxe_xmit_packet(qp, &ack_pkt, skb); if (err) { @@ -984,7 +967,7 @@ static int send_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, struct sk_buff *skb; skb = prepare_ack_packet(qp, pkt, &ack_pkt, IB_OPCODE_RC_ACKNOWLEDGE, - 0, psn, syndrome, NULL); + 0, psn, syndrome); if (!skb) { err = -ENOMEM; goto err1; @@ -1008,7 +991,7 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, skb = prepare_ack_packet(qp, pkt, &ack_pkt, IB_OPCODE_RC_ATOMIC_ACKNOWLEDGE, 0, pkt->psn, - syndrome, NULL); + syndrome); if (!skb) { rc = -ENOMEM; goto out; -- cgit v1.2.3-70-g09d2 From b6c6cc4acdf68f4c98c25fd8975d068009993cd8 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:37 -0500 Subject: RDMA/rxe: Move rxe_crc32 to a subroutine Move rxe_crc32() from rxe.h to rxe_icrc.c as a static local function. Link: https://lore.kernel.org/r/20210707040040.15434-6-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe.h | 21 --------------------- drivers/infiniband/sw/rxe/rxe_icrc.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h index 623fd17df02d..65a73c1c8b35 100644 --- a/drivers/infiniband/sw/rxe/rxe.h +++ b/drivers/infiniband/sw/rxe/rxe.h @@ -42,27 +42,6 @@ extern bool rxe_initialized; -static inline u32 rxe_crc32(struct rxe_dev *rxe, - u32 crc, void *next, size_t len) -{ - u32 retval; - int err; - - SHASH_DESC_ON_STACK(shash, rxe->tfm); - - shash->tfm = rxe->tfm; - *(u32 *)shash_desc_ctx(shash) = crc; - err = crypto_shash_update(shash, next, len); - if (unlikely(err)) { - pr_warn_ratelimited("failed crc calculation, err: %d\n", err); - return crc32_le(crc, next, len); - } - - retval = *(u32 *)shash_desc_ctx(shash); - barrier_data(shash_desc_ctx(shash)); - return retval; -} - void rxe_set_mtu(struct rxe_dev *rxe, unsigned int dev_mtu); int rxe_add(struct rxe_dev *rxe, unsigned int mtu, const char *ibdev_name); diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 08ab32eb6445..00916440f17b 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -7,6 +7,27 @@ #include "rxe.h" #include "rxe_loc.h" +static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) +{ + u32 icrc; + int err; + + SHASH_DESC_ON_STACK(shash, rxe->tfm); + + shash->tfm = rxe->tfm; + *(u32 *)shash_desc_ctx(shash) = crc; + err = crypto_shash_update(shash, next, len); + if (unlikely(err)) { + pr_warn_ratelimited("failed crc calculation, err: %d\n", err); + return crc32_le(crc, next, len); + } + + icrc = *(u32 *)shash_desc_ctx(shash); + barrier_data(shash_desc_ctx(shash)); + + return icrc; +} + /* Compute a partial ICRC for all the IB transport headers. */ u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb) { -- cgit v1.2.3-70-g09d2 From 63887510571b072217c20ea6e1f9be744dcd0f29 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:38 -0500 Subject: RDMA/rxe: Fixup rxe_icrc_hdr rxe_icrc_hdr() in rxe_icrc.c is no longer shared. This patch makes it static and changes the parameter list to match the other routines there. Link: https://lore.kernel.org/r/20210707040040.15434-7-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_icrc.c | 6 +++--- drivers/infiniband/sw/rxe/rxe_loc.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 00916440f17b..777199517e9a 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -29,7 +29,7 @@ static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) } /* Compute a partial ICRC for all the IB transport headers. */ -u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb) +static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) { unsigned int bth_offset = 0; struct iphdr *ip4h = NULL; @@ -106,7 +106,7 @@ int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); pkt_icrc = be32_to_cpu(*icrcp); - icrc = rxe_icrc_hdr(pkt, skb); + icrc = rxe_icrc_hdr(skb, pkt); icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), payload_size(pkt) + bth_pad(pkt)); icrc = (__force u32)cpu_to_be32(~icrc); @@ -134,7 +134,7 @@ void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt) u32 icrc; icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); - icrc = rxe_icrc_hdr(pkt, skb); + icrc = rxe_icrc_hdr(skb, pkt); icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), payload_size(pkt) + bth_pad(pkt)); *icrcp = (__force __be32)~icrc; diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index a832535fa35a..73a2c48a3160 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -193,7 +193,6 @@ int rxe_requester(void *arg); int rxe_responder(void *arg); /* rxe_icrc.c */ -u32 rxe_icrc_hdr(struct rxe_pkt_info *pkt, struct sk_buff *skb); int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt); void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt); -- cgit v1.2.3-70-g09d2 From add2b3b80e3a9b8f06562efe79b44809f64640db Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:39 -0500 Subject: RDMA/rxe: Move crc32 init code to rxe_icrc.c This patch collects the code from rxe_register_device() that sets up the crc32 calculation into a subroutine rxe_icrc_init() in rxe_icrc.c. Link: https://lore.kernel.org/r/20210707040040.15434-8-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe.h | 1 - drivers/infiniband/sw/rxe/rxe_icrc.c | 18 ++++++++++++++++++ drivers/infiniband/sw/rxe/rxe_loc.h | 1 + drivers/infiniband/sw/rxe/rxe_verbs.c | 11 +++-------- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe.h b/drivers/infiniband/sw/rxe/rxe.h index 65a73c1c8b35..1bb3fb618bf5 100644 --- a/drivers/infiniband/sw/rxe/rxe.h +++ b/drivers/infiniband/sw/rxe/rxe.h @@ -14,7 +14,6 @@ #include #include -#include #include #include diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 777199517e9a..62bcdfc8e96a 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -4,9 +4,27 @@ * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. */ +#include + #include "rxe.h" #include "rxe_loc.h" +int rxe_icrc_init(struct rxe_dev *rxe) +{ + struct crypto_shash *tfm; + + tfm = crypto_alloc_shash("crc32", 0, 0); + if (IS_ERR(tfm)) { + pr_warn("failed to init crc32 algorithm err:%ld\n", + PTR_ERR(tfm)); + return PTR_ERR(tfm); + } + + rxe->tfm = tfm; + + return 0; +} + static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) { u32 icrc; diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 73a2c48a3160..f0c954575bde 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -193,6 +193,7 @@ int rxe_requester(void *arg); int rxe_responder(void *arg); /* rxe_icrc.c */ +int rxe_icrc_init(struct rxe_dev *rxe); int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt); void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index c223959ac174..f7b1a1f64c13 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -1154,7 +1154,6 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) { int err; struct ib_device *dev = &rxe->ib_dev; - struct crypto_shash *tfm; strscpy(dev->node_desc, "rxe", sizeof(dev->node_desc)); @@ -1173,13 +1172,9 @@ int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) if (err) return err; - tfm = crypto_alloc_shash("crc32", 0, 0); - if (IS_ERR(tfm)) { - pr_err("failed to allocate crc algorithm err:%ld\n", - PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - rxe->tfm = tfm; + err = rxe_icrc_init(rxe); + if (err) + return err; err = ib_register_device(dev, ibdev_name, NULL); if (err) -- cgit v1.2.3-70-g09d2 From e4f5c82fefa9bce9a5e010901c2d16f2654b1f18 Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:40 -0500 Subject: RDMA/rxe: Add kernel-doc comments to rxe_icrc.c This patch adds kernel-doc style comments to rxe_icrc.c Link: https://lore.kernel.org/r/20210707040040.15434-9-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_icrc.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 62bcdfc8e96a..4473d38c171f 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -9,6 +9,12 @@ #include "rxe.h" #include "rxe_loc.h" +/** + * rxe_icrc_init() - Initialize crypto function for computing crc32 + * @rxe: rdma_rxe device object + * + * Return: 0 on success else an error + */ int rxe_icrc_init(struct rxe_dev *rxe) { struct crypto_shash *tfm; @@ -25,6 +31,15 @@ int rxe_icrc_init(struct rxe_dev *rxe) return 0; } +/** + * rxe_crc32() - Compute cumulative crc32 for a contiguous segment + * @rxe: rdma_rxe device object + * @crc: starting crc32 value from previous segments + * @next: starting address of current segment + * @len: length of current segment + * + * Return: the cumulative crc32 checksum + */ static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) { u32 icrc; @@ -46,7 +61,14 @@ static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) return icrc; } -/* Compute a partial ICRC for all the IB transport headers. */ +/** + * rxe_icrc_hdr() - Compute the partial ICRC for the network and transport + * headers of a packet. + * @skb: packet buffer + * @pkt: packet information + * + * Return: the partial ICRC + */ static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) { unsigned int bth_offset = 0; @@ -111,7 +133,7 @@ static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) * rxe_icrc_check() - Compute ICRC for a packet and compare to the ICRC * delivered in the packet. * @skb: packet buffer - * @pkt: packet info + * @pkt: packet information * * Return: 0 if the values match else an error */ @@ -145,7 +167,11 @@ int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) return 0; } -/* rxe_icrc_generate- compute ICRC for a packet. */ +/** + * rxe_icrc_generate() - compute ICRC for a packet. + * @skb: packet buffer + * @pkt: packet information + */ void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt) { __be32 *icrcp; -- cgit v1.2.3-70-g09d2 From 923232bbea88a29f18a2361790582a6474a538fc Mon Sep 17 00:00:00 2001 From: Bob Pearson Date: Tue, 6 Jul 2021 23:00:41 -0500 Subject: RDMA/rxe: Fix types in rxe_icrc.c Currently the ICRC is generated as a u32 type and then forced to a __be32 and stored into the ICRC field in the packet. The actual type of the ICRC is __be32. This patch replaces u32 by __be32 and eliminates the casts. The computation is exactly the same as the original but the types are more consistent. Link: https://lore.kernel.org/r/20210707040040.15434-10-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_icrc.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_icrc.c b/drivers/infiniband/sw/rxe/rxe_icrc.c index 4473d38c171f..e03af3012590 100644 --- a/drivers/infiniband/sw/rxe/rxe_icrc.c +++ b/drivers/infiniband/sw/rxe/rxe_icrc.c @@ -40,22 +40,22 @@ int rxe_icrc_init(struct rxe_dev *rxe) * * Return: the cumulative crc32 checksum */ -static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) +static __be32 rxe_crc32(struct rxe_dev *rxe, __be32 crc, void *next, size_t len) { - u32 icrc; + __be32 icrc; int err; SHASH_DESC_ON_STACK(shash, rxe->tfm); shash->tfm = rxe->tfm; - *(u32 *)shash_desc_ctx(shash) = crc; + *(__be32 *)shash_desc_ctx(shash) = crc; err = crypto_shash_update(shash, next, len); if (unlikely(err)) { pr_warn_ratelimited("failed crc calculation, err: %d\n", err); - return crc32_le(crc, next, len); + return (__force __be32)crc32_le((__force u32)crc, next, len); } - icrc = *(u32 *)shash_desc_ctx(shash); + icrc = *(__be32 *)shash_desc_ctx(shash); barrier_data(shash_desc_ctx(shash)); return icrc; @@ -69,14 +69,14 @@ static u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) * * Return: the partial ICRC */ -static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) +static __be32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) { unsigned int bth_offset = 0; struct iphdr *ip4h = NULL; struct ipv6hdr *ip6h = NULL; struct udphdr *udph; struct rxe_bth *bth; - int crc; + __be32 crc; int length; int hdr_size = sizeof(struct udphdr) + (skb->protocol == htons(ETH_P_IP) ? @@ -91,7 +91,7 @@ static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) /* This seed is the result of computing a CRC with a seed of * 0xfffffff and 8 bytes of 0xff representing a masked LRH. */ - crc = 0xdebb20e3; + crc = (__force __be32)0xdebb20e3; if (skb->protocol == htons(ETH_P_IP)) { /* IPv4 */ memcpy(pshdr, ip_hdr(skb), hdr_size); @@ -140,16 +140,16 @@ static u32 rxe_icrc_hdr(struct sk_buff *skb, struct rxe_pkt_info *pkt) int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) { __be32 *icrcp; - u32 pkt_icrc; - u32 icrc; + __be32 pkt_icrc; + __be32 icrc; icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); - pkt_icrc = be32_to_cpu(*icrcp); + pkt_icrc = *icrcp; icrc = rxe_icrc_hdr(skb, pkt); icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), payload_size(pkt) + bth_pad(pkt)); - icrc = (__force u32)cpu_to_be32(~icrc); + icrc = ~icrc; if (unlikely(icrc != pkt_icrc)) { if (skb->protocol == htons(ETH_P_IPV6)) @@ -175,11 +175,11 @@ int rxe_icrc_check(struct sk_buff *skb, struct rxe_pkt_info *pkt) void rxe_icrc_generate(struct sk_buff *skb, struct rxe_pkt_info *pkt) { __be32 *icrcp; - u32 icrc; + __be32 icrc; icrcp = (__be32 *)(pkt->hdr + pkt->paylen - RXE_ICRC_SIZE); icrc = rxe_icrc_hdr(skb, pkt); icrc = rxe_crc32(pkt->rxe, icrc, (u8 *)payload_addr(pkt), payload_size(pkt) + bth_pad(pkt)); - *icrcp = (__force __be32)~icrc; + *icrcp = ~icrc; } -- cgit v1.2.3-70-g09d2 From a67462fc9de8b958d6a2c2c34d0195733a8c61a6 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Tue, 13 Jul 2021 10:24:36 +0000 Subject: PCI: Refactor pci_ioremap_bar() and pci_ioremap_wc_bar() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_ioremap_bar() and pci_ioremap_wc_bar() shared similar implementations but differed in unimportant ways. Align them by adding a shared helper, __pci_ioremap_resource(). Upgrade warning message to error level, since it indicates a driver defect. Remove WARN_ON() from WC path in favor of the error message. [bhelgaas: commit log, use ioremap() since pci_iomap_range() doesn't add anything] Link: https://lore.kernel.org/r/20210713102436.304693-1-kw@linux.com Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index aacf575c15cf..2f519074f0f8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -206,32 +206,36 @@ int pci_status_get_and_clear_errors(struct pci_dev *pdev) EXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors); #ifdef CONFIG_HAS_IOMEM -void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) +static void __iomem *__pci_ioremap_resource(struct pci_dev *pdev, int bar, + bool write_combine) { struct resource *res = &pdev->resource[bar]; + resource_size_t start = res->start; + resource_size_t size = resource_size(res); /* * Make sure the BAR is actually a memory resource, not an IO resource */ if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) { - pci_warn(pdev, "can't ioremap BAR %d: %pR\n", bar, res); + pci_err(pdev, "can't ioremap BAR %d: %pR\n", bar, res); return NULL; } - return ioremap(res->start, resource_size(res)); + + if (write_combine) + return ioremap_wc(start, size); + + return ioremap(start, size); +} + +void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) +{ + return __pci_ioremap_resource(pdev, bar, false); } EXPORT_SYMBOL_GPL(pci_ioremap_bar); void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar) { - /* - * Make sure the BAR is actually a memory resource, not an IO resource - */ - if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { - WARN_ON(1); - return NULL; - } - return ioremap_wc(pci_resource_start(pdev, bar), - pci_resource_len(pdev, bar)); + return __pci_ioremap_resource(pdev, bar, true); } EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar); #endif -- cgit v1.2.3-70-g09d2 From 1c0810e79cb3d2c46bb8f2a3e98609de1f009f3e Mon Sep 17 00:00:00 2001 From: Keoseong Park Date: Mon, 28 Jun 2021 14:58:01 +0900 Subject: scsi: ufs: Refactor ufshcd_is_intr_aggr_allowed() Simplify if-else statement to return statement and remove code related to CONFIG_SCSI_UFS_DWC that is not in use. Link: https://lore.kernel.org/r/1891546521.01624860001810.JavaMail.epsvc@epcpadp3 Cc: Joao Pinto Reviewed-by: Bean Huo Reviewed-by: Bart Van Assche Signed-off-by: Keoseong Park Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 194755c9ddfe..971cfabc4a1e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -893,16 +893,8 @@ static inline bool ufshcd_is_rpm_autosuspend_allowed(struct ufs_hba *hba) static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba) { -/* DWC UFS Core has the Interrupt aggregation feature but is not detectable*/ -#ifndef CONFIG_SCSI_UFS_DWC - if ((hba->caps & UFSHCD_CAP_INTR_AGGR) && - !(hba->quirks & UFSHCD_QUIRK_BROKEN_INTR_AGGR)) - return true; - else - return false; -#else -return true; -#endif + return (hba->caps & UFSHCD_CAP_INTR_AGGR) && + !(hba->quirks & UFSHCD_QUIRK_BROKEN_INTR_AGGR); } static inline bool ufshcd_can_aggressive_pc(struct ufs_hba *hba) -- cgit v1.2.3-70-g09d2 From 7b0ddc1346089b62b45e688e350c9e1c3f7a3ab2 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 1 Jul 2021 14:08:40 -0500 Subject: scsi: be2iscsi: Fix use-after-free during IP updates This fixes a bug found by Lv Yunlong where, because beiscsi_exec_nemb_cmd() frees memory for the be_dma_mem cmd(), we can access freed memory when beiscsi_if_clr_ip()/beiscsi_if_set_ip()'s call to beiscsi_exec_nemb_cmd() fails and we access the freed req. This fixes the issue by having the caller free the cmd's memory. Link: https://lore.kernel.org/r/20210701190840.175120-1-michael.christie@oracle.com Reported-by: Lv Yunlong Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_mgmt.c | 84 ++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 462717bbb5b7..4e899ec1477d 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -235,8 +235,7 @@ static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba, wrb = alloc_mcc_wrb(phba, &tag); if (!wrb) { mutex_unlock(&ctrl->mbox_lock); - rc = -ENOMEM; - goto free_cmd; + return -ENOMEM; } sge = nonembedded_sgl(wrb); @@ -269,24 +268,6 @@ static int beiscsi_exec_nemb_cmd(struct beiscsi_hba *phba, /* copy the response, if any */ if (resp_buf) memcpy(resp_buf, nonemb_cmd->va, resp_buf_len); - /** - * This is special case of NTWK_GET_IF_INFO where the size of - * response is not known. beiscsi_if_get_info checks the return - * value to free DMA buffer. - */ - if (rc == -EAGAIN) - return rc; - - /** - * If FW is busy that is driver timed out, DMA buffer is saved with - * the tag, only when the cmd completes this buffer is freed. - */ - if (rc == -EBUSY) - return rc; - -free_cmd: - dma_free_coherent(&ctrl->pdev->dev, nonemb_cmd->size, - nonemb_cmd->va, nonemb_cmd->dma); return rc; } @@ -309,6 +290,19 @@ static int beiscsi_prep_nemb_cmd(struct beiscsi_hba *phba, return 0; } +static void beiscsi_free_nemb_cmd(struct beiscsi_hba *phba, + struct be_dma_mem *cmd, int rc) +{ + /* + * If FW is busy the DMA buffer is saved with the tag. When the cmd + * completes this buffer is freed. + */ + if (rc == -EBUSY) + return; + + dma_free_coherent(&phba->ctrl.pdev->dev, cmd->size, cmd->va, cmd->dma); +} + static void __beiscsi_eq_delay_compl(struct beiscsi_hba *phba, unsigned int tag) { struct be_dma_mem *tag_mem; @@ -344,8 +338,16 @@ int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, cpu_to_le32(set_eqd[i].delay_multiplier); } - return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, - __beiscsi_eq_delay_compl, NULL, 0); + rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, __beiscsi_eq_delay_compl, + NULL, 0); + if (rc) { + /* + * Only free on failure. Async cmds are handled like -EBUSY + * where it's handled for us. + */ + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); + } + return rc; } /** @@ -372,6 +374,7 @@ int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name, bool cfg) req->hdr.version = 1; rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, &resp, sizeof(resp)); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); if (rc) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, @@ -449,7 +452,9 @@ static int beiscsi_if_mod_gw(struct beiscsi_hba *phba, req->ip_addr.ip_type = ip_type; memcpy(req->ip_addr.addr, gw, (ip_type < BEISCSI_IP_TYPE_V6) ? IP_V4_LEN : IP_V6_LEN); - return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); + rt_val = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rt_val); + return rt_val; } int beiscsi_if_set_gw(struct beiscsi_hba *phba, u32 ip_type, u8 *gw) @@ -499,8 +504,10 @@ int beiscsi_if_get_gw(struct beiscsi_hba *phba, u32 ip_type, req = nonemb_cmd.va; req->ip_type = ip_type; - return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, - resp, sizeof(*resp)); + rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, resp, + sizeof(*resp)); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); + return rc; } static int @@ -537,6 +544,7 @@ beiscsi_if_clr_ip(struct beiscsi_hba *phba, "BG_%d : failed to clear IP: rc %d status %d\n", rc, req->ip_params.ip_record.status); } + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); return rc; } @@ -581,6 +589,7 @@ beiscsi_if_set_ip(struct beiscsi_hba *phba, u8 *ip, if (req->ip_params.ip_record.status) rc = -EINVAL; } + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); return rc; } @@ -608,6 +617,7 @@ int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type, reldhcp->interface_hndl = phba->interface_handle; reldhcp->ip_type = ip_type; rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); if (rc < 0) { beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, "BG_%d : failed to release existing DHCP: %d\n", @@ -689,7 +699,7 @@ int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type) dhcpreq->interface_hndl = phba->interface_handle; dhcpreq->ip_type = ip_type; rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, NULL, 0); - + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); exit: kfree(if_info); return rc; @@ -762,11 +772,8 @@ int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type, BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG, "BG_%d : Memory Allocation Failure\n"); - /* Free the DMA memory for the IOCTL issuing */ - dma_free_coherent(&phba->ctrl.pdev->dev, - nonemb_cmd.size, - nonemb_cmd.va, - nonemb_cmd.dma); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, + -ENOMEM); return -ENOMEM; } @@ -781,15 +788,13 @@ int beiscsi_if_get_info(struct beiscsi_hba *phba, int ip_type, nonemb_cmd.va)->actual_resp_len; ioctl_size += sizeof(struct be_cmd_req_hdr); - /* Free the previous allocated DMA memory */ - dma_free_coherent(&phba->ctrl.pdev->dev, nonemb_cmd.size, - nonemb_cmd.va, - nonemb_cmd.dma); - + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); /* Free the virtual memory */ kfree(*if_info); - } else + } else { + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); break; + } } while (true); return rc; } @@ -806,8 +811,9 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba, if (rc) return rc; - return beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, - nic, sizeof(*nic)); + rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, nic, sizeof(*nic)); + beiscsi_free_nemb_cmd(phba, &nonemb_cmd, rc); + return rc; } static void beiscsi_boot_process_compl(struct beiscsi_hba *phba, -- cgit v1.2.3-70-g09d2 From 37306698c3d023c10a2b1a01baac3089b52412f6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 2 Jul 2021 14:15:42 +0100 Subject: scsi: qla2xxx: Remove redundant continue statement in a for-loop The continue statement at the end of the for-loop is redundant, remove it. Link: https://lore.kernel.org/r/20210702131542.19880-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Continue has no effect") --- drivers/scsi/qla2xxx/qla_sup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 060c89237777..a0aeba69513d 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -2936,7 +2936,6 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, liter += dburst - 1; faddr += dburst - 1; dwptr += dburst - 1; - continue; } write_protect: -- cgit v1.2.3-70-g09d2 From 904b5bfaa8fe2be032ea81ee95fa28efe21fbef0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 12 Jul 2021 08:09:27 +0200 Subject: scsi: aacraid: Remove an unused include flush_kernel_dcache_page() is not used by aacraid, and this header already comes in through the scatterlist/block headers anyway. Link: https://lore.kernel.org/r/20210712060928.4161649-6-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 46b8dffce2dd..267934d2f14b 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -25,7 +25,6 @@ #include #include #include -#include /* For flush_kernel_dcache_page */ #include #include -- cgit v1.2.3-70-g09d2 From ae463b60235e7a5decffbb0bd7209952ccda78eb Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:32 -0700 Subject: scsi: lpfc: Fix NVMe support reporting in log message The NVMe support indicator in log message 6422 is displaying a field that was initialized but never set to indicate NVMe support. Remove obsolete nvme_support element from the lpfc_hba structure and change log message to display NVMe support status as reported in SLI4 Config Parameters mailbox command. Link: https://lore.kernel.org/r/20210707184351.67872-2-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 1 - drivers/scsi/lpfc/lpfc_init.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 17028861234b..dd3ddfa5f761 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -922,7 +922,6 @@ struct lpfc_hba { uint8_t wwpn[8]; uint32_t RandomData[7]; uint8_t fcp_embed_io; - uint8_t nvme_support; /* Firmware supports NVME */ uint8_t nvmet_support; /* driver supports NVMET */ #define LPFC_NVMET_MAX_PORTS 32 uint8_t mds_diags_support; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5983e05b648f..fc821104d5a5 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -12241,7 +12241,6 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) bf_get(cfg_xib, mbx_sli4_parameters), phba->cfg_enable_fc4_type); fcponly: - phba->nvme_support = 0; phba->nvmet_support = 0; phba->cfg_nvmet_mrq = 0; phba->cfg_nvme_seg_cnt = 0; @@ -12299,7 +12298,7 @@ fcponly: "6422 XIB %d PBDE %d: FCP %d NVME %d %d %d\n", bf_get(cfg_xib, mbx_sli4_parameters), phba->cfg_enable_pbde, - phba->fcp_embed_io, phba->nvme_support, + phba->fcp_embed_io, sli4_params->nvme, phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp); if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == -- cgit v1.2.3-70-g09d2 From e8613084053d406c22914385a488e8b85072100c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:33 -0700 Subject: scsi: lpfc: Remove use of kmalloc() in trace event logging There are instances when trace event logs are triggered from an interrupt context. The trace event log may attempt to alloc memory causing scheduling while atomic bug call traces. Remove the need for the kmalloc'ed vport array when checking the log_verbose flag, which eliminates the need for any allocation. Link: https://lore.kernel.org/r/20210707184351.67872-3-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fc821104d5a5..fd832fd957d8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -14162,8 +14162,9 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba) unsigned int temp_idx; int i; int j = 0; - unsigned long rem_nsec; - struct lpfc_vport **vports; + unsigned long rem_nsec, iflags; + bool log_verbose = false; + struct lpfc_vport *port_iterator; /* Don't dump messages if we explicitly set log_verbose for the * physical port or any vport. @@ -14171,16 +14172,24 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba) if (phba->cfg_log_verbose) return; - vports = lpfc_create_vport_work_array(phba); - if (vports != NULL) { - for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { - if (vports[i]->cfg_log_verbose) { - lpfc_destroy_vport_work_array(phba, vports); + spin_lock_irqsave(&phba->port_list_lock, iflags); + list_for_each_entry(port_iterator, &phba->port_list, listentry) { + if (port_iterator->load_flag & FC_UNLOADING) + continue; + if (scsi_host_get(lpfc_shost_from_vport(port_iterator))) { + if (port_iterator->cfg_log_verbose) + log_verbose = true; + + scsi_host_put(lpfc_shost_from_vport(port_iterator)); + + if (log_verbose) { + spin_unlock_irqrestore(&phba->port_list_lock, + iflags); return; } } } - lpfc_destroy_vport_work_array(phba, vports); + spin_unlock_irqrestore(&phba->port_list_lock, iflags); if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0) return; -- cgit v1.2.3-70-g09d2 From 16a93e83c87edab9ea646be879a1cbbe7bf3bca6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:34 -0700 Subject: scsi: lpfc: Improve firmware download logging Define additional status fields in mailbox commands to help provide additional information when downloading new firmware. Link: https://lore.kernel.org/r/20210707184351.67872-4-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 9 +++ drivers/scsi/lpfc/lpfc_sli.c | 152 ++++++++++++++++++++++++++++++------------ drivers/scsi/lpfc/lpfc_sli4.h | 2 + 3 files changed, 121 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index eb8c735a243b..7d4d179fb534 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -959,6 +959,12 @@ union lpfc_sli4_cfg_shdr { #define lpfc_mbox_hdr_add_status_SHIFT 8 #define lpfc_mbox_hdr_add_status_MASK 0x000000FF #define lpfc_mbox_hdr_add_status_WORD word7 +#define LPFC_ADD_STATUS_INCOMPAT_OBJ 0xA2 +#define lpfc_mbox_hdr_add_status_2_SHIFT 16 +#define lpfc_mbox_hdr_add_status_2_MASK 0x000000FF +#define lpfc_mbox_hdr_add_status_2_WORD word7 +#define LPFC_ADD_STATUS_2_INCOMPAT_FLASH 0x01 +#define LPFC_ADD_STATUS_2_INCORRECT_ASIC 0x02 uint32_t response_length; uint32_t actual_response_length; } response; @@ -3603,6 +3609,9 @@ struct lpfc_controller_attribute { #define lpfc_cntl_attr_eprom_ver_hi_SHIFT 8 #define lpfc_cntl_attr_eprom_ver_hi_MASK 0x000000ff #define lpfc_cntl_attr_eprom_ver_hi_WORD word17 +#define lpfc_cntl_attr_flash_id_SHIFT 16 +#define lpfc_cntl_attr_flash_id_MASK 0x000000ff +#define lpfc_cntl_attr_flash_id_WORD word17 uint32_t mbx_da_struct_ver; uint32_t ep_fw_da_struct_ver; uint32_t ncsi_ver_str[3]; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f530d8fe7a8c..e844d9a35b4c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -5674,16 +5674,20 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba) bf_get(lpfc_cntl_attr_lnk_type, cntl_attr); phba->sli4_hba.lnk_info.lnk_no = bf_get(lpfc_cntl_attr_lnk_numb, cntl_attr); + phba->sli4_hba.flash_id = bf_get(lpfc_cntl_attr_flash_id, cntl_attr); + phba->sli4_hba.asic_rev = bf_get(lpfc_cntl_attr_asic_rev, cntl_attr); memset(phba->BIOSVersion, 0, sizeof(phba->BIOSVersion)); strlcat(phba->BIOSVersion, (char *)cntl_attr->bios_ver_str, sizeof(phba->BIOSVersion)); lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s\n", + "3086 lnk_type:%d, lnk_numb:%d, bios_ver:%s, " + "flash_id: x%02x, asic_rev: x%02x\n", phba->sli4_hba.lnk_info.lnk_tp, phba->sli4_hba.lnk_info.lnk_no, - phba->BIOSVersion); + phba->BIOSVersion, phba->sli4_hba.flash_id, + phba->sli4_hba.asic_rev); out_free_mboxq: if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) lpfc_sli4_mbox_cmd_free(phba, mboxq); @@ -20020,6 +20024,91 @@ out: return; } +/** + * lpfc_log_fw_write_cmpl - logs firmware write completion status + * @phba: pointer to lpfc hba data structure + * @shdr_status: wr_object rsp's status field + * @shdr_add_status: wr_object rsp's add_status field + * @shdr_add_status_2: wr_object rsp's add_status_2 field + * @shdr_change_status: wr_object rsp's change_status field + * @shdr_csf: wr_object rsp's csf bit + * + * This routine is intended to be called after a firmware write completes. + * It will log next action items to be performed by the user to instantiate + * the newly downloaded firmware or reason for incompatibility. + **/ +static void +lpfc_log_fw_write_cmpl(struct lpfc_hba *phba, u32 shdr_status, + u32 shdr_add_status, u32 shdr_add_status_2, + u32 shdr_change_status, u32 shdr_csf) +{ + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, + "4198 %s: flash_id x%02x, asic_rev x%02x, " + "status x%02x, add_status x%02x, add_status_2 x%02x, " + "change_status x%02x, csf %01x\n", __func__, + phba->sli4_hba.flash_id, phba->sli4_hba.asic_rev, + shdr_status, shdr_add_status, shdr_add_status_2, + shdr_change_status, shdr_csf); + + if (shdr_add_status == LPFC_ADD_STATUS_INCOMPAT_OBJ) { + switch (shdr_add_status_2) { + case LPFC_ADD_STATUS_2_INCOMPAT_FLASH: + lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, + "4199 Firmware write failed: " + "image incompatible with flash x%02x\n", + phba->sli4_hba.flash_id); + break; + case LPFC_ADD_STATUS_2_INCORRECT_ASIC: + lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, + "4200 Firmware write failed: " + "image incompatible with ASIC " + "architecture x%02x\n", + phba->sli4_hba.asic_rev); + break; + default: + lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, + "4210 Firmware write failed: " + "add_status_2 x%02x\n", + shdr_add_status_2); + break; + } + } else if (!shdr_status && !shdr_add_status) { + if (shdr_change_status == LPFC_CHANGE_STATUS_FW_RESET || + shdr_change_status == LPFC_CHANGE_STATUS_PORT_MIGRATION) { + if (shdr_csf) + shdr_change_status = + LPFC_CHANGE_STATUS_PCI_RESET; + } + + switch (shdr_change_status) { + case (LPFC_CHANGE_STATUS_PHYS_DEV_RESET): + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, + "3198 Firmware write complete: System " + "reboot required to instantiate\n"); + break; + case (LPFC_CHANGE_STATUS_FW_RESET): + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, + "3199 Firmware write complete: " + "Firmware reset required to " + "instantiate\n"); + break; + case (LPFC_CHANGE_STATUS_PORT_MIGRATION): + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, + "3200 Firmware write complete: Port " + "Migration or PCI Reset required to " + "instantiate\n"); + break; + case (LPFC_CHANGE_STATUS_PCI_RESET): + lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, + "3201 Firmware write complete: PCI " + "Reset required to instantiate\n"); + break; + default: + break; + } + } +} + /** * lpfc_wr_object - write an object to the firmware * @phba: HBA structure that indicates port to create a queue on. @@ -20046,7 +20135,8 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, struct lpfc_mbx_wr_object *wr_object; LPFC_MBOXQ_t *mbox; int rc = 0, i = 0; - uint32_t shdr_status, shdr_add_status, shdr_change_status, shdr_csf; + uint32_t shdr_status, shdr_add_status, shdr_add_status_2; + uint32_t shdr_change_status = 0, shdr_csf = 0; uint32_t mbox_tmo; struct lpfc_dmabuf *dmabuf; uint32_t written = 0; @@ -20100,58 +20190,36 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, &wr_object->header.cfg_shdr.response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &wr_object->header.cfg_shdr.response); + shdr_add_status_2 = bf_get(lpfc_mbox_hdr_add_status_2, + &wr_object->header.cfg_shdr.response); if (check_change_status) { shdr_change_status = bf_get(lpfc_wr_object_change_status, &wr_object->u.response); - - if (shdr_change_status == LPFC_CHANGE_STATUS_FW_RESET || - shdr_change_status == LPFC_CHANGE_STATUS_PORT_MIGRATION) { - shdr_csf = bf_get(lpfc_wr_object_csf, - &wr_object->u.response); - if (shdr_csf) - shdr_change_status = - LPFC_CHANGE_STATUS_PCI_RESET; - } - - switch (shdr_change_status) { - case (LPFC_CHANGE_STATUS_PHYS_DEV_RESET): - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3198 Firmware write complete: System " - "reboot required to instantiate\n"); - break; - case (LPFC_CHANGE_STATUS_FW_RESET): - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3199 Firmware write complete: Firmware" - " reset required to instantiate\n"); - break; - case (LPFC_CHANGE_STATUS_PORT_MIGRATION): - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3200 Firmware write complete: Port " - "Migration or PCI Reset required to " - "instantiate\n"); - break; - case (LPFC_CHANGE_STATUS_PCI_RESET): - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3201 Firmware write complete: PCI " - "Reset required to instantiate\n"); - break; - default: - break; - } + shdr_csf = bf_get(lpfc_wr_object_csf, + &wr_object->u.response); } + if (!phba->sli4_hba.intr_enable) mempool_free(mbox, phba->mbox_mem_pool); else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); - if (shdr_status || shdr_add_status || rc) { + if (shdr_status || shdr_add_status || shdr_add_status_2 || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3025 Write Object mailbox failed with " - "status x%x add_status x%x, mbx status x%x\n", - shdr_status, shdr_add_status, rc); + "status x%x add_status x%x, add_status_2 x%x, " + "mbx status x%x\n", + shdr_status, shdr_add_status, shdr_add_status_2, + rc); rc = -ENXIO; *offset = shdr_add_status; - } else + } else { *offset += wr_object->u.response.actual_write_length; + } + + if (rc || check_change_status) + lpfc_log_fw_write_cmpl(phba, shdr_status, shdr_add_status, + shdr_add_status_2, shdr_change_status, + shdr_csf); return rc; } diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 26f19c95380f..021edbfbbca5 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -978,6 +978,8 @@ struct lpfc_sli4_hba { #define lpfc_conf_trunk_port3_nd_WORD conf_trunk #define lpfc_conf_trunk_port3_nd_SHIFT 7 #define lpfc_conf_trunk_port3_nd_MASK 0x1 + uint8_t flash_id; + uint8_t asic_rev; }; enum lpfc_sge_type { -- cgit v1.2.3-70-g09d2 From 50baa1595d30412177da3b22625bffc1ce4f65d5 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:35 -0700 Subject: scsi: lpfc: Fix function description comments for vmid routines Update comment headers for functions lpfc_vmid_cmd and lpfc_vmid_poll. Link: https://lore.kernel.org/r/20210707184351.67872-5-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_ct.c | 5 ++--- drivers/scsi/lpfc/lpfc_init.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 610b6dabb3b5..1acb8820a08e 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -3884,9 +3884,8 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /** * lpfc_vmid_cmd - Build and send a FDMI cmd to the specified NPort * @vport: pointer to a host virtual N_Port data structure. - * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID) - * cmdcode: FDMI command to send - * mask: Mask of HBA or PORT Attributes to send + * @cmdcode: application server command code to send + * @vmid: pointer to vmid info structure * * Builds and sends a FDMI command using the CT subsystem. */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index fd832fd957d8..9427bfe856f6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4845,7 +4845,7 @@ lpfc_sli4_fcf_redisc_wait_tmo(struct timer_list *t) /** * lpfc_vmid_poll - VMID timeout detection - * @ptr: Map to lpfc_hba data structure pointer. + * @t: Timer context used to obtain the pointer to lpfc hba data structure. * * This routine is invoked when there is no I/O on by a VM for the specified * amount of time. When this situation is detected, the VMID has to be -- cgit v1.2.3-70-g09d2 From e77803bdbf0aad98d36b1d3fa082852831814edd Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:36 -0700 Subject: scsi: lpfc: Discovery state machine fixes for LOGO handling If a LOGO is received for a node that is in the NPR state, post a DEVICE_RM event to allow clean up of the logged out node. Clearing the NLP_NPR_2B_DISC flag upon receipt of a LOGO ACC may cause skipping of processing outstanding PLOGIs triggered by parallel RSCN events. If an outstanding PLOGI is being retried and receipt of a LOGO ACC occurs, then allow the discovery state machine's PLOGI completion to clean up the node. Link: https://lore.kernel.org/r/20210707184351.67872-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e481f5fe29d7..b0c443a0cf92 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4612,6 +4612,15 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; if (ndlp->nlp_state == NLP_STE_NPR_NODE) { + + /* If PLOGI is being retried, PLOGI completion will cleanup the + * node. The NLP_NPR_2B_DISC flag needs to be retained to make + * progress on nodes discovered from last RSCN. + */ + if ((ndlp->nlp_flag & NLP_DELAY_TMO) && + (ndlp->nlp_last_elscmd == ELS_CMD_PLOGI)) + goto out; + /* NPort Recovery mode or node is just allocated */ if (!lpfc_nlp_not_used(ndlp)) { /* A LOGO is completing and the node is in NPR state. @@ -8948,6 +8957,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, break; } lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); + if (newnode) + lpfc_disc_state_machine(vport, ndlp, NULL, + NLP_EVT_DEVICE_RM); break; case ELS_CMD_PRLO: lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, -- cgit v1.2.3-70-g09d2 From 21990d3d1861c7aa8e3e4ed98614f0c161c29b0c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:37 -0700 Subject: scsi: lpfc: Fix target reset handler from falsely returning FAILURE Previous logic accidentally overrides the status variable to FAILURE when target reset status is SUCCESS. Refactor the non-SUCCESS logic of lpfc_vmid_vport_cleanup(), which resolves the false override. Link: https://lore.kernel.org/r/20210707184351.67872-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 68 +++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 1b248c237be1..10002a13c5c6 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6273,6 +6273,7 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_scsi_event_header scsi_event; int status; u32 logit = LOG_FCP; + u32 dev_loss_tmo = vport->cfg_devloss_tmo; unsigned long flags; DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); @@ -6314,39 +6315,44 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd) status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id, FCP_TARGET_RESET); - if (status != SUCCESS) - logit = LOG_TRACE_EVENT; - spin_lock_irqsave(&pnode->lock, flags); - if (status != SUCCESS && - (!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO)) && - !pnode->logo_waitq) { - pnode->logo_waitq = &waitq; - pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; - pnode->nlp_flag |= NLP_ISSUE_LOGO; - pnode->upcall_flags |= NLP_WAIT_FOR_LOGO; - spin_unlock_irqrestore(&pnode->lock, flags); - lpfc_unreg_rpi(vport, pnode); - wait_event_timeout(waitq, - (!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO)), - msecs_to_jiffies(vport->cfg_devloss_tmo * - 1000)); - - if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "0725 SCSI layer TGTRST failed & LOGO TMO " - " (%d, %llu) return x%x\n", tgt_id, - lun_id, status); - spin_lock_irqsave(&pnode->lock, flags); - pnode->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + if (status != SUCCESS) { + logit = LOG_TRACE_EVENT; + + /* Issue LOGO, if no LOGO is outstanding */ + spin_lock_irqsave(&pnode->lock, flags); + if (!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO) && + !pnode->logo_waitq) { + pnode->logo_waitq = &waitq; + pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; + pnode->nlp_flag |= NLP_ISSUE_LOGO; + pnode->upcall_flags |= NLP_WAIT_FOR_LOGO; + spin_unlock_irqrestore(&pnode->lock, flags); + lpfc_unreg_rpi(vport, pnode); + wait_event_timeout(waitq, + (!(pnode->upcall_flags & + NLP_WAIT_FOR_LOGO)), + msecs_to_jiffies(dev_loss_tmo * + 1000)); + + if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) { + lpfc_printf_vlog(vport, KERN_ERR, logit, + "0725 SCSI layer TGTRST " + "failed & LOGO TMO (%d, %llu) " + "return x%x\n", + tgt_id, lun_id, status); + spin_lock_irqsave(&pnode->lock, flags); + pnode->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + } else { + spin_lock_irqsave(&pnode->lock, flags); + } + pnode->logo_waitq = NULL; + spin_unlock_irqrestore(&pnode->lock, flags); + status = SUCCESS; + } else { - spin_lock_irqsave(&pnode->lock, flags); + spin_unlock_irqrestore(&pnode->lock, flags); + status = FAILED; } - pnode->logo_waitq = NULL; - spin_unlock_irqrestore(&pnode->lock, flags); - status = SUCCESS; - } else { - status = FAILED; - spin_unlock_irqrestore(&pnode->lock, flags); } lpfc_printf_vlog(vport, KERN_ERR, logit, -- cgit v1.2.3-70-g09d2 From 4e670c8afd47d535f65edf0d2b7f54f103fd59a2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:38 -0700 Subject: scsi: lpfc: Keep NDLP reference until after freeing the IOCB after ELS handling In the routine that generically cleans up an ELS after completion, the NDLP put is done prior to the freeing of the IOCB. The IOCB may reference the NDLP. Move the lpfc_nlp_put() after freeing the IOCB. Link: https://lore.kernel.org/r/20210707184351.67872-8-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e844d9a35b4c..1fdb2232729f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -11623,6 +11623,7 @@ void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { + struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; IOCB_t *irsp = &rspiocb->iocb; /* ELS cmd tag completes */ @@ -11631,11 +11632,16 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "x%x x%x x%x\n", irsp->ulpIoTag, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout); - lpfc_nlp_put((struct lpfc_nodelist *)cmdiocb->context1); + /* + * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp + * if exchange is busy. + */ if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) lpfc_ct_free_iocb(phba, cmdiocb); else lpfc_els_free_iocb(phba, cmdiocb); + + lpfc_nlp_put(ndlp); } /** -- cgit v1.2.3-70-g09d2 From 2d338eb55b14ab9d245e8b1d982adecca8c4c613 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:39 -0700 Subject: scsi: lpfc: Fix NULL ptr dereference with NPIV ports for RDF handling RDF ELS handling for NPIV ports may result in an incorrect NDLP reference count. In the event of a persistent link down, this may lead to premature release of an NDLP structure and subsequent NULL ptr dereference panic. Remove extraneous lpfc_nlp_put() call in NPIV port RDF processing. Link: https://lore.kernel.org/r/20210707184351.67872-9-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b0c443a0cf92..b1ca6f8e5970 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3413,7 +3413,6 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry) return 1; } - /* Keep the ndlp just in case RDF is being sent */ return 0; } @@ -3657,11 +3656,9 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry) lpfc_enqueue_node(vport, ndlp); } - /* RDF ELS is not required on an NPIV VN_Port. */ - if (vport->port_type == LPFC_NPIV_PORT) { - lpfc_nlp_put(ndlp); + /* RDF ELS is not required on an NPIV VN_Port. */ + if (vport->port_type == LPFC_NPIV_PORT) return -EACCES; - } elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_RDF); -- cgit v1.2.3-70-g09d2 From cd6047e92c6a5b0a44479cf98f76aac56ddfe108 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:40 -0700 Subject: scsi: lpfc: Fix memory leaks in error paths while issuing ELS RDF/SCR request The ELS job request structure, that is allocated while issuing ELS RDF/SCR request path, is not being released in an error path causing a memory leak message on driver unload. Free the ELS job structure in the error paths. Link: https://lore.kernel.org/r/20210707184351.67872-10-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b1ca6f8e5970..3381912bf982 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3375,6 +3375,7 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry) if (phba->sli_rev == LPFC_SLI_REV4) { rc = lpfc_reg_fab_ctrl_node(vport, ndlp); if (rc) { + lpfc_els_free_iocb(phba, elsiocb); lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, "0937 %s: Failed to reg fc node, rc %d\n", __func__, rc); @@ -3667,6 +3668,7 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry) if (phba->sli_rev == LPFC_SLI_REV4 && !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) { + lpfc_els_free_iocb(phba, elsiocb); lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, "0939 %s: FC_NODE x%x RPI x%x flag x%x " "ste x%x type x%x Not registered\n", -- cgit v1.2.3-70-g09d2 From e78c006f4c888231cdabb8a4286ba17980a903fa Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:41 -0700 Subject: scsi: lpfc: Remove REG_LOGIN check requirement to issue an ELS RDF Since the REG_LOGIN to the fabric controller happens in parallel with SCR, it may or may not be completed by the time RDF is sent. RDF and SCR are sent to the fabric in parallel, so checking for a completed REG_LOGIN in the RDF submit path is not needed. Remove the REG_LOGI check from the RDF submission path. Link: https://lore.kernel.org/r/20210707184351.67872-11-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3381912bf982..94dc80dc99b7 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3666,18 +3666,6 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry) if (!elsiocb) return -ENOMEM; - if (phba->sli_rev == LPFC_SLI_REV4 && - !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) { - lpfc_els_free_iocb(phba, elsiocb); - lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE, - "0939 %s: FC_NODE x%x RPI x%x flag x%x " - "ste x%x type x%x Not registered\n", - __func__, ndlp->nlp_DID, ndlp->nlp_rpi, - ndlp->nlp_flag, ndlp->nlp_state, - ndlp->nlp_type); - return -ENODEV; - } - /* Configure the payload for the supported FPIN events. */ prdf = (struct lpfc_els_rdf_req *) (((struct lpfc_dmabuf *)elsiocb->context2)->virt); -- cgit v1.2.3-70-g09d2 From affbe24429410fddf4e50ca456c090ed6d8e05bf Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:42 -0700 Subject: scsi: lpfc: Fix KASAN slab-out-of-bounds in lpfc_unreg_rpi() routine In lpfc_offline_prep() an RPI is freed and nlp_rpi set to 0xFFFF before calling lpfc_unreg_rpi(). Unfortunately, lpfc_unreg_rpi() uses nlp_rpi to index the sli4_hba.rpi_ids[] array. In lpfc_offline_prep(), unreg rpi before freeing the rpi. Link: https://lore.kernel.org/r/20210707184351.67872-12-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 9427bfe856f6..55f720ac6c8c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3541,6 +3541,8 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_NPR_ADISC; spin_unlock_irq(&ndlp->lock); + + lpfc_unreg_rpi(vports[i], ndlp); /* * Whenever an SLI4 port goes offline, free the * RPI. Get a new RPI when the adapter port @@ -3556,7 +3558,6 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; } - lpfc_unreg_rpi(vports[i], ndlp); if (ndlp->nlp_type & NLP_FABRIC) { lpfc_disc_state_machine(vports[i], ndlp, -- cgit v1.2.3-70-g09d2 From a9978e3978406ef5e35870b10e677cf75a2620b6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:43 -0700 Subject: scsi: lpfc: Clear outstanding active mailbox during PCI function reset Mailbox commands sent via ioctl/bsg from user applications may be interrupted from processing by a concurrently triggered PCI function reset. The command will not generate a completion due to the reset. This results in a user application hang waiting for the mailbox command to complete. Resolve by changing the function reset handler to detect that there was an outstanding mailbox command and simulate a mailbox completion. Add some additional debug when a mailbox command times out. Link: https://lore.kernel.org/r/20210707184351.67872-13-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 11 ++++++++++- drivers/scsi/lpfc/lpfc_sli.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 55f720ac6c8c..4fd9a8098e86 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1852,6 +1852,7 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, { int rc; uint32_t intr_mode; + LPFC_MBOXQ_t *mboxq; if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= LPFC_SLI_INTF_IF_TYPE_2) { @@ -1871,11 +1872,19 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, "Recovery...\n"); /* If we are no wait, the HBA has been reset and is not - * functional, thus we should clear LPFC_SLI_ACTIVE flag. + * functional, thus we should clear + * (LPFC_SLI_ACTIVE | LPFC_SLI_MBOX_ACTIVE) flags. */ if (mbx_action == LPFC_MBX_NO_WAIT) { spin_lock_irq(&phba->hbalock); phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE; + if (phba->sli.mbox_active) { + mboxq = phba->sli.mbox_active; + mboxq->u.mb.mbxStatus = MBX_NOT_FINISHED; + __lpfc_mbox_cmpl_put(phba, mboxq); + phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; + phba->sli.mbox_active = NULL; + } spin_unlock_irq(&phba->hbalock); } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1fdb2232729f..c34240819d92 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -8794,8 +8794,11 @@ static int lpfc_sli4_async_mbox_block(struct lpfc_hba *phba) { struct lpfc_sli *psli = &phba->sli; + LPFC_MBOXQ_t *mboxq; int rc = 0; unsigned long timeout = 0; + u32 sli_flag; + u8 cmd, subsys, opcode; /* Mark the asynchronous mailbox command posting as blocked */ spin_lock_irq(&phba->hbalock); @@ -8813,12 +8816,37 @@ lpfc_sli4_async_mbox_block(struct lpfc_hba *phba) if (timeout) lpfc_sli4_process_missed_mbox_completions(phba); - /* Wait for the outstnading mailbox command to complete */ + /* Wait for the outstanding mailbox command to complete */ while (phba->sli.mbox_active) { /* Check active mailbox complete status every 2ms */ msleep(2); if (time_after(jiffies, timeout)) { - /* Timeout, marked the outstanding cmd not complete */ + /* Timeout, mark the outstanding cmd not complete */ + + /* Sanity check sli.mbox_active has not completed or + * cancelled from another context during last 2ms sleep, + * so take hbalock to be sure before logging. + */ + spin_lock_irq(&phba->hbalock); + if (phba->sli.mbox_active) { + mboxq = phba->sli.mbox_active; + cmd = mboxq->u.mb.mbxCommand; + subsys = lpfc_sli_config_mbox_subsys_get(phba, + mboxq); + opcode = lpfc_sli_config_mbox_opcode_get(phba, + mboxq); + sli_flag = psli->sli_flag; + spin_unlock_irq(&phba->hbalock); + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + "2352 Mailbox command x%x " + "(x%x/x%x) sli_flag x%x could " + "not complete\n", + cmd, subsys, opcode, + sli_flag); + } else { + spin_unlock_irq(&phba->hbalock); + } + rc = 1; break; } -- cgit v1.2.3-70-g09d2 From 137ddf0384722afef308dd40696fba55e6680ad2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:44 -0700 Subject: scsi: lpfc: Use PBDE feature enabled bit to determine PBDE support The SLI4 interface changed the manner used to indicate PBDE support. Rework the driver to check for PBDE support via the PBDE feature bit in COMMON_GET_SLI4_PARAMETERS. Link: https://lore.kernel.org/r/20210707184351.67872-14-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 11 +++++++---- drivers/scsi/lpfc/lpfc_init.c | 7 ++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 7d4d179fb534..4d9233de9ead 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -3334,17 +3334,20 @@ struct lpfc_sli4_parameters { #define cfg_nosr_SHIFT 9 #define cfg_nosr_MASK 0x00000001 #define cfg_nosr_WORD word19 - #define cfg_bv1s_SHIFT 10 #define cfg_bv1s_MASK 0x00000001 #define cfg_bv1s_WORD word19 -#define cfg_pvl_SHIFT 13 -#define cfg_pvl_MASK 0x00000001 -#define cfg_pvl_WORD word19 #define cfg_nsler_SHIFT 12 #define cfg_nsler_MASK 0x00000001 #define cfg_nsler_WORD word19 +#define cfg_pvl_SHIFT 13 +#define cfg_pvl_MASK 0x00000001 +#define cfg_pvl_WORD word19 + +#define cfg_pbde_SHIFT 20 +#define cfg_pbde_MASK 0x00000001 +#define cfg_pbde_WORD word19 uint32_t word20; #define cfg_max_tow_xri_SHIFT 0 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4fd9a8098e86..65a7c564f1d6 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -12268,9 +12268,10 @@ fcponly: if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT; - /* Only embed PBDE for if_type 6, PBDE support requires xib be set */ - if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != - LPFC_SLI_INTF_IF_TYPE_6) || (!bf_get(cfg_xib, mbx_sli4_parameters))) + /* Enable embedded Payload BDE if support is indicated */ + if (bf_get(cfg_pbde, mbx_sli4_parameters)) + phba->cfg_enable_pbde = 1; + else phba->cfg_enable_pbde = 0; /* -- cgit v1.2.3-70-g09d2 From 816bd88dffc5716d8bff7cce9dbaa19ef375bc97 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:45 -0700 Subject: scsi: lpfc: Enable adisc discovery after RSCN by default Assign a default value of 1 to driver module parameter lpfc_use_adisc. Link: https://lore.kernel.org/r/20210707184351.67872-15-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index eb88aaaf36eb..457989cfc0b7 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -5412,9 +5412,9 @@ LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3, /* # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range -# is [0,1]. Default value is 0. +# is [0,1]. Default value is 1. */ -LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1, +LPFC_VPORT_ATTR_RW(use_adisc, 1, 0, 1, "Use ADISC on rediscovery to authenticate FCP devices"); /* -- cgit v1.2.3-70-g09d2 From 0614568361b0c1827f999b1fff21223a496c740b Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:46 -0700 Subject: scsi: lpfc: Delay unregistering from transport until GIDFT or ADISC completes On an RSCN event, the nodes specified in RSCN payload and in MAPPED state are moved to NPR state in order to revalidate the login. This triggers an immediate unregister from SCSI/NVMe backend. The assumption is that the node may be missing. The re-registration with the backend happens after either relogin (PLOGI/PRLI; if ADISC is disabled or login truly lost) or when ADISC completes successfully (rediscover with ADISC enabled). However, the NVMe-FC standard provides for an RSCN to be triggered when the remote port supports a discovery controller and there was a change of discovery log content. As the remote port typically also supports storage subsystems, this unregister causes all storage controller connections to fail and require reconnect. Correct by reworking the code to ensure that the unregistration only occurs when a login state is truly terminated, thereby leaving the NVMe storage controllers in place. The changes made are: - Retain node state in ADISC_ISSUE when scheduling ADISC ELS retry. - Do not clear wwpn/wwnn values upon ADISC failure. - Move MAPPED nodes to NPR during RSCN processing, but do not unregister with transport. On GIDFT completion, identify missing nodes (not marked NLP_NPR_2B_DISC) and unregister them. - Perform unregistration for nodes that will go through ADISC processing if ADISC completion fails. - Successful ADISC completion will move node back to MAPPED state. Link: https://lore.kernel.org/r/20210707184351.67872-16-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_disc.h | 9 +- drivers/scsi/lpfc/lpfc_els.c | 66 ++++++++----- drivers/scsi/lpfc/lpfc_hbadisc.c | 197 ++++++++++++++++++++++++++++--------- drivers/scsi/lpfc/lpfc_nportdisc.c | 9 +- drivers/scsi/lpfc/lpfc_nvme.c | 10 +- drivers/scsi/lpfc/lpfc_nvme.h | 4 +- 7 files changed, 207 insertions(+), 90 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 737483c3f01d..41e0d8ef015a 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -87,6 +87,8 @@ void lpfc_unregister_vfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_enqueue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_dequeue_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_nlp_set_state(struct lpfc_vport *, struct lpfc_nodelist *, int); +void lpfc_nlp_reg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp); +void lpfc_nlp_unreg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp); void lpfc_drop_node(struct lpfc_vport *, struct lpfc_nodelist *); void lpfc_set_disctmo(struct lpfc_vport *); int lpfc_can_disctmo(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 131374a61d7e..871b665bd72e 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -78,10 +78,11 @@ struct lpfc_node_rrqs { }; enum lpfc_fc4_xpt_flags { - NLP_WAIT_FOR_UNREG = 0x1, - SCSI_XPT_REGD = 0x2, - NVME_XPT_REGD = 0x4, - NLP_XPT_HAS_HH = 0x8, + NLP_XPT_REGD = 0x1, + SCSI_XPT_REGD = 0x2, + NVME_XPT_REGD = 0x4, + NVME_XPT_UNREG_WAIT = 0x8, + NLP_XPT_HAS_HH = 0x10 }; struct lpfc_nodelist { diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 94dc80dc99b7..32f5f00f0a85 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1664,6 +1664,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, if (!new_ndlp || (new_ndlp == ndlp)) return ndlp; + /* + * Unregister from backend if not done yet. Could have been skipped + * due to ADISC + */ + lpfc_nlp_unreg_node(vport, new_ndlp); + if (phba->sli_rev == LPFC_SLI_REV4) { active_rrqs_xri_bitmap = mempool_alloc(phba->active_rrq_pool, GFP_KERNEL); @@ -4365,7 +4371,7 @@ out_retry: (cmd == ELS_CMD_NVMEPRLI)) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); - else + else if (cmd != ELS_CMD_ADISC) lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); ndlp->nlp_last_elscmd = cmd; @@ -5653,25 +5659,40 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) /* go thru NPR nodes and issue any remaining ELS ADISCs */ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && - (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { - spin_lock_irq(&ndlp->lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(&ndlp->lock); - ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); - lpfc_issue_els_adisc(vport, ndlp, 0); - sentadisc++; - vport->num_disc_nodes++; - if (vport->num_disc_nodes >= - vport->cfg_discovery_threads) { - spin_lock_irq(shost->host_lock); - vport->fc_flag |= FC_NLP_MORE; - spin_unlock_irq(shost->host_lock); - break; - } + + if (ndlp->nlp_state != NLP_STE_NPR_NODE || + !(ndlp->nlp_flag & NLP_NPR_ADISC)) + continue; + + spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag &= ~NLP_NPR_ADISC; + spin_unlock_irq(&ndlp->lock); + + if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) { + /* This node was marked for ADISC but was not picked + * for discovery. This is possible if the node was + * missing in gidft response. + * + * At time of marking node for ADISC, we skipped unreg + * from backend + */ + lpfc_nlp_unreg_node(vport, ndlp); + continue; } + + ndlp->nlp_prev_state = ndlp->nlp_state; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); + lpfc_issue_els_adisc(vport, ndlp, 0); + sentadisc++; + vport->num_disc_nodes++; + if (vport->num_disc_nodes >= + vport->cfg_discovery_threads) { + spin_lock_irq(shost->host_lock); + vport->fc_flag |= FC_NLP_MORE; + spin_unlock_irq(shost->host_lock); + break; + } + } if (sentadisc == 0) { spin_lock_irq(shost->host_lock); @@ -6882,13 +6903,6 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) continue; } - /* Check to see if we need to NVME rescan this target - * remoteport. - */ - if (ndlp->nlp_fc4_type & NLP_FC4_NVME && - ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY)) - lpfc_nvme_rescan_port(vport, ndlp); - lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); lpfc_cancel_retry_delay_tmo(vport, ndlp); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 7cc5920979f8..32fb3be42b26 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4501,10 +4501,152 @@ lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count) spin_unlock_irqrestore(shost->host_lock, iflags); } +/* Register a node with backend if not already done */ +void +lpfc_nlp_reg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) +{ + + unsigned long iflags; + + spin_lock_irqsave(&ndlp->lock, iflags); + if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) { + /* Already registered with backend, trigger rescan */ + spin_unlock_irqrestore(&ndlp->lock, iflags); + + if (ndlp->fc4_xpt_flags & NVME_XPT_REGD && + ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY)) { + lpfc_nvme_rescan_port(vport, ndlp); + } + return; + } + + ndlp->fc4_xpt_flags |= NLP_XPT_REGD; + spin_unlock_irqrestore(&ndlp->lock, iflags); + + if (lpfc_valid_xpt_node(ndlp)) { + vport->phba->nport_event_cnt++; + /* + * Tell the fc transport about the port, if we haven't + * already. If we have, and it's a scsi entity, be + */ + lpfc_register_remote_port(vport, ndlp); + } + + /* We are done if we do not have any NVME remote node */ + if (!(ndlp->nlp_fc4_type & NLP_FC4_NVME)) + return; + + /* Notify the NVME transport of this new rport. */ + if (vport->phba->sli_rev >= LPFC_SLI_REV4 && + ndlp->nlp_fc4_type & NLP_FC4_NVME) { + if (vport->phba->nvmet_support == 0) { + /* Register this rport with the transport. + * Only NVME Target Rports are registered with + * the transport. + */ + if (ndlp->nlp_type & NLP_NVME_TARGET) { + vport->phba->nport_event_cnt++; + lpfc_nvme_register_port(vport, ndlp); + } + } else { + /* Just take an NDLP ref count since the + * target does not register rports. + */ + lpfc_nlp_get(ndlp); + } + } +} + +/* Unregister a node with backend if not already done */ +void +lpfc_nlp_unreg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) +{ + unsigned long iflags; + + spin_lock_irqsave(&ndlp->lock, iflags); + if (!(ndlp->fc4_xpt_flags & NLP_XPT_REGD)) { + spin_unlock_irqrestore(&ndlp->lock, iflags); + return; + } + + ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD; + spin_unlock_irqrestore(&ndlp->lock, iflags); + + if (ndlp->rport && + ndlp->fc4_xpt_flags & SCSI_XPT_REGD) { + vport->phba->nport_event_cnt++; + lpfc_unregister_remote_port(ndlp); + } + + if (ndlp->fc4_xpt_flags & NVME_XPT_REGD) { + vport->phba->nport_event_cnt++; + if (vport->phba->nvmet_support == 0) { + /* Start devloss if target. */ + if (ndlp->nlp_type & NLP_NVME_TARGET) + lpfc_nvme_unregister_port(vport, ndlp); + } else { + /* NVMET has no upcall. */ + lpfc_nlp_put(ndlp); + } + } + +} + +/* + * Adisc state change handling + */ +static void +lpfc_handle_adisc_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, + int new_state) +{ + switch (new_state) { + /* + * Any state to ADISC_ISSUE + * Do nothing, adisc cmpl handling will trigger state changes + */ + case NLP_STE_ADISC_ISSUE: + break; + + /* + * ADISC_ISSUE to mapped states + * Trigger a registration with backend, it will be nop if + * already registered + */ + case NLP_STE_UNMAPPED_NODE: + ndlp->nlp_type |= NLP_FC_NODE; + fallthrough; + case NLP_STE_MAPPED_NODE: + ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; + lpfc_nlp_reg_node(vport, ndlp); + break; + + /* + * ADISC_ISSUE to non-mapped states + * We are moving from ADISC_ISSUE to a non-mapped state because + * ADISC failed, we would have skipped unregistering with + * backend, attempt it now + */ + case NLP_STE_NPR_NODE: + ndlp->nlp_flag &= ~NLP_RCV_PLOGI; + fallthrough; + default: + lpfc_nlp_unreg_node(vport, ndlp); + break; + } + +} + static void lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int old_state, int new_state) { + /* Trap ADISC changes here */ + if (new_state == NLP_STE_ADISC_ISSUE || + old_state == NLP_STE_ADISC_ISSUE) { + lpfc_handle_adisc_state(vport, ndlp, new_state); + return; + } + if (new_state == NLP_STE_UNMAPPED_NODE) { ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; ndlp->nlp_type |= NLP_FC_NODE; @@ -4514,60 +4656,17 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (new_state == NLP_STE_NPR_NODE) ndlp->nlp_flag &= ~NLP_RCV_PLOGI; - /* FCP and NVME Transport interface */ + /* Reg/Unreg for FCP and NVME Transport interface */ if ((old_state == NLP_STE_MAPPED_NODE || old_state == NLP_STE_UNMAPPED_NODE)) { - if (ndlp->rport && - lpfc_valid_xpt_node(ndlp)) { - vport->phba->nport_event_cnt++; - lpfc_unregister_remote_port(ndlp); - } - - if (ndlp->nlp_fc4_type & NLP_FC4_NVME) { - vport->phba->nport_event_cnt++; - if (vport->phba->nvmet_support == 0) { - /* Start devloss if target. */ - if (ndlp->nlp_type & NLP_NVME_TARGET) - lpfc_nvme_unregister_port(vport, ndlp); - } else { - /* NVMET has no upcall. */ - lpfc_nlp_put(ndlp); - } - } + /* For nodes marked for ADISC, Handle unreg in ADISC cmpl */ + if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) + lpfc_nlp_unreg_node(vport, ndlp); } - /* FCP and NVME Transport interfaces */ - if (new_state == NLP_STE_MAPPED_NODE || - new_state == NLP_STE_UNMAPPED_NODE) { - if (lpfc_valid_xpt_node(ndlp)) { - vport->phba->nport_event_cnt++; - /* - * Tell the fc transport about the port, if we haven't - * already. If we have, and it's a scsi entity, be - */ - lpfc_register_remote_port(vport, ndlp); - } - /* Notify the NVME transport of this new rport. */ - if (vport->phba->sli_rev >= LPFC_SLI_REV4 && - ndlp->nlp_fc4_type & NLP_FC4_NVME) { - if (vport->phba->nvmet_support == 0) { - /* Register this rport with the transport. - * Only NVME Target Rports are registered with - * the transport. - */ - if (ndlp->nlp_type & NLP_NVME_TARGET) { - vport->phba->nport_event_cnt++; - lpfc_nvme_register_port(vport, ndlp); - } - } else { - /* Just take an NDLP ref count since the - * target does not register rports. - */ - lpfc_nlp_get(ndlp); - } - } - } + new_state == NLP_STE_UNMAPPED_NODE) + lpfc_nlp_reg_node(vport, ndlp); if ((new_state == NLP_STE_MAPPED_NODE) && (vport->stat_data_enabled)) { diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index e12f83fb795c..46c1905f6f39 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -863,6 +863,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; } out: + /* Unregister from backend, could have been skipped due to ADISC */ + lpfc_nlp_unreg_node(vport, ndlp); + ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); @@ -1677,9 +1680,6 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, spin_unlock_irq(&ndlp->lock); ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; - memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name)); - memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name)); - ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); lpfc_unreg_rpi(vport, ndlp); @@ -2597,13 +2597,14 @@ lpfc_device_recov_mapped_node(struct lpfc_vport *vport, void *arg, uint32_t evt) { + lpfc_disc_set_adisc(vport, ndlp); + ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME); spin_unlock_irq(&ndlp->lock); - lpfc_disc_set_adisc(vport, ndlp); return ndlp->nlp_state; } diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index bcc804cefd30..f36294e9b5dd 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -216,8 +216,8 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) /* The register rebind might have occurred before the delete * downcall. Guard against this race. */ - if (ndlp->fc4_xpt_flags & NLP_WAIT_FOR_UNREG) - ndlp->fc4_xpt_flags &= ~(NLP_WAIT_FOR_UNREG | NVME_XPT_REGD); + if (ndlp->fc4_xpt_flags & NVME_XPT_UNREG_WAIT) + ndlp->fc4_xpt_flags &= ~(NVME_XPT_UNREG_WAIT | NVME_XPT_REGD); spin_unlock_irq(&ndlp->lock); @@ -2324,7 +2324,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * race that leaves the WAIT flag set. */ spin_lock_irq(&ndlp->lock); - ndlp->fc4_xpt_flags &= ~NLP_WAIT_FOR_UNREG; + ndlp->fc4_xpt_flags &= ~NVME_XPT_UNREG_WAIT; ndlp->fc4_xpt_flags |= NVME_XPT_REGD; spin_unlock_irq(&ndlp->lock); rport = remote_port->private; @@ -2336,7 +2336,7 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) */ spin_lock_irq(&ndlp->lock); ndlp->nrport = NULL; - ndlp->fc4_xpt_flags &= ~NLP_WAIT_FOR_UNREG; + ndlp->fc4_xpt_flags &= ~NVME_XPT_UNREG_WAIT; spin_unlock_irq(&ndlp->lock); rport->ndlp = NULL; rport->remoteport = NULL; @@ -2488,7 +2488,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) * The transport will update it. */ spin_lock_irq(&vport->phba->hbalock); - ndlp->fc4_xpt_flags |= NLP_WAIT_FOR_UNREG; + ndlp->fc4_xpt_flags |= NVME_XPT_UNREG_WAIT; spin_unlock_irq(&vport->phba->hbalock); /* Don't let the host nvme transport keep sending keep-alives diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index 69a5a844c69c..060a7c111bad 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -37,8 +37,8 @@ #define LPFC_MAX_NVME_INFO_TMP_LEN 100 #define LPFC_NVME_INFO_MORE_STR "\nCould be more info...\n" -#define lpfc_ndlp_get_nrport(ndlp) \ - ((!ndlp->nrport || (ndlp->fc4_xpt_flags & NLP_WAIT_FOR_UNREG)) \ +#define lpfc_ndlp_get_nrport(ndlp) \ + ((!ndlp->nrport || (ndlp->fc4_xpt_flags & NVME_XPT_UNREG_WAIT))\ ? NULL : ndlp->nrport) struct lpfc_nvme_qhandle { -- cgit v1.2.3-70-g09d2 From c65436b21c3abbdaacd9c9f68bf2fa94e103168d Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:47 -0700 Subject: scsi: lpfc: Call discovery state machine when handling PLOGI/ADISC completions In the PLOGI and ADISC completion handling, the device removal event could be skipped during some link errors. This could leave a stale node in UNUSED state. Driver unload would hang for a long time waiting for this node to be freed. Resolve by taking the following steps: - Always post ADISC completion events to discovery state machine upon ADISC completion. - In case of a completion error for PLOGI/ADISC, ensure that init refcount is dropped if not registered with transport. Link: https://lore.kernel.org/r/20210707184351.67872-17-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 32f5f00f0a85..11e56534b8f0 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2031,9 +2031,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (lpfc_error_lost_link(irsp)) - goto check_plogi; - else + if (!lpfc_error_lost_link(irsp)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); @@ -2086,7 +2084,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, NLP_EVT_CMPL_PLOGI); } - check_plogi: if (disc && vport->num_disc_nodes) { /* Check to see if there are more PLOGIs to be sent */ lpfc_more_plogi(vport); @@ -2755,12 +2752,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "2755 ADISC failure DID:%06X Status:x%x/x%x\n", ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4]); - /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (lpfc_error_lost_link(irsp)) - goto check_adisc; - else - lpfc_disc_state_machine(vport, ndlp, cmdiocb, - NLP_EVT_CMPL_ADISC); + + lpfc_disc_state_machine(vport, ndlp, cmdiocb, + NLP_EVT_CMPL_ADISC); /* As long as this node is not registered with the SCSI or NVMe * transport, it is no longer an active node. Otherwise @@ -2778,7 +2772,6 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_ADISC); - check_adisc: /* Check to see if there are more ADISCs to be sent */ if (disc && vport->num_disc_nodes) lpfc_more_adisc(vport); -- cgit v1.2.3-70-g09d2 From 02607fbaf00d9aac8fe97b1d9643f09ebdb47922 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:48 -0700 Subject: scsi: lpfc: Skip reg_vpi when link is down for SLI3 in ADISC cmpl path During RSCN storms, some instances of LIP on SLI-3 adapters lead to a situation where FLOGIs keep failing with firmware indicating an illegal command error code. This situation was preceded by an ADISC completion that was processed while the link was down. This path on SLI-3 performs a CLEAR_LA and attempts to activate a VPI with REG_VPI. Later, as the FLOGI completes, it's no longer in sync with the VPI state. In SLI-3 it is illegal to have an active VPI during FLOGI. Resolve by circumventing the SLI-3 path that performs the CLEAR_LA and REG_VPI. The path will be taken after the FLOGI after the next Link Up. Link: https://lore.kernel.org/r/20210707184351.67872-18-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 11e56534b8f0..342c7e28ee95 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2610,6 +2610,14 @@ lpfc_adisc_done(struct lpfc_vport *vport) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && !(vport->fc_flag & FC_RSCN_MODE) && (phba->sli_rev < LPFC_SLI_REV4)) { + + /* + * If link is down, clear_la and reg_vpi will be done after + * flogi following a link up event + */ + if (!lpfc_is_link_up(phba)) + return; + /* The ADISCs are complete. Doesn't matter if they * succeeded or failed because the ADISC completion * routine guarantees to call the state machine and -- cgit v1.2.3-70-g09d2 From ab803860882514ddbf97713b143b861b524e8476 Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:49 -0700 Subject: scsi: lpfc: Skip issuing ADISC when node is in NPR state When a node moves to NPR state due to a device recovery event, the nlp_fc4_types in the node are cleared. An ADISC received for a node in the NPR state triggers an ADISC. Without fc4 types being known, the calls to register with the transport are no-op'd, thus no additional references are placed on the node by transport re-registrations. A subsequent RSCN could trigger another unregister request, which will decrement the reference counts, leading to the ref count hitting zero and the node being freed while futher discovery on the node is being attempted by the RSCN event handling. Fix by skipping the trigger of an ADISC when in NPR state. The normal ADISC process will kick off in the regular discovery path after receiving a response from name server. Link: https://lore.kernel.org/r/20210707184351.67872-19-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 46c1905f6f39..27263f02ab9f 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -736,9 +736,13 @@ out: * is already in MAPPED or UNMAPPED state. Catch this * condition and don't set the nlp_state again because * it causes an unnecessary transport unregister/register. + * + * Nodes marked for ADISC will move MAPPED or UNMAPPED state + * after issuing ADISC */ if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) { - if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) + if ((ndlp->nlp_state != NLP_STE_MAPPED_NODE) && + !(ndlp->nlp_flag & NLP_NPR_ADISC)) lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); } @@ -2646,14 +2650,13 @@ lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { - if (ndlp->nlp_flag & NLP_NPR_ADISC) { - spin_lock_irq(&ndlp->lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - spin_unlock_irq(&ndlp->lock); - lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); - lpfc_issue_els_adisc(vport, ndlp, 0); - } else { + /* + * ADISC nodes will be handled in regular discovery path after + * receiving response from NS. + * + * For other nodes, Send PLOGI to trigger an implicit LOGO. + */ + if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); @@ -2686,12 +2689,13 @@ lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, */ if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) { - if (ndlp->nlp_flag & NLP_NPR_ADISC) { - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); - lpfc_issue_els_adisc(vport, ndlp, 0); - } else { + /* + * ADISC nodes will be handled in regular discovery path after + * receiving response from NS. + * + * For other nodes, Send PLOGI to trigger an implicit LOGO. + */ + if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); -- cgit v1.2.3-70-g09d2 From 545a68e711ee4d6ed11cec956bb06cb52c95e83a Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:50 -0700 Subject: scsi: lpfc: Update lpfc version to 12.8.0.11 Update lpfc version to 12.8.0.11. Link: https://lore.kernel.org/r/20210707184351.67872-20-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 2d62fd2a9824..63b2690ab49f 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "12.8.0.10" +#define LPFC_DRIVER_VERSION "12.8.0.11" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- cgit v1.2.3-70-g09d2 From f2af8ffc63a184ab425e0a02308f7fdcf8a53f1c Mon Sep 17 00:00:00 2001 From: James Smart Date: Wed, 7 Jul 2021 11:43:51 -0700 Subject: scsi: lpfc: Copyright updates for 12.8.0.11 patches Update copyrights for files modified by the 12.8.0.11 patch set. Link: https://lore.kernel.org/r/20210707184351.67872-21-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvme.h | 2 +- drivers/scsi/lpfc/lpfc_sli4.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index 060a7c111bad..f61223fbe644 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 021edbfbbca5..f250b666ac57 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2009-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * -- cgit v1.2.3-70-g09d2 From d42d57fe86e98c2ab438e30c247d90504a146646 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 15 Jun 2021 17:39:29 +0800 Subject: clk: renesas: rzg2l: Remove unneeded semicolon Eliminate the following coccicheck warning: ./drivers/clk/renesas/renesas-rzg2l-cpg.c:299:2-3: Unneeded semicolon Reported-by: Abaci Robot Signed-off-by: Yang Li Link: https://lore.kernel.org/r/1623749970-38020-1-git-send-email-yang.lee@linux.alibaba.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index e7c59af2a1d8..a0bb8b20797d 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -297,7 +297,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, break; default: goto fail; - }; + } if (IS_ERR_OR_NULL(clk)) goto fail; -- cgit v1.2.3-70-g09d2 From 97c29755598f98c6c91f68f12bdd3f517e457890 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 17 Jun 2021 10:22:03 +0800 Subject: clk: renesas: rzg2l: Fix return value and unused assignment Currently the function returns NULL on error, so exact error code is lost. This patch changes return convention of the function to use ERR_PTR() on error instead. Reported-by: Abaci Robot Signed-off-by: Yang Li Link: https://lore.kernel.org/r/1623896524-102058-1-git-send-email-yang.lee@linux.alibaba.com [geert: Drop curly braces] Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index a0bb8b20797d..0ce84a24198c 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -182,10 +182,8 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, return ERR_CAST(parent); pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); - if (!pll_clk) { - clk = ERR_PTR(-ENOMEM); - return NULL; - } + if (!pll_clk) + return ERR_PTR(-ENOMEM); parent_name = __clk_get_name(parent); init.name = core->name; -- cgit v1.2.3-70-g09d2 From 36aaa3a0d9bc13e302dc146a20f022fb6891b605 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Jun 2021 17:14:11 +0300 Subject: clk: renesas: rzg2l: Fix a double free on error The "pll_clk" and "clock" pointers are allocated with devm_kzalloc() so freeing them with kfree() will lead to a double free. This would only happen if probe failed, and the system is not bootable. Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") Signed-off-by: Dan Carpenter Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/YMtYs7LVveYH4eRe@mwanda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 0ce84a24198c..6808390f8ee0 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -175,7 +175,6 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, struct clk_init_data init; const char *parent_name; struct pll_clk *pll_clk; - struct clk *clk; parent = clks[core->parent & 0xffff]; if (IS_ERR(parent)) @@ -198,11 +197,7 @@ rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, pll_clk->priv = priv; pll_clk->type = core->type; - clk = clk_register(NULL, &pll_clk->hw); - if (IS_ERR(clk)) - kfree(pll_clk); - - return clk; + return clk_register(NULL, &pll_clk->hw); } static struct clk @@ -471,7 +466,6 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, fail: dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", mod->name, PTR_ERR(clk)); - kfree(clock); } #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) -- cgit v1.2.3-70-g09d2 From e37868f14416bc5f22235dce073c496381d349c3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 17 Jun 2021 17:15:10 +0300 Subject: clk: renesas: rzg2l: Avoid mixing error pointers and NULL These functions accidentally return both error pointers and NULL when there is an error. It doesn't cause a problem but it is confusing and seems unintentional. Signed-off-by: Dan Carpenter Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/YMtY7nOtqEvTokh7@mwanda Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 6808390f8ee0..34e90ee46290 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -125,7 +125,7 @@ rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, core->flag, &priv->rmw_lock); if (IS_ERR(clk_hw)) - return NULL; + return ERR_CAST(clk_hw); return clk_hw->clk; } -- cgit v1.2.3-70-g09d2 From 1606e81543f80fc3b1912957cf6d8fa62e40b8e5 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 17 Jun 2021 16:54:32 +0100 Subject: clk: renesas: rzg2l: Fix off-by-one check in rzg2l_cpg_clk_src_twocell_get() Fix clock index out of range check for module clocks in rzg2l_cpg_clk_src_twocell_get(). Fixes: ef3c613ccd68 ("clk: renesas: Add CPG core wrapper for RZ/G2L SoC") Reported-by: Dan Carpenter Signed-off-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210617155432.18827-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-rzg2l-cpg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c index 34e90ee46290..9addc9dae31a 100644 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -222,7 +222,7 @@ static struct clk case CPG_MOD: type = "module"; - if (clkidx > priv->num_mod_clks) { + if (clkidx >= priv->num_mod_clks) { dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); -- cgit v1.2.3-70-g09d2 From d23fcff14568d5a5e025b9c1185531caccd605db Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 18 Jun 2021 13:46:21 +0200 Subject: clk: renesas: rzg2: Rename i2c-dvfs to iic-pmic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As RZ/G2 SoCs do not support DVFS, the "iic-dvfs" module was renamed to "iic-pmic" in the RZ/G Series, 2nd Generation User’s Manual: Hardware Rev. 1.00. Signed-off-by: Geert Uytterhoeven Reviewed-by: Niklas Söderlund Link: https://lore.kernel.org/r/3e549b41989ff2797b998a1c749c9f607845f44a.1624016693.git.geert+renesas@glider.be --- drivers/clk/renesas/r8a774a1-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774b1-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774c0-cpg-mssr.c | 2 +- drivers/clk/renesas/r8a774e1-cpg-mssr.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 4a43ebec7d5e..39b185d8e957 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774A1_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), - DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774A1_CLK_CP), DEF_MOD("i2c4", 927, R8A774A1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774A1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774A1_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c index 6f04c40fe237..af602d83c8ce 100644 --- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -206,7 +206,7 @@ static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774B1_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), - DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774B1_CLK_CP), DEF_MOD("i2c4", 927, R8A774B1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774B1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774B1_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c index ed3a2cf0e0bb..5b938eb2df25 100644 --- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -210,7 +210,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { DEF_MOD("rpc-if", 917, R8A774C0_CLK_RPCD2), DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), - DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774C0_CLK_CP), DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2), DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2), DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2), diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c index b96c486abb44..40c71466df37 100644 --- a/drivers/clk/renesas/r8a774e1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c @@ -219,7 +219,7 @@ static const struct mssr_mod_clk r8a774e1_mod_clks[] __initconst = { DEF_MOD("i2c6", 918, R8A774E1_CLK_S0D6), DEF_MOD("i2c5", 919, R8A774E1_CLK_S0D6), DEF_MOD("adg", 922, R8A774E1_CLK_S0D1), - DEF_MOD("i2c-dvfs", 926, R8A774E1_CLK_CP), + DEF_MOD("iic-pmic", 926, R8A774E1_CLK_CP), DEF_MOD("i2c4", 927, R8A774E1_CLK_S0D6), DEF_MOD("i2c3", 928, R8A774E1_CLK_S0D6), DEF_MOD("i2c2", 929, R8A774E1_CLK_S3D2), -- cgit v1.2.3-70-g09d2 From 417ed58dfc5ed6c2ec608d5ee93dd27197190e19 Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 23 Jun 2021 00:27:10 +0100 Subject: clk: renesas: r8a779a0: Add the DU clock The DU clock is added to the S3D1 clock parent. The Renesas BSP lists S2D1 as the clock parent, however there is no S2 clock on this platform. S3D1 is chosen as a best effort guess and demonstrates functionality but is not guaranteed to be correct. Signed-off-by: Kieran Bingham Link: https://lore.kernel.org/r/20210622232711.3219697-2-kieran.bingham@ideasonboard.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index acaf5a93f1d3..a1bd158defb5 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -167,6 +167,7 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0), DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0), + DEF_MOD("du", 411, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd0", 508, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd1", 509, R8A779A0_CLK_S3D1), DEF_MOD("hscif0", 514, R8A779A0_CLK_S1D2), -- cgit v1.2.3-70-g09d2 From c346ff5ccc8e87f69a520073f876b740431a5acf Mon Sep 17 00:00:00 2001 From: Kieran Bingham Date: Wed, 23 Jun 2021 00:27:11 +0100 Subject: clk: renesas: r8a779a0: Add the DSI clocks The DSI clock is incorrectly defined as a fixed clock. This demonstrates itself as the dsi-encoders failing to correctly enable and start their PPI and HS clocks internally, and causes failures. Move the DSI parent clock to match the updates in the BSP, which resolves the initialisation procedures. Signed-off-by: Kieran Bingham Fixes: 17bcc8035d2d19fc ("clk: renesas: cpg-mssr: Add support for R-Car V3U") Link: https://lore.kernel.org/r/20210622232711.3219697-3-kieran.bingham@ideasonboard.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a779a0-cpg-mssr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index a1bd158defb5..f16d125ca009 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -135,7 +135,6 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_FIXED("zt", R8A779A0_CLK_ZT, CLK_PLL1_DIV2, 2, 1), DEF_FIXED("ztr", R8A779A0_CLK_ZTR, CLK_PLL1_DIV2, 2, 1), DEF_FIXED("zr", R8A779A0_CLK_ZR, CLK_PLL1_DIV2, 1, 1), - DEF_FIXED("dsi", R8A779A0_CLK_DSI, CLK_PLL5_DIV4, 1, 1), DEF_FIXED("cnndsp", R8A779A0_CLK_CNNDSP, CLK_PLL5_DIV4, 1, 1), DEF_FIXED("vip", R8A779A0_CLK_VIP, CLK_PLL5, 5, 1), DEF_FIXED("adgh", R8A779A0_CLK_ADGH, CLK_PLL5_DIV4, 1, 1), @@ -151,6 +150,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A779A0_CLK_MSO, CLK_PLL5_DIV4, 0x87c), DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878), DEF_DIV6P1("csi0", R8A779A0_CLK_CSI0, CLK_PLL5_DIV4, 0x880), + DEF_DIV6P1("dsi", R8A779A0_CLK_DSI, CLK_PLL5_DIV4, 0x884), DEF_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), DEF_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), @@ -168,6 +168,8 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0), DEF_MOD("du", 411, R8A779A0_CLK_S3D1), + DEF_MOD("dsi0", 415, R8A779A0_CLK_DSI), + DEF_MOD("dsi1", 416, R8A779A0_CLK_DSI), DEF_MOD("fcpvd0", 508, R8A779A0_CLK_S3D1), DEF_MOD("fcpvd1", 509, R8A779A0_CLK_S3D1), DEF_MOD("hscif0", 514, R8A779A0_CLK_S1D2), -- cgit v1.2.3-70-g09d2 From 1962dd36db4ffe0411e3cb06f0797b7aacf0ca99 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 26 Jun 2021 09:13:42 +0100 Subject: clk: renesas: r9a07g044: Add I2C clocks/resets Add I2C{0,1,2,3} clock and reset entries. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210626081344.5783-9-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index ae24e0397d3c..b39a36b317fd 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -90,6 +90,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x518, 0), DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1, 0x518, 1), + DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, + 0x580, 0), + DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, + 0x580, 1), + DEF_MOD("i2c2", R9A07G044_I2C2_PCLK, R9A07G044_CLK_P0, + 0x580, 2), + DEF_MOD("i2c3", R9A07G044_I2C3_PCLK, R9A07G044_CLK_P0, + 0x580, 3), DEF_MOD("scif0", R9A07G044_SCIF0_CLK_PCK, R9A07G044_CLK_P0, 0x584, 0), DEF_MOD("scif1", R9A07G044_SCIF1_CLK_PCK, R9A07G044_CLK_P0, @@ -108,6 +116,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0), DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1), DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), + DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), + DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), + DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), + DEF_RST(R9A07G044_I2C3_MRST, 0x880, 3), DEF_RST(R9A07G044_SCIF0_RST_SYSTEM_N, 0x884, 0), DEF_RST(R9A07G044_SCIF1_RST_SYSTEM_N, 0x884, 1), DEF_RST(R9A07G044_SCIF2_RST_SYSTEM_N, 0x884, 2), -- cgit v1.2.3-70-g09d2 From eb829e549ba65e48b1c16ddecb892a32b366d5e4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sat, 26 Jun 2021 09:13:43 +0100 Subject: clk: renesas: r9a07g044: Add DMAC clocks/resets Add DMAC clock and reset entries in CPG driver. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210626081344.5783-10-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index b39a36b317fd..5d81e59f5cfe 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -37,6 +37,7 @@ enum clk_ids { CLK_PLL5, CLK_PLL5_DIV2, CLK_PLL6, + CLK_P1_DIV2, /* Module Clocks */ MOD_CLK_BASE, @@ -79,6 +80,7 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), + DEF_FIXED("P1_DIV2", CLK_P1_DIV2, R9A07G044_CLK_P1, 1, 2), DEF_DIV("P2", R9A07G044_CLK_P2, CLK_PLL3_DIV2_4_2, DIVPL3A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), }; @@ -90,6 +92,10 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x518, 0), DEF_MOD("ia55_clk", R9A07G044_IA55_CLK, R9A07G044_CLK_P1, 0x518, 1), + DEF_MOD("dmac_aclk", R9A07G044_DMAC_ACLK, R9A07G044_CLK_P1, + 0x52c, 0), + DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, + 0x52c, 1), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, 0x580, 0), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, @@ -116,6 +122,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GIC600_GICRESET_N, 0x814, 0), DEF_RST(R9A07G044_GIC600_DBG_GICRESET_N, 0x814, 1), DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), + DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), + DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), -- cgit v1.2.3-70-g09d2 From 03fa6e4b2622035389a4beb9699551d63d130493 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Jun 2021 08:30:06 +0100 Subject: clk: renesas: r9a07g044: Add USB clocks/resets Add clock/reset entries for USB PHY control, USB2.0 host and device. Signed-off-by: Biju Das Link: https://lore.kernel.org/r/20210630073013.22415-5-biju.das.jz@bp.renesas.com [geert: s/usb0_device/usb0_func] Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 5d81e59f5cfe..7af4b39a0953 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -96,6 +96,14 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), + DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1, + 0x578, 0), + DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1, + 0x578, 1), + DEF_MOD("usb0_func", R9A07G044_USB_U2P_EXR_CPUCLK, R9A07G044_CLK_P1, + 0x578, 2), + DEF_MOD("usb_pclk", R9A07G044_USB_PCLK, R9A07G044_CLK_P1, + 0x578, 3), DEF_MOD("i2c0", R9A07G044_I2C0_PCLK, R9A07G044_CLK_P0, 0x580, 0), DEF_MOD("i2c1", R9A07G044_I2C1_PCLK, R9A07G044_CLK_P0, @@ -124,6 +132,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A07G044_USB_U2H0_HRESETN, 0x878, 0), + DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1), + DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2), + DEF_RST(R9A07G044_USB_PRESETN, 0x878, 3), DEF_RST(R9A07G044_I2C0_MRST, 0x880, 0), DEF_RST(R9A07G044_I2C1_MRST, 0x880, 1), DEF_RST(R9A07G044_I2C2_MRST, 0x880, 2), -- cgit v1.2.3-70-g09d2 From d520af345189c04095bdd256d3601864601ac562 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Fri, 2 Jul 2021 14:50:03 +0100 Subject: clk: renesas: r9a07g044: Add SSIF-2 clock and reset entries Add SSIF-2 clock and reset entries in CPG driver. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Link: https://lore.kernel.org/r/20210702135010.5937-3-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 7af4b39a0953..ed5f5c11ac12 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -96,6 +96,22 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x52c, 0), DEF_MOD("dmac_pclk", R9A07G044_DMAC_PCLK, CLK_P1_DIV2, 0x52c, 1), + DEF_MOD("ssi0_pclk", R9A07G044_SSI0_PCLK2, R9A07G044_CLK_P0, + 0x570, 0), + DEF_MOD("ssi0_sfr", R9A07G044_SSI0_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 1), + DEF_MOD("ssi1_pclk", R9A07G044_SSI1_PCLK2, R9A07G044_CLK_P0, + 0x570, 2), + DEF_MOD("ssi1_sfr", R9A07G044_SSI1_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 3), + DEF_MOD("ssi2_pclk", R9A07G044_SSI2_PCLK2, R9A07G044_CLK_P0, + 0x570, 4), + DEF_MOD("ssi2_sfr", R9A07G044_SSI2_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 5), + DEF_MOD("ssi3_pclk", R9A07G044_SSI3_PCLK2, R9A07G044_CLK_P0, + 0x570, 6), + DEF_MOD("ssi3_sfr", R9A07G044_SSI3_PCLK_SFR, R9A07G044_CLK_P0, + 0x570, 7), DEF_MOD("usb0_host", R9A07G044_USB_U2H0_HCLK, R9A07G044_CLK_P1, 0x578, 0), DEF_MOD("usb1_host", R9A07G044_USB_U2H1_HCLK, R9A07G044_CLK_P1, @@ -132,6 +148,10 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_IA55_RESETN, 0x818, 0), DEF_RST(R9A07G044_DMAC_ARESETN, 0x82c, 0), DEF_RST(R9A07G044_DMAC_RST_ASYNC, 0x82c, 1), + DEF_RST(R9A07G044_SSI0_RST_M2_REG, 0x870, 0), + DEF_RST(R9A07G044_SSI1_RST_M2_REG, 0x870, 1), + DEF_RST(R9A07G044_SSI2_RST_M2_REG, 0x870, 2), + DEF_RST(R9A07G044_SSI3_RST_M2_REG, 0x870, 3), DEF_RST(R9A07G044_USB_U2H0_HRESETN, 0x878, 0), DEF_RST(R9A07G044_USB_U2H1_HRESETN, 0x878, 1), DEF_RST(R9A07G044_USB_U2P_EXL_SYSRST, 0x878, 2), -- cgit v1.2.3-70-g09d2 From d85b82f09a03c2e1f06da740c6c47dd098b16ca5 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 12 Jul 2021 20:44:20 +0100 Subject: clk: renesas: r9a07g044: Add GPIO clock and reset entries Add GPIO clock and reset entries in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210712194422.12405-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index ed5f5c11ac12..78fae93cf249 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -140,6 +140,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x584, 4), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, 0x588, 0), + DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, + 0x598, 0), }; static struct rzg2l_reset r9a07g044_resets[] = { @@ -166,6 +168,9 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A07G044_SCI0_RST, 0x888, 0), + DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), + DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), + DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), }; static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { -- cgit v1.2.3-70-g09d2 From 0aae437ac5c264e8e2cb6c3fead20b44d2fa31d1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Jul 2021 15:26:01 +0200 Subject: clk: renesas: Rename renesas-rzg2l-cpg.[ch] to rzg2l-cpg.[ch] Rename renesas-rzg2l-cpg.c and renesas-rzg2l-cpg.h to rzg2l-cpg.c resp. rzg2l-cpg.h, for consistency with other (sub)drivers. Signed-off-by: Geert Uytterhoeven Reviewed-by: Lad Prabhakar Acked-by: Biju Das Link: https://lore.kernel.org/r/edc442daaedffcf10e835ff479d906fcae0e59db.1626268821.git.geert+renesas@glider.be --- drivers/clk/renesas/Makefile | 2 +- drivers/clk/renesas/r9a07g044-cpg.c | 2 +- drivers/clk/renesas/renesas-rzg2l-cpg.c | 750 -------------------------------- drivers/clk/renesas/renesas-rzg2l-cpg.h | 155 ------- drivers/clk/renesas/rzg2l-cpg.c | 750 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/rzg2l-cpg.h | 155 +++++++ 6 files changed, 907 insertions(+), 907 deletions(-) delete mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.c delete mode 100644 drivers/clk/renesas/renesas-rzg2l-cpg.h create mode 100644 drivers/clk/renesas/rzg2l-cpg.c create mode 100644 drivers/clk/renesas/rzg2l-cpg.h diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 5c6c5c721d98..7d018700d08b 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_CLK_RCAR_CPG_LIB) += rcar-cpg-lib.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o -obj-$(CONFIG_CLK_RZG2L) += renesas-rzg2l-cpg.o +obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o # Generic obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 78fae93cf249..6a1d9532a690 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -12,7 +12,7 @@ #include -#include "renesas-rzg2l-cpg.h" +#include "rzg2l-cpg.h" enum clk_ids { /* Core Clock Outputs exported to DT */ diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c deleted file mode 100644 index 9addc9dae31a..000000000000 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.c +++ /dev/null @@ -1,750 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * RZ/G2L Clock Pulse Generator - * - * Copyright (C) 2021 Renesas Electronics Corp. - * - * Based on renesas-cpg-mssr.c - * - * Copyright (C) 2015 Glider bvba - * Copyright (C) 2013 Ideas On Board SPRL - * Copyright (C) 2015 Renesas Electronics Corp. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "renesas-rzg2l-cpg.h" - -#ifdef DEBUG -#define WARN_DEBUG(x) WARN_ON(x) -#else -#define WARN_DEBUG(x) do { } while (0) -#endif - -#define DIV_RSMASK(v, s, m) ((v >> s) & m) -#define GET_SHIFT(val) ((val >> 12) & 0xff) -#define GET_WIDTH(val) ((val >> 8) & 0xf) - -#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) -#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) -#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) -#define SDIV(val) DIV_RSMASK(val, 0, 0x7) - -#define CLK_ON_R(reg) (reg) -#define CLK_MON_R(reg) (0x180 + (reg)) -#define CLK_RST_R(reg) (reg) -#define CLK_MRST_R(reg) (0x180 + (reg)) - -#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) -#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) -#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) - -/** - * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data - * - * @rcdev: Reset controller entity - * @dev: CPG device - * @base: CPG register block base address - * @rmw_lock: protects register accesses - * @clks: Array containing all Core and Module Clocks - * @num_core_clks: Number of Core Clocks in clks[] - * @num_mod_clks: Number of Module Clocks in clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @notifiers: Notifier chain to save/restore clock state for system resume - * @info: Pointer to platform data - */ -struct rzg2l_cpg_priv { - struct reset_controller_dev rcdev; - struct device *dev; - void __iomem *base; - spinlock_t rmw_lock; - - struct clk **clks; - unsigned int num_core_clks; - unsigned int num_mod_clks; - unsigned int num_resets; - unsigned int last_dt_core_clk; - - struct raw_notifier_head notifiers; - const struct rzg2l_cpg_info *info; -}; - -static void rzg2l_cpg_del_clk_provider(void *data) -{ - of_clk_del_provider(data); -} - -static struct clk * __init -rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, - struct clk **clks, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - struct device *dev = priv->dev; - const struct clk *parent; - const char *parent_name; - struct clk_hw *clk_hw; - - parent = clks[core->parent & 0xffff]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - parent_name = __clk_get_name(parent); - - if (core->dtable) - clk_hw = clk_hw_register_divider_table(dev, core->name, - parent_name, 0, - base + GET_REG_OFFSET(core->conf), - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, - core->dtable, - &priv->rmw_lock); - else - clk_hw = clk_hw_register_divider(dev, core->name, - parent_name, 0, - base + GET_REG_OFFSET(core->conf), - GET_SHIFT(core->conf), - GET_WIDTH(core->conf), - core->flag, &priv->rmw_lock); - - if (IS_ERR(clk_hw)) - return ERR_CAST(clk_hw); - - return clk_hw->clk; -} - -struct pll_clk { - struct clk_hw hw; - unsigned int conf; - unsigned int type; - void __iomem *base; - struct rzg2l_cpg_priv *priv; -}; - -#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) - -static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct pll_clk *pll_clk = to_pll(hw); - struct rzg2l_cpg_priv *priv = pll_clk->priv; - unsigned int val1, val2; - unsigned int mult = 1; - unsigned int div = 1; - - if (pll_clk->type != CLK_TYPE_SAM_PLL) - return parent_rate; - - val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); - val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); - mult = MDIV(val1) + KDIV(val1) / 65536; - div = PDIV(val1) * (1 << SDIV(val2)); - - return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); -} - -static const struct clk_ops rzg2l_cpg_pll_ops = { - .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate, -}; - -static struct clk * __init -rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, - struct clk **clks, - void __iomem *base, - struct rzg2l_cpg_priv *priv) -{ - struct device *dev = priv->dev; - const struct clk *parent; - struct clk_init_data init; - const char *parent_name; - struct pll_clk *pll_clk; - - parent = clks[core->parent & 0xffff]; - if (IS_ERR(parent)) - return ERR_CAST(parent); - - pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); - if (!pll_clk) - return ERR_PTR(-ENOMEM); - - parent_name = __clk_get_name(parent); - init.name = core->name; - init.ops = &rzg2l_cpg_pll_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - pll_clk->hw.init = &init; - pll_clk->conf = core->conf; - pll_clk->base = base; - pll_clk->priv = priv; - pll_clk->type = core->type; - - return clk_register(NULL, &pll_clk->hw); -} - -static struct clk -*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, - void *data) -{ - unsigned int clkidx = clkspec->args[1]; - struct rzg2l_cpg_priv *priv = data; - struct device *dev = priv->dev; - const char *type; - struct clk *clk; - - switch (clkspec->args[0]) { - case CPG_CORE: - type = "core"; - if (clkidx > priv->last_dt_core_clk) { - dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[clkidx]; - break; - - case CPG_MOD: - type = "module"; - if (clkidx >= priv->num_mod_clks) { - dev_err(dev, "Invalid %s clock index %u\n", type, - clkidx); - return ERR_PTR(-EINVAL); - } - clk = priv->clks[priv->num_core_clks + clkidx]; - break; - - default: - dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); - return ERR_PTR(-EINVAL); - } - - if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, - PTR_ERR(clk)); - else - dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", - clkspec->args[0], clkspec->args[1], clk, - clk_get_rate(clk)); - return clk; -} - -static void __init -rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, - const struct rzg2l_cpg_info *info, - struct rzg2l_cpg_priv *priv) -{ - struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; - struct device *dev = priv->dev; - unsigned int id = core->id, div = core->div; - const char *parent_name; - - WARN_DEBUG(id >= priv->num_core_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - if (!core->name) { - /* Skip NULLified clock */ - return; - } - - switch (core->type) { - case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); - break; - case CLK_TYPE_FF: - WARN_DEBUG(core->parent >= priv->num_core_clks); - parent = priv->clks[core->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - parent_name = __clk_get_name(parent); - clk = clk_register_fixed_factor(NULL, core->name, - parent_name, CLK_SET_RATE_PARENT, - core->mult, div); - break; - case CLK_TYPE_SAM_PLL: - clk = rzg2l_cpg_pll_clk_register(core, priv->clks, - priv->base, priv); - break; - case CLK_TYPE_DIV: - clk = rzg2l_cpg_div_clk_register(core, priv->clks, - priv->base, priv); - break; - default: - goto fail; - } - - if (IS_ERR_OR_NULL(clk)) - goto fail; - - dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", - core->name, PTR_ERR(clk)); -} - -/** - * struct mstp_clock - MSTP gating clock - * - * @hw: handle between common and hardware-specific interfaces - * @off: register offset - * @bit: ON/MON bit - * @priv: CPG/MSTP private data - */ -struct mstp_clock { - struct clk_hw hw; - u16 off; - u8 bit; - struct rzg2l_cpg_priv *priv; -}; - -#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) - -static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) -{ - struct mstp_clock *clock = to_mod_clock(hw); - struct rzg2l_cpg_priv *priv = clock->priv; - unsigned int reg = clock->off; - struct device *dev = priv->dev; - unsigned long flags; - unsigned int i; - u32 bitmask = BIT(clock->bit); - u32 value; - - if (!clock->off) { - dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); - return 0; - } - - dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, - enable ? "ON" : "OFF"); - spin_lock_irqsave(&priv->rmw_lock, flags); - - if (enable) - value = (bitmask << 16) | bitmask; - else - value = bitmask << 16; - writel(value, priv->base + CLK_ON_R(reg)); - - spin_unlock_irqrestore(&priv->rmw_lock, flags); - - if (!enable) - return 0; - - for (i = 1000; i > 0; --i) { - if (((readl(priv->base + CLK_MON_R(reg))) & bitmask)) - break; - cpu_relax(); - } - - if (!i) { - dev_err(dev, "Failed to enable CLK_ON %p\n", - priv->base + CLK_ON_R(reg)); - return -ETIMEDOUT; - } - - return 0; -} - -static int rzg2l_mod_clock_enable(struct clk_hw *hw) -{ - return rzg2l_mod_clock_endisable(hw, true); -} - -static void rzg2l_mod_clock_disable(struct clk_hw *hw) -{ - rzg2l_mod_clock_endisable(hw, false); -} - -static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) -{ - struct mstp_clock *clock = to_mod_clock(hw); - struct rzg2l_cpg_priv *priv = clock->priv; - u32 bitmask = BIT(clock->bit); - u32 value; - - if (!clock->off) { - dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); - return 1; - } - - value = readl(priv->base + CLK_MON_R(clock->off)); - - return !(value & bitmask); -} - -static const struct clk_ops rzg2l_mod_clock_ops = { - .enable = rzg2l_mod_clock_enable, - .disable = rzg2l_mod_clock_disable, - .is_enabled = rzg2l_mod_clock_is_enabled, -}; - -static void __init -rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, - const struct rzg2l_cpg_info *info, - struct rzg2l_cpg_priv *priv) -{ - struct mstp_clock *clock = NULL; - struct device *dev = priv->dev; - unsigned int id = mod->id; - struct clk_init_data init; - struct clk *parent, *clk; - const char *parent_name; - unsigned int i; - - WARN_DEBUG(id < priv->num_core_clks); - WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); - WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); - - if (!mod->name) { - /* Skip NULLified clock */ - return; - } - - parent = priv->clks[mod->parent]; - if (IS_ERR(parent)) { - clk = parent; - goto fail; - } - - clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); - if (!clock) { - clk = ERR_PTR(-ENOMEM); - goto fail; - } - - init.name = mod->name; - init.ops = &rzg2l_mod_clock_ops; - init.flags = CLK_SET_RATE_PARENT; - for (i = 0; i < info->num_crit_mod_clks; i++) - if (id == info->crit_mod_clks[i]) { - dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n", - mod->name); - init.flags |= CLK_IS_CRITICAL; - break; - } - - parent_name = __clk_get_name(parent); - init.parent_names = &parent_name; - init.num_parents = 1; - - clock->off = mod->off; - clock->bit = mod->bit; - clock->priv = priv; - clock->hw.init = &init; - - clk = clk_register(NULL, &clock->hw); - if (IS_ERR(clk)) - goto fail; - - dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); - priv->clks[id] = clk; - return; - -fail: - dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", - mod->name, PTR_ERR(clk)); -} - -#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) - -static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 we = dis << 16; - - dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - /* Reset module */ - writel(we, priv->base + CLK_RST_R(reg)); - - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); - - /* Release module from reset state */ - writel(we | dis, priv->base + CLK_RST_R(reg)); - - return 0; -} - -static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 value = BIT(info->resets[id].bit) << 16; - - dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); - return 0; -} - -static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 value = (dis << 16) | dis; - - dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, - CLK_RST_R(reg)); - - writel(value, priv->base + CLK_RST_R(reg)); - return 0; -} - -static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 bitmask = BIT(info->resets[id].bit); - - return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); -} - -static const struct reset_control_ops rzg2l_cpg_reset_ops = { - .reset = rzg2l_cpg_reset, - .assert = rzg2l_cpg_assert, - .deassert = rzg2l_cpg_deassert, - .status = rzg2l_cpg_status, -}; - -static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev, - const struct of_phandle_args *reset_spec) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int id = reset_spec->args[0]; - - if (id >= rcdev->nr_resets || !info->resets[id].off) { - dev_err(rcdev->dev, "Invalid reset index %u\n", id); - return -EINVAL; - } - - return id; -} - -static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) -{ - priv->rcdev.ops = &rzg2l_cpg_reset_ops; - priv->rcdev.of_node = priv->dev->of_node; - priv->rcdev.dev = priv->dev; - priv->rcdev.of_reset_n_cells = 1; - priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; - priv->rcdev.nr_resets = priv->num_resets; - - return devm_reset_controller_register(priv->dev, &priv->rcdev); -} - -static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec) -{ - if (clkspec->args_count != 2) - return false; - - switch (clkspec->args[0]) { - case CPG_MOD: - return true; - - default: - return false; - } -} - -static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev) -{ - struct device_node *np = dev->of_node; - struct of_phandle_args clkspec; - bool once = true; - struct clk *clk; - int error; - int i = 0; - - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, - &clkspec)) { - if (rzg2l_cpg_is_pm_clk(&clkspec)) { - if (once) { - once = false; - error = pm_clk_create(dev); - if (error) { - of_node_put(clkspec.np); - goto err; - } - } - clk = of_clk_get_from_provider(&clkspec); - of_node_put(clkspec.np); - if (IS_ERR(clk)) { - error = PTR_ERR(clk); - goto fail_destroy; - } - - error = pm_clk_add_clk(dev, clk); - if (error) { - dev_err(dev, "pm_clk_add_clk failed %d\n", - error); - goto fail_put; - } - } else { - of_node_put(clkspec.np); - } - i++; - } - - return 0; - -fail_put: - clk_put(clk); - -fail_destroy: - pm_clk_destroy(dev); -err: - return error; -} - -static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev) -{ - if (!pm_clk_no_clocks(dev)) - pm_clk_destroy(dev); -} - -static int __init rzg2l_cpg_add_clk_domain(struct device *dev) -{ - struct device_node *np = dev->of_node; - struct generic_pm_domain *genpd; - - genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); - if (!genpd) - return -ENOMEM; - - genpd->name = np->name; - genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | - GENPD_FLAG_ACTIVE_WAKEUP; - genpd->attach_dev = rzg2l_cpg_attach_dev; - genpd->detach_dev = rzg2l_cpg_detach_dev; - pm_genpd_init(genpd, &pm_domain_always_on_gov, false); - - of_genpd_add_provider_simple(np, genpd); - return 0; -} - -static int __init rzg2l_cpg_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct rzg2l_cpg_info *info; - struct rzg2l_cpg_priv *priv; - unsigned int nclks, i; - struct clk **clks; - int error; - - info = of_device_get_match_data(dev); - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->dev = dev; - priv->info = info; - spin_lock_init(&priv->rmw_lock); - - priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; - - dev_set_drvdata(dev, priv); - priv->clks = clks; - priv->num_core_clks = info->num_total_core_clks; - priv->num_mod_clks = info->num_hw_mod_clks; - priv->num_resets = info->num_resets; - priv->last_dt_core_clk = info->last_dt_core_clk; - - for (i = 0; i < nclks; i++) - clks[i] = ERR_PTR(-ENOENT); - - for (i = 0; i < info->num_core_clks; i++) - rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); - - for (i = 0; i < info->num_mod_clks; i++) - rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); - - error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv); - if (error) - return error; - - error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np); - if (error) - return error; - - error = rzg2l_cpg_add_clk_domain(dev); - if (error) - return error; - - error = rzg2l_cpg_reset_controller_register(priv); - if (error) - return error; - - return 0; -} - -static const struct of_device_id rzg2l_cpg_match[] = { -#ifdef CONFIG_CLK_R9A07G044 - { - .compatible = "renesas,r9a07g044-cpg", - .data = &r9a07g044_cpg_info, - }, -#endif - { /* sentinel */ } -}; - -static struct platform_driver rzg2l_cpg_driver = { - .driver = { - .name = "rzg2l-cpg", - .of_match_table = rzg2l_cpg_match, - }, -}; - -static int __init rzg2l_cpg_init(void) -{ - return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); -} - -subsys_initcall(rzg2l_cpg_init); - -MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h deleted file mode 100644 index 63695280ce8b..000000000000 --- a/drivers/clk/renesas/renesas-rzg2l-cpg.h +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * RZ/G2L Clock Pulse Generator - * - * Copyright (C) 2021 Renesas Electronics Corp. - * - */ - -#ifndef __RENESAS_RZG2L_CPG_H__ -#define __RENESAS_RZG2L_CPG_H__ - -#define CPG_PL2_DDIV (0x204) -#define CPG_PL3A_DDIV (0x208) - -/* n = 0/1/2 for PLL1/4/6 */ -#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) -#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) - -#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12) - -#define DDIV_PACK(offset, bitpos, size) \ - (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) -#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) -#define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) -#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) - -/** - * Definitions of CPG Core Clocks - * - * These include: - * - Clock outputs exported to DT - * - External input clocks - * - Internal CPG clocks - */ -struct cpg_core_clk { - const char *name; - unsigned int id; - unsigned int parent; - unsigned int div; - unsigned int mult; - unsigned int type; - unsigned int conf; - const struct clk_div_table *dtable; - const char * const *parent_names; - int flag; - int num_parents; -}; - -enum clk_types { - /* Generic */ - CLK_TYPE_IN, /* External Clock Input */ - CLK_TYPE_FF, /* Fixed Factor Clock */ - CLK_TYPE_SAM_PLL, - - /* Clock with divider */ - CLK_TYPE_DIV, -}; - -#define DEF_TYPE(_name, _id, _type...) \ - { .name = _name, .id = _id, .type = _type } -#define DEF_BASE(_name, _id, _type, _parent...) \ - DEF_TYPE(_name, _id, _type, .parent = _parent) -#define DEF_SAMPLL(_name, _id, _parent, _conf) \ - DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) -#define DEF_INPUT(_name, _id) \ - DEF_TYPE(_name, _id, CLK_TYPE_IN) -#define DEF_FIXED(_name, _id, _parent, _mult, _div) \ - DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) -#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ - DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ - .parent = _parent, .dtable = _dtable, .flag = _flag) - -/** - * struct rzg2l_mod_clk - Module Clocks definitions - * - * @name: handle between common and hardware-specific interfaces - * @id: clock index in array containing all Core and Module Clocks - * @parent: id of parent clock - * @off: register offset - * @bit: ON/MON bit - */ -struct rzg2l_mod_clk { - const char *name; - unsigned int id; - unsigned int parent; - u16 off; - u8 bit; -}; - -#define DEF_MOD(_name, _id, _parent, _off, _bit) \ - { \ - .name = _name, \ - .id = MOD_CLK_BASE + (_id), \ - .parent = (_parent), \ - .off = (_off), \ - .bit = (_bit), \ - } - -/** - * struct rzg2l_reset - Reset definitions - * - * @off: register offset - * @bit: reset bit - */ -struct rzg2l_reset { - u16 off; - u8 bit; -}; - -#define DEF_RST(_id, _off, _bit) \ - [_id] = { \ - .off = (_off), \ - .bit = (_bit) \ - } - -/** - * struct rzg2l_cpg_info - SoC-specific CPG Description - * - * @core_clks: Array of Core Clock definitions - * @num_core_clks: Number of entries in core_clks[] - * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @num_total_core_clks: Total number of Core Clocks (exported + internal) - * - * @mod_clks: Array of Module Clock definitions - * @num_mod_clks: Number of entries in mod_clks[] - * @num_hw_mod_clks: Number of Module Clocks supported by the hardware - * - * @crit_mod_clks: Array with Module Clock IDs of critical clocks that - * should not be disabled without a knowledgeable driver - * @num_crit_mod_clks: Number of entries in crit_mod_clks[] - */ -struct rzg2l_cpg_info { - /* Core Clocks */ - const struct cpg_core_clk *core_clks; - unsigned int num_core_clks; - unsigned int last_dt_core_clk; - unsigned int num_total_core_clks; - - /* Module Clocks */ - const struct rzg2l_mod_clk *mod_clks; - unsigned int num_mod_clks; - unsigned int num_hw_mod_clks; - - /* Resets */ - const struct rzg2l_reset *resets; - unsigned int num_resets; - - /* Critical Module Clocks that should not be disabled */ - const unsigned int *crit_mod_clks; - unsigned int num_crit_mod_clks; -}; - -extern const struct rzg2l_cpg_info r9a07g044_cpg_info; - -#endif diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c new file mode 100644 index 000000000000..3b3b2c3347f3 --- /dev/null +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -0,0 +1,750 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + * Based on renesas-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "rzg2l-cpg.h" + +#ifdef DEBUG +#define WARN_DEBUG(x) WARN_ON(x) +#else +#define WARN_DEBUG(x) do { } while (0) +#endif + +#define DIV_RSMASK(v, s, m) ((v >> s) & m) +#define GET_SHIFT(val) ((val >> 12) & 0xff) +#define GET_WIDTH(val) ((val >> 8) & 0xf) + +#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) +#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) +#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) +#define SDIV(val) DIV_RSMASK(val, 0, 0x7) + +#define CLK_ON_R(reg) (reg) +#define CLK_MON_R(reg) (0x180 + (reg)) +#define CLK_RST_R(reg) (reg) +#define CLK_MRST_R(reg) (0x180 + (reg)) + +#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) +#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) +#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) + +/** + * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data + * + * @rcdev: Reset controller entity + * @dev: CPG device + * @base: CPG register block base address + * @rmw_lock: protects register accesses + * @clks: Array containing all Core and Module Clocks + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @notifiers: Notifier chain to save/restore clock state for system resume + * @info: Pointer to platform data + */ +struct rzg2l_cpg_priv { + struct reset_controller_dev rcdev; + struct device *dev; + void __iomem *base; + spinlock_t rmw_lock; + + struct clk **clks; + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int num_resets; + unsigned int last_dt_core_clk; + + struct raw_notifier_head notifiers; + const struct rzg2l_cpg_info *info; +}; + +static void rzg2l_cpg_del_clk_provider(void *data) +{ + of_clk_del_provider(data); +} + +static struct clk * __init +rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + parent_name = __clk_get_name(parent); + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &priv->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &priv->rmw_lock); + + if (IS_ERR(clk_hw)) + return ERR_CAST(clk_hw); + + return clk_hw->clk; +} + +struct pll_clk { + struct clk_hw hw; + unsigned int conf; + unsigned int type; + void __iomem *base; + struct rzg2l_cpg_priv *priv; +}; + +#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) + +static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + unsigned int val1, val2; + unsigned int mult = 1; + unsigned int div = 1; + + if (pll_clk->type != CLK_TYPE_SAM_PLL) + return parent_rate; + + val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); + val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); + mult = MDIV(val1) + KDIV(val1) / 65536; + div = PDIV(val1) * (1 << SDIV(val2)); + + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); +} + +static const struct clk_ops rzg2l_cpg_pll_ops = { + .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate, +}; + +static struct clk * __init +rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + struct clk_init_data init; + const char *parent_name; + struct pll_clk *pll_clk; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return ERR_PTR(-ENOMEM); + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzg2l_cpg_pll_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll_clk->hw.init = &init; + pll_clk->conf = core->conf; + pll_clk->base = base; + pll_clk->priv = priv; + pll_clk->type = core->type; + + return clk_register(NULL, &pll_clk->hw); +} + +static struct clk +*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, + void *data) +{ + unsigned int clkidx = clkspec->args[1]; + struct rzg2l_cpg_priv *priv = data; + struct device *dev = priv->dev; + const char *type; + struct clk *clk; + + switch (clkspec->args[0]) { + case CPG_CORE: + type = "core"; + if (clkidx > priv->last_dt_core_clk) { + dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[clkidx]; + break; + + case CPG_MOD: + type = "module"; + if (clkidx >= priv->num_mod_clks) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[priv->num_core_clks + clkidx]; + break; + + default: + dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR(clk)) + dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + PTR_ERR(clk)); + else + dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", + clkspec->args[0], clkspec->args[1], clk, + clk_get_rate(clk)); + return clk; +} + +static void __init +rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; + struct device *dev = priv->dev; + unsigned int id = core->id, div = core->div; + const char *parent_name; + + WARN_DEBUG(id >= priv->num_core_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!core->name) { + /* Skip NULLified clock */ + return; + } + + switch (core->type) { + case CLK_TYPE_IN: + clk = of_clk_get_by_name(priv->dev->of_node, core->name); + break; + case CLK_TYPE_FF: + WARN_DEBUG(core->parent >= priv->num_core_clks); + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + parent_name = __clk_get_name(parent); + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, CLK_SET_RATE_PARENT, + core->mult, div); + break; + case CLK_TYPE_SAM_PLL: + clk = rzg2l_cpg_pll_clk_register(core, priv->clks, + priv->base, priv); + break; + case CLK_TYPE_DIV: + clk = rzg2l_cpg_div_clk_register(core, priv->clks, + priv->base, priv); + break; + default: + goto fail; + } + + if (IS_ERR_OR_NULL(clk)) + goto fail; + + dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", + core->name, PTR_ERR(clk)); +} + +/** + * struct mstp_clock - MSTP gating clock + * + * @hw: handle between common and hardware-specific interfaces + * @off: register offset + * @bit: ON/MON bit + * @priv: CPG/MSTP private data + */ +struct mstp_clock { + struct clk_hw hw; + u16 off; + u8 bit; + struct rzg2l_cpg_priv *priv; +}; + +#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + unsigned int reg = clock->off; + struct device *dev = priv->dev; + unsigned long flags; + unsigned int i; + u32 bitmask = BIT(clock->bit); + u32 value; + + if (!clock->off) { + dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); + return 0; + } + + dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->rmw_lock, flags); + + if (enable) + value = (bitmask << 16) | bitmask; + else + value = bitmask << 16; + writel(value, priv->base + CLK_ON_R(reg)); + + spin_unlock_irqrestore(&priv->rmw_lock, flags); + + if (!enable) + return 0; + + for (i = 1000; i > 0; --i) { + if (((readl(priv->base + CLK_MON_R(reg))) & bitmask)) + break; + cpu_relax(); + } + + if (!i) { + dev_err(dev, "Failed to enable CLK_ON %p\n", + priv->base + CLK_ON_R(reg)); + return -ETIMEDOUT; + } + + return 0; +} + +static int rzg2l_mod_clock_enable(struct clk_hw *hw) +{ + return rzg2l_mod_clock_endisable(hw, true); +} + +static void rzg2l_mod_clock_disable(struct clk_hw *hw) +{ + rzg2l_mod_clock_endisable(hw, false); +} + +static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + u32 bitmask = BIT(clock->bit); + u32 value; + + if (!clock->off) { + dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); + return 1; + } + + value = readl(priv->base + CLK_MON_R(clock->off)); + + return !(value & bitmask); +} + +static const struct clk_ops rzg2l_mod_clock_ops = { + .enable = rzg2l_mod_clock_enable, + .disable = rzg2l_mod_clock_disable, + .is_enabled = rzg2l_mod_clock_is_enabled, +}; + +static void __init +rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct mstp_clock *clock = NULL; + struct device *dev = priv->dev; + unsigned int id = mod->id; + struct clk_init_data init; + struct clk *parent, *clk; + const char *parent_name; + unsigned int i; + + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!mod->name) { + /* Skip NULLified clock */ + return; + } + + parent = priv->clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); + if (!clock) { + clk = ERR_PTR(-ENOMEM); + goto fail; + } + + init.name = mod->name; + init.ops = &rzg2l_mod_clock_ops; + init.flags = CLK_SET_RATE_PARENT; + for (i = 0; i < info->num_crit_mod_clks; i++) + if (id == info->crit_mod_clks[i]) { + dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n", + mod->name); + init.flags |= CLK_IS_CRITICAL; + break; + } + + parent_name = __clk_get_name(parent); + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->off = mod->off; + clock->bit = mod->bit; + clock->priv = priv; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto fail; + + dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", + mod->name, PTR_ERR(clk)); +} + +#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) + +static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 dis = BIT(info->resets[id].bit); + u32 we = dis << 16; + + dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + /* Reset module */ + writel(we, priv->base + CLK_RST_R(reg)); + + /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ + udelay(35); + + /* Release module from reset state */ + writel(we | dis, priv->base + CLK_RST_R(reg)); + + return 0; +} + +static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 value = BIT(info->resets[id].bit) << 16; + + dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 dis = BIT(info->resets[id].bit); + u32 value = (dis << 16) | dis; + + dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, + CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->resets[id].off; + u32 bitmask = BIT(info->resets[id].bit); + + return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); +} + +static const struct reset_control_ops rzg2l_cpg_reset_ops = { + .reset = rzg2l_cpg_reset, + .assert = rzg2l_cpg_assert, + .deassert = rzg2l_cpg_deassert, + .status = rzg2l_cpg_status, +}; + +static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int id = reset_spec->args[0]; + + if (id >= rcdev->nr_resets || !info->resets[id].off) { + dev_err(rcdev->dev, "Invalid reset index %u\n", id); + return -EINVAL; + } + + return id; +} + +static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) +{ + priv->rcdev.ops = &rzg2l_cpg_reset_ops; + priv->rcdev.of_node = priv->dev->of_node; + priv->rcdev.dev = priv->dev; + priv->rcdev.of_reset_n_cells = 1; + priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; + priv->rcdev.nr_resets = priv->num_resets; + + return devm_reset_controller_register(priv->dev, &priv->rcdev); +} + +static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec) +{ + if (clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_MOD: + return true; + + default: + return false; + } +} + +static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + bool once = true; + struct clk *clk; + int error; + int i = 0; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (rzg2l_cpg_is_pm_clk(&clkspec)) { + if (once) { + once = false; + error = pm_clk_create(dev); + if (error) { + of_node_put(clkspec.np); + goto err; + } + } + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + if (IS_ERR(clk)) { + error = PTR_ERR(clk); + goto fail_destroy; + } + + error = pm_clk_add_clk(dev, clk); + if (error) { + dev_err(dev, "pm_clk_add_clk failed %d\n", + error); + goto fail_put; + } + } else { + of_node_put(clkspec.np); + } + i++; + } + + return 0; + +fail_put: + clk_put(clk); + +fail_destroy: + pm_clk_destroy(dev); +err: + return error; +} + +static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + if (!pm_clk_no_clocks(dev)) + pm_clk_destroy(dev); +} + +static int __init rzg2l_cpg_add_clk_domain(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct generic_pm_domain *genpd; + + genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); + if (!genpd) + return -ENOMEM; + + genpd->name = np->name; + genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | + GENPD_FLAG_ACTIVE_WAKEUP; + genpd->attach_dev = rzg2l_cpg_attach_dev; + genpd->detach_dev = rzg2l_cpg_detach_dev; + pm_genpd_init(genpd, &pm_domain_always_on_gov, false); + + of_genpd_add_provider_simple(np, genpd); + return 0; +} + +static int __init rzg2l_cpg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct rzg2l_cpg_info *info; + struct rzg2l_cpg_priv *priv; + unsigned int nclks, i; + struct clk **clks; + int error; + + info = of_device_get_match_data(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->info = info; + spin_lock_init(&priv->rmw_lock); + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + nclks = info->num_total_core_clks + info->num_hw_mod_clks; + clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + priv->clks = clks; + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->num_resets = info->num_resets; + priv->last_dt_core_clk = info->last_dt_core_clk; + + for (i = 0; i < nclks; i++) + clks[i] = ERR_PTR(-ENOENT); + + for (i = 0; i < info->num_core_clks; i++) + rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); + + for (i = 0; i < info->num_mod_clks; i++) + rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); + + error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv); + if (error) + return error; + + error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np); + if (error) + return error; + + error = rzg2l_cpg_add_clk_domain(dev); + if (error) + return error; + + error = rzg2l_cpg_reset_controller_register(priv); + if (error) + return error; + + return 0; +} + +static const struct of_device_id rzg2l_cpg_match[] = { +#ifdef CONFIG_CLK_R9A07G044 + { + .compatible = "renesas,r9a07g044-cpg", + .data = &r9a07g044_cpg_info, + }, +#endif + { /* sentinel */ } +}; + +static struct platform_driver rzg2l_cpg_driver = { + .driver = { + .name = "rzg2l-cpg", + .of_match_table = rzg2l_cpg_match, + }, +}; + +static int __init rzg2l_cpg_init(void) +{ + return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); +} + +subsys_initcall(rzg2l_cpg_init); + +MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/rzg2l-cpg.h b/drivers/clk/renesas/rzg2l-cpg.h new file mode 100644 index 000000000000..63695280ce8b --- /dev/null +++ b/drivers/clk/renesas/rzg2l-cpg.h @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + */ + +#ifndef __RENESAS_RZG2L_CPG_H__ +#define __RENESAS_RZG2L_CPG_H__ + +#define CPG_PL2_DDIV (0x204) +#define CPG_PL3A_DDIV (0x208) + +/* n = 0/1/2 for PLL1/4/6 */ +#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) +#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) + +#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12) + +#define DDIV_PACK(offset, bitpos, size) \ + (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) +#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) +#define DIVPL3A DDIV_PACK(CPG_PL3A_DDIV, 0, 3) +#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) + +/** + * Definitions of CPG Core Clocks + * + * These include: + * - Clock outputs exported to DT + * - External input clocks + * - Internal CPG clocks + */ +struct cpg_core_clk { + const char *name; + unsigned int id; + unsigned int parent; + unsigned int div; + unsigned int mult; + unsigned int type; + unsigned int conf; + const struct clk_div_table *dtable; + const char * const *parent_names; + int flag; + int num_parents; +}; + +enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ + CLK_TYPE_FF, /* Fixed Factor Clock */ + CLK_TYPE_SAM_PLL, + + /* Clock with divider */ + CLK_TYPE_DIV, +}; + +#define DEF_TYPE(_name, _id, _type...) \ + { .name = _name, .id = _id, .type = _type } +#define DEF_BASE(_name, _id, _type, _parent...) \ + DEF_TYPE(_name, _id, _type, .parent = _parent) +#define DEF_SAMPLL(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) +#define DEF_INPUT(_name, _id) \ + DEF_TYPE(_name, _id, CLK_TYPE_IN) +#define DEF_FIXED(_name, _id, _parent, _mult, _div) \ + DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ + DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = _flag) + +/** + * struct rzg2l_mod_clk - Module Clocks definitions + * + * @name: handle between common and hardware-specific interfaces + * @id: clock index in array containing all Core and Module Clocks + * @parent: id of parent clock + * @off: register offset + * @bit: ON/MON bit + */ +struct rzg2l_mod_clk { + const char *name; + unsigned int id; + unsigned int parent; + u16 off; + u8 bit; +}; + +#define DEF_MOD(_name, _id, _parent, _off, _bit) \ + { \ + .name = _name, \ + .id = MOD_CLK_BASE + (_id), \ + .parent = (_parent), \ + .off = (_off), \ + .bit = (_bit), \ + } + +/** + * struct rzg2l_reset - Reset definitions + * + * @off: register offset + * @bit: reset bit + */ +struct rzg2l_reset { + u16 off; + u8 bit; +}; + +#define DEF_RST(_id, _off, _bit) \ + [_id] = { \ + .off = (_off), \ + .bit = (_bit) \ + } + +/** + * struct rzg2l_cpg_info - SoC-specific CPG Description + * + * @core_clks: Array of Core Clock definitions + * @num_core_clks: Number of entries in core_clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @num_total_core_clks: Total number of Core Clocks (exported + internal) + * + * @mod_clks: Array of Module Clock definitions + * @num_mod_clks: Number of entries in mod_clks[] + * @num_hw_mod_clks: Number of Module Clocks supported by the hardware + * + * @crit_mod_clks: Array with Module Clock IDs of critical clocks that + * should not be disabled without a knowledgeable driver + * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + */ +struct rzg2l_cpg_info { + /* Core Clocks */ + const struct cpg_core_clk *core_clks; + unsigned int num_core_clks; + unsigned int last_dt_core_clk; + unsigned int num_total_core_clks; + + /* Module Clocks */ + const struct rzg2l_mod_clk *mod_clks; + unsigned int num_mod_clks; + unsigned int num_hw_mod_clks; + + /* Resets */ + const struct rzg2l_reset *resets; + unsigned int num_resets; + + /* Critical Module Clocks that should not be disabled */ + const unsigned int *crit_mod_clks; + unsigned int num_crit_mod_clks; +}; + +extern const struct rzg2l_cpg_info r9a07g044_cpg_info; + +#endif -- cgit v1.2.3-70-g09d2 From 3b5c734592ade51fed3982bc840a830e066e668e Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Thu, 15 Jul 2021 19:21:22 +0100 Subject: clk: renesas: r9a07g044: Add clock and reset entries for CANFD Add clock and reset entries for CANFD in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210715182123.23372-6-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 6a1d9532a690..0c8e07c14a22 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -140,6 +140,8 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x584, 4), DEF_MOD("sci0", R9A07G044_SCI0_CLKP, R9A07G044_CLK_P0, 0x588, 0), + DEF_MOD("canfd", R9A07G044_CANFD_PCLK, R9A07G044_CLK_P0, + 0x594, 0), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, 0x598, 0), }; @@ -168,6 +170,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_SCIF3_RST_SYSTEM_N, 0x884, 3), DEF_RST(R9A07G044_SCIF4_RST_SYSTEM_N, 0x884, 4), DEF_RST(R9A07G044_SCI0_RST, 0x888, 0), + DEF_RST(R9A07G044_CANFD_RSTP_N, 0x894, 0), + DEF_RST(R9A07G044_CANFD_RSTC_N, 0x894, 1), DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), -- cgit v1.2.3-70-g09d2 From 1b87d5bba32c1f25a12ba0625546e5375e3f998d Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 19 Jul 2021 09:58:39 +0100 Subject: clk: renesas: r9a07g044: Add clock and reset entries for ADC Add clock and reset entries for ADC block in CPG driver. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210719085840.21842-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 0c8e07c14a22..9e9e8fb6d00d 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -144,6 +144,10 @@ static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { 0x594, 0), DEF_MOD("gpio", R9A07G044_GPIO_HCLK, R9A07G044_OSCCLK, 0x598, 0), + DEF_MOD("adc_adclk", R9A07G044_ADC_ADCLK, R9A07G044_CLK_TSU, + 0x5a8, 0), + DEF_MOD("adc_pclk", R9A07G044_ADC_PCLK, R9A07G044_CLK_P0, + 0x5a8, 1), }; static struct rzg2l_reset r9a07g044_resets[] = { @@ -175,6 +179,8 @@ static struct rzg2l_reset r9a07g044_resets[] = { DEF_RST(R9A07G044_GPIO_RSTN, 0x898, 0), DEF_RST(R9A07G044_GPIO_PORT_RESETN, 0x898, 1), DEF_RST(R9A07G044_GPIO_SPARE_RESETN, 0x898, 2), + DEF_RST(R9A07G044_ADC_PRESETN, 0x8a8, 0), + DEF_RST(R9A07G044_ADC_ADRST_N, 0x8a8, 1), }; static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { -- cgit v1.2.3-70-g09d2 From 14d72af7ab00d9c2eb5b473b4fdf3b751b8cf8e2 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Fri, 16 Jul 2021 00:57:07 +0800 Subject: MIPS: Ingenic: Add system type for new Ingenic SoCs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add JZ4730, JZ4750, JZ4755, JZ4760, JZ4760B, X2000H, and X2100 system type for cat /proc/cpuinfo to give out JZ4730, JZ4750, JZ4755, JZ4760, JZ4760B, X2000H, and X2100. Signed-off-by: 周琰杰 (Zhou Yanjie) Reviewed-by: Paul Cercueil Signed-off-by: Thomas Bogendoerfer --- arch/mips/generic/board-ingenic.c | 21 +++++++++++++++++++++ arch/mips/include/asm/bootinfo.h | 3 +++ arch/mips/include/asm/cpu.h | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/mips/generic/board-ingenic.c b/arch/mips/generic/board-ingenic.c index 0cec0bea13d6..e86e0016c548 100644 --- a/arch/mips/generic/board-ingenic.c +++ b/arch/mips/generic/board-ingenic.c @@ -21,6 +21,10 @@ static __init char *ingenic_get_system_type(unsigned long machtype) { switch (machtype) { + case MACH_INGENIC_X2100: + return "X2100"; + case MACH_INGENIC_X2000H: + return "X2000H"; case MACH_INGENIC_X2000E: return "X2000E"; case MACH_INGENIC_X2000: @@ -37,8 +41,18 @@ static __init char *ingenic_get_system_type(unsigned long machtype) return "JZ4775"; case MACH_INGENIC_JZ4770: return "JZ4770"; + case MACH_INGENIC_JZ4760B: + return "JZ4760B"; + case MACH_INGENIC_JZ4760: + return "JZ4760"; + case MACH_INGENIC_JZ4755: + return "JZ4755"; + case MACH_INGENIC_JZ4750: + return "JZ4750"; case MACH_INGENIC_JZ4725B: return "JZ4725B"; + case MACH_INGENIC_JZ4730: + return "JZ4730"; default: return "JZ4740"; } @@ -61,8 +75,13 @@ static __init const void *ingenic_fixup_fdt(const void *fdt, const void *match_d } static const struct of_device_id ingenic_of_match[] __initconst = { + { .compatible = "ingenic,jz4730", .data = (void *)MACH_INGENIC_JZ4730 }, { .compatible = "ingenic,jz4740", .data = (void *)MACH_INGENIC_JZ4740 }, { .compatible = "ingenic,jz4725b", .data = (void *)MACH_INGENIC_JZ4725B }, + { .compatible = "ingenic,jz4750", .data = (void *)MACH_INGENIC_JZ4750 }, + { .compatible = "ingenic,jz4755", .data = (void *)MACH_INGENIC_JZ4755 }, + { .compatible = "ingenic,jz4760", .data = (void *)MACH_INGENIC_JZ4760 }, + { .compatible = "ingenic,jz4760b", .data = (void *)MACH_INGENIC_JZ4760B }, { .compatible = "ingenic,jz4770", .data = (void *)MACH_INGENIC_JZ4770 }, { .compatible = "ingenic,jz4775", .data = (void *)MACH_INGENIC_JZ4775 }, { .compatible = "ingenic,jz4780", .data = (void *)MACH_INGENIC_JZ4780 }, @@ -71,6 +90,8 @@ static const struct of_device_id ingenic_of_match[] __initconst = { { .compatible = "ingenic,x1830", .data = (void *)MACH_INGENIC_X1830 }, { .compatible = "ingenic,x2000", .data = (void *)MACH_INGENIC_X2000 }, { .compatible = "ingenic,x2000e", .data = (void *)MACH_INGENIC_X2000E }, + { .compatible = "ingenic,x2000h", .data = (void *)MACH_INGENIC_X2000H }, + { .compatible = "ingenic,x2100", .data = (void *)MACH_INGENIC_X2100 }, {} }; diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 4c2e8173e6ec..2128ba903391 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h @@ -75,6 +75,7 @@ enum ingenic_machine_type { MACH_INGENIC_JZ4750, MACH_INGENIC_JZ4755, MACH_INGENIC_JZ4760, + MACH_INGENIC_JZ4760B, MACH_INGENIC_JZ4770, MACH_INGENIC_JZ4775, MACH_INGENIC_JZ4780, @@ -83,6 +84,8 @@ enum ingenic_machine_type { MACH_INGENIC_X1830, MACH_INGENIC_X2000, MACH_INGENIC_X2000E, + MACH_INGENIC_X2000H, + MACH_INGENIC_X2100, }; extern char *system_type; diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 9e6211e6d76b..d45a52f65b7a 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -46,8 +46,8 @@ #define PRID_COMP_NETLOGIC 0x0c0000 #define PRID_COMP_CAVIUM 0x0d0000 #define PRID_COMP_LOONGSON 0x140000 -#define PRID_COMP_INGENIC_13 0x130000 /* X2000 */ -#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750, X1830 */ +#define PRID_COMP_INGENIC_13 0x130000 /* X2000, X2100 */ +#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4730, JZ4740, JZ4750, JZ4755, JZ4760, X1830 */ #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */ #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ -- cgit v1.2.3-70-g09d2 From e98b461bb057aaea6fa766260788c08825213837 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 13 Jul 2021 10:49:15 -0700 Subject: MIPS: octeon: Remove vestiges of CONFIG_CAVIUM_RESERVE32 The config option CAVIUM_RESERVE32 is not used. Remove the dead code controlled by it. Signed-off-by: Joe Perches Signed-off-by: Thomas Bogendoerfer --- arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c | 21 +++--------- arch/mips/cavium-octeon/setup.c | 38 +--------------------- 2 files changed, 5 insertions(+), 54 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c index 3839feba68f2..fb42e8e21ea0 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c +++ b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c @@ -57,27 +57,14 @@ EXPORT_SYMBOL_GPL(__cvmx_cmd_queue_state_ptr); static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void) { char *alloc_name = "cvmx_cmd_queues"; -#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32 - extern uint64_t octeon_reserve32_memory; -#endif if (likely(__cvmx_cmd_queue_state_ptr)) return CVMX_CMD_QUEUE_SUCCESS; -#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32 - if (octeon_reserve32_memory) - __cvmx_cmd_queue_state_ptr = - cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr), - octeon_reserve32_memory, - octeon_reserve32_memory + - (CONFIG_CAVIUM_RESERVE32 << - 20) - 1, 128, alloc_name); - else -#endif - __cvmx_cmd_queue_state_ptr = - cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr), - 128, - alloc_name); + __cvmx_cmd_queue_state_ptr = + cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr), + 128, + alloc_name); if (__cvmx_cmd_queue_state_ptr) memset(__cvmx_cmd_queue_state_ptr, 0, sizeof(*__cvmx_cmd_queue_state_ptr)); diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index ce4e2806159b..0ddd3cc16ee4 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -284,11 +284,6 @@ void octeon_crash_smp_send_stop(void) #endif /* CONFIG_KEXEC */ -#ifdef CONFIG_CAVIUM_RESERVE32 -uint64_t octeon_reserve32_memory; -EXPORT_SYMBOL(octeon_reserve32_memory); -#endif - #ifdef CONFIG_KEXEC /* crashkernel cmdline parameter is parsed _after_ memory setup * we also parse it here (workaround for EHB5200) */ @@ -665,9 +660,7 @@ void __init prom_init(void) int i; u64 t; int argc; -#ifdef CONFIG_CAVIUM_RESERVE32 - int64_t addr = -1; -#endif + /* * The bootloader passes a pointer to the boot descriptor in * $a3, this is available as fw_arg3. @@ -782,25 +775,6 @@ void __init prom_init(void) cvmx_write_csr(CVMX_LED_UDD_DATX(1), 0); cvmx_write_csr(CVMX_LED_EN, 1); } -#ifdef CONFIG_CAVIUM_RESERVE32 - /* - * We need to temporarily allocate all memory in the reserve32 - * region. This makes sure the kernel doesn't allocate this - * memory when it is getting memory from the - * bootloader. Later, after the memory allocations are - * complete, the reserve32 will be freed. - * - * Allocate memory for RESERVED32 aligned on 2MB boundary. This - * is in case we later use hugetlb entries with it. - */ - addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20, - 0, 0, 2 << 20, - "CAVIUM_RESERVE32", 0); - if (addr < 0) - pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n"); - else - octeon_reserve32_memory = addr; -#endif #ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2 if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) { @@ -1078,16 +1052,6 @@ void __init plat_mem_setup(void) cvmx_bootmem_unlock(); #endif /* CONFIG_CRASH_DUMP */ -#ifdef CONFIG_CAVIUM_RESERVE32 - /* - * Now that we've allocated the kernel memory it is safe to - * free the reserved region. We free it here so that builtin - * drivers can use the memory. - */ - if (octeon_reserve32_memory) - cvmx_bootmem_free_named("CAVIUM_RESERVE32"); -#endif /* CONFIG_CAVIUM_RESERVE32 */ - if (total == 0) panic("Unable to allocate memory from " "cvmx_bootmem_phy_alloc"); -- cgit v1.2.3-70-g09d2 From 4c5afb74d9450edc2e2e37243b469cc278b120d4 Mon Sep 17 00:00:00 2001 From: Reiner Huober Date: Tue, 6 Jul 2021 15:02:52 +0200 Subject: module: combine constructors in module linker script The constructor code for modules must be aware of init code inside different sections. Newer GCC compilers write constructors in more than one section, e.g. ".ctors.65435". These must be combined into a single ".ctors" section. In the module loader, only the ".ctors" section is searched and the constructors therein are initialized, when CONFIG_CONSTRUCTORS=y is set. Other constructors are ignored. This change combines all ".ctors.*" and the ".ctors" section, if any, in .ko into a single ."ctors" section. For code coverage in GCC, this is necessary to show the code coverage for modules, since code coverage uses such constructors when initializing a module in newer version of GCC. Signed-off-by: Reiner Huober Signed-off-by: Jessica Yu --- scripts/module.lds.S | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 04c5685c25cf..1d0e1e4dc3d2 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -24,6 +24,7 @@ SECTIONS { __kcrctab 0 : { *(SORT(___kcrctab+*)) } __kcrctab_gpl 0 : { *(SORT(___kcrctab_gpl+*)) } + .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } -- cgit v1.2.3-70-g09d2 From feb704bd17786c8ff52a49d7759b8ee4f3a5aaac Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:34 -0400 Subject: fs: dlm: use sk->sk_socket instead of con->sock Instead of dereference "con->sock" we can get the socket structure over "sk->sk_socket" as well. This patch will switch to this behaviour. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 0ea9ae35da0b..bf309c12a2c0 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -583,8 +583,7 @@ static void lowcomms_error_report(struct sock *sk) goto out; orig_report = listen_sock.sk_error_report; - if (con->sock == NULL || - kernel_getpeername(con->sock, (struct sockaddr *)&saddr) < 0) { + if (kernel_getpeername(sk->sk_socket, (struct sockaddr *)&saddr) < 0) { printk_ratelimited(KERN_ERR "dlm: node %d: socket error " "sending to node %d, port %d, " "sk_err=%d/%d\n", dlm_our_nodeid(), -- cgit v1.2.3-70-g09d2 From d921a23f3e1a703875db436cc7cdb4404cf1565f Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:35 -0400 Subject: fs: dlm: use READ_ONCE for config var This patch will use READ_ONCE to signal the compiler to read this variable only one time. If we don't do that it could be that the compiler read this value more than one time, because some optimizations, from the configure data which might can be changed during this time. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lockspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index d71aba8c3e64..23c2d7308050 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -498,7 +498,7 @@ static int new_lockspace(const char *name, const char *cluster, ls->ls_exflags = (flags & ~(DLM_LSFL_TIMEWARN | DLM_LSFL_FS | DLM_LSFL_NEWEXCL)); - size = dlm_config.ci_rsbtbl_size; + size = READ_ONCE(dlm_config.ci_rsbtbl_size); ls->ls_rsbtbl_size = size; ls->ls_rsbtbl = vmalloc(array_size(size, sizeof(struct dlm_rsbtable))); -- cgit v1.2.3-70-g09d2 From b892e4792c992a0d5a272c3bdd6155bf772acfa7 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:36 -0400 Subject: fs: dlm: fix typo in tlv prefix This patch fixes a small typo in a unused struct field. It should named be t_pad instead of o_pad. Came over this as I updated wireshark dissector. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/dlm_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 91d1ca3a121a..5f57538b5d45 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -468,7 +468,7 @@ struct dlm_rcom { struct dlm_opt_header { uint16_t t_type; uint16_t t_length; - uint32_t o_pad; + uint32_t t_pad; /* need to be 8 byte aligned */ char t_value[]; }; -- cgit v1.2.3-70-g09d2 From 052849beeab02306d1420d03da959e7db883b375 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:37 -0400 Subject: fs: dlm: clear CF_APP_LIMITED on close If send_to_sock() sets CF_APP_LIMITED limited bit and it has not been cleared by a waiting lowcomms_write_space() yet and a close_connection() apprears we should clear the CF_APP_LIMITED bit again because the connection starts from a new state again at reconnect. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index bf309c12a2c0..1bdd24bce709 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -800,6 +800,7 @@ static void close_connection(struct connection *con, bool and_other, con->rx_leftover = 0; con->retries = 0; + clear_bit(CF_APP_LIMITED, &con->flags); clear_bit(CF_CONNECTED, &con->flags); clear_bit(CF_DELAY_CONNECT, &con->flags); clear_bit(CF_RECONNECT, &con->flags); -- cgit v1.2.3-70-g09d2 From 88aa023a2556aae92664f135eae794be9449e4f3 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:38 -0400 Subject: fs: dlm: cleanup and remove _send_rcom The _send_rcom() can be removed and we call directly dlm_rcom_out(). As we doing that we removing the struct dlm_ls parameter which isn't used. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/rcom.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 5651933f54a4..6cba86470278 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -89,22 +89,15 @@ static int create_rcom_stateless(struct dlm_ls *ls, int to_nodeid, int type, return 0; } -static void _send_rcom(struct dlm_ls *ls, struct dlm_rcom *rc) +static void send_rcom(struct dlm_mhandle *mh, struct dlm_rcom *rc) { dlm_rcom_out(rc); -} - -static void send_rcom(struct dlm_ls *ls, struct dlm_mhandle *mh, - struct dlm_rcom *rc) -{ - _send_rcom(ls, rc); dlm_midcomms_commit_mhandle(mh); } -static void send_rcom_stateless(struct dlm_ls *ls, struct dlm_msg *msg, - struct dlm_rcom *rc) +static void send_rcom_stateless(struct dlm_msg *msg, struct dlm_rcom *rc) { - _send_rcom(ls, rc); + dlm_rcom_out(rc); dlm_lowcomms_commit_msg(msg); dlm_lowcomms_put_msg(msg); } @@ -204,7 +197,7 @@ retry: allow_sync_reply(ls, &rc->rc_id); memset(ls->ls_recover_buf, 0, DLM_MAX_SOCKET_BUFSIZE); - send_rcom_stateless(ls, msg, rc); + send_rcom_stateless(msg, rc); error = dlm_wait_function(ls, &rcom_response); disallow_sync_reply(ls); @@ -287,7 +280,7 @@ static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in) spin_unlock(&ls->ls_recover_lock); do_send: - send_rcom_stateless(ls, msg, rc); + send_rcom_stateless(msg, rc); } static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) @@ -327,7 +320,7 @@ retry: allow_sync_reply(ls, &rc->rc_id); memset(ls->ls_recover_buf, 0, DLM_MAX_SOCKET_BUFSIZE); - send_rcom_stateless(ls, msg, rc); + send_rcom_stateless(msg, rc); error = dlm_wait_function(ls, &rcom_response); disallow_sync_reply(ls); @@ -356,7 +349,7 @@ static void receive_rcom_names(struct dlm_ls *ls, struct dlm_rcom *rc_in) dlm_copy_master_names(ls, rc_in->rc_buf, inlen, rc->rc_buf, outlen, nodeid); - send_rcom_stateless(ls, msg, rc); + send_rcom_stateless(msg, rc); } int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) @@ -373,7 +366,7 @@ int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid) memcpy(rc->rc_buf, r->res_name, r->res_length); rc->rc_id = (unsigned long) r->res_id; - send_rcom(ls, mh, rc); + send_rcom(mh, rc); out: return error; } @@ -404,7 +397,7 @@ static void receive_rcom_lookup(struct dlm_ls *ls, struct dlm_rcom *rc_in) rc->rc_id = rc_in->rc_id; rc->rc_seq_reply = rc_in->rc_seq; - send_rcom(ls, mh, rc); + send_rcom(mh, rc); } static void receive_rcom_lookup_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) @@ -461,7 +454,7 @@ int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb) pack_rcom_lock(r, lkb, rl); rc->rc_id = (unsigned long) r; - send_rcom(ls, mh, rc); + send_rcom(mh, rc); out: return error; } @@ -487,7 +480,7 @@ static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) rc->rc_id = rc_in->rc_id; rc->rc_seq_reply = rc_in->rc_seq; - send_rcom(ls, mh, rc); + send_rcom(mh, rc); } /* If the lockspace doesn't exist then still send a status message -- cgit v1.2.3-70-g09d2 From 66d5955a098d504b5a34c35d56a967c536264673 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:39 -0400 Subject: fs: dlm: introduce con_next_wq helper This patch introduce a function to determine if something is ready to being send in the writequeue. It's not just that the writequeue is not empty additional the first entry need to have a valid length field. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 57 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 1bdd24bce709..9d21a8b9e9fb 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -175,6 +175,22 @@ static void sctp_connect_to_sock(struct connection *con); static void tcp_connect_to_sock(struct connection *con); static void dlm_tcp_shutdown(struct connection *con); +/* need to held writequeue_lock */ +static struct writequeue_entry *con_next_wq(struct connection *con) +{ + struct writequeue_entry *e; + + if (list_empty(&con->writequeue)) + return NULL; + + e = list_first_entry(&con->writequeue, struct writequeue_entry, + list); + if (e->len == 0) + return NULL; + + return e; +} + static struct connection *__find_con(int nodeid, int r) { struct connection *con; @@ -1646,10 +1662,9 @@ int dlm_lowcomms_resend_msg(struct dlm_msg *msg) /* Send a message */ static void send_to_sock(struct connection *con) { - int ret = 0; const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; struct writequeue_entry *e; - int len, offset; + int len, offset, ret; int count = 0; mutex_lock(&con->sock_mutex); @@ -1658,7 +1673,8 @@ static void send_to_sock(struct connection *con) spin_lock(&con->writequeue_lock); for (;;) { - if (list_empty(&con->writequeue)) + e = con_next_wq(con); + if (!e) break; e = list_first_entry(&con->writequeue, struct writequeue_entry, list); @@ -1667,25 +1683,22 @@ static void send_to_sock(struct connection *con) BUG_ON(len == 0 && e->users == 0); spin_unlock(&con->writequeue_lock); - ret = 0; - if (len) { - ret = kernel_sendpage(con->sock, e->page, offset, len, - msg_flags); - if (ret == -EAGAIN || ret == 0) { - if (ret == -EAGAIN && - test_bit(SOCKWQ_ASYNC_NOSPACE, &con->sock->flags) && - !test_and_set_bit(CF_APP_LIMITED, &con->flags)) { - /* Notify TCP that we're limited by the - * application window size. - */ - set_bit(SOCK_NOSPACE, &con->sock->flags); - con->sock->sk->sk_write_pending++; - } - cond_resched(); - goto out; - } else if (ret < 0) - goto out; - } + ret = kernel_sendpage(con->sock, e->page, offset, len, + msg_flags); + if (ret == -EAGAIN || ret == 0) { + if (ret == -EAGAIN && + test_bit(SOCKWQ_ASYNC_NOSPACE, &con->sock->flags) && + !test_and_set_bit(CF_APP_LIMITED, &con->flags)) { + /* Notify TCP that we're limited by the + * application window size. + */ + set_bit(SOCK_NOSPACE, &con->sock->flags); + con->sock->sk->sk_write_pending++; + } + cond_resched(); + goto out; + } else if (ret < 0) + goto out; /* Don't starve people filling buffers */ if (++count >= MAX_SEND_MSG_COUNT) { -- cgit v1.2.3-70-g09d2 From a66c008cd16a122e340d48f01ddf8cd768368717 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:40 -0400 Subject: fs: dlm: move to static proto ops This patch moves the per transport socket callbacks to a static const array. We can support only one transport socket for the init namespace which will be determinted by reading the dlm config at lowcomms_start(). Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 9d21a8b9e9fb..9a4e7421567e 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -84,9 +84,6 @@ struct connection { struct list_head writequeue; /* List of outgoing writequeue_entries */ spinlock_t writequeue_lock; atomic_t writequeue_cnt; - void (*connect_action) (struct connection *); /* What to do to connect */ - void (*shutdown_action)(struct connection *con); /* What to do to shutdown */ - bool (*eof_condition)(struct connection *con); /* What to do to eof check */ int retries; #define MAX_CONNECT_RETRIES 3 struct hlist_node list; @@ -145,6 +142,15 @@ struct dlm_node_addr { struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT]; }; +struct dlm_proto_ops { + /* What to do to connect */ + void (*connect_action)(struct connection *con); + /* What to do to shutdown */ + void (*shutdown_action)(struct connection *con); + /* What to do to eof check */ + bool (*eof_condition)(struct connection *con); +}; + static struct listen_sock_callbacks { void (*sk_error_report)(struct sock *); void (*sk_data_ready)(struct sock *); @@ -168,12 +174,13 @@ static struct hlist_head connection_hash[CONN_HASH_SIZE]; static DEFINE_SPINLOCK(connections_lock); DEFINE_STATIC_SRCU(connections_srcu); +static const struct dlm_proto_ops *dlm_proto_ops; + static void process_recv_sockets(struct work_struct *work); static void process_send_sockets(struct work_struct *work); static void sctp_connect_to_sock(struct connection *con); static void tcp_connect_to_sock(struct connection *con); -static void dlm_tcp_shutdown(struct connection *con); /* need to held writequeue_lock */ static struct writequeue_entry *con_next_wq(struct connection *con) @@ -224,20 +231,6 @@ static int dlm_con_init(struct connection *con, int nodeid) INIT_WORK(&con->rwork, process_recv_sockets); init_waitqueue_head(&con->shutdown_wait); - switch (dlm_config.ci_protocol) { - case DLM_PROTO_TCP: - con->connect_action = tcp_connect_to_sock; - con->shutdown_action = dlm_tcp_shutdown; - con->eof_condition = tcp_eof_condition; - break; - case DLM_PROTO_SCTP: - con->connect_action = sctp_connect_to_sock; - break; - default: - kfree(con->rx_buf); - return -EINVAL; - } - return 0; } @@ -962,7 +955,8 @@ out_close: log_print("connection %p got EOF from %d", con, con->nodeid); - if (con->eof_condition && con->eof_condition(con)) { + if (dlm_proto_ops->eof_condition && + dlm_proto_ops->eof_condition(con)) { set_bit(CF_EOF, &con->flags); mutex_unlock(&con->sock_mutex); } else { @@ -1813,7 +1807,7 @@ static void process_send_sockets(struct work_struct *work) if (con->sock == NULL) { /* not mutex protected so check it inside too */ if (test_and_clear_bit(CF_DELAY_CONNECT, &con->flags)) msleep(1000); - con->connect_action(con); + dlm_proto_ops->connect_action(con); } if (!list_empty(&con->writequeue)) send_to_sock(con); @@ -1853,8 +1847,8 @@ static int work_start(void) static void shutdown_conn(struct connection *con) { - if (con->shutdown_action) - con->shutdown_action(con); + if (dlm_proto_ops->shutdown_action) + dlm_proto_ops->shutdown_action(con); } void dlm_lowcomms_shutdown(void) @@ -1961,8 +1955,20 @@ void dlm_lowcomms_stop(void) srcu_read_unlock(&connections_srcu, idx); work_stop(); deinit_local(); + + dlm_proto_ops = NULL; } +static const struct dlm_proto_ops dlm_tcp_ops = { + .connect_action = tcp_connect_to_sock, + .shutdown_action = dlm_tcp_shutdown, + .eof_condition = tcp_eof_condition, +}; + +static const struct dlm_proto_ops dlm_sctp_ops = { + .connect_action = sctp_connect_to_sock, +}; + int dlm_lowcomms_start(void) { int error = -EINVAL; @@ -1989,9 +1995,11 @@ int dlm_lowcomms_start(void) /* Start listening */ switch (dlm_config.ci_protocol) { case DLM_PROTO_TCP: + dlm_proto_ops = &dlm_tcp_ops; error = tcp_listen_for_all(); break; case DLM_PROTO_SCTP: + dlm_proto_ops = &dlm_sctp_ops; error = sctp_listen_for_all(&listen_con); break; default: -- cgit v1.2.3-70-g09d2 From 2dc6b1158c28c3a5e86d162628810312f98d5e97 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:41 -0400 Subject: fs: dlm: introduce generic listen This patch combines each transport layer listen functionality into one listen function. Per transport layer differences are provided by additional callbacks in dlm_proto_ops. This patch drops silently sock_set_keepalive() for listen tcp sockets only. This socket option is not set at connecting sockets, I also don't see the sense of set keepalive for sockets which are created by accept() only. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 228 +++++++++++++++++++++++++++--------------------------- 1 file changed, 113 insertions(+), 115 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 9a4e7421567e..a042ea413f74 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -143,6 +143,13 @@ struct dlm_node_addr { }; struct dlm_proto_ops { + const char *name; + int proto; + + int (*listen_validate)(void); + void (*listen_sockopts)(struct socket *sock); + int (*listen_bind)(struct socket *sock); + /* What to do to connect */ void (*connect_action)(struct connection *con); /* What to do to shutdown */ @@ -1327,59 +1334,6 @@ out: return; } -/* On error caller must run dlm_close_sock() for the - * listen connection socket. - */ -static int tcp_create_listen_sock(struct listen_connection *con, - struct sockaddr_storage *saddr) -{ - struct socket *sock = NULL; - int result = 0; - int addr_len; - - if (dlm_local_addr[0]->ss_family == AF_INET) - addr_len = sizeof(struct sockaddr_in); - else - addr_len = sizeof(struct sockaddr_in6); - - /* Create a socket to communicate with */ - result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, - SOCK_STREAM, IPPROTO_TCP, &sock); - if (result < 0) { - log_print("Can't create listening comms socket"); - goto create_out; - } - - sock_set_mark(sock->sk, dlm_config.ci_mark); - - /* Turn off Nagle's algorithm */ - tcp_sock_set_nodelay(sock->sk); - - sock_set_reuseaddr(sock->sk); - - add_listen_sock(sock, con); - - /* Bind to our port */ - make_sockaddr(saddr, dlm_config.ci_tcp_port, &addr_len); - result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len); - if (result < 0) { - log_print("Can't bind to port %d", dlm_config.ci_tcp_port); - goto create_out; - } - sock_set_keepalive(sock->sk); - - result = sock->ops->listen(sock, 5); - if (result < 0) { - log_print("Can't listen on port %d", dlm_config.ci_tcp_port); - goto create_out; - } - - return 0; - -create_out: - return result; -} - /* Get local addresses */ static void init_local(void) { @@ -1406,63 +1360,6 @@ static void deinit_local(void) kfree(dlm_local_addr[i]); } -/* Initialise SCTP socket and bind to all interfaces - * On error caller must run dlm_close_sock() for the - * listen connection socket. - */ -static int sctp_listen_for_all(struct listen_connection *con) -{ - struct socket *sock = NULL; - int result = -EINVAL; - - log_print("Using SCTP for communications"); - - result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, - SOCK_STREAM, IPPROTO_SCTP, &sock); - if (result < 0) { - log_print("Can't create comms socket, check SCTP is loaded"); - goto out; - } - - sock_set_rcvbuf(sock->sk, NEEDED_RMEM); - sock_set_mark(sock->sk, dlm_config.ci_mark); - sctp_sock_set_nodelay(sock->sk); - - add_listen_sock(sock, con); - - /* Bind to all addresses. */ - result = sctp_bind_addrs(con->sock, dlm_config.ci_tcp_port); - if (result < 0) - goto out; - - result = sock->ops->listen(sock, 5); - if (result < 0) { - log_print("Can't set socket listening"); - goto out; - } - - return 0; - -out: - return result; -} - -static int tcp_listen_for_all(void) -{ - /* We don't support multi-homed hosts */ - if (dlm_local_count > 1) { - log_print("TCP protocol can't handle multi-homed hosts, " - "try SCTP"); - return -EINVAL; - } - - log_print("Using TCP for communications"); - - return tcp_create_listen_sock(&listen_con, dlm_local_addr[0]); -} - - - static struct writequeue_entry *new_writequeue_entry(struct connection *con, gfp_t allocation) { @@ -1959,13 +1856,112 @@ void dlm_lowcomms_stop(void) dlm_proto_ops = NULL; } +static int dlm_listen_for_all(void) +{ + struct socket *sock; + int result; + + log_print("Using %s for communications", + dlm_proto_ops->name); + + if (dlm_proto_ops->listen_validate) { + result = dlm_proto_ops->listen_validate(); + if (result < 0) + return result; + } + + result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, + SOCK_STREAM, dlm_proto_ops->proto, &sock); + if (result < 0) { + log_print("Can't create comms socket, check SCTP is loaded"); + goto out; + } + + sock_set_mark(sock->sk, dlm_config.ci_mark); + dlm_proto_ops->listen_sockopts(sock); + + result = dlm_proto_ops->listen_bind(sock); + if (result < 0) + goto out; + + save_listen_callbacks(sock); + add_listen_sock(sock, &listen_con); + + INIT_WORK(&listen_con.rwork, process_listen_recv_socket); + result = sock->ops->listen(sock, 5); + if (result < 0) { + dlm_close_sock(&listen_con.sock); + goto out; + } + + return 0; + +out: + sock_release(sock); + return result; +} + +static int dlm_tcp_listen_validate(void) +{ + /* We don't support multi-homed hosts */ + if (dlm_local_count > 1) { + log_print("TCP protocol can't handle multi-homed hosts, try SCTP"); + return -EINVAL; + } + + return 0; +} + +static void dlm_tcp_sockopts(struct socket *sock) +{ + /* Turn off Nagle's algorithm */ + tcp_sock_set_nodelay(sock->sk); +} + +static void dlm_tcp_listen_sockopts(struct socket *sock) +{ + dlm_tcp_sockopts(sock); + sock_set_reuseaddr(sock->sk); +} + +static int dlm_tcp_listen_bind(struct socket *sock) +{ + int addr_len; + + /* Bind to our port */ + make_sockaddr(dlm_local_addr[0], dlm_config.ci_tcp_port, &addr_len); + return sock->ops->bind(sock, (struct sockaddr *)dlm_local_addr[0], + addr_len); +} + static const struct dlm_proto_ops dlm_tcp_ops = { + .name = "TCP", + .proto = IPPROTO_TCP, + .listen_validate = dlm_tcp_listen_validate, + .listen_sockopts = dlm_tcp_listen_sockopts, + .listen_bind = dlm_tcp_listen_bind, .connect_action = tcp_connect_to_sock, .shutdown_action = dlm_tcp_shutdown, .eof_condition = tcp_eof_condition, }; +static int dlm_sctp_bind_listen(struct socket *sock) +{ + return sctp_bind_addrs(sock, dlm_config.ci_tcp_port); +} + +static void dlm_sctp_sockopts(struct socket *sock) +{ + /* Turn off Nagle's algorithm */ + sctp_sock_set_nodelay(sock->sk); + sock_set_rcvbuf(sock->sk, NEEDED_RMEM); +} + static const struct dlm_proto_ops dlm_sctp_ops = { + .name = "SCTP", + .proto = IPPROTO_SCTP, + .listen_sockopts = dlm_sctp_sockopts, + .listen_bind = dlm_sctp_bind_listen, .connect_action = sctp_connect_to_sock, }; @@ -1996,24 +1992,26 @@ int dlm_lowcomms_start(void) switch (dlm_config.ci_protocol) { case DLM_PROTO_TCP: dlm_proto_ops = &dlm_tcp_ops; - error = tcp_listen_for_all(); break; case DLM_PROTO_SCTP: dlm_proto_ops = &dlm_sctp_ops; - error = sctp_listen_for_all(&listen_con); break; default: log_print("Invalid protocol identifier %d set", dlm_config.ci_protocol); error = -EINVAL; - break; + goto fail_proto_ops; } + + error = dlm_listen_for_all(); if (error) - goto fail_unlisten; + goto fail_listen; return 0; -fail_unlisten: +fail_listen: + dlm_proto_ops = NULL; +fail_proto_ops: dlm_allow_conn = 0; dlm_close_sock(&listen_con.sock); work_stop(); -- cgit v1.2.3-70-g09d2 From 90d21fc0479dc0b5d338d664ddb55e5017b44f3e Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:42 -0400 Subject: fs: dlm: auto load sctp module This patch adds a "for now" better handling of missing SCTP support in the kernel and try to load the sctp module if SCTP is set. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index a042ea413f74..30d10d19ecac 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1864,11 +1864,9 @@ static int dlm_listen_for_all(void) log_print("Using %s for communications", dlm_proto_ops->name); - if (dlm_proto_ops->listen_validate) { - result = dlm_proto_ops->listen_validate(); - if (result < 0) - return result; - } + result = dlm_proto_ops->listen_validate(); + if (result < 0) + return result; result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, SOCK_STREAM, dlm_proto_ops->proto, &sock); @@ -1945,6 +1943,17 @@ static const struct dlm_proto_ops dlm_tcp_ops = { .eof_condition = tcp_eof_condition, }; +static int dlm_sctp_listen_validate(void) +{ + if (!IS_ENABLED(CONFIG_IP_SCTP)) { + log_print("SCTP is not enabled by this kernel"); + return -EOPNOTSUPP; + } + + request_module("sctp"); + return 0; +} + static int dlm_sctp_bind_listen(struct socket *sock) { return sctp_bind_addrs(sock, dlm_config.ci_tcp_port); @@ -1960,6 +1969,7 @@ static void dlm_sctp_sockopts(struct socket *sock) static const struct dlm_proto_ops dlm_sctp_ops = { .name = "SCTP", .proto = IPPROTO_SCTP, + .listen_validate = dlm_sctp_listen_validate, .listen_sockopts = dlm_sctp_sockopts, .listen_bind = dlm_sctp_bind_listen, .connect_action = sctp_connect_to_sock, -- cgit v1.2.3-70-g09d2 From 8728a455d20ddadecd767337475fc1371e031d79 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:43 -0400 Subject: fs: dlm: generic connect func This patch adds a generic connect function for TCP and SCTP. If the connect functionality differs from each other additional callbacks in dlm_proto_ops were added. The sockopts callback handling will guarantee that sockets created by connect() will use the same options as sockets created by accept(). Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 343 ++++++++++++++++++++++++------------------------------ 1 file changed, 150 insertions(+), 193 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 30d10d19ecac..75e702c3678c 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -143,15 +143,17 @@ struct dlm_node_addr { }; struct dlm_proto_ops { + bool try_new_addr; const char *name; int proto; + int (*connect)(struct connection *con, struct socket *sock, + struct sockaddr *addr, int addr_len); + void (*sockopts)(struct socket *sock); + int (*bind)(struct socket *sock); int (*listen_validate)(void); void (*listen_sockopts)(struct socket *sock); int (*listen_bind)(struct socket *sock); - - /* What to do to connect */ - void (*connect_action)(struct connection *con); /* What to do to shutdown */ void (*shutdown_action)(struct connection *con); /* What to do to eof check */ @@ -186,9 +188,6 @@ static const struct dlm_proto_ops *dlm_proto_ops; static void process_recv_sockets(struct work_struct *work); static void process_send_sockets(struct work_struct *work); -static void sctp_connect_to_sock(struct connection *con); -static void tcp_connect_to_sock(struct connection *con); - /* need to held writequeue_lock */ static struct writequeue_entry *con_next_wq(struct connection *con) { @@ -1151,189 +1150,6 @@ static int sctp_bind_addrs(struct socket *sock, uint16_t port) return result; } -/* Initiate an SCTP association. - This is a special case of send_to_sock() in that we don't yet have a - peeled-off socket for this association, so we use the listening socket - and add the primary IP address of the remote node. - */ -static void sctp_connect_to_sock(struct connection *con) -{ - struct sockaddr_storage daddr; - int result; - int addr_len; - struct socket *sock; - unsigned int mark; - - mutex_lock(&con->sock_mutex); - - /* Some odd races can cause double-connects, ignore them */ - if (con->retries++ > MAX_CONNECT_RETRIES) - goto out; - - if (con->sock) { - log_print("node %d already connected.", con->nodeid); - goto out; - } - - memset(&daddr, 0, sizeof(daddr)); - result = nodeid_to_addr(con->nodeid, &daddr, NULL, true, &mark); - if (result < 0) { - log_print("no address for nodeid %d", con->nodeid); - goto out; - } - - /* Create a socket to communicate with */ - result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, - SOCK_STREAM, IPPROTO_SCTP, &sock); - if (result < 0) - goto socket_err; - - sock_set_mark(sock->sk, mark); - - add_sock(sock, con); - - /* Bind to all addresses. */ - if (sctp_bind_addrs(con->sock, 0)) - goto bind_err; - - make_sockaddr(&daddr, dlm_config.ci_tcp_port, &addr_len); - - log_print_ratelimited("connecting to %d", con->nodeid); - - /* Turn off Nagle's algorithm */ - sctp_sock_set_nodelay(sock->sk); - - /* - * Make sock->ops->connect() function return in specified time, - * since O_NONBLOCK argument in connect() function does not work here, - * then, we should restore the default value of this attribute. - */ - sock_set_sndtimeo(sock->sk, 5); - result = sock->ops->connect(sock, (struct sockaddr *)&daddr, addr_len, - 0); - sock_set_sndtimeo(sock->sk, 0); - - if (result == -EINPROGRESS) - result = 0; - if (result == 0) { - if (!test_and_set_bit(CF_CONNECTED, &con->flags)) - log_print("successful connected to node %d", con->nodeid); - goto out; - } - -bind_err: - con->sock = NULL; - sock_release(sock); - -socket_err: - /* - * Some errors are fatal and this list might need adjusting. For other - * errors we try again until the max number of retries is reached. - */ - if (result != -EHOSTUNREACH && - result != -ENETUNREACH && - result != -ENETDOWN && - result != -EINVAL && - result != -EPROTONOSUPPORT) { - log_print("connect %d try %d error %d", con->nodeid, - con->retries, result); - mutex_unlock(&con->sock_mutex); - msleep(1000); - lowcomms_connect_sock(con); - return; - } - -out: - mutex_unlock(&con->sock_mutex); -} - -/* Connect a new socket to its peer */ -static void tcp_connect_to_sock(struct connection *con) -{ - struct sockaddr_storage saddr, src_addr; - unsigned int mark; - int addr_len; - struct socket *sock = NULL; - int result; - - mutex_lock(&con->sock_mutex); - if (con->retries++ > MAX_CONNECT_RETRIES) - goto out; - - /* Some odd races can cause double-connects, ignore them */ - if (con->sock) - goto out; - - /* Create a socket to communicate with */ - result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, - SOCK_STREAM, IPPROTO_TCP, &sock); - if (result < 0) - goto out_err; - - memset(&saddr, 0, sizeof(saddr)); - result = nodeid_to_addr(con->nodeid, &saddr, NULL, false, &mark); - if (result < 0) { - log_print("no address for nodeid %d", con->nodeid); - goto out_err; - } - - sock_set_mark(sock->sk, mark); - - add_sock(sock, con); - - /* Bind to our cluster-known address connecting to avoid - routing problems */ - memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr)); - make_sockaddr(&src_addr, 0, &addr_len); - result = sock->ops->bind(sock, (struct sockaddr *) &src_addr, - addr_len); - if (result < 0) { - log_print("could not bind for connect: %d", result); - /* This *may* not indicate a critical error */ - } - - make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); - - log_print_ratelimited("connecting to %d", con->nodeid); - - /* Turn off Nagle's algorithm */ - tcp_sock_set_nodelay(sock->sk); - - result = sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, - O_NONBLOCK); - if (result == -EINPROGRESS) - result = 0; - if (result == 0) - goto out; - -out_err: - if (con->sock) { - sock_release(con->sock); - con->sock = NULL; - } else if (sock) { - sock_release(sock); - } - /* - * Some errors are fatal and this list might need adjusting. For other - * errors we try again until the max number of retries is reached. - */ - if (result != -EHOSTUNREACH && - result != -ENETUNREACH && - result != -ENETDOWN && - result != -EINVAL && - result != -EPROTONOSUPPORT) { - log_print("connect %d try %d error %d", con->nodeid, - con->retries, result); - mutex_unlock(&con->sock_mutex); - msleep(1000); - lowcomms_connect_sock(con); - return; - } -out: - mutex_unlock(&con->sock_mutex); - return; -} - /* Get local addresses */ static void init_local(void) { @@ -1687,6 +1503,74 @@ static void process_listen_recv_socket(struct work_struct *work) accept_from_sock(&listen_con); } +static void dlm_connect(struct connection *con) +{ + struct sockaddr_storage addr; + int result, addr_len; + struct socket *sock; + unsigned int mark; + + /* Some odd races can cause double-connects, ignore them */ + if (con->retries++ > MAX_CONNECT_RETRIES) + return; + + if (con->sock) { + log_print("node %d already connected.", con->nodeid); + return; + } + + memset(&addr, 0, sizeof(addr)); + result = nodeid_to_addr(con->nodeid, &addr, NULL, + dlm_proto_ops->try_new_addr, &mark); + if (result < 0) { + log_print("no address for nodeid %d", con->nodeid); + return; + } + + /* Create a socket to communicate with */ + result = sock_create_kern(&init_net, dlm_local_addr[0]->ss_family, + SOCK_STREAM, dlm_proto_ops->proto, &sock); + if (result < 0) + goto socket_err; + + sock_set_mark(sock->sk, mark); + dlm_proto_ops->sockopts(sock); + + add_sock(sock, con); + + result = dlm_proto_ops->bind(sock); + if (result < 0) + goto add_sock_err; + + log_print_ratelimited("connecting to %d", con->nodeid); + make_sockaddr(&addr, dlm_config.ci_tcp_port, &addr_len); + result = dlm_proto_ops->connect(con, sock, (struct sockaddr *)&addr, + addr_len); + if (result < 0) + goto add_sock_err; + + return; + +add_sock_err: + dlm_close_sock(&con->sock); + +socket_err: + /* + * Some errors are fatal and this list might need adjusting. For other + * errors we try again until the max number of retries is reached. + */ + if (result != -EHOSTUNREACH && + result != -ENETUNREACH && + result != -ENETDOWN && + result != -EINVAL && + result != -EPROTONOSUPPORT) { + log_print("connect %d try %d error %d", con->nodeid, + con->retries, result); + msleep(1000); + lowcomms_connect_sock(con); + } +} + /* Send workqueue function */ static void process_send_sockets(struct work_struct *work) { @@ -1701,11 +1585,15 @@ static void process_send_sockets(struct work_struct *work) dlm_midcomms_unack_msg_resend(con->nodeid); } - if (con->sock == NULL) { /* not mutex protected so check it inside too */ + if (con->sock == NULL) { if (test_and_clear_bit(CF_DELAY_CONNECT, &con->flags)) msleep(1000); - dlm_proto_ops->connect_action(con); + + mutex_lock(&con->sock_mutex); + dlm_connect(con); + mutex_unlock(&con->sock_mutex); } + if (!list_empty(&con->writequeue)) send_to_sock(con); } @@ -1899,6 +1787,43 @@ out: return result; } +static int dlm_tcp_bind(struct socket *sock) +{ + struct sockaddr_storage src_addr; + int result, addr_len; + + /* Bind to our cluster-known address connecting to avoid + * routing problems. + */ + memcpy(&src_addr, dlm_local_addr[0], sizeof(src_addr)); + make_sockaddr(&src_addr, 0, &addr_len); + + result = sock->ops->bind(sock, (struct sockaddr *)&src_addr, + addr_len); + if (result < 0) { + /* This *may* not indicate a critical error */ + log_print("could not bind for connect: %d", result); + } + + return 0; +} + +static int dlm_tcp_connect(struct connection *con, struct socket *sock, + struct sockaddr *addr, int addr_len) +{ + int ret; + + ret = sock->ops->connect(sock, addr, addr_len, O_NONBLOCK); + switch (ret) { + case -EINPROGRESS: + fallthrough; + case 0: + return 0; + } + + return ret; +} + static int dlm_tcp_listen_validate(void) { /* We don't support multi-homed hosts */ @@ -1935,14 +1860,43 @@ static int dlm_tcp_listen_bind(struct socket *sock) static const struct dlm_proto_ops dlm_tcp_ops = { .name = "TCP", .proto = IPPROTO_TCP, + .connect = dlm_tcp_connect, + .sockopts = dlm_tcp_sockopts, + .bind = dlm_tcp_bind, .listen_validate = dlm_tcp_listen_validate, .listen_sockopts = dlm_tcp_listen_sockopts, .listen_bind = dlm_tcp_listen_bind, - .connect_action = tcp_connect_to_sock, .shutdown_action = dlm_tcp_shutdown, .eof_condition = tcp_eof_condition, }; +static int dlm_sctp_bind(struct socket *sock) +{ + return sctp_bind_addrs(sock, 0); +} + +static int dlm_sctp_connect(struct connection *con, struct socket *sock, + struct sockaddr *addr, int addr_len) +{ + int ret; + + /* + * Make sock->ops->connect() function return in specified time, + * since O_NONBLOCK argument in connect() function does not work here, + * then, we should restore the default value of this attribute. + */ + sock_set_sndtimeo(sock->sk, 5); + ret = sock->ops->connect(sock, addr, addr_len, 0); + sock_set_sndtimeo(sock->sk, 0); + if (ret < 0) + return ret; + + if (!test_and_set_bit(CF_CONNECTED, &con->flags)) + log_print("successful connected to node %d", con->nodeid); + + return 0; +} + static int dlm_sctp_listen_validate(void) { if (!IS_ENABLED(CONFIG_IP_SCTP)) { @@ -1969,10 +1923,13 @@ static void dlm_sctp_sockopts(struct socket *sock) static const struct dlm_proto_ops dlm_sctp_ops = { .name = "SCTP", .proto = IPPROTO_SCTP, + .try_new_addr = true, + .connect = dlm_sctp_connect, + .sockopts = dlm_sctp_sockopts, + .bind = dlm_sctp_bind, .listen_validate = dlm_sctp_listen_validate, .listen_sockopts = dlm_sctp_sockopts, .listen_bind = dlm_sctp_bind_listen, - .connect_action = sctp_connect_to_sock, }; int dlm_lowcomms_start(void) -- cgit v1.2.3-70-g09d2 From c51b0221798b695ac1beac6597d3a0acf039384b Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:44 -0400 Subject: fs: dlm: fix multiple empty writequeue alloc This patch will add a mutex that a connection can allocate a writequeue entry buffer only at a sleepable context at one time. If multiple caller waits at the writequeue spinlock and the spinlock gets release it could be that multiple new writequeue page buffers were allocated instead of allocate one writequeue page buffer and other waiters will use remaining buffer of it. It will only be the case for sleepable context which is the common case. In non-sleepable contexts like retransmission we just don't care about such behaviour. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 75e702c3678c..11e061619a9f 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -84,6 +84,7 @@ struct connection { struct list_head writequeue; /* List of outgoing writequeue_entries */ spinlock_t writequeue_lock; atomic_t writequeue_cnt; + struct mutex wq_alloc; int retries; #define MAX_CONNECT_RETRIES 3 struct hlist_node list; @@ -264,6 +265,8 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc) return NULL; } + mutex_init(&con->wq_alloc); + spin_lock(&connections_lock); /* Because multiple workqueues/threads calls this function it can * race on multiple cpu's. Instead of locking hot path __find_con() @@ -1251,19 +1254,37 @@ static struct dlm_msg *dlm_lowcomms_new_msg_con(struct connection *con, int len, { struct writequeue_entry *e; struct dlm_msg *msg; + bool sleepable; msg = kzalloc(sizeof(*msg), allocation); if (!msg) return NULL; + /* this mutex is being used as a wait to avoid multiple "fast" + * new writequeue page list entry allocs in new_wq_entry in + * normal operation which is sleepable context. Without it + * we could end in multiple writequeue entries with one + * dlm message because multiple callers were waiting at + * the writequeue_lock in new_wq_entry(). + */ + sleepable = gfpflags_normal_context(allocation); + if (sleepable) + mutex_lock(&con->wq_alloc); + kref_init(&msg->ref); e = new_wq_entry(con, len, allocation, ppc, cb, mh); if (!e) { + if (sleepable) + mutex_unlock(&con->wq_alloc); + kfree(msg); return NULL; } + if (sleepable) + mutex_unlock(&con->wq_alloc); + msg->ppc = *ppc; msg->len = len; msg->entry = e; -- cgit v1.2.3-70-g09d2 From 62699b3f0a62435fceb8debf295e90a5ea259e04 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Fri, 16 Jul 2021 16:22:45 -0400 Subject: fs: dlm: move receive loop into receive handler This patch moves the kernel_recvmsg() loop call into the receive_from_sock() function instead of doing the loop outside the function and abort the loop over it's return value. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 68 +++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 11e061619a9f..cce1d50aa09f 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -895,7 +895,6 @@ static int con_realloc_receive_buf(struct connection *con, int newlen) /* Data received from remote end */ static int receive_from_sock(struct connection *con) { - int call_again_soon = 0; struct msghdr msg; struct kvec iov; int ret, buflen; @@ -915,41 +914,39 @@ static int receive_from_sock(struct connection *con) goto out_resched; } - /* calculate new buffer parameter regarding last receive and - * possible leftover bytes - */ - iov.iov_base = con->rx_buf + con->rx_leftover; - iov.iov_len = con->rx_buflen - con->rx_leftover; - - memset(&msg, 0, sizeof(msg)); - msg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; - ret = kernel_recvmsg(con->sock, &msg, &iov, 1, iov.iov_len, - msg.msg_flags); - if (ret <= 0) - goto out_close; - else if (ret == iov.iov_len) - call_again_soon = 1; - - /* new buflen according readed bytes and leftover from last receive */ - buflen = ret + con->rx_leftover; - ret = dlm_process_incoming_buffer(con->nodeid, con->rx_buf, buflen); - if (ret < 0) - goto out_close; + for (;;) { + /* calculate new buffer parameter regarding last receive and + * possible leftover bytes + */ + iov.iov_base = con->rx_buf + con->rx_leftover; + iov.iov_len = con->rx_buflen - con->rx_leftover; + + memset(&msg, 0, sizeof(msg)); + msg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; + ret = kernel_recvmsg(con->sock, &msg, &iov, 1, iov.iov_len, + msg.msg_flags); + if (ret == -EAGAIN) + break; + else if (ret <= 0) + goto out_close; - /* calculate leftover bytes from process and put it into begin of - * the receive buffer, so next receive we have the full message - * at the start address of the receive buffer. - */ - con->rx_leftover = buflen - ret; - if (con->rx_leftover) { - memmove(con->rx_buf, con->rx_buf + ret, - con->rx_leftover); - call_again_soon = true; + /* new buflen according readed bytes and leftover from last receive */ + buflen = ret + con->rx_leftover; + ret = dlm_process_incoming_buffer(con->nodeid, con->rx_buf, buflen); + if (ret < 0) + goto out_close; + + /* calculate leftover bytes from process and put it into begin of + * the receive buffer, so next receive we have the full message + * at the start address of the receive buffer. + */ + con->rx_leftover = buflen - ret; + if (con->rx_leftover) { + memmove(con->rx_buf, con->rx_buf + ret, + con->rx_leftover); + } } - if (call_again_soon) - goto out_resched; - mutex_unlock(&con->sock_mutex); return 0; @@ -1511,12 +1508,9 @@ int dlm_lowcomms_close(int nodeid) static void process_recv_sockets(struct work_struct *work) { struct connection *con = container_of(work, struct connection, rwork); - int err; clear_bit(CF_READ_PENDING, &con->flags); - do { - err = receive_from_sock(con); - } while (!err); + receive_from_sock(con); } static void process_listen_recv_socket(struct work_struct *work) -- cgit v1.2.3-70-g09d2 From 10d0786b39b3b91c4fbf8c2926e97ab456a4eea1 Mon Sep 17 00:00:00 2001 From: Jia Yang Date: Wed, 14 Jul 2021 15:46:06 +0800 Subject: f2fs: Revert "f2fs: Fix indefinite loop in f2fs_gc() v1" This reverts commit 957fa47823dfe449c5a15a944e4e7a299a6601db. The patch "f2fs: Fix indefinite loop in f2fs_gc()" v1 and v4 are all merged. Patch v4 is test info for patch v1. Patch v1 doesn't work and may cause that sbi->cur_victim_sec can't be resetted to NULL_SEGNO, which makes SSR unable to get segment of sbi->cur_victim_sec. So it should be reverted. The mails record: [1] https://lore.kernel.org/linux-f2fs-devel/7288dcd4-b168-7656-d1af-7e2cafa4f720@huawei.com/T/ [2] https://lore.kernel.org/linux-f2fs-devel/20190809153653.GD93481@jaegeuk-macbookpro.roam.corp.google.com/T/ Signed-off-by: Jia Yang Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/gc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index d9511827dc83..9dce44619069 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1748,7 +1748,7 @@ gc_more: round++; } - if (gc_type == FG_GC && seg_freed) + if (gc_type == FG_GC) sbi->cur_victim_sec = NULL_SEGNO; if (sync) -- cgit v1.2.3-70-g09d2 From 9aa75914e5fcb39e79fc6de9e44cd12943732c38 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 14 Jul 2021 12:11:02 -0700 Subject: Input: ixp4xx-beeper - delete driver The NSLU2 has been migrated to devicetree and there we use the gpio-beeper.c driver instead, the boardfile will be deleted for kernel v5.15 so drop this custom and now unneeded driver. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20210714115028.916360-1-linus.walleij@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 12 --- drivers/input/misc/Makefile | 1 - drivers/input/misc/ixp4xx-beeper.c | 183 ------------------------------------- 3 files changed, 196 deletions(-) delete mode 100644 drivers/input/misc/ixp4xx-beeper.c diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 498cde376981..ae01507b7afd 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -309,18 +309,6 @@ config INPUT_GPIO_VIBRA To compile this driver as a module, choose M here: the module will be called gpio-vibra. -config INPUT_IXP4XX_BEEPER - tristate "IXP4XX Beeper support" - depends on ARCH_IXP4XX - help - If you say yes here, you can connect a beeper to the - ixp4xx gpio pins. This is used by the LinkSys NSLU2. - - If unsure, say Y. - - To compile this driver as a module, choose M here: the - module will be called ixp4xx-beeper. - config INPUT_COBALT_BTNS tristate "Cobalt button interface" depends on MIPS_COBALT diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index f593beed7e05..2a0943507467 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -44,7 +44,6 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o obj-$(CONFIG_INPUT_IQS626A) += iqs626a.o -obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c deleted file mode 100644 index 05018d0c97c7..000000000000 --- a/drivers/input/misc/ixp4xx-beeper.c +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Generic IXP4xx beeper driver - * - * Copyright (C) 2005 Tower Technologies - * - * based on nslu2-io.c - * Copyright (C) 2004 Karen Spearel - * - * Author: Alessandro Zummo - * Maintainers: http://www.nslu2-linux.org/ - */ - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("ixp4xx beeper driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ixp4xx-beeper"); - -static DEFINE_SPINLOCK(beep_lock); - -static int ixp4xx_timer2_irq; - -static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) -{ - unsigned long flags; - - spin_lock_irqsave(&beep_lock, flags); - - if (count) { - gpio_direction_output(pin, 0); - *IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; - } else { - gpio_direction_output(pin, 1); - gpio_direction_input(pin); - *IXP4XX_OSRT2 = 0; - } - - spin_unlock_irqrestore(&beep_lock, flags); -} - -static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) -{ - unsigned int pin = (unsigned int) input_get_drvdata(dev); - unsigned int count = 0; - - if (type != EV_SND) - return -1; - - switch (code) { - case SND_BELL: - if (value) - value = 1000; - case SND_TONE: - break; - default: - return -1; - } - - if (value > 20 && value < 32767) - count = (ixp4xx_timer_freq / (value * 4)) - 1; - - ixp4xx_spkr_control(pin, count); - - return 0; -} - -static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id) -{ - unsigned int pin = (unsigned int) dev_id; - - /* clear interrupt */ - *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND; - - /* flip the beeper output */ - gpio_set_value(pin, !gpio_get_value(pin)); - - return IRQ_HANDLED; -} - -static int ixp4xx_spkr_probe(struct platform_device *dev) -{ - struct input_dev *input_dev; - int irq; - int err; - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - input_set_drvdata(input_dev, (void *) dev->id); - - input_dev->name = "ixp4xx beeper"; - input_dev->phys = "ixp4xx/gpio"; - input_dev->id.bustype = BUS_HOST; - input_dev->id.vendor = 0x001f; - input_dev->id.product = 0x0001; - input_dev->id.version = 0x0100; - input_dev->dev.parent = &dev->dev; - - input_dev->evbit[0] = BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); - input_dev->event = ixp4xx_spkr_event; - - irq = platform_get_irq(dev, 0); - if (irq < 0) { - err = irq; - goto err_free_device; - } - - err = gpio_request(dev->id, "ixp4-beeper"); - if (err) - goto err_free_device; - - err = request_irq(irq, &ixp4xx_spkr_interrupt, - IRQF_NO_SUSPEND, "ixp4xx-beeper", - (void *) dev->id); - if (err) - goto err_free_gpio; - ixp4xx_timer2_irq = irq; - - err = input_register_device(input_dev); - if (err) - goto err_free_irq; - - platform_set_drvdata(dev, input_dev); - - return 0; - - err_free_irq: - free_irq(irq, (void *)dev->id); - err_free_gpio: - gpio_free(dev->id); - err_free_device: - input_free_device(input_dev); - - return err; -} - -static int ixp4xx_spkr_remove(struct platform_device *dev) -{ - struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_get_drvdata(input_dev); - - input_unregister_device(input_dev); - - /* turn the speaker off */ - disable_irq(ixp4xx_timer2_irq); - ixp4xx_spkr_control(pin, 0); - - free_irq(ixp4xx_timer2_irq, (void *)dev->id); - gpio_free(dev->id); - - return 0; -} - -static void ixp4xx_spkr_shutdown(struct platform_device *dev) -{ - struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_get_drvdata(input_dev); - - /* turn off the speaker */ - disable_irq(ixp4xx_timer2_irq); - ixp4xx_spkr_control(pin, 0); -} - -static struct platform_driver ixp4xx_spkr_platform_driver = { - .driver = { - .name = "ixp4xx-beeper", - }, - .probe = ixp4xx_spkr_probe, - .remove = ixp4xx_spkr_remove, - .shutdown = ixp4xx_spkr_shutdown, -}; -module_platform_driver(ixp4xx_spkr_platform_driver); - -- cgit v1.2.3-70-g09d2 From 81c7c0a350bfe9306ad9fb10356534ede8f4ab31 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 19 Jul 2021 14:34:40 -0700 Subject: Input: serio - make write method mandatory Given that all serio drivers except one implement write() method let's make it mandatory to avoid testing for its presence whenever we attempt to use it. Link: https://lore.kernel.org/r/YFgUxG/TljMuVeQ3@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/ams_delta_serio.c | 6 ++++++ drivers/input/serio/serio.c | 5 +++++ include/linux/serio.h | 5 +---- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 1c0be299f179..a1c314897951 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -89,6 +89,11 @@ static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +static int ams_delta_serio_write(struct serio *serio, u8 data) +{ + return -EINVAL; +} + static int ams_delta_serio_open(struct serio *serio) { struct ams_delta_serio *priv = serio->port_data; @@ -157,6 +162,7 @@ static int ams_delta_serio_init(struct platform_device *pdev) priv->serio = serio; serio->id.type = SERIO_8042; + serio->write = ams_delta_serio_write; serio->open = ams_delta_serio_open; serio->close = ams_delta_serio_close; strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name)); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 29f491082926..8d229a11bb6b 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -694,6 +694,11 @@ EXPORT_SYMBOL(serio_reconnect); */ void __serio_register_port(struct serio *serio, struct module *owner) { + if (!serio->write) { + pr_err("%s: refusing to register %s without write method\n", + __func__, serio->name); + return; + } serio_init_port(serio); serio_queue_event(serio, owner, SERIO_REGISTER_PORT); } diff --git a/include/linux/serio.h b/include/linux/serio.h index 6c27d413da92..075f1b8d76fa 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -121,10 +121,7 @@ void serio_unregister_driver(struct serio_driver *drv); static inline int serio_write(struct serio *serio, unsigned char data) { - if (serio->write) - return serio->write(serio, data); - else - return -1; + return serio->write(serio, data); } static inline void serio_drv_write_wakeup(struct serio *serio) -- cgit v1.2.3-70-g09d2 From 133b6558c75566bf692460fd1a09b3b795ef2c1a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 19 Jul 2021 14:56:57 -0700 Subject: Input: parkbd - switch to use module_parport_driver() Switch to use module_parport_driver() to reduce boilerplate code. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210616140432.39406-1-andriy.shevchenko@linux.intel.com Signed-off-by: Dmitry Torokhov --- drivers/input/serio/parkbd.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index 3ac57a91ede4..51b68501896c 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -220,16 +220,4 @@ static struct parport_driver parkbd_parport_driver = { .detach = parkbd_detach, .devmodel = true, }; - -static int __init parkbd_init(void) -{ - return parport_register_driver(&parkbd_parport_driver); -} - -static void __exit parkbd_exit(void) -{ - parport_unregister_driver(&parkbd_parport_driver); -} - -module_init(parkbd_init); -module_exit(parkbd_exit); +module_parport_driver(parkbd_parport_driver); -- cgit v1.2.3-70-g09d2 From 1ffc8f5f7751f91fe6af527d426a723231b741a6 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 14 Jul 2021 16:14:02 -0700 Subject: f2fs: let's keep writing IOs on SBI_NEED_FSCK SBI_NEED_FSCK is an indicator that fsck.f2fs needs to be triggered, so it is not fully critical to stop any IO writes. So, let's allow to write data instead of reporting EIO forever given SBI_NEED_FSCK, but do keep OPU. Fixes: 955772787667 ("f2fs: drop inplace IO if fs status is abnormal") Cc: # v5.13+ Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 ++ fs/f2fs/segment.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d2cf48c5a2e4..ba120d55e9b1 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2498,6 +2498,8 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) return true; if (f2fs_is_atomic_file(inode)) return true; + if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) + return true; /* swap file is migrating in aligned write mode */ if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 15cc89eef28d..f9b7fb785e1d 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -3563,7 +3563,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) goto drop_bio; } - if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || f2fs_cp_error(sbi)) { + if (f2fs_cp_error(sbi)) { err = -EIO; goto drop_bio; } -- cgit v1.2.3-70-g09d2 From 9de71ede81e6d1a111fdd868b2d78d459fa77f80 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Mon, 19 Jul 2021 16:46:47 +0800 Subject: f2fs: quota: fix potential deadlock xfstest generic/587 reports a deadlock issue as below: ====================================================== WARNING: possible circular locking dependency detected 5.14.0-rc1 #69 Not tainted ------------------------------------------------------ repquota/8606 is trying to acquire lock: ffff888022ac9320 (&sb->s_type->i_mutex_key#18){+.+.}-{3:3}, at: f2fs_quota_sync+0x207/0x300 [f2fs] but task is already holding lock: ffff8880084bcde8 (&sbi->quota_sem){.+.+}-{3:3}, at: f2fs_quota_sync+0x59/0x300 [f2fs] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (&sbi->quota_sem){.+.+}-{3:3}: __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_read+0x3b/0x2a0 f2fs_quota_sync+0x59/0x300 [f2fs] f2fs_quota_on+0x48/0x100 [f2fs] do_quotactl+0x5e3/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae -> #1 (&sbi->cp_rwsem){++++}-{3:3}: __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_read+0x3b/0x2a0 f2fs_unlink+0x353/0x670 [f2fs] vfs_unlink+0x1c7/0x380 do_unlinkat+0x413/0x4b0 __x64_sys_unlinkat+0x50/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae -> #0 (&sb->s_type->i_mutex_key#18){+.+.}-{3:3}: check_prev_add+0xdc/0xb30 validate_chain+0xa67/0xb20 __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_write+0x39/0xc0 f2fs_quota_sync+0x207/0x300 [f2fs] do_quotactl+0xaff/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae other info that might help us debug this: Chain exists of: &sb->s_type->i_mutex_key#18 --> &sbi->cp_rwsem --> &sbi->quota_sem Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&sbi->quota_sem); lock(&sbi->cp_rwsem); lock(&sbi->quota_sem); lock(&sb->s_type->i_mutex_key#18); *** DEADLOCK *** 3 locks held by repquota/8606: #0: ffff88801efac0e0 (&type->s_umount_key#53){++++}-{3:3}, at: user_get_super+0xd9/0x190 #1: ffff8880084bc380 (&sbi->cp_rwsem){++++}-{3:3}, at: f2fs_quota_sync+0x3e/0x300 [f2fs] #2: ffff8880084bcde8 (&sbi->quota_sem){.+.+}-{3:3}, at: f2fs_quota_sync+0x59/0x300 [f2fs] stack backtrace: CPU: 6 PID: 8606 Comm: repquota Not tainted 5.14.0-rc1 #69 Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 Call Trace: dump_stack_lvl+0xce/0x134 dump_stack+0x17/0x20 print_circular_bug.isra.0.cold+0x239/0x253 check_noncircular+0x1be/0x1f0 check_prev_add+0xdc/0xb30 validate_chain+0xa67/0xb20 __lock_acquire+0x648/0x10b0 lock_acquire+0x128/0x470 down_write+0x39/0xc0 f2fs_quota_sync+0x207/0x300 [f2fs] do_quotactl+0xaff/0xb30 __x64_sys_quotactl+0x23a/0x4e0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f883b0b4efe The root cause is ABBA deadlock of inode lock and cp_rwsem, reorder locks in f2fs_quota_sync() as below to fix this issue: - lock inode - lock cp_rwsem - lock quota_sem Fixes: db6ec53b7e03 ("f2fs: add a rw_sem to cover quota flag changes") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 84 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8fecd3050ccd..72eb9d70969f 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2518,6 +2518,33 @@ static int f2fs_enable_quotas(struct super_block *sb) return 0; } +static int f2fs_quota_sync_file(struct f2fs_sb_info *sbi, int type) +{ + struct quota_info *dqopt = sb_dqopt(sbi->sb); + struct address_space *mapping = dqopt->files[type]->i_mapping; + int ret = 0; + + ret = dquot_writeback_dquots(sbi->sb, type); + if (ret) + goto out; + + ret = filemap_fdatawrite(mapping); + if (ret) + goto out; + + /* if we are using journalled quota */ + if (is_journalled_quota(sbi)) + goto out; + + ret = filemap_fdatawait(mapping); + + truncate_inode_pages(&dqopt->files[type]->i_data, 0); +out: + if (ret) + set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); + return ret; +} + int f2fs_quota_sync(struct super_block *sb, int type) { struct f2fs_sb_info *sbi = F2FS_SB(sb); @@ -2525,57 +2552,42 @@ int f2fs_quota_sync(struct super_block *sb, int type) int cnt; int ret; - /* - * do_quotactl - * f2fs_quota_sync - * down_read(quota_sem) - * dquot_writeback_dquots() - * f2fs_dquot_commit - * block_operation - * down_read(quota_sem) - */ - f2fs_lock_op(sbi); - - down_read(&sbi->quota_sem); - ret = dquot_writeback_dquots(sb, type); - if (ret) - goto out; - /* * Now when everything is written we can discard the pagecache so * that userspace sees the changes. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - struct address_space *mapping; if (type != -1 && cnt != type) continue; - if (!sb_has_quota_active(sb, cnt)) - continue; - mapping = dqopt->files[cnt]->i_mapping; + if (!sb_has_quota_active(sb, type)) + return 0; - ret = filemap_fdatawrite(mapping); - if (ret) - goto out; + inode_lock(dqopt->files[cnt]); - /* if we are using journalled quota */ - if (is_journalled_quota(sbi)) - continue; + /* + * do_quotactl + * f2fs_quota_sync + * down_read(quota_sem) + * dquot_writeback_dquots() + * f2fs_dquot_commit + * block_operation + * down_read(quota_sem) + */ + f2fs_lock_op(sbi); + down_read(&sbi->quota_sem); - ret = filemap_fdatawait(mapping); - if (ret) - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); + ret = f2fs_quota_sync_file(sbi, cnt); + + up_read(&sbi->quota_sem); + f2fs_unlock_op(sbi); - inode_lock(dqopt->files[cnt]); - truncate_inode_pages(&dqopt->files[cnt]->i_data, 0); inode_unlock(dqopt->files[cnt]); + + if (ret) + break; } -out: - if (ret) - set_sbi_flag(F2FS_SB(sb), SBI_QUOTA_NEED_REPAIR); - up_read(&sbi->quota_sem); - f2fs_unlock_op(sbi); return ret; } -- cgit v1.2.3-70-g09d2 From d3af3f647bd57be2f6a007d12eaf55e20524fb96 Mon Sep 17 00:00:00 2001 From: Mahesh Rajashekhara Date: Wed, 14 Jul 2021 13:28:39 -0500 Subject: scsi: smartpqi: Add PCI IDs for H3C P4408 controllers Add support for H3C P4408-Ma-8i-2GB device ID: VID_9005, DID_028F, SVID_193D and SDID_1108 VID_9005, DID_028F, SVID_193D and SDID_1109 Link: https://lore.kernel.org/r/20210714182847.50360-2-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Mike McGowen Reviewed-by: Murthy Bhat Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Mahesh Rajashekhara Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index dcc0b9618a64..64ea4650ca10 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8711,6 +8711,14 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x1107) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x1108) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x1109) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x8460) -- cgit v1.2.3-70-g09d2 From 889653ecfc989349bf61736e45695b614d5b64d1 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Wed, 14 Jul 2021 13:28:40 -0500 Subject: scsi: smartpqi: Update copyright notices Updated copyright notices and company name strings to reflect Microchip ownership. Link: https://lore.kernel.org/r/20210714182847.50360-3-don.brace@microchip.com Reviewed-by: Mike McGowen Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/Kconfig | 2 +- drivers/scsi/smartpqi/smartpqi.h | 6 +++--- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++-- drivers/scsi/smartpqi/smartpqi_sas_transport.c | 4 ++-- drivers/scsi/smartpqi/smartpqi_sis.c | 4 ++-- drivers/scsi/smartpqi/smartpqi_sis.h | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/smartpqi/Kconfig b/drivers/scsi/smartpqi/Kconfig index cb9e4e968b60..eac7baecf42f 100644 --- a/drivers/scsi/smartpqi/Kconfig +++ b/drivers/scsi/smartpqi/Kconfig @@ -1,7 +1,7 @@ # # Kernel configuration file for the SMARTPQI # -# Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries +# Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries # Copyright (c) 2017-2018 Microsemi Corporation # Copyright (c) 2016 Microsemi Corporation # Copyright (c) 2016 PMC-Sierra, Inc. diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index d7dac5572274..f340afc011b5 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * driver for Microsemi PQI-based storage controllers - * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries + * driver for Microchip PQI-based storage controllers + * Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries * Copyright (c) 2016-2018 Microsemi Corporation * Copyright (c) 2016 PMC-Sierra, Inc. * @@ -59,7 +59,7 @@ struct pqi_device_registers { /* * controller registers * - * These are defined by the Microsemi implementation. + * These are defined by the Microchip implementation. * * Some registers (those named sis_*) are only used when in * legacy SIS mode before we transition the controller into diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 64ea4650ca10..6ce17a191c0b 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* - * driver for Microsemi PQI-based storage controllers - * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries + * driver for Microchip PQI-based storage controllers + * Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries * Copyright (c) 2016-2018 Microsemi Corporation * Copyright (c) 2016 PMC-Sierra, Inc. * diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index dd628cc87f78..afd9bafebd1d 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* - * driver for Microsemi PQI-based storage controllers - * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries + * driver for Microchip PQI-based storage controllers + * Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries * Copyright (c) 2016-2018 Microsemi Corporation * Copyright (c) 2016 PMC-Sierra, Inc. * diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index c954620628e0..d63c46a8e38b 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* - * driver for Microsemi PQI-based storage controllers - * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries + * driver for Microchip PQI-based storage controllers + * Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries * Copyright (c) 2016-2018 Microsemi Corporation * Copyright (c) 2016 PMC-Sierra, Inc. * diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index 12cd2ab1aead..d29c1352a826 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * driver for Microsemi PQI-based storage controllers - * Copyright (c) 2019-2020 Microchip Technology Inc. and its subsidiaries + * driver for Microchip PQI-based storage controllers + * Copyright (c) 2019-2021 Microchip Technology Inc. and its subsidiaries * Copyright (c) 2016-2018 Microsemi Corporation * Copyright (c) 2016 PMC-Sierra, Inc. * -- cgit v1.2.3-70-g09d2 From 6aa26b5a2c70ca302718dc0d5db092780e4b6f6c Mon Sep 17 00:00:00 2001 From: Don Brace Date: Wed, 14 Jul 2021 13:28:41 -0500 Subject: scsi: smartpqi: Change driver module macros to Microchip Change driver module macros to reflect copyright changes: Microsemi to Microchip. Link: https://lore.kernel.org/r/20210714182847.50360-4-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Gerry Morong Reviewed-by: Justin Lindley Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 6ce17a191c0b..29382b290243 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -39,7 +39,7 @@ #define DRIVER_RELEASE 8 #define DRIVER_REVISION 45 -#define DRIVER_NAME "Microsemi PQI Driver (v" \ +#define DRIVER_NAME "Microchip SmartPQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")" #define DRIVER_NAME_SHORT "smartpqi" @@ -48,8 +48,8 @@ #define PQI_POST_RESET_DELAY_SECS 5 #define PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS 10 -MODULE_AUTHOR("Microsemi"); -MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version " +MODULE_AUTHOR("Microchip"); +MODULE_DESCRIPTION("Driver for Microchip Smart Family Controller version " DRIVER_VERSION); MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); @@ -8451,7 +8451,7 @@ static void pqi_print_ctrl_info(struct pci_dev *pci_dev, if (id->driver_data) ctrl_description = (char *)id->driver_data; else - ctrl_description = "Microsemi Smart Family Controller"; + ctrl_description = "Microchip Smart Family Controller"; dev_info(&pci_dev->dev, "%s found\n", ctrl_description); } -- cgit v1.2.3-70-g09d2 From 8e505fceaa2b7c7841b70ed530167727bb66517b Mon Sep 17 00:00:00 2001 From: Don Brace Date: Wed, 14 Jul 2021 13:28:42 -0500 Subject: scsi: smartpqi: Change Kconfig menu entry to Microchip Change Microsemi to Microchip. Link: https://lore.kernel.org/r/20210714182847.50360-5-don.brace@microchip.com Reviewed-by: Scott Benesh Reviewed-by: Gerry Morong Reviewed-by: Justin Lindley Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/smartpqi/Kconfig b/drivers/scsi/smartpqi/Kconfig index eac7baecf42f..6f83e2df4d64 100644 --- a/drivers/scsi/smartpqi/Kconfig +++ b/drivers/scsi/smartpqi/Kconfig @@ -38,14 +38,14 @@ # HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES config SCSI_SMARTPQI - tristate "Microsemi PQI Driver" + tristate "Microchip PQI Driver" depends on PCI && SCSI && !S390 select SCSI_SAS_ATTRS select RAID_ATTRS help - This driver supports Microsemi PQI controllers. + This driver supports Microchip PQI controllers. - + To compile this driver as a module, choose M here: the module will be called smartpqi. -- cgit v1.2.3-70-g09d2 From f0e473e0f603bcd4fbbbd2913208aaad8191efec Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Wed, 14 Jul 2021 13:28:43 -0500 Subject: scsi: smartpqi: Add SCSI cmd info for resets Report on SCSI command that has triggered the reset. Also add check for NULL SCSI commands resulting from issuing sg_reset when there is no outstanding commands. Example: sg_reset -d /dev/sgXY smartpqi 0000:39:00.0: resetting scsi 4:0:1:0 due to cmd 0x12 Link: https://lore.kernel.org/r/20210714182847.50360-6-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Mike McGowen Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 29382b290243..ffc7ca221e27 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6033,8 +6033,10 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) mutex_lock(&ctrl_info->lun_reset_mutex); dev_err(&ctrl_info->pci_dev->dev, - "resetting scsi %d:%d:%d:%d\n", - shost->host_no, device->bus, device->target, device->lun); + "resetting scsi %d:%d:%d:%d due to cmd 0x%02x\n", + shost->host_no, + device->bus, device->target, device->lun, + scmd->cmd_len > 0 ? scmd->cmnd[0] : 0xff); pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) -- cgit v1.2.3-70-g09d2 From e326b97c92ccbe0fa9256902ca0c20e2b6c40168 Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Wed, 14 Jul 2021 13:28:44 -0500 Subject: scsi: smartpqi: Add PCI ID for new ntcom controller Add support for Norsi ntcom Raid-24i controller: VID_0x9005, DID_0x028f, SVID_0x1dfc, SDID_0x3161 Link: https://lore.kernel.org/r/20210714182847.50360-7-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Mike McGowen Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ffc7ca221e27..c0b181ba795c 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -9181,6 +9181,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_GIGABYTE, 0x1000) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1dfc, 0x3161) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_ANY_ID, PCI_ANY_ID) -- cgit v1.2.3-70-g09d2 From 09d9968a8eff8c098149295ebb62a453a862b9c6 Mon Sep 17 00:00:00 2001 From: Balsundar P Date: Wed, 14 Jul 2021 13:28:45 -0500 Subject: scsi: smartpqi: Add PCI IDs for new ZTE controllers Add support for ZTE RM241-18i 2G device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_5445 Add support for ZTE RM242-18i 4G device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_5446 Add support for ZTE RM243-18i device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_5447 Add support for ZTE SDPSA/B-18i 4G device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_0B27 Add support for ZTE SDPSA/B_I-18i device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_0B29 Add support for ZTE SDPSA/B_L-18i 2G device ID: VID_9005, DID_028F, SVID_1CF2 and SDID_0B45 Link: https://lore.kernel.org/r/20210714182847.50360-8-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Mike McGowen Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Balsundar P Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c0b181ba795c..f0e84354f782 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -9185,6 +9185,30 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1dfc, 0x3161) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x5445) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x5446) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x5447) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x0b27) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x0b29) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1cf2, 0x0b45) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_ANY_ID, PCI_ANY_ID) -- cgit v1.2.3-70-g09d2 From 0777a3fb98f0ea546561d04db4fd325248c39961 Mon Sep 17 00:00:00 2001 From: Mike McGowen Date: Wed, 14 Jul 2021 13:28:46 -0500 Subject: scsi: smartpqi: Fix ISR accessing uninitialized data Correct driver's ISR accessing a data structure member that has not been fully initialized during driver initialization. The pqi queue groups can have uninitialized members when an interrupt fires. This has not resulted in any driver crashes. This was found during our own internal testing. No bugs were ever filed. Link: https://lore.kernel.org/r/20210714182847.50360-9-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Mike McGowen Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index f0e84354f782..ab1c9c483478 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -7760,11 +7760,11 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) pqi_init_operational_queues(ctrl_info); - rc = pqi_request_irqs(ctrl_info); + rc = pqi_create_queues(ctrl_info); if (rc) return rc; - rc = pqi_create_queues(ctrl_info); + rc = pqi_request_irqs(ctrl_info); if (rc) return rc; -- cgit v1.2.3-70-g09d2 From f339c7e491a8150d416d4aa657fe379c20fe6b79 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Wed, 14 Jul 2021 13:28:47 -0500 Subject: scsi: smartpqi: Update version to 2.1.10-020 Link: https://lore.kernel.org/r/20210714182847.50360-10-don.brace@microchip.com Reviewed-by: Kevin Barnett Reviewed-by: Mike McGowen Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Gerry Morong Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ab1c9c483478..c1f0f8da9fe2 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -33,11 +33,11 @@ #define BUILD_TIMESTAMP #endif -#define DRIVER_VERSION "2.1.8-045" +#define DRIVER_VERSION "2.1.10-020" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 1 -#define DRIVER_RELEASE 8 -#define DRIVER_REVISION 45 +#define DRIVER_RELEASE 10 +#define DRIVER_REVISION 20 #define DRIVER_NAME "Microchip SmartPQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")" -- cgit v1.2.3-70-g09d2 From ef0eea5b151aefe1efea78e2fa7c507ff3c56bf0 Mon Sep 17 00:00:00 2001 From: Chris Blake Date: Mon, 7 Jun 2021 18:35:35 -0500 Subject: mfd: lpc_ich: Enable GPIO driver for DH89xxCC Based on the Intel Datasheet for the DH89xxCC PCH, the GPIO driver is the same as ICH_v5_GPIO, minus the fact the DH89xxCC also has blink support. However, blink support isn't supported by the GPIO driver so we should use ICH_v5_GPIO. Tested and working on a Meraki MX100-HW. Signed-off-by: Chris Blake Co-developed-by: Christian Lamparter Signed-off-by: Lee Jones --- drivers/mfd/lpc_ich.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 3bbb29a7e7a5..f10e53187f67 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -489,6 +489,7 @@ static struct lpc_ich_info lpc_chipset_info[] = { [LPC_DH89XXCC] = { .name = "DH89xxCC", .iTCO_version = 2, + .gpio_version = ICH_V5_GPIO, }, [LPC_PPT] = { .name = "Panther Point", -- cgit v1.2.3-70-g09d2 From 32979fcf5ab5df9359b98796886c5356b9cf4298 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 3 Jun 2021 19:51:28 +0300 Subject: mfd: intel-lpss: Add Intel Cannon Lake ACPI IDs Some of the machines, like Dell Precision 3630, may expose LPSS devices via ACPI. Add their IDs to the list. Signed-off-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss-acpi.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index 1f396039d58f..3f1d976eb67c 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -89,6 +89,11 @@ static const struct intel_lpss_platform_info apl_i2c_info = { .swnode = &apl_i2c_node, }; +static const struct intel_lpss_platform_info cnl_i2c_info = { + .clk_rate = 216000000, + .swnode = &spt_i2c_node, +}; + static const struct acpi_device_id intel_lpss_acpi_ids[] = { /* SPT */ { "INT3440", (kernel_ulong_t)&spt_info }, @@ -102,6 +107,19 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { { "INT3448", (kernel_ulong_t)&spt_uart_info }, { "INT3449", (kernel_ulong_t)&spt_uart_info }, { "INT344A", (kernel_ulong_t)&spt_uart_info }, + /* CNL */ + { "INT34B0", (kernel_ulong_t)&spt_info }, + { "INT34B1", (kernel_ulong_t)&spt_info }, + { "INT34B2", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B3", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B4", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B5", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B6", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B7", (kernel_ulong_t)&cnl_i2c_info }, + { "INT34B8", (kernel_ulong_t)&spt_uart_info }, + { "INT34B9", (kernel_ulong_t)&spt_uart_info }, + { "INT34BA", (kernel_ulong_t)&spt_uart_info }, + { "INT34BC", (kernel_ulong_t)&spt_info }, /* BXT */ { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, { "80860ABC", (kernel_ulong_t)&bxt_info }, -- cgit v1.2.3-70-g09d2 From 49c4959f04b587c8909b33adca4066995c768d60 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 14 Jul 2021 14:57:19 -0700 Subject: dmaengine: idxd: fix sequence for pci driver remove() and shutdown() ->shutdown() call should only be responsible for quiescing the device. Currently it is doing PCI device tear down. This causes issue when things like MMIO mapping is removed while idxd_unregister_devices() will trigger removal of idxd device sub-driver and still initiates MMIO writes to the device. Another issue is with the unregistering of idxd 'struct device', the memory context gets freed. So the teardown calls are accessing freed memory and can cause kernel oops. Move all the teardown bits that doesn't belong in shutdown to ->remove() call. Move unregistering of the idxd conf_dev 'struct device' to after doing all the teardown to free all the memory that's no longer needed. Fixes: 47c16ac27d4c ("dmaengine: idxd: fix idxd conf_dev 'struct device' lifetime") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162629983901.395844.17964803190905549615.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/init.c | 26 +++++++++++++++++--------- drivers/dma/idxd/sysfs.c | 2 -- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 7eac0d167bde..75ac6a4bc9d1 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -754,32 +754,40 @@ static void idxd_shutdown(struct pci_dev *pdev) for (i = 0; i < msixcnt; i++) { irq_entry = &idxd->irq_entries[i]; synchronize_irq(irq_entry->vector); - free_irq(irq_entry->vector, irq_entry); if (i == 0) continue; idxd_flush_pending_llist(irq_entry); idxd_flush_work_list(irq_entry); } - - idxd_msix_perm_clear(idxd); - idxd_release_int_handles(idxd); - pci_free_irq_vectors(pdev); - pci_iounmap(pdev, idxd->reg_base); - pci_disable_device(pdev); - destroy_workqueue(idxd->wq); + flush_workqueue(idxd->wq); } static void idxd_remove(struct pci_dev *pdev) { struct idxd_device *idxd = pci_get_drvdata(pdev); + struct idxd_irq_entry *irq_entry; + int msixcnt = pci_msix_vec_count(pdev); + int i; dev_dbg(&pdev->dev, "%s called\n", __func__); idxd_shutdown(pdev); if (device_pasid_enabled(idxd)) idxd_disable_system_pasid(idxd); idxd_unregister_devices(idxd); - perfmon_pmu_remove(idxd); + + for (i = 0; i < msixcnt; i++) { + irq_entry = &idxd->irq_entries[i]; + free_irq(irq_entry->vector, irq_entry); + } + idxd_msix_perm_clear(idxd); + idxd_release_int_handles(idxd); + pci_free_irq_vectors(pdev); + pci_iounmap(pdev, idxd->reg_base); iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA); + pci_disable_device(pdev); + destroy_workqueue(idxd->wq); + perfmon_pmu_remove(idxd); + device_unregister(&idxd->conf_dev); } static struct pci_driver idxd_pci_driver = { diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index a193de32536d..33c27df40f1e 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -1751,8 +1751,6 @@ void idxd_unregister_devices(struct idxd_device *idxd) device_unregister(&group->conf_dev); } - - device_unregister(&idxd->conf_dev); } int idxd_register_bus_type(void) -- cgit v1.2.3-70-g09d2 From 2013b4d525273e8ce6a6ff6518a4df3f8a8250cb Mon Sep 17 00:00:00 2001 From: Lior Nahmanson Date: Mon, 21 Jun 2021 10:06:15 +0300 Subject: RDMA/mlx5: Separate DCI QP creation logic This patch isolates DCI QP creation logic to separate function, so this change will reduce complexity when adding new features to DCI QP without interfering with other QP types. The code was copied from create_user_qp() while taking only DCI relevant bits. Link: https://lore.kernel.org/r/b4530bdd999349c59691224f016ff1efb5dc3b92.1624258894.git.leonro@nvidia.com Reviewed-by: Meir Lichtinger Signed-off-by: Lior Nahmanson Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/qp.c | 157 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index a77db29f8391..b70fdfe6e8a5 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -1982,6 +1982,160 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, return 0; } +static int create_dci(struct mlx5_ib_dev *dev, struct ib_pd *pd, + struct mlx5_ib_qp *qp, + struct mlx5_create_qp_params *params) +{ + struct ib_qp_init_attr *init_attr = params->attr; + struct mlx5_ib_create_qp *ucmd = params->ucmd; + u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {}; + struct ib_udata *udata = params->udata; + u32 uidx = params->uidx; + struct mlx5_ib_resources *devr = &dev->devr; + int inlen = MLX5_ST_SZ_BYTES(create_qp_in); + struct mlx5_core_dev *mdev = dev->mdev; + struct mlx5_ib_cq *send_cq; + struct mlx5_ib_cq *recv_cq; + unsigned long flags; + struct mlx5_ib_qp_base *base; + int ts_format; + int mlx5_st; + void *qpc; + u32 *in; + int err; + + spin_lock_init(&qp->sq.lock); + spin_lock_init(&qp->rq.lock); + + mlx5_st = to_mlx5_st(qp->type); + if (mlx5_st < 0) + return -EINVAL; + + if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) + qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE; + + base = &qp->trans_qp.base; + + qp->has_rq = qp_has_rq(init_attr); + err = set_rq_size(dev, &init_attr->cap, qp->has_rq, qp, ucmd); + if (err) { + mlx5_ib_dbg(dev, "err %d\n", err); + return err; + } + + if (ucmd->rq_wqe_shift != qp->rq.wqe_shift || + ucmd->rq_wqe_count != qp->rq.wqe_cnt) + return -EINVAL; + + if (ucmd->sq_wqe_count > (1 << MLX5_CAP_GEN(mdev, log_max_qp_sz))) + return -EINVAL; + + ts_format = get_qp_ts_format(dev, to_mcq(init_attr->send_cq), + to_mcq(init_attr->recv_cq)); + + if (ts_format < 0) + return ts_format; + + err = _create_user_qp(dev, pd, qp, udata, init_attr, &in, ¶ms->resp, + &inlen, base, ucmd); + if (err) + return err; + + if (MLX5_CAP_GEN(mdev, ece_support)) + MLX5_SET(create_qp_in, in, ece, ucmd->ece_options); + qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); + + MLX5_SET(qpc, qpc, st, mlx5_st); + MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED); + MLX5_SET(qpc, qpc, pd, to_mpd(pd)->pdn); + + if (qp->flags_en & MLX5_QP_FLAG_SIGNATURE) + MLX5_SET(qpc, qpc, wq_signature, 1); + + if (qp->flags & IB_QP_CREATE_CROSS_CHANNEL) + MLX5_SET(qpc, qpc, cd_master, 1); + if (qp->flags & IB_QP_CREATE_MANAGED_SEND) + MLX5_SET(qpc, qpc, cd_slave_send, 1); + if (qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) + configure_requester_scat_cqe(dev, qp, init_attr, qpc); + + if (qp->rq.wqe_cnt) { + MLX5_SET(qpc, qpc, log_rq_stride, qp->rq.wqe_shift - 4); + MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt)); + } + + MLX5_SET(qpc, qpc, ts_format, ts_format); + MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr)); + + MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt)); + + /* Set default resources */ + if (init_attr->srq) { + MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0); + MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, + to_msrq(init_attr->srq)->msrq.srqn); + } else { + MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1); + MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, + to_msrq(devr->s1)->msrq.srqn); + } + + if (init_attr->send_cq) + MLX5_SET(qpc, qpc, cqn_snd, + to_mcq(init_attr->send_cq)->mcq.cqn); + + if (init_attr->recv_cq) + MLX5_SET(qpc, qpc, cqn_rcv, + to_mcq(init_attr->recv_cq)->mcq.cqn); + + MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma); + + /* 0xffffff means we ask to work with cqe version 0 */ + if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1) + MLX5_SET(qpc, qpc, user_index, uidx); + + if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING) { + MLX5_SET(qpc, qpc, end_padding_mode, + MLX5_WQ_END_PAD_MODE_ALIGN); + /* Special case to clean flag */ + qp->flags &= ~IB_QP_CREATE_PCI_WRITE_END_PADDING; + } + + err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out); + + kvfree(in); + if (err) + goto err_create; + + base->container_mibqp = qp; + base->mqp.event = mlx5_ib_qp_event; + if (MLX5_CAP_GEN(mdev, ece_support)) + params->resp.ece_options = MLX5_GET(create_qp_out, out, ece); + + get_cqs(qp->type, init_attr->send_cq, init_attr->recv_cq, + &send_cq, &recv_cq); + spin_lock_irqsave(&dev->reset_flow_resource_lock, flags); + mlx5_ib_lock_cqs(send_cq, recv_cq); + /* Maintain device to QPs access, needed for further handling via reset + * flow + */ + list_add_tail(&qp->qps_list, &dev->qp_list); + /* Maintain CQ to QPs access, needed for further handling via reset flow + */ + if (send_cq) + list_add_tail(&qp->cq_send_list, &send_cq->list_send_qp); + if (recv_cq) + list_add_tail(&qp->cq_recv_list, &recv_cq->list_recv_qp); + mlx5_ib_unlock_cqs(send_cq, recv_cq); + spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags); + + return 0; + +err_create: + destroy_qp(dev, qp, base, udata); + return err; +} + static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, struct mlx5_ib_qp *qp, struct mlx5_create_qp_params *params) @@ -2848,6 +3002,9 @@ static int create_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, case MLX5_IB_QPT_DCT: err = create_dct(dev, pd, qp, params); break; + case MLX5_IB_QPT_DCI: + err = create_dci(dev, pd, qp, params); + break; case IB_QPT_XRC_TGT: err = create_xrc_tgt_qp(dev, qp, params); break; -- cgit v1.2.3-70-g09d2 From 11656f593a869a4345e3421037614d2b75ae2ad3 Mon Sep 17 00:00:00 2001 From: Lior Nahmanson Date: Mon, 21 Jun 2021 10:06:16 +0300 Subject: RDMA/mlx5: Add DCS offload support DCS is an offload to SW load balancing of DC initiator work requests. A single DCI can be connected to only one target at the time and can't start new connection until the previous work request is completed. This limitation will cause to delay when the initiator process needs to transfer data to multiple targets at the same time. The SW solution is to use a process that handling and spreading the work request on many DCIs according to destinations. This feature is an offload to this process and coming to reduce the load from the CPU and improve the performance. Link: https://lore.kernel.org/r/491c2c2afdb5b07de7f03eab3f93cf0704549dbc.1624258894.git.leonro@nvidia.com Reviewed-by: Meir Lichtinger Signed-off-by: Lior Nahmanson Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/main.c | 10 ++++++++++ drivers/infiniband/hw/mlx5/qp.c | 11 +++++++++++ include/uapi/rdma/mlx5-abi.h | 17 +++++++++++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 094c976b1eed..cac0c52ed1d9 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1174,6 +1174,16 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, MLX5_IB_TUNNELED_OFFLOADS_MPLS_UDP; } + if (offsetofend(typeof(resp), dci_streams_caps) <= uhw_outlen) { + resp.response_length += sizeof(resp.dci_streams_caps); + + resp.dci_streams_caps.max_log_num_concurent = + MLX5_CAP_GEN(mdev, log_max_dci_stream_channels); + + resp.dci_streams_caps.max_log_num_errored = + MLX5_CAP_GEN(mdev, log_max_dci_errored_streams); + } + if (uhw_outlen) { err = ib_copy_to_udata(uhw, &resp, resp.response_length); diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index b70fdfe6e8a5..a056b7a8e0c3 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -2064,6 +2064,13 @@ static int create_dci(struct mlx5_ib_dev *dev, struct ib_pd *pd, MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt)); } + if (qp->flags_en & MLX5_QP_FLAG_DCI_STREAM) { + MLX5_SET(qpc, qpc, log_num_dci_stream_channels, + ucmd->dci_streams.log_num_concurent); + MLX5_SET(qpc, qpc, log_num_dci_errored_streams, + ucmd->dci_streams.log_num_errored); + } + MLX5_SET(qpc, qpc, ts_format, ts_format); MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr)); @@ -2807,6 +2814,10 @@ static int process_vendor_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCI, true, qp); process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCT, true, qp); + process_vendor_flag(dev, &flags, MLX5_QP_FLAG_DCI_STREAM, + MLX5_CAP_GEN(mdev, log_max_dci_stream_channels) && + MLX5_CAP_GEN(mdev, log_max_dci_errored_streams), + qp); process_vendor_flag(dev, &flags, MLX5_QP_FLAG_SIGNATURE, true, qp); process_vendor_flag(dev, &flags, MLX5_QP_FLAG_SCATTER_CQE, diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h index 8597e6f22a1c..86be4a92b67b 100644 --- a/include/uapi/rdma/mlx5-abi.h +++ b/include/uapi/rdma/mlx5-abi.h @@ -50,6 +50,7 @@ enum { MLX5_QP_FLAG_ALLOW_SCATTER_CQE = 1 << 8, MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE = 1 << 9, MLX5_QP_FLAG_UAR_PAGE_INDEX = 1 << 10, + MLX5_QP_FLAG_DCI_STREAM = 1 << 11, }; enum { @@ -238,6 +239,11 @@ struct mlx5_ib_striding_rq_caps { __u32 reserved; }; +struct mlx5_ib_dci_streams_caps { + __u8 max_log_num_concurent; + __u8 max_log_num_errored; +}; + enum mlx5_ib_query_dev_resp_flags { /* Support 128B CQE compression */ MLX5_IB_QUERY_DEV_RESP_FLAGS_CQE_128B_COMP = 1 << 0, @@ -266,7 +272,8 @@ struct mlx5_ib_query_device_resp { struct mlx5_ib_sw_parsing_caps sw_parsing_caps; struct mlx5_ib_striding_rq_caps striding_rq_caps; __u32 tunnel_offloads_caps; /* enum mlx5_ib_tunnel_offloads */ - __u32 reserved; + struct mlx5_ib_dci_streams_caps dci_streams_caps; + __u16 reserved; }; enum mlx5_ib_create_cq_flags { @@ -313,6 +320,11 @@ struct mlx5_ib_create_srq_resp { __u32 reserved; }; +struct mlx5_ib_create_qp_dci_streams { + __u8 log_num_concurent; + __u8 log_num_errored; +}; + struct mlx5_ib_create_qp { __aligned_u64 buf_addr; __aligned_u64 db_addr; @@ -327,7 +339,8 @@ struct mlx5_ib_create_qp { __aligned_u64 access_key; }; __u32 ece_options; - __u32 reserved; + struct mlx5_ib_create_qp_dci_streams dci_streams; + __u16 reserved; }; /* RX Hash function flags */ -- cgit v1.2.3-70-g09d2 From 8bde9dd381be46728ba731da08eeadc504798546 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:17 +0530 Subject: dt-bindings: clock: qcom: Update license for GCC SC7280 Update BSD license for GCC clock ids. Fixes: 87a3d523b38c ("dt-bindings: clock: Add SC7280 GCC clock binding") Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-2-git-send-email-tdas@codeaurora.org Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/qcom,gcc-sc7280.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dt-bindings/clock/qcom,gcc-sc7280.h b/include/dt-bindings/clock/qcom,gcc-sc7280.h index 4394f15111c6..3d5724b79bff 100644 --- a/include/dt-bindings/clock/qcom,gcc-sc7280.h +++ b/include/dt-bindings/clock/qcom,gcc-sc7280.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ -- cgit v1.2.3-70-g09d2 From ced3aaead0ba4c1b11eec51adc51465fa56aa5da Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:18 +0530 Subject: dt-bindings: clock: Add SC7280 DISPCC clock binding Add device tree bindings for display clock controller subsystem for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-3-git-send-email-tdas@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/clock/qcom,sc7280-dispcc.yaml | 94 ++++++++++++++++++++++ include/dt-bindings/clock/qcom,dispcc-sc7280.h | 55 +++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml create mode 100644 include/dt-bindings/clock/qcom,dispcc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml new file mode 100644 index 000000000000..2178666fb697 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-dispcc.yaml @@ -0,0 +1,94 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,sc7280-dispcc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Display Clock & Reset Controller Binding for SC7280 + +maintainers: + - Taniya Das + +description: | + Qualcomm display clock control module which supports the clocks, resets and + power domains on SC7280. + + See also dt-bindings/clock/qcom,dispcc-sc7280.h. + +properties: + compatible: + const: qcom,sc7280-dispcc + + clocks: + items: + - description: Board XO source + - description: GPLL0 source from GCC + - description: Byte clock from DSI PHY + - description: Pixel clock from DSI PHY + - description: Link clock from DP PHY + - description: VCO DIV clock from DP PHY + - description: Link clock from EDP PHY + - description: VCO DIV clock from EDP PHY + + clock-names: + items: + - const: bi_tcxo + - const: gcc_disp_gpll0_clk + - const: dsi0_phy_pll_out_byteclk + - const: dsi0_phy_pll_out_dsiclk + - const: dp_phy_pll_link_clk + - const: dp_phy_pll_vco_div_clk + - const: edp_phy_pll_link_clk + - const: edp_phy_pll_vco_div_clk + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include + #include + clock-controller@af00000 { + compatible = "qcom,sc7280-dispcc"; + reg = <0x0af00000 0x200000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_DISP_GPLL0_CLK_SRC>, + <&dsi_phy 0>, + <&dsi_phy 1>, + <&dp_phy 0>, + <&dp_phy 1>, + <&edp_phy 0>, + <&edp_phy 1>; + clock-names = "bi_tcxo", + "gcc_disp_gpll0_clk", + "dsi0_phy_pll_out_byteclk", + "dsi0_phy_pll_out_dsiclk", + "dp_phy_pll_link_clk", + "dp_phy_pll_vco_div_clk", + "edp_phy_pll_link_clk", + "edp_phy_pll_vco_div_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/include/dt-bindings/clock/qcom,dispcc-sc7280.h b/include/dt-bindings/clock/qcom,dispcc-sc7280.h new file mode 100644 index 000000000000..a4a692c20acf --- /dev/null +++ b/include/dt-bindings/clock/qcom,dispcc-sc7280.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7280_H + +/* DISP_CC clocks */ +#define DISP_CC_PLL0 0 +#define DISP_CC_MDSS_AHB_CLK 1 +#define DISP_CC_MDSS_AHB_CLK_SRC 2 +#define DISP_CC_MDSS_BYTE0_CLK 3 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 4 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 5 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 6 +#define DISP_CC_MDSS_DP_AUX_CLK 7 +#define DISP_CC_MDSS_DP_AUX_CLK_SRC 8 +#define DISP_CC_MDSS_DP_CRYPTO_CLK 9 +#define DISP_CC_MDSS_DP_CRYPTO_CLK_SRC 10 +#define DISP_CC_MDSS_DP_LINK_CLK 11 +#define DISP_CC_MDSS_DP_LINK_CLK_SRC 12 +#define DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC 13 +#define DISP_CC_MDSS_DP_LINK_INTF_CLK 14 +#define DISP_CC_MDSS_DP_PIXEL_CLK 15 +#define DISP_CC_MDSS_DP_PIXEL_CLK_SRC 16 +#define DISP_CC_MDSS_EDP_AUX_CLK 17 +#define DISP_CC_MDSS_EDP_AUX_CLK_SRC 18 +#define DISP_CC_MDSS_EDP_LINK_CLK 19 +#define DISP_CC_MDSS_EDP_LINK_CLK_SRC 20 +#define DISP_CC_MDSS_EDP_LINK_DIV_CLK_SRC 21 +#define DISP_CC_MDSS_EDP_LINK_INTF_CLK 22 +#define DISP_CC_MDSS_EDP_PIXEL_CLK 23 +#define DISP_CC_MDSS_EDP_PIXEL_CLK_SRC 24 +#define DISP_CC_MDSS_ESC0_CLK 25 +#define DISP_CC_MDSS_ESC0_CLK_SRC 26 +#define DISP_CC_MDSS_MDP_CLK 27 +#define DISP_CC_MDSS_MDP_CLK_SRC 28 +#define DISP_CC_MDSS_MDP_LUT_CLK 29 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 30 +#define DISP_CC_MDSS_PCLK0_CLK 31 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 32 +#define DISP_CC_MDSS_ROT_CLK 33 +#define DISP_CC_MDSS_ROT_CLK_SRC 34 +#define DISP_CC_MDSS_RSCC_AHB_CLK 35 +#define DISP_CC_MDSS_RSCC_VSYNC_CLK 36 +#define DISP_CC_MDSS_VSYNC_CLK 37 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 38 +#define DISP_CC_SLEEP_CLK 39 +#define DISP_CC_XO_CLK 40 + +/* DISP_CC power domains */ +#define DISP_CC_MDSS_CORE_GDSC 0 + +#endif -- cgit v1.2.3-70-g09d2 From 1a00c962f9cd0095a2759225ac25061218e99e78 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:19 +0530 Subject: clk: qcom: Add display clock controller driver for SC7280 Add support for the display clock controller found on SC7280 based devices. This would allow display drivers to probe and control their clocks. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-4-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 9 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/dispcc-sc7280.c | 908 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 918 insertions(+) create mode 100644 drivers/clk/qcom/dispcc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 62e00e15495c..d7a8ce7a6e6f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -332,6 +332,15 @@ config SC_DISPCC_7180 Say Y if you want to support display devices and functionality such as splash screen. +config SC_DISPCC_7280 + tristate "SC7280 Display Clock Controller" + select SC_GCC_7280 + help + Support for the display clock controller on Qualcomm Technologies, Inc. + SC7280 devices. + Say Y if you want to support display devices and functionality such as + splash screen. + config SC_GCC_7180 tristate "SC7180 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c2a1cafb31bc..871758d39786 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o +obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o diff --git a/drivers/clk/qcom/dispcc-sc7280.c b/drivers/clk/qcom/dispcc-sc7280.c new file mode 100644 index 000000000000..4ef4ae231794 --- /dev/null +++ b/drivers/clk/qcom/dispcc-sc7280.c @@ -0,0 +1,908 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_EVEN, + P_DISP_CC_PLL0_OUT_MAIN, + P_DP_PHY_PLL_LINK_CLK, + P_DP_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_EDP_PHY_PLL_LINK_CLK, + P_EDP_PHY_PLL_VCO_DIV_CLK, + P_GCC_DISP_GPLL0_CLK, +}; + +static const struct pll_vco lucid_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +/* 1520MHz Configuration*/ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0x4F, + .alpha = 0x2AAA, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DP_PHY_PLL_LINK_CLK, 1 }, + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dp_phy_pll_link_clk" }, + { .fw_name = "dp_phy_pll_vco_div_clk" }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dsi0_phy_pll_out_byteclk" }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_EDP_PHY_PLL_LINK_CLK, 1 }, + { P_EDP_PHY_PLL_VCO_DIV_CLK, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "edp_phy_pll_link_clk" }, + { .fw_name = "edp_phy_pll_vco_div_clk" }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_GCC_DISP_GPLL0_CLK, 4 }, + { P_DISP_CC_PLL0_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .fw_name = "gcc_disp_gpll0_clk" }, + { .hw = &disp_cc_pll0.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GCC_DISP_GPLL0_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "gcc_disp_gpll0_clk" }, +}; + +static const struct parent_map disp_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_6[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "dsi0_phy_pll_out_dsiclk" }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0), + F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x1170, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x10d8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { + .cmd_rcgr = 0x1158, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { + .cmd_rcgr = 0x1128, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { + .cmd_rcgr = 0x110c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { + .cmd_rcgr = 0x1140, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_aux_clk_src = { + .cmd_rcgr = 0x11d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_link_clk_src = { + .cmd_rcgr = 0x11a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_pixel_clk_src = { + .cmd_rcgr = 0x1188, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_pixel_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x10f4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), + F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(506666667, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x1090, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x1078, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { + .cmd_rcgr = 0x10a8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rot_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x10c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x10f0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = { + .reg = 0x1124, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "disp_cc_mdss_dp_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_edp_link_div_clk_src = { + .reg = 0x11b8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "disp_cc_mdss_edp_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x1050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x1030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x1034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_aux_clk = { + .halt_reg = 0x104c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x104c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_aux_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_crypto_clk = { + .halt_reg = 0x1044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_crypto_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_crypto_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_link_clk = { + .halt_reg = 0x103c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x103c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { + .halt_reg = 0x1040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_link_intf_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dp_pixel_clk = { + .halt_reg = 0x1048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_dp_pixel_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_dp_pixel_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_aux_clk = { + .halt_reg = 0x1060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_aux_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_link_clk = { + .halt_reg = 0x1058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_link_intf_clk = { + .halt_reg = 0x105c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x105c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_intf_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_link_div_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_pixel_clk = { + .halt_reg = 0x1054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_pixel_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_pixel_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x1038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x1014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x1024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0x2004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x1010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rot_clk = { + .halt_reg = 0x101c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rot_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_rot_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { + .halt_reg = 0x200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rscc_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { + .halt_reg = 0x2008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_rscc_vsync_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x102c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x102c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_sleep_clk = { + .halt_reg = 0x5004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x1004, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *disp_cc_sc7280_clocks[] = { + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, + [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, + [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, + [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = + &disp_cc_mdss_dp_link_div_clk_src.clkr, + [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, + [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, + [DISP_CC_MDSS_EDP_AUX_CLK] = &disp_cc_mdss_edp_aux_clk.clkr, + [DISP_CC_MDSS_EDP_AUX_CLK_SRC] = &disp_cc_mdss_edp_aux_clk_src.clkr, + [DISP_CC_MDSS_EDP_LINK_CLK] = &disp_cc_mdss_edp_link_clk.clkr, + [DISP_CC_MDSS_EDP_LINK_CLK_SRC] = &disp_cc_mdss_edp_link_clk_src.clkr, + [DISP_CC_MDSS_EDP_LINK_DIV_CLK_SRC] = + &disp_cc_mdss_edp_link_div_clk_src.clkr, + [DISP_CC_MDSS_EDP_LINK_INTF_CLK] = &disp_cc_mdss_edp_link_intf_clk.clkr, + [DISP_CC_MDSS_EDP_PIXEL_CLK] = &disp_cc_mdss_edp_pixel_clk.clkr, + [DISP_CC_MDSS_EDP_PIXEL_CLK_SRC] = &disp_cc_mdss_edp_pixel_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr, +}; + +static struct gdsc *disp_cc_sc7280_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, +}; + +static const struct regmap_config disp_cc_sc7280_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x10000, + .fast_io = true, +}; + +static const struct qcom_cc_desc disp_cc_sc7280_desc = { + .config = &disp_cc_sc7280_regmap_config, + .clks = disp_cc_sc7280_clocks, + .num_clks = ARRAY_SIZE(disp_cc_sc7280_clocks), + .gdscs = disp_cc_sc7280_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_sc7280_gdscs), +}; + +static const struct of_device_id disp_cc_sc7280_match_table[] = { + { .compatible = "qcom,sc7280-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_sc7280_match_table); + +static int disp_cc_sc7280_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &disp_cc_sc7280_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); + + /* + * Keep the clocks always-ON + * DISP_CC_XO_CLK + */ + regmap_update_bits(regmap, 0x5008, BIT(0), BIT(0)); + + return qcom_cc_really_probe(pdev, &disp_cc_sc7280_desc, regmap); +} + +static struct platform_driver disp_cc_sc7280_driver = { + .probe = disp_cc_sc7280_probe, + .driver = { + .name = "disp_cc-sc7280", + .of_match_table = disp_cc_sc7280_match_table, + }, +}; + +static int __init disp_cc_sc7280_init(void) +{ + return platform_driver_register(&disp_cc_sc7280_driver); +} +subsys_initcall(disp_cc_sc7280_init); + +static void __exit disp_cc_sc7280_exit(void) +{ + platform_driver_unregister(&disp_cc_sc7280_driver); +} +module_exit(disp_cc_sc7280_exit); + +MODULE_DESCRIPTION("QTI DISP_CC sc7280 Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 6f1a1ced9ee616fe1e5bdebcfe060d0f03a89336 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:20 +0530 Subject: dt-bindings: clock: Add SC7280 GPUCC clock binding Add device tree bindings for graphics clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-5-git-send-email-tdas@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,gpucc.yaml | 6 ++-- include/dt-bindings/clock/qcom,gpucc-sc7280.h | 35 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/clock/qcom,gpucc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml index df943c4c3234..ecfe21284073 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/clock/qcom,gpucc.yaml# @@ -11,11 +11,12 @@ maintainers: description: | Qualcomm graphics clock control module which supports the clocks, resets and - power domains on SDM845/SC7180/SM8150/SM8250. + power domains on Qualcomm SoCs. See also: dt-bindings/clock/qcom,gpucc-sdm845.h dt-bindings/clock/qcom,gpucc-sc7180.h + dt-bindings/clock/qcom,gpucc-sc7280.h dt-bindings/clock/qcom,gpucc-sm8150.h dt-bindings/clock/qcom,gpucc-sm8250.h @@ -24,6 +25,7 @@ properties: enum: - qcom,sdm845-gpucc - qcom,sc7180-gpucc + - qcom,sc7280-gpucc - qcom,sm8150-gpucc - qcom,sm8250-gpucc diff --git a/include/dt-bindings/clock/qcom,gpucc-sc7280.h b/include/dt-bindings/clock/qcom,gpucc-sc7280.h new file mode 100644 index 000000000000..669b23b606ba --- /dev/null +++ b/include/dt-bindings/clock/qcom,gpucc-sc7280.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7280_H + +/* GPU_CC clocks */ +#define GPU_CC_PLL0 0 +#define GPU_CC_PLL1 1 +#define GPU_CC_AHB_CLK 2 +#define GPU_CC_CB_CLK 3 +#define GPU_CC_CRC_AHB_CLK 4 +#define GPU_CC_CX_GMU_CLK 5 +#define GPU_CC_CX_SNOC_DVM_CLK 6 +#define GPU_CC_CXO_AON_CLK 7 +#define GPU_CC_CXO_CLK 8 +#define GPU_CC_GMU_CLK_SRC 9 +#define GPU_CC_GX_GMU_CLK 10 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 11 +#define GPU_CC_HUB_AHB_DIV_CLK_SRC 12 +#define GPU_CC_HUB_AON_CLK 13 +#define GPU_CC_HUB_CLK_SRC 14 +#define GPU_CC_HUB_CX_INT_CLK 15 +#define GPU_CC_HUB_CX_INT_DIV_CLK_SRC 16 +#define GPU_CC_MND1X_0_GFX3D_CLK 17 +#define GPU_CC_MND1X_1_GFX3D_CLK 18 +#define GPU_CC_SLEEP_CLK 19 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +#endif -- cgit v1.2.3-70-g09d2 From 3e0f01d6c7e746c1bcf577c9180775c83780ce5b Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:21 +0530 Subject: clk: qcom: Add graphics clock controller driver for SC7280 Add support for the graphics clock controller found on SC7280 based devices. This would allow graphics drivers to probe and control their clocks. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-6-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/gpucc-sc7280.c | 491 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 500 insertions(+) create mode 100644 drivers/clk/qcom/gpucc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index d7a8ce7a6e6f..80b2b6b70d68 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -385,6 +385,14 @@ config SC_GPUCC_7180 Say Y if you want to support graphics controller devices and functionality such as 3D graphics. +config SC_GPUCC_7280 + tristate "SC7280 Graphics Clock Controller" + select SC_GCC_7280 + help + Support for the graphics clock controller on SC7280 devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + config SC_MSS_7180 tristate "SC7180 Modem Clock Controller" select SC_GCC_7180 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 871758d39786..9d5f9db40d3d 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o +obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c new file mode 100644 index 000000000000..9a832f2bcf49 --- /dev/null +++ b/drivers/clk/qcom/gpucc-sc7280.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_GCC_GPU_GPLL0_CLK_SRC, + P_GCC_GPU_GPLL0_DIV_CLK_SRC, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL1_OUT_MAIN, +}; + +static const struct pll_vco lucid_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +/* 500MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll1_config = { + .l = 0x1A, + .alpha = 0xAAA, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll gpu_cc_pll1 = { + .offset = 0x100, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GCC_GPU_GPLL0_CLK_SRC, 5 }, + { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL1_OUT_MAIN, 3 }, + { P_GCC_GPU_GPLL0_CLK_SRC, 5 }, + { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo", }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src", }, + { .fw_name = "gcc_gpu_gpll0_div_clk_src", }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0), + F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x1120, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { + F(150000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 2, 0, 0), + F(240000000, P_GCC_GPU_GPLL0_CLK_SRC, 2.5, 0, 0), + F(300000000, P_GCC_GPU_GPLL0_CLK_SRC, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x117c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_1, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_1, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = { + .reg = 0x11c0, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gpu_cc_hub_ahb_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = { + .reg = 0x11bc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(struct clk_init_data) { + .name = "gpu_cc_hub_cx_int_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x1078, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_ahb_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x107c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x107c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_crc_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_ahb_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x1098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x108c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_snoc_dvm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_aon_clk = { + .halt_reg = 0x1004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x109c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x109c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gmu_clk = { + .halt_reg = 0x1064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gmu_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { + .halt_reg = 0x5000, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x5000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x1178, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1178, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_cx_int_clk = { + .halt_reg = 0x1204, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1204, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = { + .halt_reg = 0x802c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x802c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_mnd1x_0_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_mnd1x_1_gfx3d_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_sleep_clk = { + .halt_reg = 0x1090, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cx_gdsc = { + .gdscr = 0x106c, + .gds_hw_ctrl = 0x1540, + .pd = { + .name = "cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE, +}; + +static struct gdsc gx_gdsc = { + .gdscr = 0x100c, + .clamp_io_ctrl = 0x1508, + .pd = { + .name = "gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = CLAMP_IO | RETAIN_FF_ENABLE, +}; + +static struct gdsc *gpu_cc_sc7180_gdscs[] = { + [GPU_CC_CX_GDSC] = &cx_gdsc, + [GPU_CC_GX_GDSC] = &gx_gdsc, +}; + +static struct clk_regmap *gpu_cc_sc7280_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, + [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr, + [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr, + [GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, + [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, +}; + +static const struct regmap_config gpu_cc_sc7280_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x8030, + .fast_io = true, +}; + +static const struct qcom_cc_desc gpu_cc_sc7280_desc = { + .config = &gpu_cc_sc7280_regmap_config, + .clks = gpu_cc_sc7280_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_sc7280_clocks), + .gdscs = gpu_cc_sc7180_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs), +}; + +static const struct of_device_id gpu_cc_sc7280_match_table[] = { + { .compatible = "qcom,sc7280-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_sc7280_match_table); + +static int gpu_cc_sc7280_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gpu_cc_sc7280_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + + /* + * Keep the clocks always-ON + * GPU_CC_CB_CLK, GPUCC_CX_GMU_CLK + */ + regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0)); + + return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap); +} + +static struct platform_driver gpu_cc_sc7280_driver = { + .probe = gpu_cc_sc7280_probe, + .driver = { + .name = "gpu_cc-sc7280", + .of_match_table = gpu_cc_sc7280_match_table, + }, +}; + +static int __init gpu_cc_sc7280_init(void) +{ + return platform_driver_register(&gpu_cc_sc7280_driver); +} +subsys_initcall(gpu_cc_sc7280_init); + +static void __exit gpu_cc_sc7280_exit(void) +{ + platform_driver_unregister(&gpu_cc_sc7280_driver); +} +module_exit(gpu_cc_sc7280_exit); + +MODULE_DESCRIPTION("QTI GPU_CC SC7280 Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From f1f5a30385631d528ee2d121a456931f7279139d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:22 +0530 Subject: dt-bindings: clock: Add SC7280 VideoCC clock binding Add device tree bindings for video clock subsystem clock controller for Qualcomm Technology Inc's SC7280 SoCs. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-7-git-send-email-tdas@codeaurora.org Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,videocc.yaml | 6 +++-- include/dt-bindings/clock/qcom,videocc-sc7280.h | 27 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 include/dt-bindings/clock/qcom,videocc-sc7280.h diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml index 567202942b88..0d224f114b5b 100644 --- a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2 --- $id: http://devicetree.org/schemas/clock/qcom,videocc.yaml# @@ -11,10 +11,11 @@ maintainers: description: | Qualcomm video clock control module which supports the clocks, resets and - power domains on SDM845/SC7180/SM8150/SM8250. + power domains on Qualcomm SoCs. See also: dt-bindings/clock/qcom,videocc-sc7180.h + dt-bindings/clock/qcom,videocc-sc7280.h dt-bindings/clock/qcom,videocc-sdm845.h dt-bindings/clock/qcom,videocc-sm8150.h dt-bindings/clock/qcom,videocc-sm8250.h @@ -23,6 +24,7 @@ properties: compatible: enum: - qcom,sc7180-videocc + - qcom,sc7280-videocc - qcom,sdm845-videocc - qcom,sm8150-videocc - qcom,sm8250-videocc diff --git a/include/dt-bindings/clock/qcom,videocc-sc7280.h b/include/dt-bindings/clock/qcom,videocc-sc7280.h new file mode 100644 index 000000000000..9e00c3a5f75e --- /dev/null +++ b/include/dt-bindings/clock/qcom,videocc-sc7280.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7280_H + +/* VIDEO_CC clocks */ +#define VIDEO_PLL0 0 +#define VIDEO_CC_IRIS_AHB_CLK 1 +#define VIDEO_CC_IRIS_CLK_SRC 2 +#define VIDEO_CC_MVS0_AXI_CLK 3 +#define VIDEO_CC_MVS0_CORE_CLK 4 +#define VIDEO_CC_MVSC_CORE_CLK 5 +#define VIDEO_CC_MVSC_CTL_AXI_CLK 6 +#define VIDEO_CC_SLEEP_CLK 7 +#define VIDEO_CC_SLEEP_CLK_SRC 8 +#define VIDEO_CC_VENUS_AHB_CLK 9 +#define VIDEO_CC_XO_CLK 10 +#define VIDEO_CC_XO_CLK_SRC 11 + +/* VIDEO_CC power domains */ +#define MVS0_GDSC 0 +#define MVSC_GDSC 1 + +#endif -- cgit v1.2.3-70-g09d2 From fae7617bb1428eae812f2cce5bdaa2838d0a9662 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Tue, 13 Jul 2021 20:42:23 +0530 Subject: clk: qcom: Add video clock controller driver for SC7280 Add support for the video clock controller found on SC7280 based devices. This would allow video drivers to probe and control their clocks. Signed-off-by: Taniya Das Link: https://lore.kernel.org/r/1626189143-12957-8-git-send-email-tdas@codeaurora.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/videocc-sc7280.c | 325 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+) create mode 100644 drivers/clk/qcom/videocc-sc7280.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 80b2b6b70d68..85b090a8d9c6 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -410,6 +410,14 @@ config SC_VIDEOCC_7180 Say Y if you want to support video devices and functionality such as video encode and decode. +config SC_VIDEOCC_7280 + tristate "SC7280 Video Clock Controller" + select SC_GCC_7280 + help + Support for the video clock controller on SC7280 devices. + Say Y if you want to support video devices and functionality such as + video encode and decode. + config SDM_CAMCC_845 tristate "SDM845 Camera Clock Controller" select SDM_GCC_845 diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 9d5f9db40d3d..27cefe572ac2 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o +obj-$(CONFIG_SC_VIDEOCC_7280) += videocc-sc7280.o obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o diff --git a/drivers/clk/qcom/videocc-sc7280.c b/drivers/clk/qcom/videocc-sc7280.c new file mode 100644 index 000000000000..615695d82319 --- /dev/null +++ b/drivers/clk/qcom/videocc-sc7280.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "common.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_SLEEP_CLK, + P_VIDEO_PLL0_OUT_EVEN, +}; + +static const struct pll_vco lucid_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +/* 400MHz Configuration */ +static const struct alpha_pll_config video_pll0_config = { + .l = 0x14, + .alpha = 0xD555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A299C, + .user_ctl_val = 0x00000001, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll video_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "video_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_PLL0_OUT_EVEN, 3 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &video_pll0.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .fw_name = "sleep_clk" }, +}; + +static const struct freq_tbl ftbl_video_cc_iris_clk_src[] = { + F(133333333, P_VIDEO_PLL0_OUT_EVEN, 3, 0, 0), + F(240000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(335000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(424000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + F(460000000, P_VIDEO_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_iris_clk_src = { + .cmd_rcgr = 0x1000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_iris_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_iris_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_sleep_clk_src = { + .cmd_rcgr = 0x701c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_sleep_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "video_cc_sleep_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch video_cc_iris_ahb_clk = { + .halt_reg = 0x5004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x5004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_iris_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &video_cc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_axi_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_mvs0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_core_clk = { + .halt_reg = 0x3010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_mvs0_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &video_cc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvsc_core_clk = { + .halt_reg = 0x2014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_mvsc_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &video_cc_iris_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvsc_ctl_axi_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_mvsc_ctl_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_sleep_clk = { + .halt_reg = 0x7034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_sleep_clk", + .parent_hws = (const struct clk_hw*[]){ + &video_cc_sleep_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_venus_ahb_clk = { + .halt_reg = 0x801c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x801c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "video_cc_venus_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc mvs0_gdsc = { + .gdscr = 0x3004, + .pd = { + .name = "mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL | RETAIN_FF_ENABLE, +}; + +static struct gdsc mvsc_gdsc = { + .gdscr = 0x2004, + .pd = { + .name = "mvsc_gdsc", + }, + .flags = RETAIN_FF_ENABLE, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *video_cc_sc7280_clocks[] = { + [VIDEO_CC_IRIS_AHB_CLK] = &video_cc_iris_ahb_clk.clkr, + [VIDEO_CC_IRIS_CLK_SRC] = &video_cc_iris_clk_src.clkr, + [VIDEO_CC_MVS0_AXI_CLK] = &video_cc_mvs0_axi_clk.clkr, + [VIDEO_CC_MVS0_CORE_CLK] = &video_cc_mvs0_core_clk.clkr, + [VIDEO_CC_MVSC_CORE_CLK] = &video_cc_mvsc_core_clk.clkr, + [VIDEO_CC_MVSC_CTL_AXI_CLK] = &video_cc_mvsc_ctl_axi_clk.clkr, + [VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr, + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, + [VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr, + [VIDEO_PLL0] = &video_pll0.clkr, +}; + +static struct gdsc *video_cc_sc7280_gdscs[] = { + [MVS0_GDSC] = &mvs0_gdsc, + [MVSC_GDSC] = &mvsc_gdsc, +}; + +static const struct regmap_config video_cc_sc7280_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xb000, + .fast_io = true, +}; + +static const struct qcom_cc_desc video_cc_sc7280_desc = { + .config = &video_cc_sc7280_regmap_config, + .clks = video_cc_sc7280_clocks, + .num_clks = ARRAY_SIZE(video_cc_sc7280_clocks), + .gdscs = video_cc_sc7280_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_sc7280_gdscs), +}; + +static const struct of_device_id video_cc_sc7280_match_table[] = { + { .compatible = "qcom,sc7280-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_sc7280_match_table); + +static int video_cc_sc7280_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &video_cc_sc7280_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); + + return qcom_cc_really_probe(pdev, &video_cc_sc7280_desc, regmap); +} + +static struct platform_driver video_cc_sc7280_driver = { + .probe = video_cc_sc7280_probe, + .driver = { + .name = "video_cc-sc7280", + .of_match_table = video_cc_sc7280_match_table, + }, +}; + +static int __init video_cc_sc7280_init(void) +{ + return platform_driver_register(&video_cc_sc7280_driver); +} +subsys_initcall(video_cc_sc7280_init); + +static void __exit video_cc_sc7280_exit(void) +{ + platform_driver_unregister(&video_cc_sc7280_driver); +} +module_exit(video_cc_sc7280_exit); + +MODULE_DESCRIPTION("QTI VIDEO_CC sc7280 Driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From eb32f9f990d974a7878a8792cee9bb821720c24b Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:47 +0200 Subject: kcsan: Improve some Kconfig comments Improve comment for CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE. Also shorten the comment above the "strictness" configuration options. Acked-by: Mark Rutland Signed-off-by: Marco Elver Signed-off-by: Paul E. McKenney --- lib/Kconfig.kcsan | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 0440f373248e..6152fbd5cbb4 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -40,10 +40,14 @@ menuconfig KCSAN if KCSAN -# Compiler capabilities that should not fail the test if they are unavailable. config CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=thread -mllvm -tsan-compound-read-before-write=1)) || \ (CC_IS_GCC && $(cc-option,-fsanitize=thread --param tsan-compound-read-before-write=1)) + help + The compiler instruments plain compound read-write operations + differently (++, --, +=, -=, |=, &=, etc.), which allows KCSAN to + distinguish them from other plain accesses. This is currently + supported by Clang 12 or later. config KCSAN_VERBOSE bool "Show verbose reports with more information about system state" @@ -169,13 +173,9 @@ config KCSAN_REPORT_ONCE_IN_MS reporting to avoid flooding the console with reports. Setting this to 0 disables rate limiting. -# The main purpose of the below options is to control reported data races (e.g. -# in fuzzer configs), and are not expected to be switched frequently by other -# users. We could turn some of them into boot parameters, but given they should -# not be switched normally, let's keep them here to simplify configuration. -# -# The defaults below are chosen to be very conservative, and may miss certain -# bugs. +# The main purpose of the below options is to control reported data races, and +# are not expected to be switched frequently by non-testers or at runtime. +# The defaults are chosen to be conservative, and can miss certain bugs. config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN bool "Report races of unknown origin" -- cgit v1.2.3-70-g09d2 From a7a73697360ea81244eea550138b8f614348860c Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:48 +0200 Subject: kcsan: Remove CONFIG_KCSAN_DEBUG By this point CONFIG_KCSAN_DEBUG is pretty useless, as the system just isn't usable with it due to spamming console (I imagine a randconfig test robot will run into this sooner or later). Remove it. Back in 2019 I used it occasionally to record traces of watchpoints and verify the encoding is correct, but these days we have proper tests. If something similar is needed in future, just add it back ad-hoc. Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- kernel/kcsan/core.c | 9 --------- lib/Kconfig.kcsan | 3 --- 2 files changed, 12 deletions(-) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 26709ea65c71..d92977ede7e1 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -479,15 +479,6 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) break; /* ignore; we do not diff the values */ } - if (IS_ENABLED(CONFIG_KCSAN_DEBUG)) { - kcsan_disable_current(); - pr_err("watching %s, size: %zu, addr: %px [slot: %d, encoded: %lx]\n", - is_write ? "write" : "read", size, ptr, - watchpoint_slot((unsigned long)ptr), - encode_watchpoint((unsigned long)ptr, size, is_write)); - kcsan_enable_current(); - } - /* * Delay this thread, to increase probability of observing a racy * conflicting access. diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 6152fbd5cbb4..5304f211f81f 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -62,9 +62,6 @@ config KCSAN_VERBOSE generated from any one of them, system stability may suffer due to deadlocks or recursion. If in doubt, say N. -config KCSAN_DEBUG - bool "Debugging of KCSAN internals" - config KCSAN_SELFTEST bool "Perform short selftests on boot" default y -- cgit v1.2.3-70-g09d2 From e675d2533a74acfa95c62e7bb088335866f44fd2 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:49 +0200 Subject: kcsan: Introduce CONFIG_KCSAN_STRICT Add a simpler Kconfig variable to configure KCSAN's "strict" mode. This makes it simpler in documentation or messages to suggest just a single configuration option to select the strictest checking mode (vs. currently having to list several options). Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- Documentation/dev-tools/kcsan.rst | 4 ++++ lib/Kconfig.kcsan | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/Documentation/dev-tools/kcsan.rst b/Documentation/dev-tools/kcsan.rst index 6a600cf8430b..69dc9c502ccc 100644 --- a/Documentation/dev-tools/kcsan.rst +++ b/Documentation/dev-tools/kcsan.rst @@ -127,6 +127,10 @@ Kconfig options: causes KCSAN to not report data races due to conflicts where the only plain accesses are aligned writes up to word size. +To use the strictest possible rules, select ``CONFIG_KCSAN_STRICT=y``, which +configures KCSAN to follow the Linux-kernel memory consistency model (LKMM) as +closely as possible. + DebugFS interface ~~~~~~~~~~~~~~~~~ diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 5304f211f81f..c76fbb3ee09e 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -183,9 +183,17 @@ config KCSAN_REPORT_RACE_UNKNOWN_ORIGIN reported if it was only possible to infer a race due to a data value change while an access is being delayed on a watchpoint. +config KCSAN_STRICT + bool "Strict data-race checking" + help + KCSAN will report data races with the strictest possible rules, which + closely aligns with the rules defined by the Linux-kernel memory + consistency model (LKMM). + config KCSAN_REPORT_VALUE_CHANGE_ONLY bool "Only report races where watcher observed a data value change" default y + depends on !KCSAN_STRICT help If enabled and a conflicting write is observed via a watchpoint, but the data value of the memory location was observed to remain @@ -194,6 +202,7 @@ config KCSAN_REPORT_VALUE_CHANGE_ONLY config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC bool "Assume that plain aligned writes up to word size are atomic" default y + depends on !KCSAN_STRICT help Assume that plain aligned writes up to word size are atomic by default, and also not subject to other unsafe compiler optimizations @@ -206,6 +215,7 @@ config KCSAN_ASSUME_PLAIN_WRITES_ATOMIC config KCSAN_IGNORE_ATOMICS bool "Do not instrument marked atomic accesses" + depends on !KCSAN_STRICT help Never instrument marked atomic accesses. This option can be used for additional filtering. Conflicting marked atomic reads and plain -- cgit v1.2.3-70-g09d2 From 08cac6049412061e571fadadc3e23464dc46d0f2 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:50 +0200 Subject: kcsan: Reduce get_ctx() uses in kcsan_found_watchpoint() There are a number get_ctx() calls that are close to each other, which results in poor codegen (repeated preempt_count loads). Specifically in kcsan_found_watchpoint() (even though it's a slow-path) it is beneficial to keep the race-window small until the watchpoint has actually been consumed to avoid missed opportunities to report a race. Let's clean it up a bit before we add more code in kcsan_found_watchpoint(). Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- kernel/kcsan/core.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index d92977ede7e1..906100923b88 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -301,9 +301,9 @@ static inline void reset_kcsan_skip(void) this_cpu_write(kcsan_skip, skip_count); } -static __always_inline bool kcsan_is_enabled(void) +static __always_inline bool kcsan_is_enabled(struct kcsan_ctx *ctx) { - return READ_ONCE(kcsan_enabled) && get_ctx()->disable_count == 0; + return READ_ONCE(kcsan_enabled) && !ctx->disable_count; } /* Introduce delay depending on context and configuration. */ @@ -353,10 +353,17 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, atomic_long_t *watchpoint, long encoded_watchpoint) { + struct kcsan_ctx *ctx = get_ctx(); unsigned long flags; bool consumed; - if (!kcsan_is_enabled()) + /* + * We know a watchpoint exists. Let's try to keep the race-window + * between here and finally consuming the watchpoint below as small as + * possible -- avoid unneccessarily complex code until consumed. + */ + + if (!kcsan_is_enabled(ctx)) return; /* @@ -364,14 +371,12 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, * reporting a race where e.g. the writer set up the watchpoint, but the * reader has access_mask!=0, we have to ignore the found watchpoint. */ - if (get_ctx()->access_mask != 0) + if (ctx->access_mask) return; /* - * Consume the watchpoint as soon as possible, to minimize the chances - * of !consumed. Consuming the watchpoint must always be guarded by - * kcsan_is_enabled() check, as otherwise we might erroneously - * triggering reports when disabled. + * Consuming the watchpoint must be guarded by kcsan_is_enabled() to + * avoid erroneously triggering reports if the context is disabled. */ consumed = try_consume_watchpoint(watchpoint, encoded_watchpoint); @@ -409,6 +414,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) unsigned long access_mask; enum kcsan_value_change value_change = KCSAN_VALUE_CHANGE_MAYBE; unsigned long ua_flags = user_access_save(); + struct kcsan_ctx *ctx = get_ctx(); unsigned long irq_flags = 0; /* @@ -417,7 +423,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) */ reset_kcsan_skip(); - if (!kcsan_is_enabled()) + if (!kcsan_is_enabled(ctx)) goto out; /* @@ -489,7 +495,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) * Re-read value, and check if it is as expected; if not, we infer a * racy access. */ - access_mask = get_ctx()->access_mask; + access_mask = ctx->access_mask; new = 0; switch (size) { case 1: -- cgit v1.2.3-70-g09d2 From 49f72d5358dd3c0d28bcd2232c513000b15480f0 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:51 +0200 Subject: kcsan: Rework atomic.h into permissive.h Rework atomic.h into permissive.h to better reflect its purpose, and introduce kcsan_ignore_address() and kcsan_ignore_data_race(). Introduce CONFIG_KCSAN_PERMISSIVE and update the stub functions in preparation for subsequent changes. As before, developers who choose to use KCSAN in "strict" mode will see all data races and are not affected. Furthermore, by relying on the value-change filter logic for kcsan_ignore_data_race(), even if the permissive rules are enabled, the opt-outs in report.c:skip_report() override them (such as for RCU-related functions by default). The option CONFIG_KCSAN_PERMISSIVE is disabled by default, so that the documented default behaviour of KCSAN does not change. Instead, like CONFIG_KCSAN_IGNORE_ATOMICS, the option needs to be explicitly opted in. Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- Documentation/dev-tools/kcsan.rst | 8 +++++++ kernel/kcsan/atomic.h | 23 ------------------- kernel/kcsan/core.c | 33 +++++++++++++++++++-------- kernel/kcsan/permissive.h | 47 +++++++++++++++++++++++++++++++++++++++ lib/Kconfig.kcsan | 10 +++++++++ 5 files changed, 89 insertions(+), 32 deletions(-) delete mode 100644 kernel/kcsan/atomic.h create mode 100644 kernel/kcsan/permissive.h diff --git a/Documentation/dev-tools/kcsan.rst b/Documentation/dev-tools/kcsan.rst index 69dc9c502ccc..7db43c7c09b8 100644 --- a/Documentation/dev-tools/kcsan.rst +++ b/Documentation/dev-tools/kcsan.rst @@ -127,6 +127,14 @@ Kconfig options: causes KCSAN to not report data races due to conflicts where the only plain accesses are aligned writes up to word size. +* ``CONFIG_KCSAN_PERMISSIVE``: Enable additional permissive rules to ignore + certain classes of common data races. Unlike the above, the rules are more + complex involving value-change patterns, access type, and address. This + option depends on ``CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=y``. For details + please see the ``kernel/kcsan/permissive.h``. Testers and maintainers that + only focus on reports from specific subsystems and not the whole kernel are + recommended to disable this option. + To use the strictest possible rules, select ``CONFIG_KCSAN_STRICT=y``, which configures KCSAN to follow the Linux-kernel memory consistency model (LKMM) as closely as possible. diff --git a/kernel/kcsan/atomic.h b/kernel/kcsan/atomic.h deleted file mode 100644 index 530ae1bda8e7..000000000000 --- a/kernel/kcsan/atomic.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Rules for implicitly atomic memory accesses. - * - * Copyright (C) 2019, Google LLC. - */ - -#ifndef _KERNEL_KCSAN_ATOMIC_H -#define _KERNEL_KCSAN_ATOMIC_H - -#include - -/* - * Special rules for certain memory where concurrent conflicting accesses are - * common, however, the current convention is to not mark them; returns true if - * access to @ptr should be considered atomic. Called from slow-path. - */ -static bool kcsan_is_atomic_special(const volatile void *ptr) -{ - return false; -} - -#endif /* _KERNEL_KCSAN_ATOMIC_H */ diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 906100923b88..439edb9dcbb1 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -20,9 +20,9 @@ #include #include -#include "atomic.h" #include "encoding.h" #include "kcsan.h" +#include "permissive.h" static bool kcsan_early_enable = IS_ENABLED(CONFIG_KCSAN_EARLY_ENABLE); unsigned int kcsan_udelay_task = CONFIG_KCSAN_UDELAY_TASK; @@ -353,6 +353,7 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, atomic_long_t *watchpoint, long encoded_watchpoint) { + const bool is_assert = (type & KCSAN_ACCESS_ASSERT) != 0; struct kcsan_ctx *ctx = get_ctx(); unsigned long flags; bool consumed; @@ -374,6 +375,16 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, if (ctx->access_mask) return; + /* + * If the other thread does not want to ignore the access, and there was + * a value change as a result of this thread's operation, we will still + * generate a report of unknown origin. + * + * Use CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN=n to filter. + */ + if (!is_assert && kcsan_ignore_address(ptr)) + return; + /* * Consuming the watchpoint must be guarded by kcsan_is_enabled() to * avoid erroneously triggering reports if the context is disabled. @@ -396,7 +407,7 @@ static noinline void kcsan_found_watchpoint(const volatile void *ptr, atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_REPORT_RACES]); } - if ((type & KCSAN_ACCESS_ASSERT) != 0) + if (is_assert) atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]); else atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_DATA_RACES]); @@ -427,12 +438,10 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) goto out; /* - * Special atomic rules: unlikely to be true, so we check them here in - * the slow-path, and not in the fast-path in is_atomic(). Call after - * kcsan_is_enabled(), as we may access memory that is not yet - * initialized during early boot. + * Check to-ignore addresses after kcsan_is_enabled(), as we may access + * memory that is not yet initialized during early boot. */ - if (!is_assert && kcsan_is_atomic_special(ptr)) + if (!is_assert && kcsan_ignore_address(ptr)) goto out; if (!check_encodable((unsigned long)ptr, size)) { @@ -518,8 +527,14 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) if (access_mask) diff &= access_mask; - /* Were we able to observe a value-change? */ - if (diff != 0) + /* + * Check if we observed a value change. + * + * Also check if the data race should be ignored (the rules depend on + * non-zero diff); if it is to be ignored, the below rules for + * KCSAN_VALUE_CHANGE_MAYBE apply. + */ + if (diff && !kcsan_ignore_data_race(size, type, old, new, diff)) value_change = KCSAN_VALUE_CHANGE_TRUE; /* Check if this access raced with another. */ diff --git a/kernel/kcsan/permissive.h b/kernel/kcsan/permissive.h new file mode 100644 index 000000000000..f90e30800c11 --- /dev/null +++ b/kernel/kcsan/permissive.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Special rules for ignoring entire classes of data-racy memory accesses. None + * of the rules here imply that such data races are generally safe! + * + * All rules in this file can be configured via CONFIG_KCSAN_PERMISSIVE. Keep + * them separate from core code to make it easier to audit. + * + * Copyright (C) 2019, Google LLC. + */ + +#ifndef _KERNEL_KCSAN_PERMISSIVE_H +#define _KERNEL_KCSAN_PERMISSIVE_H + +#include + +/* + * Access ignore rules based on address. + */ +static __always_inline bool kcsan_ignore_address(const volatile void *ptr) +{ + if (!IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) + return false; + + return false; +} + +/* + * Data race ignore rules based on access type and value change patterns. + */ +static bool +kcsan_ignore_data_race(size_t size, int type, u64 old, u64 new, u64 diff) +{ + if (!IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) + return false; + + /* + * Rules here are only for plain read accesses, so that we still report + * data races between plain read-write accesses. + */ + if (type || size > sizeof(long)) + return false; + + return false; +} + +#endif /* _KERNEL_KCSAN_PERMISSIVE_H */ diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index c76fbb3ee09e..26f03c754d39 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -231,4 +231,14 @@ config KCSAN_IGNORE_ATOMICS due to two conflicting plain writes will be reported (aligned and unaligned, if CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n). +config KCSAN_PERMISSIVE + bool "Enable all additional permissive rules" + depends on KCSAN_REPORT_VALUE_CHANGE_ONLY + help + Enable additional permissive rules to ignore certain classes of data + races (also see kernel/kcsan/permissive.h). None of the permissive + rules imply that such data races are generally safe, but can be used + to further reduce reported data races due to data-racy patterns + common across the kernel. + endif # KCSAN -- cgit v1.2.3-70-g09d2 From 9c827cd1fcdf54bb50f874f91af0d5de2aceb035 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:52 +0200 Subject: kcsan: Print if strict or non-strict during init Show a brief message if KCSAN is strict or non-strict, and if non-strict also say that CONFIG_KCSAN_STRICT=y can be used to see all data races. This is to hint to users of KCSAN who blindly use the default config that their configuration might miss data races of interest. Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- kernel/kcsan/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 439edb9dcbb1..76e67d1e02d4 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -656,6 +656,15 @@ void __init kcsan_init(void) pr_info("enabled early\n"); WRITE_ONCE(kcsan_enabled, true); } + + if (IS_ENABLED(CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY) || + IS_ENABLED(CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC) || + IS_ENABLED(CONFIG_KCSAN_PERMISSIVE) || + IS_ENABLED(CONFIG_KCSAN_IGNORE_ATOMICS)) { + pr_warn("non-strict mode configured - use CONFIG_KCSAN_STRICT=y to see all data races\n"); + } else { + pr_info("strict mode configured\n"); + } } /* === Exported interface =================================================== */ -- cgit v1.2.3-70-g09d2 From d8fd74d35a8d3c602232e3238e916bda9d03d520 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 7 Jun 2021 14:56:53 +0200 Subject: kcsan: permissive: Ignore data-racy 1-bit value changes Add rules to ignore data-racy reads with only 1-bit value changes. Details about the rules are captured in comments in kernel/kcsan/permissive.h. More background follows. While investigating a number of data races, we've encountered data-racy accesses on flags variables to be very common. The typical pattern is a reader masking all but one bit, and/or the writer setting/clearing only 1 bit (current->flags being a frequently encountered case; more examples in mm/sl[au]b.c, which disable KCSAN for this reason). Since these types of data-racy accesses are common (with the assumption they are intentional and hard to miscompile) having the option (with CONFIG_KCSAN_PERMISSIVE=y) to filter them will avoid forcing everyone to mark them, and deliberately left to preference at this time. One important motivation for having this option built-in is to move closer to being able to enable KCSAN on CI systems or for testers wishing to test the whole kernel, while more easily filtering less interesting data races with higher probability. For the implementation, we considered several alternatives, but had one major requirement: that the rules be kept together with the Linux-kernel tree. Adding them to the compiler would preclude us from making changes quickly; if the rules require tweaks, having them part of the compiler requires waiting another ~1 year for the next release -- that's not realistic. We are left with the following options: 1. Maintain compiler plugins as part of the kernel-tree that removes instrumentation for some accesses (e.g. plain-& with 1-bit mask). The analysis would be reader-side focused, as no assumption can be made about racing writers. Because it seems unrealistic to maintain 2 plugins, one for LLVM and GCC, we would likely pick LLVM. Furthermore, no kernel infrastructure exists to maintain LLVM plugins, and the build-system implications and maintenance overheads do not look great (historically, plugins written against old LLVM APIs are not guaranteed to work with newer LLVM APIs). 2. Find a set of rules that can be expressed in terms of observed value changes, and make it part of the KCSAN runtime. The analysis is writer-side focused, given we rely on observed value changes. The approach taken here is (2). While a complete approach requires both (1) and (2), experiments show that the majority of data races involving trivial bit operations on flags variables can be removed with (2) alone. It goes without saying that the filtering of data races using (1) or (2) does _not_ guarantee they are safe! Therefore, limiting ourselves to (2) for now is the conservative choice for setups that wish to enable CONFIG_KCSAN_PERMISSIVE=y. Signed-off-by: Marco Elver Acked-by: Mark Rutland Signed-off-by: Paul E. McKenney --- kernel/kcsan/kcsan_test.c | 32 +++++++++++++++++++++++++++++++ kernel/kcsan/permissive.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c index 8bcffbdef3d3..dc55fd5a36fc 100644 --- a/kernel/kcsan/kcsan_test.c +++ b/kernel/kcsan/kcsan_test.c @@ -414,6 +414,14 @@ static noinline void test_kernel_atomic_builtins(void) __atomic_load_n(&test_var, __ATOMIC_RELAXED); } +static noinline void test_kernel_xor_1bit(void) +{ + /* Do not report data races between the read-writes. */ + kcsan_nestable_atomic_begin(); + test_var ^= 0x10000; + kcsan_nestable_atomic_end(); +} + /* ===== Test cases ===== */ /* Simple test with normal data race. */ @@ -952,6 +960,29 @@ static void test_atomic_builtins(struct kunit *test) KUNIT_EXPECT_FALSE(test, match_never); } +__no_kcsan +static void test_1bit_value_change(struct kunit *test) +{ + const struct expect_report expect = { + .access = { + { test_kernel_read, &test_var, sizeof(test_var), 0 }, + { test_kernel_xor_1bit, &test_var, sizeof(test_var), __KCSAN_ACCESS_RW(KCSAN_ACCESS_WRITE) }, + }, + }; + bool match = false; + + begin_test_checks(test_kernel_read, test_kernel_xor_1bit); + do { + match = IS_ENABLED(CONFIG_KCSAN_PERMISSIVE) + ? report_available() + : report_matches(&expect); + } while (!end_test_checks(match)); + if (IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) + KUNIT_EXPECT_FALSE(test, match); + else + KUNIT_EXPECT_TRUE(test, match); +} + /* * Generate thread counts for all test cases. Values generated are in interval * [2, 5] followed by exponentially increasing thread counts from 8 to 32. @@ -1024,6 +1055,7 @@ static struct kunit_case kcsan_test_cases[] = { KCSAN_KUNIT_CASE(test_jiffies_noreport), KCSAN_KUNIT_CASE(test_seqlock_noreport), KCSAN_KUNIT_CASE(test_atomic_builtins), + KCSAN_KUNIT_CASE(test_1bit_value_change), {}, }; diff --git a/kernel/kcsan/permissive.h b/kernel/kcsan/permissive.h index f90e30800c11..2c01fe4a59ee 100644 --- a/kernel/kcsan/permissive.h +++ b/kernel/kcsan/permissive.h @@ -12,6 +12,8 @@ #ifndef _KERNEL_KCSAN_PERMISSIVE_H #define _KERNEL_KCSAN_PERMISSIVE_H +#include +#include #include /* @@ -22,7 +24,11 @@ static __always_inline bool kcsan_ignore_address(const volatile void *ptr) if (!IS_ENABLED(CONFIG_KCSAN_PERMISSIVE)) return false; - return false; + /* + * Data-racy bitops on current->flags are too common, ignore completely + * for now. + */ + return ptr == ¤t->flags; } /* @@ -41,6 +47,47 @@ kcsan_ignore_data_race(size_t size, int type, u64 old, u64 new, u64 diff) if (type || size > sizeof(long)) return false; + /* + * A common pattern is checking/setting just 1 bit in a variable; for + * example: + * + * if (flags & SOME_FLAG) { ... } + * + * and elsewhere flags is updated concurrently: + * + * flags |= SOME_OTHER_FLAG; // just 1 bit + * + * While it is still recommended that such accesses be marked + * appropriately, in many cases these types of data races are so common + * that marking them all is often unrealistic and left to maintainer + * preference. + * + * The assumption in all cases is that with all known compiler + * optimizations (including those that tear accesses), because no more + * than 1 bit changed, the plain accesses are safe despite the presence + * of data races. + * + * The rules here will ignore the data races if we observe no more than + * 1 bit changed. + * + * Of course many operations can effecively change just 1 bit, but the + * general assuption that data races involving 1-bit changes can be + * tolerated still applies. + * + * And in case a true bug is missed, the bug likely manifests as a + * reportable data race elsewhere. + */ + if (hweight64(diff) == 1) { + /* + * Exception: Report data races where the values look like + * ordinary booleans (one of them was 0 and the 0th bit was + * changed) More often than not, they come with interesting + * memory ordering requirements, so let's report them. + */ + if (!((!old || !new) && diff == 1)) + return true; + } + return false; } -- cgit v1.2.3-70-g09d2 From e04938042d77addc7f41d983aebea125cddbed33 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Tue, 15 Jun 2021 20:39:38 +0200 Subject: kcsan: Make strict mode imply interruptible watchers If CONFIG_KCSAN_STRICT=y, select CONFIG_KCSAN_INTERRUPT_WATCHER as well. With interruptible watchers, we'll also report same-CPU data races; if we requested strict mode, we might as well show these, too. Suggested-by: Paul E. McKenney Signed-off-by: Marco Elver Signed-off-by: Paul E. McKenney --- lib/Kconfig.kcsan | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 26f03c754d39..e0a93ffdef30 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -150,7 +150,8 @@ config KCSAN_SKIP_WATCH_RANDOMIZE KCSAN_WATCH_SKIP. config KCSAN_INTERRUPT_WATCHER - bool "Interruptible watchers" + bool "Interruptible watchers" if !KCSAN_STRICT + default KCSAN_STRICT help If enabled, a task that set up a watchpoint may be interrupted while delayed. This option will allow KCSAN to detect races between -- cgit v1.2.3-70-g09d2 From 1846a7fa767fbf8cf42d71daf75d51e30e3c8327 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 13 May 2021 11:17:02 -0700 Subject: tools/memory-model: Make read_foo_diagnostic() more clearly diagnostic The current definition of read_foo_diagnostic() in the "Lock Protection With Lockless Diagnostic Access" section returns a value, which could be use for any purpose. This could mislead people into incorrectly using data_race() in cases where READ_ONCE() is required. This commit therefore makes read_foo_diagnostic() simply print the value read. Reported-by: Manfred Spraul Signed-off-by: Paul E. McKenney --- tools/memory-model/Documentation/access-marking.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/memory-model/Documentation/access-marking.txt b/tools/memory-model/Documentation/access-marking.txt index 1ab189f51f55..58bff2619876 100644 --- a/tools/memory-model/Documentation/access-marking.txt +++ b/tools/memory-model/Documentation/access-marking.txt @@ -259,9 +259,9 @@ diagnostic purposes. The code might look as follows: return ret; } - int read_foo_diagnostic(void) + void read_foo_diagnostic(void) { - return data_race(foo); + pr_info("Current value of foo: %d\n", data_race(foo)); } The reader-writer lock prevents the compiler from introducing concurrency -- cgit v1.2.3-70-g09d2 From a82adfd5c7cb4b8bb37ef439aed954f9972bb618 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 12 Apr 2021 19:56:54 -0700 Subject: hardening: Introduce CONFIG_ZERO_CALL_USED_REGS When CONFIG_ZERO_CALL_USED_REGS is enabled, build the kernel with "-fzero-call-used-regs=used-gpr" (in GCC 11). This option will zero any caller-used register contents just before returning from a function, ensuring that temporary values are not leaked beyond the function boundary. This means that register contents are less likely to be available for side channel attacks and information exposures. Additionally this helps reduce the number of useful ROP gadgets in the kernel image by about 20%: $ ROPgadget.py --nosys --nojop --binary vmlinux.stock | tail -n1 Unique gadgets found: 337245 $ ROPgadget.py --nosys --nojop --binary vmlinux.zero-call-regs | tail -n1 Unique gadgets found: 267175 and more notably removes simple "write-what-where" gadgets: $ ROPgadget.py --ropchain --binary vmlinux.stock | sed -n '/Step 1/,/Step 2/p' - Step 1 -- Write-what-where gadgets [+] Gadget found: 0xffffffff8102d76c mov qword ptr [rsi], rdx ; ret [+] Gadget found: 0xffffffff81000cf5 pop rsi ; ret [+] Gadget found: 0xffffffff8104d7c8 pop rdx ; ret [-] Can't find the 'xor rdx, rdx' gadget. Try with another 'mov [reg], reg' [+] Gadget found: 0xffffffff814c2b4c mov qword ptr [rsi], rdi ; ret [+] Gadget found: 0xffffffff81000cf5 pop rsi ; ret [+] Gadget found: 0xffffffff81001e51 pop rdi ; ret [-] Can't find the 'xor rdi, rdi' gadget. Try with another 'mov [reg], reg' [+] Gadget found: 0xffffffff81540d61 mov qword ptr [rsi], rdi ; pop rbx ; pop rbp ; ret [+] Gadget found: 0xffffffff81000cf5 pop rsi ; ret [+] Gadget found: 0xffffffff81001e51 pop rdi ; ret [-] Can't find the 'xor rdi, rdi' gadget. Try with another 'mov [reg], reg' [+] Gadget found: 0xffffffff8105341e mov qword ptr [rsi], rax ; ret [+] Gadget found: 0xffffffff81000cf5 pop rsi ; ret [+] Gadget found: 0xffffffff81029a11 pop rax ; ret [+] Gadget found: 0xffffffff811f1c3b xor rax, rax ; ret - Step 2 -- Init syscall number gadgets $ ROPgadget.py --ropchain --binary vmlinux.zero* | sed -n '/Step 1/,/Step 2/p' - Step 1 -- Write-what-where gadgets [-] Can't find the 'mov qword ptr [r64], r64' gadget For an x86_64 parallel build tests, this has a less than 1% performance impact, and grows the image size less than 1%: $ size vmlinux.stock vmlinux.zero-call-regs text data bss dec hex filename 22437676 8559152 14127340 45124168 2b08a48 vmlinux.stock 22453184 8563248 14110956 45127388 2b096dc vmlinux.zero-call-regs Impact for other architectures may vary. For example, arm64 sees a 5.5% image size growth, mainly due to needing to always clear x16 and x17: https://lore.kernel.org/lkml/20210510134503.GA88495@C02TD0UTHF1T.local/ Signed-off-by: Kees Cook --- Makefile | 5 +++++ security/Kconfig.hardening | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Makefile b/Makefile index e4f5895badb5..5def36c7882a 100644 --- a/Makefile +++ b/Makefile @@ -842,6 +842,11 @@ endif # for the randomize_kstack_offset feature. Disable it for all compilers. KBUILD_CFLAGS += $(call cc-option, -fno-stack-clash-protection) +# Clear used registers at func exit (to reduce data lifetime and ROP gadgets). +ifdef CONFIG_ZERO_CALL_USED_REGS +KBUILD_CFLAGS += -fzero-call-used-regs=used-gpr +endif + DEBUG_CFLAGS := # Workaround for GCC versions < 5.0 diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index a56c36470cb1..023aea5e117c 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -217,6 +217,25 @@ config INIT_ON_FREE_DEFAULT_ON touching "cold" memory areas. Most cases see 3-5% impact. Some synthetic workloads have measured as high as 8%. +config CC_HAS_ZERO_CALL_USED_REGS + def_bool $(cc-option,-fzero-call-used-regs=used-gpr) + +config ZERO_CALL_USED_REGS + bool "Enable register zeroing on function exit" + depends on CC_HAS_ZERO_CALL_USED_REGS + help + At the end of functions, always zero any caller-used register + contents. This helps ensure that temporary values are not + leaked beyond the function boundary. This means that register + contents are less likely to be available for side channels + and information exposures. Additionally, this helps reduce the + number of useful ROP gadgets by about 20% (and removes compiler + generated "write-what-where" gadgets) in the resulting kernel + image. This has a less than 1% performance impact on most + workloads. Image size growth depends on architecture, and should + be evaluated for suitability. For example, x86_64 grows by less + than 1%, and arm64 grows by about 5%. + endmenu endmenu -- cgit v1.2.3-70-g09d2 From 7ba46799d34695534666a3f71a2be10ea85ece6c Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:15 -0400 Subject: scsi: core: Add scsi_prot_ref_tag() helper We are about to remove the request pointer from struct scsi_cmnd and that will complicate getting to the ref_tag via t10_pi_ref_tag() in the various drivers. Introduce a helper function to retrieve the reference tag so drivers will not have to worry about the details. Link: https://lore.kernel.org/r/20210609033929.3815-2-martin.petersen@oracle.com Reviewed-by: Bart Van Assche Reviewed-by: Benjamin Block Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-2-martin.petersen@oracle.com> --- include/scsi/scsi_cmnd.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 779a59fe8676..301b9cd4ddd0 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -287,6 +287,13 @@ static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) return blk_rq_pos(scmd->request); } +static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd) +{ + struct request *rq = blk_mq_rq_from_pdu(scmd); + + return t10_pi_ref_tag(rq); +} + static inline unsigned int scsi_prot_interval(struct scsi_cmnd *scmd) { return scmd->device->sector_size; -- cgit v1.2.3-70-g09d2 From e2e9cd68fb3c673f7c1e12792f3137b77f6f7431 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:17 -0400 Subject: scsi: qla2xxx: Use the proper SCSI midlayer interfaces for PI Use the SCSI midlayer interfaces to query protection interval, reference tag, and per-command DIX flags. Link: https://lore.kernel.org/r/20210609033929.3815-4-martin.petersen@oracle.com Reviewed-by: Arun Easi Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-4-martin.petersen@oracle.com> --- drivers/scsi/qla2xxx/qla_iocb.c | 77 +++++++---------------------------------- 1 file changed, 12 insertions(+), 65 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index d0ee843f6b04..1376aafe1c5c 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -145,7 +145,6 @@ inline int qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) { struct scsi_cmnd *cmd = GET_CMD_SP(sp); - uint8_t guard = scsi_host_get_guard(cmd->device->host); /* We always use DIFF Bundling for best performance */ *fw_prot_opts = 0; @@ -166,7 +165,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: - if (guard & SHOST_DIX_GUARD_IP) + if (cmd->prot_flags & SCSI_PROT_IP_CHECKSUM) *fw_prot_opts |= PO_MODE_DIF_TCP_CKSUM; else *fw_prot_opts |= PO_MODE_DIF_PASS; @@ -176,6 +175,9 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts) break; } + if (!(cmd->prot_flags & SCSI_PROT_GUARD_CHECK)) + *fw_prot_opts |= PO_DISABLE_GUARD_CHECK; + return scsi_prot_sg_count(cmd); } @@ -772,74 +774,19 @@ qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, { struct scsi_cmnd *cmd = GET_CMD_SP(sp); - switch (scsi_get_prot_type(cmd)) { - case SCSI_PROT_DIF_TYPE0: - /* - * No check for ql2xenablehba_err_chk, as it would be an - * I/O error if hba tag generation is not done. - */ - pkt->ref_tag = cpu_to_le32((uint32_t) - (0xffffffff & scsi_get_lba(cmd))); - - if (!qla2x00_hba_err_chk_enabled(sp)) - break; + pkt->ref_tag = cpu_to_le32(scsi_prot_ref_tag(cmd)); + if (cmd->prot_flags & SCSI_PROT_REF_CHECK && + qla2x00_hba_err_chk_enabled(sp)) { pkt->ref_tag_mask[0] = 0xff; pkt->ref_tag_mask[1] = 0xff; pkt->ref_tag_mask[2] = 0xff; pkt->ref_tag_mask[3] = 0xff; - break; - - /* - * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to - * match LBA in CDB + N - */ - case SCSI_PROT_DIF_TYPE2: - pkt->app_tag = cpu_to_le16(0); - pkt->app_tag_mask[0] = 0x0; - pkt->app_tag_mask[1] = 0x0; - - pkt->ref_tag = cpu_to_le32((uint32_t) - (0xffffffff & scsi_get_lba(cmd))); - - if (!qla2x00_hba_err_chk_enabled(sp)) - break; - - /* enable ALL bytes of the ref tag */ - pkt->ref_tag_mask[0] = 0xff; - pkt->ref_tag_mask[1] = 0xff; - pkt->ref_tag_mask[2] = 0xff; - pkt->ref_tag_mask[3] = 0xff; - break; - - /* For Type 3 protection: 16 bit GUARD only */ - case SCSI_PROT_DIF_TYPE3: - pkt->ref_tag_mask[0] = pkt->ref_tag_mask[1] = - pkt->ref_tag_mask[2] = pkt->ref_tag_mask[3] = - 0x00; - break; - - /* - * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and - * 16 bit app tag. - */ - case SCSI_PROT_DIF_TYPE1: - pkt->ref_tag = cpu_to_le32((uint32_t) - (0xffffffff & scsi_get_lba(cmd))); - pkt->app_tag = cpu_to_le16(0); - pkt->app_tag_mask[0] = 0x0; - pkt->app_tag_mask[1] = 0x0; - - if (!qla2x00_hba_err_chk_enabled(sp)) - break; - - /* enable ALL bytes of the ref tag */ - pkt->ref_tag_mask[0] = 0xff; - pkt->ref_tag_mask[1] = 0xff; - pkt->ref_tag_mask[2] = 0xff; - pkt->ref_tag_mask[3] = 0xff; - break; } + + pkt->app_tag = cpu_to_le16(0); + pkt->app_tag_mask[0] = 0x0; + pkt->app_tag_mask[1] = 0x0; } int @@ -905,7 +852,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, memset(&sgx, 0, sizeof(struct qla2_sgx)); if (sp) { cmd = GET_CMD_SP(sp); - prot_int = cmd->device->sector_size; + prot_int = scsi_prot_interval(cmd); sgx.tot_bytes = scsi_bufflen(cmd); sgx.cur_sg = scsi_sglist(cmd); -- cgit v1.2.3-70-g09d2 From 73e61d5c22bfad25573a5373739ee1be8bb7d63d Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:20 -0400 Subject: scsi: zfcp: Use the proper SCSI midlayer interfaces for PI Use scsi_prot_ref_tag() and scsi_prot_interval() instead scsi_get_lba() and sector_size. Link: https://lore.kernel.org/r/20210609033929.3815-7-martin.petersen@oracle.com Reviewed-by: Benjamin Block Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-7-martin.petersen@oracle.com> --- drivers/s390/scsi/zfcp_fsf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 2e4804ef2fb9..1990216cf289 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2599,8 +2599,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) io->fcp_cmnd_length = FCP_CMND_LEN; if (scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) { - io->data_block_length = scsi_cmnd->device->sector_size; - io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF; + io->data_block_length = scsi_prot_interval(scsi_cmnd); + io->ref_tag_value = scsi_prot_ref_tag(scsi_cmnd); } if (zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction)) -- cgit v1.2.3-70-g09d2 From c78be80d20cd52c302b92640550087ede9c4304a Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:22 -0400 Subject: scsi: scsi_debug: Remove dump_sector() The function used to dump sectors containing protection information errors was useful during initial development over a decade ago. However, dump_sector() substantially slows down the system during testing due to writing an entire sector's worth of data to syslog on every error. We now log plenty of information about the nature of detected protection information errors throughout the stack. Dumping the entire contents of an offending sector is no longer needed. Link: https://lore.kernel.org/r/20210609033929.3815-9-martin.petersen@oracle.com Reviewed-by: Bart Van Assche Reviewed-by: Douglas Gilbert Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-9-martin.petersen@oracle.com> --- drivers/scsi/scsi_debug.c | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5b3a20a140f9..9033ab4911ba 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -3232,28 +3232,6 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) return 0; } -static void dump_sector(unsigned char *buf, int len) -{ - int i, j, n; - - pr_err(">>> Sector Dump <<<\n"); - for (i = 0 ; i < len ; i += 16) { - char b[128]; - - for (j = 0, n = 0; j < 16; j++) { - unsigned char c = buf[i+j]; - - if (c >= 0x20 && c < 0x7e) - n += scnprintf(b + n, sizeof(b) - n, - " %c ", buf[i+j]); - else - n += scnprintf(b + n, sizeof(b) - n, - "%02x ", buf[i+j]); - } - pr_err("%04d: %s\n", i, b); - } -} - static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, unsigned int sectors, u32 ei_lba) { @@ -3300,10 +3278,8 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, daddr = diter.addr + dpage_offset; ret = dif_verify(sdt, daddr, sector, ei_lba); - if (ret) { - dump_sector(daddr, sdebug_sector_size); + if (ret) goto out; - } sector++; ei_lba++; -- cgit v1.2.3-70-g09d2 From f7be677227a5375cefd084df2c88864fc673e24a Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:23 -0400 Subject: scsi: scsi_debug: Improve RDPROTECT/WRPROTECT handling It is useful for testing purposes to be able to inject errors by writing bad protection information to media with checking disabled and then attempting to read it back. Extend scsi_debug's PI verification logic to give the driver feature parity with commercially available drives. Almost all devices with PI capability support RDPROTECT and WRPROTECT values of 0, 1, and 3. Link: https://lore.kernel.org/r/20210609033929.3815-10-martin.petersen@oracle.com Reviewed-by: Douglas Gilbert Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-10-martin.petersen@oracle.com> --- drivers/scsi/scsi_debug.c | 90 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 9033ab4911ba..25112b15ab14 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -3076,6 +3076,7 @@ static void dif_copy_prot(struct scsi_cmnd *scp, sector_t sector, static int prot_verify_read(struct scsi_cmnd *scp, sector_t start_sec, unsigned int sectors, u32 ei_lba) { + int ret = 0; unsigned int i; sector_t sector; struct sdeb_store_info *sip = devip2sip((struct sdebug_dev_info *) @@ -3083,26 +3084,33 @@ static int prot_verify_read(struct scsi_cmnd *scp, sector_t start_sec, struct t10_pi_tuple *sdt; for (i = 0; i < sectors; i++, ei_lba++) { - int ret; - sector = start_sec + i; sdt = dif_store(sip, sector); if (sdt->app_tag == cpu_to_be16(0xffff)) continue; - ret = dif_verify(sdt, lba2fake_store(sip, sector), sector, - ei_lba); - if (ret) { - dif_errors++; - return ret; + /* + * Because scsi_debug acts as both initiator and + * target we proceed to verify the PI even if + * RDPROTECT=3. This is done so the "initiator" knows + * which type of error to return. Otherwise we would + * have to iterate over the PI twice. + */ + if (scp->cmnd[1] >> 5) { /* RDPROTECT */ + ret = dif_verify(sdt, lba2fake_store(sip, sector), + sector, ei_lba); + if (ret) { + dif_errors++; + break; + } } } dif_copy_prot(scp, start_sec, sectors, true); dix_reads++; - return 0; + return ret; } static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) @@ -3196,12 +3204,29 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) /* DIX + T10 DIF */ if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { - int prot_ret = prot_verify_read(scp, lba, num, ei_lba); - - if (prot_ret) { - read_unlock(macc_lckp); - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, prot_ret); - return illegal_condition_result; + switch (prot_verify_read(scp, lba, num, ei_lba)) { + case 1: /* Guard tag error */ + if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ + read_unlock(macc_lckp); + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); + return check_condition_result; + } else if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { + read_unlock(macc_lckp); + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); + return illegal_condition_result; + } + break; + case 3: /* Reference tag error */ + if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ + read_unlock(macc_lckp); + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 3); + return check_condition_result; + } else if (scp->prot_flags & SCSI_PROT_REF_CHECK) { + read_unlock(macc_lckp); + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 3); + return illegal_condition_result; + } + break; } } @@ -3277,9 +3302,11 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, sdt = piter.addr + ppage_offset; daddr = diter.addr + dpage_offset; - ret = dif_verify(sdt, daddr, sector, ei_lba); - if (ret) - goto out; + if (SCpnt->cmnd[1] >> 5 != 3) { /* WRPROTECT */ + ret = dif_verify(sdt, daddr, sector, ei_lba); + if (ret) + goto out; + } sector++; ei_lba++; @@ -3456,12 +3483,29 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) /* DIX + T10 DIF */ if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { - int prot_ret = prot_verify_write(scp, lba, num, ei_lba); - - if (prot_ret) { - write_unlock(macc_lckp); - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, prot_ret); - return illegal_condition_result; + switch (prot_verify_write(scp, lba, num, ei_lba)) { + case 1: /* Guard tag error */ + if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { + write_unlock(macc_lckp); + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); + return illegal_condition_result; + } else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ + write_unlock(macc_lckp); + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); + return check_condition_result; + } + break; + case 3: /* Reference tag error */ + if (scp->prot_flags & SCSI_PROT_REF_CHECK) { + write_unlock(macc_lckp); + mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 3); + return illegal_condition_result; + } else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ + write_unlock(macc_lckp); + mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 3); + return check_condition_result; + } + break; } } -- cgit v1.2.3-70-g09d2 From f0f214fe8cd32224267ebea93817b8c32074623d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 8 Jun 2021 23:39:24 -0400 Subject: scsi: core: Introduce scsi_get_sector() Since scsi_get_lba() returns a sector_t value instead of the LBA, the name of that function is confusing. Introduce an identical function scsi_get_sector(). Link: https://lore.kernel.org/r/20210513223757.3938-2-bvanassche@acm.org Link: https://lore.kernel.org/r/20210609033929.3815-11-martin.petersen@oracle.com Cc: Christoph Hellwig Cc: Ming Lei Cc: Hannes Reinecke Reviewed-by: Damien Le Moal Reviewed-by: Benjamin Block Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-11-martin.petersen@oracle.com> --- include/scsi/scsi_cmnd.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 301b9cd4ddd0..cba63377d46a 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -220,6 +220,11 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, buf, buflen); } +static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) +{ + return blk_rq_pos(scmd->request); +} + /* * The operations below are hints that tell the controller driver how * to handle I/Os with DIF or similar types of protection information. -- cgit v1.2.3-70-g09d2 From 87662a472a9d8980b26ba5803447df2c4981d467 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 8 Jun 2021 23:39:25 -0400 Subject: scsi: iser: Use scsi_get_sector() instead of scsi_get_lba() Use scsi_get_sector() instead of scsi_get_lba() since the name of the latter is confusing. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210513223757.3938-3-bvanassche@acm.org Link: https://lore.kernel.org/r/20210609033929.3815-12-martin.petersen@oracle.com Reviewed-by: Sagi Grimberg Reviewed-by: Damien Le Moal Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-12-martin.petersen@oracle.com> --- drivers/infiniband/ulp/iser/iser_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index b44cbb8e84eb..b566f7cb7797 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -949,7 +949,7 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, sector_t sector_off = mr_status.sig_err.sig_err_offset; sector_div(sector_off, sector_size + 8); - *sector = scsi_get_lba(iser_task->sc) + sector_off; + *sector = scsi_get_sector(iser_task->sc) + sector_off; iser_err("PI error found type %d at sector %llx " "expected %x vs actual %x\n", -- cgit v1.2.3-70-g09d2 From d2c945f01d233085fedc9e3cf7ec180eaa2b7a85 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:26 -0400 Subject: scsi: core: Make scsi_get_lba() return the LBA scsi_get_lba() confusingly returned the block layer sector number expressed in units of 512 bytes. Now that we have a more aptly named scsi_get_sector() function, make scsi_get_lba() return the actual LBA. Link: https://lore.kernel.org/r/20210609033929.3815-13-martin.petersen@oracle.com Reviewed-by: Bart Van Assche Reviewed-by: Benjamin Block Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-13-martin.petersen@oracle.com> --- include/scsi/scsi_cmnd.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index cba63377d46a..90da9617d28a 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -225,6 +225,13 @@ static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) return blk_rq_pos(scmd->request); } +static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) +{ + unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; + + return blk_rq_pos(scmd->request) >> shift; +} + /* * The operations below are hints that tell the controller driver how * to handle I/Os with DIF or similar types of protection information. @@ -287,11 +294,6 @@ static inline unsigned char scsi_get_prot_type(struct scsi_cmnd *scmd) return scmd->prot_type; } -static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) -{ - return blk_rq_pos(scmd->request); -} - static inline u32 scsi_prot_ref_tag(struct scsi_cmnd *scmd) { struct request *rq = blk_mq_rq_from_pdu(scmd); -- cgit v1.2.3-70-g09d2 From 54815088859fa766c7879a06ee028e0cee4f589e Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 8 Jun 2021 23:39:29 -0400 Subject: scsi: ufs: core: Use scsi_get_lba() to get LBA Use the scsi_get_lba() helper instead of a function internal to the SCSI disk driver. Remove #include "sd.h". Link: https://lore.kernel.org/r/20210609033929.3815-16-martin.petersen@oracle.com Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen Message-Id: <20210609033929.3815-16-martin.petersen@oracle.com> --- drivers/scsi/ufs/ufshcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 708b3b62fc4d..064a44e628d6 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -25,7 +25,6 @@ #include "ufs_bsg.h" #include "ufshcd-crypto.h" #include -#include "../sd.h" #define CREATE_TRACE_POINTS #include @@ -390,7 +389,7 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, /* trace UPIU also */ ufshcd_add_cmd_upiu_trace(hba, tag, str_t); opcode = cmd->cmnd[0]; - lba = sectors_to_logical(cmd->device, blk_rq_pos(cmd->request)); + lba = scsi_get_lba(cmd); if (opcode == READ_10 || opcode == WRITE_10) { /* -- cgit v1.2.3-70-g09d2 From e15f669cd996b85bb07b0e787fa78806477bf211 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Fri, 16 Jul 2021 15:45:51 +0800 Subject: scsi: libsas: Allow libsas to include SCSI header files directly libsas needs to include some header files in the scsi directory. However these are currently hardcoded with the path "../" in the C files. Do this in the Makefile to avoid hardcoding the path. Link: https://lore.kernel.org/r/20210716074551.771312-1-yanaijie@huawei.com Cc: John Garry Reviewed-by: John Garry Signed-off-by: Jason Yan Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/Makefile | 2 +- drivers/scsi/libsas/sas_ata.c | 4 ++-- drivers/scsi/libsas/sas_discover.c | 2 +- drivers/scsi/libsas/sas_expander.c | 2 +- drivers/scsi/libsas/sas_host_smp.c | 2 +- drivers/scsi/libsas/sas_init.c | 2 +- drivers/scsi/libsas/sas_phy.c | 2 +- drivers/scsi/libsas/sas_port.c | 2 +- drivers/scsi/libsas/sas_scsi_host.c | 6 +++--- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile index e63a54f5ab8c..9dc32736cf21 100644 --- a/drivers/scsi/libsas/Makefile +++ b/drivers/scsi/libsas/Makefile @@ -18,4 +18,4 @@ libsas-y += sas_init.o \ libsas-$(CONFIG_SCSI_SAS_ATA) += sas_ata.o libsas-$(CONFIG_SCSI_SAS_HOST_SMP) += sas_host_smp.o -ccflags-y := -DDEBUG +ccflags-y := -DDEBUG -I$(srctree)/drivers/scsi diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 4aa1fda95f35..1e0df6b17227 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -20,8 +20,8 @@ #include #include #include -#include "../scsi_sas_internal.h" -#include "../scsi_transport_api.h" +#include "scsi_sas_internal.h" +#include "scsi_transport_api.h" #include static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index dd205414e505..12e1e36d7c04 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -16,7 +16,7 @@ #include #include #include -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" /* ---------- Basic task processing for discovery purposes ---------- */ diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index e00688540219..c2150a818423 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -18,7 +18,7 @@ #include #include #include -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" static int sas_discover_expander(struct domain_device *dev); static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr); diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c index eca2a6bf3601..32cdc969b736 100644 --- a/drivers/scsi/libsas/sas_host_smp.c +++ b/drivers/scsi/libsas/sas_host_smp.c @@ -14,7 +14,7 @@ #include #include -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" static void sas_host_smp_discover(struct sas_ha_struct *sas_ha, u8 *resp_data, u8 phy_id) diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 2b0f98ca6ec3..80592f53017a 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -19,7 +19,7 @@ #include "sas_internal.h" -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" static struct kmem_cache *sas_task_cache; static struct kmem_cache *sas_event_cache; diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index 4ca4b1f30bd0..a0d592d11dfb 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c @@ -10,7 +10,7 @@ #include #include #include -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" /* ---------- Phy events ---------- */ diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index e3d03d744713..67b429dcf1ff 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -10,7 +10,7 @@ #include #include -#include "../scsi_sas_internal.h" +#include "scsi_sas_internal.h" static bool phy_is_wideport_member(struct asd_sas_port *port, struct asd_sas_phy *phy) { diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index ee44a0d7730b..5db10248f187 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -22,9 +22,9 @@ #include #include #include -#include "../scsi_sas_internal.h" -#include "../scsi_transport_api.h" -#include "../scsi_priv.h" +#include "scsi_sas_internal.h" +#include "scsi_transport_api.h" +#include "scsi_priv.h" #include #include -- cgit v1.2.3-70-g09d2 From 3ecfc9135e6c82183d121c5578ed5d6f07a53ec8 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:09 -0700 Subject: dmaengine: idxd: add driver register helper Add helper functions for dsa-driver registration similar to other bus-types. In particular, do not require dsa-drivers to open-code the bus, owner, and mod_name fields. Let registration and unregistration operate on the 'struct idxd_device_driver' instead of the raw / embedded 'struct device_driver'. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637458949.744545.14996726325385482050.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 7 +++++++ drivers/dma/idxd/init.c | 17 +++++++++++++++++ drivers/dma/idxd/sysfs.c | 7 ++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index d875b3d41ed2..8db19b899709 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -402,6 +402,13 @@ static inline int idxd_wq_refcount(struct idxd_wq *wq) return wq->client_count; }; +int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, + struct module *module, const char *mod_name); +#define idxd_driver_register(driver) \ + __idxd_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) + +void idxd_driver_unregister(struct idxd_device_driver *idxd_drv); + int idxd_register_bus_type(void); void idxd_unregister_bus_type(void); int idxd_register_devices(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 75ac6a4bc9d1..b15817751d5f 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -855,3 +855,20 @@ static void __exit idxd_exit_module(void) perfmon_exit(); } module_exit(idxd_exit_module); + +int __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *owner, + const char *mod_name) +{ + struct device_driver *drv = &idxd_drv->drv; + + drv->bus = &dsa_bus_type; + drv->owner = owner; + drv->mod_name = mod_name; + + return driver_register(drv); +} + +void idxd_driver_unregister(struct idxd_device_driver *idxd_drv) +{ + driver_unregister(&idxd_drv->drv); +} diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 33c27df40f1e..bf229b12d527 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -313,21 +313,18 @@ struct bus_type dsa_bus_type = { static struct idxd_device_driver dsa_drv = { .drv = { .name = "dsa", - .bus = &dsa_bus_type, - .owner = THIS_MODULE, - .mod_name = KBUILD_MODNAME, }, }; /* IDXD generic driver setup */ int idxd_register_driver(void) { - return driver_register(&dsa_drv.drv); + return idxd_driver_register(&dsa_drv); } void idxd_unregister_driver(void) { - driver_unregister(&dsa_drv.drv); + idxd_driver_unregister(&dsa_drv); } /* IDXD engine attributes */ -- cgit v1.2.3-70-g09d2 From da5a11d75d6837c9c5ef40810f66ce9d2db6ca5e Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:15 -0700 Subject: dmaengine: idxd: add driver name Add name field in idxd_device_driver so we don't have to touch the 'struct device_driver' during declaration. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637459517.744545.7572915135318813722.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/init.c | 1 + drivers/dma/idxd/sysfs.c | 4 +--- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 8db19b899709..e8721ff028c2 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -34,6 +34,7 @@ enum idxd_type { #define IDXD_PMU_EVENT_MAX 64 struct idxd_device_driver { + const char *name; struct device_driver drv; }; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index b15817751d5f..6403d55c7ff7 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -861,6 +861,7 @@ int __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *o { struct device_driver *drv = &idxd_drv->drv; + drv->name = idxd_drv->name; drv->bus = &dsa_bus_type; drv->owner = owner; drv->mod_name = mod_name; diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index bf229b12d527..60779f57c118 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -311,9 +311,7 @@ struct bus_type dsa_bus_type = { }; static struct idxd_device_driver dsa_drv = { - .drv = { - .name = "dsa", - }, + .name = "dsa", }; /* IDXD generic driver setup */ -- cgit v1.2.3-70-g09d2 From 700af3a0a26cbac87e4a0ae1dfa79597d0056d5f Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:20 -0700 Subject: dmaengine: idxd: add 'struct idxd_dev' as wrapper for conf_dev Add a 'struct idxd_dev' that wraps the 'struct device' for idxd conf_dev that registers with the dsa bus. This is introduced in order to deal with multiple different types of 'devices' that are registered on the dsa_bus when the compat driver needs to route them to the correct driver to attach. The bind() call now can determine the type of device and then do the appropriate driver matching. Reviewed-by Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637460065.744545.584492831446090984.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/cdev.c | 11 ++- drivers/dma/idxd/dma.c | 4 +- drivers/dma/idxd/idxd.h | 82 ++++++++++++++-- drivers/dma/idxd/init.c | 98 +++++++++++-------- drivers/dma/idxd/irq.c | 2 +- drivers/dma/idxd/sysfs.c | 239 +++++++++++++++++++++-------------------------- 6 files changed, 251 insertions(+), 185 deletions(-) diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index e9def577c697..18a003b93812 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -41,7 +41,7 @@ struct idxd_user_context { static void idxd_cdev_dev_release(struct device *dev) { - struct idxd_cdev *idxd_cdev = container_of(dev, struct idxd_cdev, dev); + struct idxd_cdev *idxd_cdev = dev_to_cdev(dev); struct idxd_cdev_context *cdev_ctx; struct idxd_wq *wq = idxd_cdev->wq; @@ -256,9 +256,10 @@ int idxd_wq_add_cdev(struct idxd_wq *wq) if (!idxd_cdev) return -ENOMEM; + idxd_cdev->idxd_dev.type = IDXD_DEV_CDEV; idxd_cdev->wq = wq; cdev = &idxd_cdev->cdev; - dev = &idxd_cdev->dev; + dev = cdev_dev(idxd_cdev); cdev_ctx = &ictx[wq->idxd->data->type]; minor = ida_simple_get(&cdev_ctx->minor_ida, 0, MINORMASK, GFP_KERNEL); if (minor < 0) { @@ -268,7 +269,7 @@ int idxd_wq_add_cdev(struct idxd_wq *wq) idxd_cdev->minor = minor; device_initialize(dev); - dev->parent = &wq->conf_dev; + dev->parent = wq_confdev(wq); dev->bus = &dsa_bus_type; dev->type = &idxd_cdev_device_type; dev->devt = MKDEV(MAJOR(cdev_ctx->devt), minor); @@ -299,8 +300,8 @@ void idxd_wq_del_cdev(struct idxd_wq *wq) idxd_cdev = wq->idxd_cdev; wq->idxd_cdev = NULL; - cdev_device_del(&idxd_cdev->cdev, &idxd_cdev->dev); - put_device(&idxd_cdev->dev); + cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev)); + put_device(cdev_dev(idxd_cdev)); } int idxd_cdev_register(void) diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index 77439b645044..2e52f9a50519 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -245,7 +245,7 @@ int idxd_register_dma_channel(struct idxd_wq *wq) wq->idxd_chan = idxd_chan; idxd_chan->wq = wq; - get_device(&wq->conf_dev); + get_device(wq_confdev(wq)); return 0; } @@ -260,5 +260,5 @@ void idxd_unregister_dma_channel(struct idxd_wq *wq) list_del(&chan->device_node); kfree(wq->idxd_chan); wq->idxd_chan = NULL; - put_device(&wq->conf_dev); + put_device(wq_confdev(wq)); } diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index e8721ff028c2..ae60fcc7b625 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -17,8 +17,24 @@ extern struct kmem_cache *idxd_desc_pool; -struct idxd_device; struct idxd_wq; +struct idxd_dev; + +enum idxd_dev_type { + IDXD_DEV_NONE = -1, + IDXD_DEV_DSA = 0, + IDXD_DEV_IAX, + IDXD_DEV_WQ, + IDXD_DEV_GROUP, + IDXD_DEV_ENGINE, + IDXD_DEV_CDEV, + IDXD_DEV_MAX_TYPE, +}; + +struct idxd_dev { + struct device conf_dev; + enum idxd_dev_type type; +}; #define IDXD_REG_TIMEOUT 50 #define IDXD_DRAIN_TIMEOUT 5000 @@ -52,7 +68,7 @@ struct idxd_irq_entry { }; struct idxd_group { - struct device conf_dev; + struct idxd_dev idxd_dev; struct idxd_device *idxd; struct grpcfg grpcfg; int id; @@ -111,7 +127,7 @@ enum idxd_wq_type { struct idxd_cdev { struct idxd_wq *wq; struct cdev cdev; - struct device dev; + struct idxd_dev idxd_dev; int minor; }; @@ -139,7 +155,7 @@ struct idxd_wq { void __iomem *portal; struct percpu_ref wq_active; struct completion wq_dead; - struct device conf_dev; + struct idxd_dev idxd_dev; struct idxd_cdev *idxd_cdev; struct wait_queue_head err_queue; struct idxd_device *idxd; @@ -174,7 +190,7 @@ struct idxd_wq { }; struct idxd_engine { - struct device conf_dev; + struct idxd_dev idxd_dev; int id; struct idxd_group *group; struct idxd_device *idxd; @@ -218,7 +234,7 @@ struct idxd_driver_data { }; struct idxd_device { - struct device conf_dev; + struct idxd_dev idxd_dev; struct idxd_driver_data *data; struct list_head list; struct idxd_hw hw; @@ -301,8 +317,58 @@ enum idxd_completion_status { IDXD_COMP_DESC_ABORT = 0xff, }; -#define confdev_to_idxd(dev) container_of(dev, struct idxd_device, conf_dev) -#define confdev_to_wq(dev) container_of(dev, struct idxd_wq, conf_dev) +#define idxd_confdev(idxd) &idxd->idxd_dev.conf_dev +#define wq_confdev(wq) &wq->idxd_dev.conf_dev +#define engine_confdev(engine) &engine->idxd_dev.conf_dev +#define group_confdev(group) &group->idxd_dev.conf_dev +#define cdev_dev(cdev) &cdev->idxd_dev.conf_dev + +#define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev) + +static inline struct idxd_device *confdev_to_idxd(struct device *dev) +{ + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return container_of(idxd_dev, struct idxd_device, idxd_dev); +} + +static inline struct idxd_wq *confdev_to_wq(struct device *dev) +{ + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return container_of(idxd_dev, struct idxd_wq, idxd_dev); +} + +static inline struct idxd_engine *confdev_to_engine(struct device *dev) +{ + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return container_of(idxd_dev, struct idxd_engine, idxd_dev); +} + +static inline struct idxd_group *confdev_to_group(struct device *dev) +{ + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return container_of(idxd_dev, struct idxd_group, idxd_dev); +} + +static inline struct idxd_cdev *dev_to_cdev(struct device *dev) +{ + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return container_of(idxd_dev, struct idxd_cdev, idxd_dev); +} + +static inline void idxd_dev_set_type(struct idxd_dev *idev, int type) +{ + if (type >= IDXD_DEV_MAX_TYPE) { + idev->type = IDXD_DEV_NONE; + return; + } + + idev->type = type; +} extern struct bus_type dsa_bus_type; extern struct bus_type iax_bus_type; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 6403d55c7ff7..f500076882d2 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -200,6 +200,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd) { struct device *dev = &idxd->pdev->dev; struct idxd_wq *wq; + struct device *conf_dev; int i, rc; idxd->wqs = kcalloc_node(idxd->max_wqs, sizeof(struct idxd_wq *), @@ -214,15 +215,17 @@ static int idxd_setup_wqs(struct idxd_device *idxd) goto err; } + idxd_dev_set_type(&wq->idxd_dev, IDXD_DEV_WQ); + conf_dev = wq_confdev(wq); wq->id = i; wq->idxd = idxd; - device_initialize(&wq->conf_dev); - wq->conf_dev.parent = &idxd->conf_dev; - wq->conf_dev.bus = &dsa_bus_type; - wq->conf_dev.type = &idxd_wq_device_type; - rc = dev_set_name(&wq->conf_dev, "wq%d.%d", idxd->id, wq->id); + device_initialize(wq_confdev(wq)); + conf_dev->parent = idxd_confdev(idxd); + conf_dev->bus = &dsa_bus_type; + conf_dev->type = &idxd_wq_device_type; + rc = dev_set_name(conf_dev, "wq%d.%d", idxd->id, wq->id); if (rc < 0) { - put_device(&wq->conf_dev); + put_device(conf_dev); goto err; } @@ -233,7 +236,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd) wq->max_batch_size = idxd->max_batch_size; wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); if (!wq->wqcfg) { - put_device(&wq->conf_dev); + put_device(conf_dev); rc = -ENOMEM; goto err; } @@ -243,8 +246,11 @@ static int idxd_setup_wqs(struct idxd_device *idxd) return 0; err: - while (--i >= 0) - put_device(&idxd->wqs[i]->conf_dev); + while (--i >= 0) { + wq = idxd->wqs[i]; + conf_dev = wq_confdev(wq); + put_device(conf_dev); + } return rc; } @@ -252,6 +258,7 @@ static int idxd_setup_engines(struct idxd_device *idxd) { struct idxd_engine *engine; struct device *dev = &idxd->pdev->dev; + struct device *conf_dev; int i, rc; idxd->engines = kcalloc_node(idxd->max_engines, sizeof(struct idxd_engine *), @@ -266,15 +273,17 @@ static int idxd_setup_engines(struct idxd_device *idxd) goto err; } + idxd_dev_set_type(&engine->idxd_dev, IDXD_DEV_ENGINE); + conf_dev = engine_confdev(engine); engine->id = i; engine->idxd = idxd; - device_initialize(&engine->conf_dev); - engine->conf_dev.parent = &idxd->conf_dev; - engine->conf_dev.bus = &dsa_bus_type; - engine->conf_dev.type = &idxd_engine_device_type; - rc = dev_set_name(&engine->conf_dev, "engine%d.%d", idxd->id, engine->id); + device_initialize(conf_dev); + conf_dev->parent = idxd_confdev(idxd); + conf_dev->bus = &dsa_bus_type; + conf_dev->type = &idxd_engine_device_type; + rc = dev_set_name(conf_dev, "engine%d.%d", idxd->id, engine->id); if (rc < 0) { - put_device(&engine->conf_dev); + put_device(conf_dev); goto err; } @@ -284,14 +293,18 @@ static int idxd_setup_engines(struct idxd_device *idxd) return 0; err: - while (--i >= 0) - put_device(&idxd->engines[i]->conf_dev); + while (--i >= 0) { + engine = idxd->engines[i]; + conf_dev = engine_confdev(engine); + put_device(conf_dev); + } return rc; } static int idxd_setup_groups(struct idxd_device *idxd) { struct device *dev = &idxd->pdev->dev; + struct device *conf_dev; struct idxd_group *group; int i, rc; @@ -307,15 +320,17 @@ static int idxd_setup_groups(struct idxd_device *idxd) goto err; } + idxd_dev_set_type(&group->idxd_dev, IDXD_DEV_GROUP); + conf_dev = group_confdev(group); group->id = i; group->idxd = idxd; - device_initialize(&group->conf_dev); - group->conf_dev.parent = &idxd->conf_dev; - group->conf_dev.bus = &dsa_bus_type; - group->conf_dev.type = &idxd_group_device_type; - rc = dev_set_name(&group->conf_dev, "group%d.%d", idxd->id, group->id); + device_initialize(conf_dev); + conf_dev->parent = idxd_confdev(idxd); + conf_dev->bus = &dsa_bus_type; + conf_dev->type = &idxd_group_device_type; + rc = dev_set_name(conf_dev, "group%d.%d", idxd->id, group->id); if (rc < 0) { - put_device(&group->conf_dev); + put_device(conf_dev); goto err; } @@ -327,8 +342,10 @@ static int idxd_setup_groups(struct idxd_device *idxd) return 0; err: - while (--i >= 0) - put_device(&idxd->groups[i]->conf_dev); + while (--i >= 0) { + group = idxd->groups[i]; + put_device(group_confdev(group)); + } return rc; } @@ -337,11 +354,11 @@ static void idxd_cleanup_internals(struct idxd_device *idxd) int i; for (i = 0; i < idxd->max_groups; i++) - put_device(&idxd->groups[i]->conf_dev); + put_device(group_confdev(idxd->groups[i])); for (i = 0; i < idxd->max_engines; i++) - put_device(&idxd->engines[i]->conf_dev); + put_device(engine_confdev(idxd->engines[i])); for (i = 0; i < idxd->max_wqs; i++) - put_device(&idxd->wqs[i]->conf_dev); + put_device(wq_confdev(idxd->wqs[i])); destroy_workqueue(idxd->wq); } @@ -381,13 +398,13 @@ static int idxd_setup_internals(struct idxd_device *idxd) err_wkq_create: for (i = 0; i < idxd->max_groups; i++) - put_device(&idxd->groups[i]->conf_dev); + put_device(group_confdev(idxd->groups[i])); err_group: for (i = 0; i < idxd->max_engines; i++) - put_device(&idxd->engines[i]->conf_dev); + put_device(engine_confdev(idxd->engines[i])); err_engine: for (i = 0; i < idxd->max_wqs; i++) - put_device(&idxd->wqs[i]->conf_dev); + put_device(wq_confdev(idxd->wqs[i])); err_wqs: kfree(idxd->int_handles); return rc; @@ -469,6 +486,7 @@ static void idxd_read_caps(struct idxd_device *idxd) static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data) { struct device *dev = &pdev->dev; + struct device *conf_dev; struct idxd_device *idxd; int rc; @@ -476,19 +494,21 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d if (!idxd) return NULL; + conf_dev = idxd_confdev(idxd); idxd->pdev = pdev; idxd->data = data; + idxd_dev_set_type(&idxd->idxd_dev, idxd->data->type); idxd->id = ida_alloc(&idxd_ida, GFP_KERNEL); if (idxd->id < 0) return NULL; - device_initialize(&idxd->conf_dev); - idxd->conf_dev.parent = dev; - idxd->conf_dev.bus = &dsa_bus_type; - idxd->conf_dev.type = idxd->data->dev_type; - rc = dev_set_name(&idxd->conf_dev, "%s%d", idxd->data->name_prefix, idxd->id); + device_initialize(conf_dev); + conf_dev->parent = dev; + conf_dev->bus = &dsa_bus_type; + conf_dev->type = idxd->data->dev_type; + rc = dev_set_name(conf_dev, "%s%d", idxd->data->name_prefix, idxd->id); if (rc < 0) { - put_device(&idxd->conf_dev); + put_device(conf_dev); return NULL; } @@ -674,7 +694,7 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) err: pci_iounmap(pdev, idxd->reg_base); err_iomap: - put_device(&idxd->conf_dev); + put_device(idxd_confdev(idxd)); err_idxd_alloc: pci_disable_device(pdev); return rc; @@ -787,7 +807,7 @@ static void idxd_remove(struct pci_dev *pdev) pci_disable_device(pdev); destroy_workqueue(idxd->wq); perfmon_pmu_remove(idxd); - device_unregister(&idxd->conf_dev); + device_unregister(idxd_confdev(idxd)); } static struct pci_driver idxd_pci_driver = { diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 2924819ca8f3..be65d55e1fc4 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -51,7 +51,7 @@ static void idxd_device_reinit(struct work_struct *work) rc = idxd_wq_enable(wq); if (rc < 0) { dev_warn(dev, "Unable to re-enable wq %s\n", - dev_name(&wq->conf_dev)); + dev_name(wq_confdev(wq))); } } } diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 60779f57c118..f603b11141c4 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -164,7 +164,7 @@ static int enable_wq(struct idxd_wq *wq) } mutex_unlock(&wq->wq_lock); - dev_info(dev, "wq %s enabled\n", dev_name(&wq->conf_dev)); + dev_info(dev, "wq %s enabled\n", dev_name(wq_confdev(wq))); return 0; } @@ -230,7 +230,7 @@ static void disable_wq(struct idxd_wq *wq) struct device *dev = &idxd->pdev->dev; mutex_lock(&wq->wq_lock); - dev_dbg(dev, "%s removing WQ %s\n", __func__, dev_name(&wq->conf_dev)); + dev_dbg(dev, "%s removing WQ %s\n", __func__, dev_name(wq_confdev(wq))); if (wq->state == IDXD_WQ_DISABLED) { mutex_unlock(&wq->wq_lock); return; @@ -257,7 +257,7 @@ static void disable_wq(struct idxd_wq *wq) wq->client_count = 0; mutex_unlock(&wq->wq_lock); - dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev)); + dev_info(dev, "wq %s disabled\n", dev_name(wq_confdev(wq))); } static int idxd_config_bus_remove(struct device *dev) @@ -274,15 +274,15 @@ static int idxd_config_bus_remove(struct device *dev) int i; dev_dbg(dev, "%s removing dev %s\n", __func__, - dev_name(&idxd->conf_dev)); + dev_name(idxd_confdev(idxd))); for (i = 0; i < idxd->max_wqs; i++) { struct idxd_wq *wq = idxd->wqs[i]; if (wq->state == IDXD_WQ_DISABLED) continue; dev_warn(dev, "Active wq %d on disable %s.\n", i, - dev_name(&idxd->conf_dev)); - device_release_driver(&wq->conf_dev); + dev_name(wq_confdev(wq))); + device_release_driver(wq_confdev(wq)); } idxd_unregister_dma_device(idxd); @@ -329,8 +329,7 @@ void idxd_unregister_driver(void) static ssize_t engine_group_id_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_engine *engine = - container_of(dev, struct idxd_engine, conf_dev); + struct idxd_engine *engine = confdev_to_engine(dev); if (engine->group) return sysfs_emit(buf, "%d\n", engine->group->id); @@ -342,8 +341,7 @@ static ssize_t engine_group_id_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_engine *engine = - container_of(dev, struct idxd_engine, conf_dev); + struct idxd_engine *engine = confdev_to_engine(dev); struct idxd_device *idxd = engine->idxd; long id; int rc; @@ -397,7 +395,7 @@ static const struct attribute_group *idxd_engine_attribute_groups[] = { static void idxd_conf_engine_release(struct device *dev) { - struct idxd_engine *engine = container_of(dev, struct idxd_engine, conf_dev); + struct idxd_engine *engine = confdev_to_engine(dev); kfree(engine); } @@ -427,8 +425,7 @@ static ssize_t group_tokens_reserved_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); return sysfs_emit(buf, "%u\n", group->tokens_reserved); } @@ -437,8 +434,7 @@ static ssize_t group_tokens_reserved_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); struct idxd_device *idxd = group->idxd; unsigned long val; int rc; @@ -475,8 +471,7 @@ static ssize_t group_tokens_allowed_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); return sysfs_emit(buf, "%u\n", group->tokens_allowed); } @@ -485,8 +480,7 @@ static ssize_t group_tokens_allowed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); struct idxd_device *idxd = group->idxd; unsigned long val; int rc; @@ -520,8 +514,7 @@ static ssize_t group_use_token_limit_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); return sysfs_emit(buf, "%u\n", group->use_token_limit); } @@ -530,8 +523,7 @@ static ssize_t group_use_token_limit_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); struct idxd_device *idxd = group->idxd; unsigned long val; int rc; @@ -563,8 +555,7 @@ static struct device_attribute dev_attr_group_use_token_limit = static ssize_t group_engines_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); int i, rc = 0; struct idxd_device *idxd = group->idxd; @@ -592,8 +583,7 @@ static struct device_attribute dev_attr_group_engines = static ssize_t group_work_queues_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); int i, rc = 0; struct idxd_device *idxd = group->idxd; @@ -622,8 +612,7 @@ static ssize_t group_traffic_class_a_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); return sysfs_emit(buf, "%d\n", group->tc_a); } @@ -632,8 +621,7 @@ static ssize_t group_traffic_class_a_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); struct idxd_device *idxd = group->idxd; long val; int rc; @@ -663,8 +651,7 @@ static ssize_t group_traffic_class_b_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); return sysfs_emit(buf, "%d\n", group->tc_b); } @@ -673,8 +660,7 @@ static ssize_t group_traffic_class_b_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_group *group = - container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); struct idxd_device *idxd = group->idxd; long val; int rc; @@ -722,7 +708,7 @@ static const struct attribute_group *idxd_group_attribute_groups[] = { static void idxd_conf_group_release(struct device *dev) { - struct idxd_group *group = container_of(dev, struct idxd_group, conf_dev); + struct idxd_group *group = confdev_to_group(dev); kfree(group); } @@ -737,7 +723,7 @@ struct device_type idxd_group_device_type = { static ssize_t wq_clients_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%d\n", wq->client_count); } @@ -748,7 +734,7 @@ static struct device_attribute dev_attr_wq_clients = static ssize_t wq_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); switch (wq->state) { case IDXD_WQ_DISABLED: @@ -766,7 +752,7 @@ static struct device_attribute dev_attr_wq_state = static ssize_t wq_group_id_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); if (wq->group) return sysfs_emit(buf, "%u\n", wq->group->id); @@ -778,7 +764,7 @@ static ssize_t wq_group_id_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; long id; int rc; @@ -821,7 +807,7 @@ static struct device_attribute dev_attr_wq_group_id = static ssize_t wq_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%s\n", wq_dedicated(wq) ? "dedicated" : "shared"); } @@ -830,7 +816,7 @@ static ssize_t wq_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) @@ -857,7 +843,7 @@ static struct device_attribute dev_attr_wq_mode = static ssize_t wq_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", wq->size); } @@ -880,7 +866,7 @@ static ssize_t wq_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); unsigned long size; struct idxd_device *idxd = wq->idxd; int rc; @@ -908,7 +894,7 @@ static struct device_attribute dev_attr_wq_size = static ssize_t wq_priority_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", wq->priority); } @@ -917,7 +903,7 @@ static ssize_t wq_priority_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); unsigned long prio; struct idxd_device *idxd = wq->idxd; int rc; @@ -945,7 +931,7 @@ static struct device_attribute dev_attr_wq_priority = static ssize_t wq_block_on_fault_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", test_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags)); } @@ -954,7 +940,7 @@ static ssize_t wq_block_on_fault_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; bool bof; int rc; @@ -984,7 +970,7 @@ static struct device_attribute dev_attr_wq_block_on_fault = static ssize_t wq_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", wq->threshold); } @@ -993,7 +979,7 @@ static ssize_t wq_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; unsigned int val; int rc; @@ -1025,7 +1011,7 @@ static struct device_attribute dev_attr_wq_threshold = static ssize_t wq_type_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); switch (wq->type) { case IDXD_WQT_KERNEL: @@ -1044,7 +1030,7 @@ static ssize_t wq_type_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); enum idxd_wq_type old_type; if (wq->state != IDXD_WQ_DISABLED) @@ -1073,7 +1059,7 @@ static struct device_attribute dev_attr_wq_type = static ssize_t wq_name_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%s\n", wq->name); } @@ -1082,7 +1068,7 @@ static ssize_t wq_name_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); if (wq->state != IDXD_WQ_DISABLED) return -EPERM; @@ -1109,7 +1095,7 @@ static struct device_attribute dev_attr_wq_name = static ssize_t wq_cdev_minor_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); int minor = -1; mutex_lock(&wq->wq_lock); @@ -1143,7 +1129,7 @@ static int __get_sysfs_u64(const char *buf, u64 *val) static ssize_t wq_max_transfer_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%llu\n", wq->max_xfer_bytes); } @@ -1151,7 +1137,7 @@ static ssize_t wq_max_transfer_size_show(struct device *dev, struct device_attri static ssize_t wq_max_transfer_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; u64 xfer_size; int rc; @@ -1177,7 +1163,7 @@ static struct device_attribute dev_attr_wq_max_transfer_size = static ssize_t wq_max_batch_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", wq->max_batch_size); } @@ -1185,7 +1171,7 @@ static ssize_t wq_max_batch_size_show(struct device *dev, struct device_attribut static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; u64 batch_size; int rc; @@ -1210,7 +1196,7 @@ static struct device_attribute dev_attr_wq_max_batch_size = static ssize_t wq_ats_disable_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); return sysfs_emit(buf, "%u\n", wq->ats_dis); } @@ -1218,7 +1204,7 @@ static ssize_t wq_ats_disable_show(struct device *dev, struct device_attribute * static ssize_t wq_ats_disable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); struct idxd_device *idxd = wq->idxd; bool ats_dis; int rc; @@ -1289,7 +1275,7 @@ static const struct attribute_group *idxd_wq_attribute_groups[] = { static void idxd_conf_wq_release(struct device *dev) { - struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev); + struct idxd_wq *wq = confdev_to_wq(dev); kfree(wq->wqcfg); kfree(wq); @@ -1305,8 +1291,7 @@ struct device_type idxd_wq_device_type = { static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%#x\n", idxd->hw.version); } @@ -1316,8 +1301,7 @@ static ssize_t max_work_queues_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_wq_size); } @@ -1326,8 +1310,7 @@ static DEVICE_ATTR_RO(max_work_queues_size); static ssize_t max_groups_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_groups); } @@ -1336,8 +1319,7 @@ static DEVICE_ATTR_RO(max_groups); static ssize_t max_work_queues_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_wqs); } @@ -1346,8 +1328,7 @@ static DEVICE_ATTR_RO(max_work_queues); static ssize_t max_engines_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_engines); } @@ -1356,8 +1337,7 @@ static DEVICE_ATTR_RO(max_engines); static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%d\n", dev_to_node(&idxd->pdev->dev)); } @@ -1366,8 +1346,7 @@ static DEVICE_ATTR_RO(numa_node); static ssize_t max_batch_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_batch_size); } @@ -1377,8 +1356,7 @@ static ssize_t max_transfer_size_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%llu\n", idxd->max_xfer_bytes); } @@ -1387,8 +1365,7 @@ static DEVICE_ATTR_RO(max_transfer_size); static ssize_t op_cap_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); int i, rc = 0; for (i = 0; i < 4; i++) @@ -1403,8 +1380,7 @@ static DEVICE_ATTR_RO(op_cap); static ssize_t gen_cap_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%#llx\n", idxd->hw.gen_cap.bits); } @@ -1413,8 +1389,7 @@ static DEVICE_ATTR_RO(gen_cap); static ssize_t configurable_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)); } @@ -1423,8 +1398,7 @@ static DEVICE_ATTR_RO(configurable); static ssize_t clients_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); unsigned long flags; int count = 0, i; @@ -1443,8 +1417,7 @@ static DEVICE_ATTR_RO(clients); static ssize_t pasid_enabled_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", device_pasid_enabled(idxd)); } @@ -1453,8 +1426,7 @@ static DEVICE_ATTR_RO(pasid_enabled); static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); switch (idxd->state) { case IDXD_DEV_DISABLED: @@ -1473,8 +1445,7 @@ static DEVICE_ATTR_RO(state); static ssize_t errors_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); int i, out = 0; unsigned long flags; @@ -1491,8 +1462,7 @@ static DEVICE_ATTR_RO(errors); static ssize_t max_tokens_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->max_tokens); } @@ -1501,8 +1471,7 @@ static DEVICE_ATTR_RO(max_tokens); static ssize_t token_limit_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->token_limit); } @@ -1511,8 +1480,7 @@ static ssize_t token_limit_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); unsigned long val; int rc; @@ -1540,8 +1508,7 @@ static DEVICE_ATTR_RW(token_limit); static ssize_t cdev_major_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = - container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%u\n", idxd->major); } @@ -1550,7 +1517,7 @@ static DEVICE_ATTR_RO(cdev_major); static ssize_t cmd_status_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct idxd_device *idxd = container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); return sysfs_emit(buf, "%#x\n", idxd->cmd_status); } @@ -1590,7 +1557,7 @@ static const struct attribute_group *idxd_attribute_groups[] = { static void idxd_conf_device_release(struct device *dev) { - struct idxd_device *idxd = container_of(dev, struct idxd_device, conf_dev); + struct idxd_device *idxd = confdev_to_idxd(dev); kfree(idxd->groups); kfree(idxd->wqs); @@ -1615,12 +1582,12 @@ struct device_type iax_device_type = { static int idxd_register_engine_devices(struct idxd_device *idxd) { + struct idxd_engine *engine; int i, j, rc; for (i = 0; i < idxd->max_engines; i++) { - struct idxd_engine *engine = idxd->engines[i]; - - rc = device_add(&engine->conf_dev); + engine = idxd->engines[i]; + rc = device_add(engine_confdev(engine)); if (rc < 0) goto cleanup; } @@ -1629,22 +1596,26 @@ static int idxd_register_engine_devices(struct idxd_device *idxd) cleanup: j = i - 1; - for (; i < idxd->max_engines; i++) - put_device(&idxd->engines[i]->conf_dev); + for (; i < idxd->max_engines; i++) { + engine = idxd->engines[i]; + put_device(engine_confdev(engine)); + } - while (j--) - device_unregister(&idxd->engines[j]->conf_dev); + while (j--) { + engine = idxd->engines[j]; + device_unregister(engine_confdev(engine)); + } return rc; } static int idxd_register_group_devices(struct idxd_device *idxd) { + struct idxd_group *group; int i, j, rc; for (i = 0; i < idxd->max_groups; i++) { - struct idxd_group *group = idxd->groups[i]; - - rc = device_add(&group->conf_dev); + group = idxd->groups[i]; + rc = device_add(group_confdev(group)); if (rc < 0) goto cleanup; } @@ -1653,22 +1624,26 @@ static int idxd_register_group_devices(struct idxd_device *idxd) cleanup: j = i - 1; - for (; i < idxd->max_groups; i++) - put_device(&idxd->groups[i]->conf_dev); + for (; i < idxd->max_groups; i++) { + group = idxd->groups[i]; + put_device(group_confdev(group)); + } - while (j--) - device_unregister(&idxd->groups[j]->conf_dev); + while (j--) { + group = idxd->groups[j]; + device_unregister(group_confdev(group)); + } return rc; } static int idxd_register_wq_devices(struct idxd_device *idxd) { + struct idxd_wq *wq; int i, rc, j; for (i = 0; i < idxd->max_wqs; i++) { - struct idxd_wq *wq = idxd->wqs[i]; - - rc = device_add(&wq->conf_dev); + wq = idxd->wqs[i]; + rc = device_add(wq_confdev(wq)); if (rc < 0) goto cleanup; } @@ -1677,11 +1652,15 @@ static int idxd_register_wq_devices(struct idxd_device *idxd) cleanup: j = i - 1; - for (; i < idxd->max_wqs; i++) - put_device(&idxd->wqs[i]->conf_dev); + for (; i < idxd->max_wqs; i++) { + wq = idxd->wqs[i]; + put_device(wq_confdev(wq)); + } - while (j--) - device_unregister(&idxd->wqs[j]->conf_dev); + while (j--) { + wq = idxd->wqs[j]; + device_unregister(wq_confdev(wq)); + } return rc; } @@ -1690,7 +1669,7 @@ int idxd_register_devices(struct idxd_device *idxd) struct device *dev = &idxd->pdev->dev; int rc, i; - rc = device_add(&idxd->conf_dev); + rc = device_add(idxd_confdev(idxd)); if (rc < 0) return rc; @@ -1716,12 +1695,12 @@ int idxd_register_devices(struct idxd_device *idxd) err_group: for (i = 0; i < idxd->max_engines; i++) - device_unregister(&idxd->engines[i]->conf_dev); + device_unregister(engine_confdev(idxd->engines[i])); err_engine: for (i = 0; i < idxd->max_wqs; i++) - device_unregister(&idxd->wqs[i]->conf_dev); + device_unregister(wq_confdev(idxd->wqs[i])); err_wq: - device_del(&idxd->conf_dev); + device_del(idxd_confdev(idxd)); return rc; } @@ -1732,19 +1711,19 @@ void idxd_unregister_devices(struct idxd_device *idxd) for (i = 0; i < idxd->max_wqs; i++) { struct idxd_wq *wq = idxd->wqs[i]; - device_unregister(&wq->conf_dev); + device_unregister(wq_confdev(wq)); } for (i = 0; i < idxd->max_engines; i++) { struct idxd_engine *engine = idxd->engines[i]; - device_unregister(&engine->conf_dev); + device_unregister(engine_confdev(engine)); } for (i = 0; i < idxd->max_groups; i++) { struct idxd_group *group = idxd->groups[i]; - device_unregister(&group->conf_dev); + device_unregister(group_confdev(group)); } } -- cgit v1.2.3-70-g09d2 From f52058ae11523304a337de249c4c07ba5076f288 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:26 -0700 Subject: dmaengine: idxd: remove IDXD_DEV_CONF_READY The IDXD_DEV_CONF_READY state flag is no longer needed. The current implementation uses this flag to stop the device from doing configuration until the pci driver probe has completed. With the driver architecture going towards multiple sub-driver attached to the dsa_bus, this is no longer feasible. The sub-drivers will be allowed to probe and return with failure when they are not ready to complete the probe rather than using a state flag to gate the probing. There is no expectation that the devices auto-attach to a driver. Userspace configuration is expected to setup the device before enabling. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637460633.744545.8902095097471365420.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 4 ++-- drivers/dma/idxd/idxd.h | 1 - drivers/dma/idxd/init.c | 2 -- drivers/dma/idxd/sysfs.c | 14 -------------- 4 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index c8cf1de72176..4a2af9799239 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -576,7 +576,7 @@ int idxd_device_disable(struct idxd_device *idxd) spin_lock_irqsave(&idxd->dev_lock, flags); idxd_device_clear_state(idxd); - idxd->state = IDXD_DEV_CONF_READY; + idxd->state = IDXD_DEV_DISABLED; spin_unlock_irqrestore(&idxd->dev_lock, flags); return 0; } @@ -588,7 +588,7 @@ void idxd_device_reset(struct idxd_device *idxd) idxd_cmd_exec(idxd, IDXD_CMD_RESET_DEVICE, 0, NULL); spin_lock_irqsave(&idxd->dev_lock, flags); idxd_device_clear_state(idxd); - idxd->state = IDXD_DEV_CONF_READY; + idxd->state = IDXD_DEV_DISABLED; spin_unlock_irqrestore(&idxd->dev_lock, flags); } diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index ae60fcc7b625..9fc1a88f336d 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -210,7 +210,6 @@ struct idxd_hw { enum idxd_device_state { IDXD_DEV_HALTED = -1, IDXD_DEV_DISABLED = 0, - IDXD_DEV_CONF_READY, IDXD_DEV_ENABLED, }; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index f500076882d2..c22225b14c5d 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -682,8 +682,6 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_dev_register; } - idxd->state = IDXD_DEV_CONF_READY; - dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n", idxd->hw.version); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index f603b11141c4..2a978055e22b 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -22,17 +22,9 @@ static int idxd_config_bus_match(struct device *dev, int matched = 0; if (is_idxd_dev(dev)) { - struct idxd_device *idxd = confdev_to_idxd(dev); - - if (idxd->state != IDXD_DEV_CONF_READY) - return 0; matched = 1; } else if (is_idxd_wq_dev(dev)) { struct idxd_wq *wq = confdev_to_wq(dev); - struct idxd_device *idxd = wq->idxd; - - if (idxd->state < IDXD_DEV_CONF_READY) - return 0; if (wq->state != IDXD_WQ_DISABLED) { dev_dbg(dev, "%s not disabled\n", dev_name(dev)); @@ -179,11 +171,6 @@ static int idxd_config_bus_probe(struct device *dev) if (is_idxd_dev(dev)) { struct idxd_device *idxd = confdev_to_idxd(dev); - if (idxd->state != IDXD_DEV_CONF_READY) { - dev_warn(dev, "Device not ready for config\n"); - return -EBUSY; - } - if (!try_module_get(THIS_MODULE)) return -ENXIO; @@ -1430,7 +1417,6 @@ static ssize_t state_show(struct device *dev, switch (idxd->state) { case IDXD_DEV_DISABLED: - case IDXD_DEV_CONF_READY: return sysfs_emit(buf, "disabled\n"); case IDXD_DEV_ENABLED: return sysfs_emit(buf, "enabled\n"); -- cgit v1.2.3-70-g09d2 From 1f2bb40337f0df1d9af80793e9fdacff7706e654 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:31 -0700 Subject: dmaengine: idxd: move wq_enable() to device.c Move the wq_enable() function to device.c in preparation of setting up the idxd internal sub-driver framework. No logic changes. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637461176.744545.3806109011554118998.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/sysfs.c | 124 +--------------------------------------------- 3 files changed, 126 insertions(+), 123 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 4a2af9799239..b1c509bcfa31 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1129,3 +1129,127 @@ int idxd_device_load_config(struct idxd_device *idxd) return 0; } + +static int __drv_enable_wq(struct idxd_wq *wq) +{ + struct idxd_device *idxd = wq->idxd; + struct device *dev = &idxd->pdev->dev; + unsigned long flags; + int rc = -ENXIO; + + lockdep_assert_held(&wq->wq_lock); + + if (idxd->state != IDXD_DEV_ENABLED) + goto err; + + if (wq->state != IDXD_WQ_DISABLED) { + dev_dbg(dev, "wq %d already enabled.\n", wq->id); + rc = -EBUSY; + goto err; + } + + if (!wq->group) { + dev_dbg(dev, "wq %d not attached to group.\n", wq->id); + goto err; + } + + if (strlen(wq->name) == 0) { + dev_dbg(dev, "wq %d name not set.\n", wq->id); + goto err; + } + + /* Shared WQ checks */ + if (wq_shared(wq)) { + if (!device_swq_supported(idxd)) { + dev_dbg(dev, "PASID not enabled and shared wq.\n"); + goto err; + } + /* + * Shared wq with the threshold set to 0 means the user + * did not set the threshold or transitioned from a + * dedicated wq but did not set threshold. A value + * of 0 would effectively disable the shared wq. The + * driver does not allow a value of 0 to be set for + * threshold via sysfs. + */ + if (wq->threshold == 0) { + dev_dbg(dev, "Shared wq and threshold 0.\n"); + goto err; + } + } + + rc = idxd_wq_alloc_resources(wq); + if (rc < 0) { + dev_dbg(dev, "wq resource alloc failed\n"); + goto err; + } + + spin_lock_irqsave(&idxd->dev_lock, flags); + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) + rc = idxd_device_config(idxd); + spin_unlock_irqrestore(&idxd->dev_lock, flags); + if (rc < 0) { + dev_dbg(dev, "Writing wq %d config failed: %d\n", wq->id, rc); + goto err; + } + + rc = idxd_wq_enable(wq); + if (rc < 0) { + dev_dbg(dev, "wq %d enabling failed: %d\n", wq->id, rc); + goto err; + } + + rc = idxd_wq_map_portal(wq); + if (rc < 0) { + dev_dbg(dev, "wq %d portal mapping failed: %d\n", wq->id, rc); + goto err_map_portal; + } + + wq->client_count = 0; + + if (wq->type == IDXD_WQT_KERNEL) { + rc = idxd_wq_init_percpu_ref(wq); + if (rc < 0) { + dev_dbg(dev, "wq %d percpu_ref setup failed\n", wq->id); + goto err_cpu_ref; + } + } + + if (is_idxd_wq_dmaengine(wq)) { + rc = idxd_register_dma_channel(wq); + if (rc < 0) { + dev_dbg(dev, "wq %d DMA channel register failed\n", wq->id); + goto err_client; + } + } else if (is_idxd_wq_cdev(wq)) { + rc = idxd_wq_add_cdev(wq); + if (rc < 0) { + dev_dbg(dev, "wq %d cdev creation failed\n", wq->id); + goto err_client; + } + } + + dev_info(dev, "wq %s enabled\n", dev_name(wq_confdev(wq))); + return 0; + +err_client: + idxd_wq_quiesce(wq); +err_cpu_ref: + idxd_wq_unmap_portal(wq); +err_map_portal: + rc = idxd_wq_disable(wq, false); + if (rc < 0) + dev_dbg(dev, "wq %s disable failed\n", dev_name(wq_confdev(wq))); +err: + return rc; +} + +int drv_enable_wq(struct idxd_wq *wq) +{ + int rc; + + mutex_lock(&wq->wq_lock); + rc = __drv_enable_wq(wq); + mutex_unlock(&wq->wq_lock); + return rc; +} diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 9fc1a88f336d..551a61fa1aff 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -495,6 +495,7 @@ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id); void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); /* device control */ +int drv_enable_wq(struct idxd_wq *wq); int idxd_device_init_reset(struct idxd_device *idxd); int idxd_device_enable(struct idxd_device *idxd); int idxd_device_disable(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 2a978055e22b..3e8cc07ebcdc 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -39,128 +39,6 @@ static int idxd_config_bus_match(struct device *dev, return matched; } -static int enable_wq(struct idxd_wq *wq) -{ - struct idxd_device *idxd = wq->idxd; - struct device *dev = &idxd->pdev->dev; - unsigned long flags; - int rc; - - mutex_lock(&wq->wq_lock); - - if (idxd->state != IDXD_DEV_ENABLED) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "Enabling while device not enabled.\n"); - return -EPERM; - } - - if (wq->state != IDXD_WQ_DISABLED) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "WQ %d already enabled.\n", wq->id); - return -EBUSY; - } - - if (!wq->group) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "WQ not attached to group.\n"); - return -EINVAL; - } - - if (strlen(wq->name) == 0) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "WQ name not set.\n"); - return -EINVAL; - } - - /* Shared WQ checks */ - if (wq_shared(wq)) { - if (!device_swq_supported(idxd)) { - dev_warn(dev, "PASID not enabled and shared WQ.\n"); - mutex_unlock(&wq->wq_lock); - return -ENXIO; - } - /* - * Shared wq with the threshold set to 0 means the user - * did not set the threshold or transitioned from a - * dedicated wq but did not set threshold. A value - * of 0 would effectively disable the shared wq. The - * driver does not allow a value of 0 to be set for - * threshold via sysfs. - */ - if (wq->threshold == 0) { - dev_warn(dev, "Shared WQ and threshold 0.\n"); - mutex_unlock(&wq->wq_lock); - return -EINVAL; - } - } - - rc = idxd_wq_alloc_resources(wq); - if (rc < 0) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "WQ resource alloc failed\n"); - return rc; - } - - spin_lock_irqsave(&idxd->dev_lock, flags); - if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) - rc = idxd_device_config(idxd); - spin_unlock_irqrestore(&idxd->dev_lock, flags); - if (rc < 0) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "Writing WQ %d config failed: %d\n", wq->id, rc); - return rc; - } - - rc = idxd_wq_enable(wq); - if (rc < 0) { - mutex_unlock(&wq->wq_lock); - dev_warn(dev, "WQ %d enabling failed: %d\n", wq->id, rc); - return rc; - } - - rc = idxd_wq_map_portal(wq); - if (rc < 0) { - dev_warn(dev, "wq portal mapping failed: %d\n", rc); - rc = idxd_wq_disable(wq, false); - if (rc < 0) - dev_warn(dev, "IDXD wq disable failed\n"); - mutex_unlock(&wq->wq_lock); - return rc; - } - - wq->client_count = 0; - - if (wq->type == IDXD_WQT_KERNEL) { - rc = idxd_wq_init_percpu_ref(wq); - if (rc < 0) { - dev_dbg(dev, "percpu_ref setup failed\n"); - mutex_unlock(&wq->wq_lock); - return rc; - } - } - - if (is_idxd_wq_dmaengine(wq)) { - rc = idxd_register_dma_channel(wq); - if (rc < 0) { - dev_dbg(dev, "DMA channel register failed\n"); - mutex_unlock(&wq->wq_lock); - return rc; - } - } else if (is_idxd_wq_cdev(wq)) { - rc = idxd_wq_add_cdev(wq); - if (rc < 0) { - dev_dbg(dev, "Cdev creation failed\n"); - mutex_unlock(&wq->wq_lock); - return rc; - } - } - - mutex_unlock(&wq->wq_lock); - dev_info(dev, "wq %s enabled\n", dev_name(wq_confdev(wq))); - - return 0; -} - static int idxd_config_bus_probe(struct device *dev) { int rc = 0; @@ -205,7 +83,7 @@ static int idxd_config_bus_probe(struct device *dev) } else if (is_idxd_wq_dev(dev)) { struct idxd_wq *wq = confdev_to_wq(dev); - return enable_wq(wq); + return drv_enable_wq(wq); } return -ENODEV; -- cgit v1.2.3-70-g09d2 From 69e4f8be596d897679e44e86a323629537c02975 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:37 -0700 Subject: dmaengine: idxd: move wq_disable() to device.c Move the wq_disable() function to device.c in preparation of setting up the idxd internal sub-driver framework. No logic changes. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637461775.744545.9644048686618957886.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/sysfs.c | 38 +------------------------------------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index b1c509bcfa31..8d8e249931a9 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1253,3 +1253,40 @@ int drv_enable_wq(struct idxd_wq *wq) mutex_unlock(&wq->wq_lock); return rc; } + +static void __drv_disable_wq(struct idxd_wq *wq) +{ + struct idxd_device *idxd = wq->idxd; + struct device *dev = &idxd->pdev->dev; + + lockdep_assert_held(&wq->wq_lock); + + if (wq->type == IDXD_WQT_KERNEL) + idxd_wq_quiesce(wq); + + if (is_idxd_wq_dmaengine(wq)) + idxd_unregister_dma_channel(wq); + else if (is_idxd_wq_cdev(wq)) + idxd_wq_del_cdev(wq); + + if (idxd_wq_refcount(wq)) + dev_warn(dev, "Clients has claim on wq %d: %d\n", + wq->id, idxd_wq_refcount(wq)); + + idxd_wq_unmap_portal(wq); + + idxd_wq_drain(wq); + idxd_wq_reset(wq); + + idxd_wq_free_resources(wq); + wq->client_count = 0; + + dev_info(dev, "wq %s disabled\n", dev_name(wq_confdev(wq))); +} + +void drv_disable_wq(struct idxd_wq *wq) +{ + mutex_lock(&wq->wq_lock); + __drv_disable_wq(wq); + mutex_unlock(&wq->wq_lock); +} diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 551a61fa1aff..e96ddbfc4569 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -496,6 +496,7 @@ void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); /* device control */ int drv_enable_wq(struct idxd_wq *wq); +void drv_disable_wq(struct idxd_wq *wq); int idxd_device_init_reset(struct idxd_device *idxd); int idxd_device_enable(struct idxd_device *idxd); int idxd_device_disable(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 3e8cc07ebcdc..9967fad58a01 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -89,42 +89,6 @@ static int idxd_config_bus_probe(struct device *dev) return -ENODEV; } -static void disable_wq(struct idxd_wq *wq) -{ - struct idxd_device *idxd = wq->idxd; - struct device *dev = &idxd->pdev->dev; - - mutex_lock(&wq->wq_lock); - dev_dbg(dev, "%s removing WQ %s\n", __func__, dev_name(wq_confdev(wq))); - if (wq->state == IDXD_WQ_DISABLED) { - mutex_unlock(&wq->wq_lock); - return; - } - - if (wq->type == IDXD_WQT_KERNEL) - idxd_wq_quiesce(wq); - - if (is_idxd_wq_dmaengine(wq)) - idxd_unregister_dma_channel(wq); - else if (is_idxd_wq_cdev(wq)) - idxd_wq_del_cdev(wq); - - if (idxd_wq_refcount(wq)) - dev_warn(dev, "Clients has claim on wq %d: %d\n", - wq->id, idxd_wq_refcount(wq)); - - idxd_wq_unmap_portal(wq); - - idxd_wq_drain(wq); - idxd_wq_reset(wq); - - idxd_wq_free_resources(wq); - wq->client_count = 0; - mutex_unlock(&wq->wq_lock); - - dev_info(dev, "wq %s disabled\n", dev_name(wq_confdev(wq))); -} - static int idxd_config_bus_remove(struct device *dev) { dev_dbg(dev, "%s called for %s\n", __func__, dev_name(dev)); @@ -133,7 +97,7 @@ static int idxd_config_bus_remove(struct device *dev) if (is_idxd_wq_dev(dev)) { struct idxd_wq *wq = confdev_to_wq(dev); - disable_wq(wq); + drv_disable_wq(wq); } else if (is_idxd_dev(dev)) { struct idxd_device *idxd = confdev_to_idxd(dev); int i; -- cgit v1.2.3-70-g09d2 From 3a5cc01647f07431b342e9703cda0542457ec467 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:43 -0700 Subject: dmaengine: idxd: remove bus shutdown Remove ->shutdown() function for the dsa bus as it does not do anything and is not necessary. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637462319.744545.10383189484257042066.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/sysfs.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 9967fad58a01..c3c869d8119a 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -126,17 +126,11 @@ static int idxd_config_bus_remove(struct device *dev) return 0; } -static void idxd_config_bus_shutdown(struct device *dev) -{ - dev_dbg(dev, "%s called\n", __func__); -} - struct bus_type dsa_bus_type = { .name = "dsa", .match = idxd_config_bus_match, .probe = idxd_config_bus_probe, .remove = idxd_config_bus_remove, - .shutdown = idxd_config_bus_shutdown, }; static struct idxd_device_driver dsa_drv = { -- cgit v1.2.3-70-g09d2 From 1c264299431e9a105f3974ad49b6bccc3f03540f Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:49 -0700 Subject: dmaengine: idxd: remove iax_bus_type prototype Remove unused iax_bus_type prototype declaration. Should have been removed when iax_bus_type was removed. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637462909.744545.7106049898386277608.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index e96ddbfc4569..4c3d3eb94450 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -370,7 +370,6 @@ static inline void idxd_dev_set_type(struct idxd_dev *idev, int type) } extern struct bus_type dsa_bus_type; -extern struct bus_type iax_bus_type; extern bool support_enqcmd; extern struct ida idxd_ida; -- cgit v1.2.3-70-g09d2 From fcc2281b142bf14e3534d6b1150991194f8d1d44 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:43:55 -0700 Subject: dmaengine: idxd: fix bus_probe() and bus_remove() for dsa_bus Current implementation have put all the code that should be in a driver probe/remove in the bus probe/remove function. Add ->probe() and ->remove() support for the dsa_drv and move all those code out of bus probe/remove. The change does not split out the distinction between device sub-driver and wq sub-driver. It only cleans up the bus calls. The split out will be addressed in follow on patches. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637463586.744545.5806250155539938643.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 24 ++++++----- drivers/dma/idxd/sysfs.c | 108 ++++++++++++++++++++++++----------------------- 2 files changed, 69 insertions(+), 63 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 4c3d3eb94450..493958ecc208 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -51,6 +51,8 @@ enum idxd_type { struct idxd_device_driver { const char *name; + int (*probe)(struct idxd_dev *idxd_dev); + void (*remove)(struct idxd_dev *idxd_dev); struct device_driver drv; }; @@ -323,19 +325,21 @@ enum idxd_completion_status { #define cdev_dev(cdev) &cdev->idxd_dev.conf_dev #define confdev_to_idxd_dev(dev) container_of(dev, struct idxd_dev, conf_dev) +#define idxd_dev_to_idxd(idxd_dev) container_of(idxd_dev, struct idxd_device, idxd_dev) +#define idxd_dev_to_wq(idxd_dev) container_of(idxd_dev, struct idxd_wq, idxd_dev) static inline struct idxd_device *confdev_to_idxd(struct device *dev) { struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - return container_of(idxd_dev, struct idxd_device, idxd_dev); + return idxd_dev_to_idxd(idxd_dev); } static inline struct idxd_wq *confdev_to_wq(struct device *dev) { struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - return container_of(idxd_dev, struct idxd_wq, idxd_dev); + return idxd_dev_to_wq(idxd_dev); } static inline struct idxd_engine *confdev_to_engine(struct device *dev) @@ -379,24 +383,24 @@ extern struct device_type idxd_wq_device_type; extern struct device_type idxd_engine_device_type; extern struct device_type idxd_group_device_type; -static inline bool is_dsa_dev(struct device *dev) +static inline bool is_dsa_dev(struct idxd_dev *idxd_dev) { - return dev->type == &dsa_device_type; + return idxd_dev->type == IDXD_DEV_DSA; } -static inline bool is_iax_dev(struct device *dev) +static inline bool is_iax_dev(struct idxd_dev *idxd_dev) { - return dev->type == &iax_device_type; + return idxd_dev->type == IDXD_DEV_IAX; } -static inline bool is_idxd_dev(struct device *dev) +static inline bool is_idxd_dev(struct idxd_dev *idxd_dev) { - return is_dsa_dev(dev) || is_iax_dev(dev); + return is_dsa_dev(idxd_dev) || is_iax_dev(idxd_dev); } -static inline bool is_idxd_wq_dev(struct device *dev) +static inline bool is_idxd_wq_dev(struct idxd_dev *idxd_dev) { - return dev->type == &idxd_wq_device_type; + return idxd_dev->type == IDXD_DEV_WQ; } static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq) diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index c3c869d8119a..f82416eec926 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -19,69 +19,80 @@ static char *idxd_wq_type_names[] = { static int idxd_config_bus_match(struct device *dev, struct device_driver *drv) { - int matched = 0; + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - if (is_idxd_dev(dev)) { - matched = 1; - } else if (is_idxd_wq_dev(dev)) { - struct idxd_wq *wq = confdev_to_wq(dev); + return (is_idxd_dev(idxd_dev) || is_idxd_wq_dev(idxd_dev)); +} - if (wq->state != IDXD_WQ_DISABLED) { - dev_dbg(dev, "%s not disabled\n", dev_name(dev)); - return 0; - } - matched = 1; - } +static int idxd_config_bus_probe(struct device *dev) +{ + struct idxd_device_driver *idxd_drv = + container_of(dev->driver, struct idxd_device_driver, drv); + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - if (matched) - dev_dbg(dev, "%s matched\n", dev_name(dev)); + return idxd_drv->probe(idxd_dev); +} - return matched; +static int idxd_config_bus_remove(struct device *dev) +{ + struct idxd_device_driver *idxd_drv = + container_of(dev->driver, struct idxd_device_driver, drv); + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + idxd_drv->remove(idxd_dev); + return 0; } -static int idxd_config_bus_probe(struct device *dev) +struct bus_type dsa_bus_type = { + .name = "dsa", + .match = idxd_config_bus_match, + .probe = idxd_config_bus_probe, + .remove = idxd_config_bus_remove, +}; + +static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) { - int rc = 0; + struct device *dev = &idxd_dev->conf_dev; unsigned long flags; + int rc; - dev_dbg(dev, "%s called\n", __func__); - - if (is_idxd_dev(dev)) { - struct idxd_device *idxd = confdev_to_idxd(dev); + if (is_idxd_dev(idxd_dev)) { + struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); - if (!try_module_get(THIS_MODULE)) + if (idxd->state != IDXD_DEV_DISABLED) return -ENXIO; - /* Perform IDXD configuration and enabling */ + /* Device configuration */ spin_lock_irqsave(&idxd->dev_lock, flags); if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) rc = idxd_device_config(idxd); spin_unlock_irqrestore(&idxd->dev_lock, flags); if (rc < 0) { - module_put(THIS_MODULE); - dev_warn(dev, "Device config failed: %d\n", rc); + dev_dbg(dev, "Device config failed: %d\n", rc); return rc; } - /* start device */ + /* Start device */ rc = idxd_device_enable(idxd); if (rc < 0) { - module_put(THIS_MODULE); dev_warn(dev, "Device enable failed: %d\n", rc); return rc; } - dev_info(dev, "Device %s enabled\n", dev_name(dev)); - + /* Setup DMA device without channels */ rc = idxd_register_dma_device(idxd); if (rc < 0) { - module_put(THIS_MODULE); dev_dbg(dev, "Failed to register dmaengine device\n"); + idxd_device_disable(idxd); return rc; } + + dev_info(dev, "Device %s enabled\n", dev_name(dev)); return 0; - } else if (is_idxd_wq_dev(dev)) { - struct idxd_wq *wq = confdev_to_wq(dev); + } + + if (is_idxd_wq_dev(idxd_dev)) { + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); return drv_enable_wq(wq); } @@ -89,21 +100,14 @@ static int idxd_config_bus_probe(struct device *dev) return -ENODEV; } -static int idxd_config_bus_remove(struct device *dev) +static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) { - dev_dbg(dev, "%s called for %s\n", __func__, dev_name(dev)); - - /* disable workqueue here */ - if (is_idxd_wq_dev(dev)) { - struct idxd_wq *wq = confdev_to_wq(dev); + struct device *dev = &idxd_dev->conf_dev; - drv_disable_wq(wq); - } else if (is_idxd_dev(dev)) { - struct idxd_device *idxd = confdev_to_idxd(dev); + if (is_idxd_dev(idxd_dev)) { + struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); int i; - dev_dbg(dev, "%s removing dev %s\n", __func__, - dev_name(idxd_confdev(idxd))); for (i = 0; i < idxd->max_wqs; i++) { struct idxd_wq *wq = idxd->wqs[i]; @@ -118,23 +122,21 @@ static int idxd_config_bus_remove(struct device *dev) idxd_device_disable(idxd); if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) idxd_device_reset(idxd); - module_put(THIS_MODULE); - - dev_info(dev, "Device %s disabled\n", dev_name(dev)); + return; } - return 0; -} + if (is_idxd_wq_dev(idxd_dev)) { + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); -struct bus_type dsa_bus_type = { - .name = "dsa", - .match = idxd_config_bus_match, - .probe = idxd_config_bus_probe, - .remove = idxd_config_bus_remove, -}; + drv_disable_wq(wq); + return; + } +} static struct idxd_device_driver dsa_drv = { .name = "dsa", + .probe = idxd_dsa_drv_probe, + .remove = idxd_dsa_drv_remove, }; /* IDXD generic driver setup */ -- cgit v1.2.3-70-g09d2 From bd42805b5da33b9c75f3ce0ae9d6ff0ec3f2cd6b Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:01 -0700 Subject: dmaengine: idxd: move probe() bits for idxd 'struct device' to device.c Move the code related to a ->probe() function for the idxd 'struct device' to device.c to prep for the idxd device sub-driver in device.c. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637464189.744545.17423830646786162194.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/sysfs.c | 40 ++-------------------------------------- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 8d8e249931a9..b9aa209efee4 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1290,3 +1290,40 @@ void drv_disable_wq(struct idxd_wq *wq) __drv_disable_wq(wq); mutex_unlock(&wq->wq_lock); } + +int idxd_device_drv_probe(struct idxd_dev *idxd_dev) +{ + struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); + unsigned long flags; + int rc = 0; + + /* + * Device should be in disabled state for the idxd_drv to load. If it's in + * enabled state, then the device was altered outside of driver's control. + * If the state is in halted state, then we don't want to proceed. + */ + if (idxd->state != IDXD_DEV_DISABLED) + return -ENXIO; + + /* Device configuration */ + spin_lock_irqsave(&idxd->dev_lock, flags); + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) + rc = idxd_device_config(idxd); + spin_unlock_irqrestore(&idxd->dev_lock, flags); + if (rc < 0) + return -ENXIO; + + /* Start device */ + rc = idxd_device_enable(idxd); + if (rc < 0) + return rc; + + /* Setup DMA device without channels */ + rc = idxd_register_dma_device(idxd); + if (rc < 0) { + idxd_device_disable(idxd); + return rc; + } + + return 0; +} diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 493958ecc208..dbbd36feb462 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -498,6 +498,7 @@ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id); void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); /* device control */ +int idxd_device_drv_probe(struct idxd_dev *idxd_dev); int drv_enable_wq(struct idxd_wq *wq); void drv_disable_wq(struct idxd_wq *wq); int idxd_device_init_reset(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index f82416eec926..221a61e3bb9c 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -52,44 +52,8 @@ struct bus_type dsa_bus_type = { static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) { - struct device *dev = &idxd_dev->conf_dev; - unsigned long flags; - int rc; - - if (is_idxd_dev(idxd_dev)) { - struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); - - if (idxd->state != IDXD_DEV_DISABLED) - return -ENXIO; - - /* Device configuration */ - spin_lock_irqsave(&idxd->dev_lock, flags); - if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) - rc = idxd_device_config(idxd); - spin_unlock_irqrestore(&idxd->dev_lock, flags); - if (rc < 0) { - dev_dbg(dev, "Device config failed: %d\n", rc); - return rc; - } - - /* Start device */ - rc = idxd_device_enable(idxd); - if (rc < 0) { - dev_warn(dev, "Device enable failed: %d\n", rc); - return rc; - } - - /* Setup DMA device without channels */ - rc = idxd_register_dma_device(idxd); - if (rc < 0) { - dev_dbg(dev, "Failed to register dmaengine device\n"); - idxd_device_disable(idxd); - return rc; - } - - dev_info(dev, "Device %s enabled\n", dev_name(dev)); - return 0; - } + if (is_idxd_dev(idxd_dev)) + return idxd_device_drv_probe(idxd_dev); if (is_idxd_wq_dev(idxd_dev)) { struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); -- cgit v1.2.3-70-g09d2 From 745e92a6d816277fcbd231bda5ad2d882b22fe52 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:07 -0700 Subject: dmaengine: idxd: idxd: move remove() bits for idxd 'struct device' to device.c Move the code related to a ->remove() function for the idxd 'struct device' to device.c to prep for the idxd device sub-driver in device.c. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637464768.744545.15797285510999151668.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 22 ++++++++++++++++++++++ drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/sysfs.c | 20 +------------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index b9aa209efee4..d5a0b6fff3b9 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1327,3 +1327,25 @@ int idxd_device_drv_probe(struct idxd_dev *idxd_dev) return 0; } + +void idxd_device_drv_remove(struct idxd_dev *idxd_dev) +{ + struct device *dev = &idxd_dev->conf_dev; + struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); + int i; + + for (i = 0; i < idxd->max_wqs; i++) { + struct idxd_wq *wq = idxd->wqs[i]; + struct device *wq_dev = wq_confdev(wq); + + if (wq->state == IDXD_WQ_DISABLED) + continue; + dev_warn(dev, "Active wq %d on disable %s.\n", i, dev_name(wq_dev)); + device_release_driver(wq_dev); + } + + idxd_unregister_dma_device(idxd); + idxd_device_disable(idxd); + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) + idxd_device_reset(idxd); +} diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index dbbd36feb462..1c8abba13470 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -499,6 +499,7 @@ void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); /* device control */ int idxd_device_drv_probe(struct idxd_dev *idxd_dev); +void idxd_device_drv_remove(struct idxd_dev *idxd_dev); int drv_enable_wq(struct idxd_wq *wq); void drv_disable_wq(struct idxd_wq *wq); int idxd_device_init_reset(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 221a61e3bb9c..abea8aca6799 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -66,26 +66,8 @@ static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) { - struct device *dev = &idxd_dev->conf_dev; - if (is_idxd_dev(idxd_dev)) { - struct idxd_device *idxd = idxd_dev_to_idxd(idxd_dev); - int i; - - for (i = 0; i < idxd->max_wqs; i++) { - struct idxd_wq *wq = idxd->wqs[i]; - - if (wq->state == IDXD_WQ_DISABLED) - continue; - dev_warn(dev, "Active wq %d on disable %s.\n", i, - dev_name(wq_confdev(wq))); - device_release_driver(wq_confdev(wq)); - } - - idxd_unregister_dma_device(idxd); - idxd_device_disable(idxd); - if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) - idxd_device_reset(idxd); + idxd_device_drv_remove(idxd_dev); return; } -- cgit v1.2.3-70-g09d2 From c05257b5600bb35a580ecdb25695efff26326d59 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:13 -0700 Subject: dmanegine: idxd: open code the dsa_drv registration Don't need a wrapper to register the driver. Just do it directly. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637465319.744545.16325178432532362906.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 2 ++ drivers/dma/idxd/init.c | 10 +++++----- drivers/dma/idxd/sysfs.c | 13 +------------ 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 1c8abba13470..7fc26b7727c0 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -56,6 +56,8 @@ struct idxd_device_driver { struct device_driver drv; }; +extern struct idxd_device_driver dsa_drv; + struct idxd_irq_entry { struct idxd_device *idxd; int id; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index c22225b14c5d..5b628e6c04bf 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -840,9 +840,9 @@ static int __init idxd_init_module(void) if (err < 0) return err; - err = idxd_register_driver(); + err = idxd_driver_register(&dsa_drv); if (err < 0) - goto err_idxd_driver_register; + goto err_dsa_driver_register; err = idxd_cdev_register(); if (err) @@ -857,8 +857,8 @@ static int __init idxd_init_module(void) err_pci_register: idxd_cdev_remove(); err_cdev_register: - idxd_unregister_driver(); -err_idxd_driver_register: + idxd_driver_unregister(&dsa_drv); +err_dsa_driver_register: idxd_unregister_bus_type(); return err; } @@ -866,7 +866,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { - idxd_unregister_driver(); + idxd_driver_unregister(&dsa_drv); pci_unregister_driver(&idxd_pci_driver); idxd_cdev_remove(); idxd_unregister_bus_type(); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index abea8aca6799..9f2d06c2aa98 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -79,23 +79,12 @@ static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) } } -static struct idxd_device_driver dsa_drv = { +struct idxd_device_driver dsa_drv = { .name = "dsa", .probe = idxd_dsa_drv_probe, .remove = idxd_dsa_drv_remove, }; -/* IDXD generic driver setup */ -int idxd_register_driver(void) -{ - return idxd_driver_register(&dsa_drv); -} - -void idxd_unregister_driver(void) -{ - idxd_driver_unregister(&dsa_drv); -} - /* IDXD engine attributes */ static ssize_t engine_group_id_show(struct device *dev, struct device_attribute *attr, char *buf) -- cgit v1.2.3-70-g09d2 From 5fee6567ec387088ec965ee60c63051bbe102cac Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:18 -0700 Subject: dmaengine: idxd: add type to driver in order to allow device matching Add an array of support device types to the idxd_device_driver definition in order to enable simple matching of device type to a given driver. The deprecated / omnibus dsa_drv driver specifies IDXD_DEV_NONE as its only role is to service legacy userspace (old accel-config) directed bind requests and route them to them the proper driver. It need not attach to a device when the bus is autoprobed. The accel-config tooling is being updated to drop its dependency on this deprecated bind scheme. Reviewed-by: Dan Willliams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637465882.744545.17456174666211577867.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/init.c | 5 +++++ drivers/dma/idxd/sysfs.c | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 7fc26b7727c0..4bb5a65ec237 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -51,6 +51,7 @@ enum idxd_type { struct idxd_device_driver { const char *name; + enum idxd_dev_type *type; int (*probe)(struct idxd_dev *idxd_dev); void (*remove)(struct idxd_dev *idxd_dev); struct device_driver drv; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 5b628e6c04bf..544ff7137292 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -879,6 +879,11 @@ int __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *o { struct device_driver *drv = &idxd_drv->drv; + if (!idxd_drv->type) { + pr_debug("driver type not set (%ps)\n", __builtin_return_address(0)); + return -EINVAL; + } + drv->name = idxd_drv->name; drv->bus = &dsa_bus_type; drv->owner = owner; diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 9f2d06c2aa98..8d48903df131 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -19,9 +19,18 @@ static char *idxd_wq_type_names[] = { static int idxd_config_bus_match(struct device *dev, struct device_driver *drv) { + struct idxd_device_driver *idxd_drv = + container_of(drv, struct idxd_device_driver, drv); struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + int i = 0; + + while (idxd_drv->type[i] != IDXD_DEV_NONE) { + if (idxd_dev->type == idxd_drv->type[i]) + return 1; + i++; + } - return (is_idxd_dev(idxd_dev) || is_idxd_wq_dev(idxd_dev)); + return 0; } static int idxd_config_bus_probe(struct device *dev) @@ -79,10 +88,15 @@ static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) } } +static enum idxd_dev_type dev_types[] = { + IDXD_DEV_NONE, +}; + struct idxd_device_driver dsa_drv = { .name = "dsa", .probe = idxd_dsa_drv_probe, .remove = idxd_dsa_drv_remove, + .type = dev_types, }; /* IDXD engine attributes */ -- cgit v1.2.3-70-g09d2 From 034b3290ba257f1a3c8730f3fba72e11645e7b50 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:24 -0700 Subject: dmaengine: idxd: create idxd_device sub-driver The original architecture of /sys/bus/dsa invented a scheme whereby a single entry in the list of bus drivers, /sys/bus/drivers/dsa, handled all device types and internally routed them to different drivers. Those internal drivers were invisible to userspace. Now, as /sys/bus/dsa wants to grow support for alternate drivers for a given device, for example vfio-mdev instead of kernel-internal-dmaengine, a proper bus device-driver model is needed. The first step in that process is separating the existing omnibus/implicit "dsa" driver into proper individual drivers registered on /sys/bus/dsa. Establish the idxd_drv driver that control the enabling and disabling of the accelerator device. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637466439.744545.15210886092627144577.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 13 +++++++++++++ drivers/dma/idxd/idxd.h | 3 +++ drivers/dma/idxd/init.c | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index d5a0b6fff3b9..12ae3f1639f1 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1349,3 +1349,16 @@ void idxd_device_drv_remove(struct idxd_dev *idxd_dev) if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) idxd_device_reset(idxd); } + +static enum idxd_dev_type dev_types[] = { + IDXD_DEV_DSA, + IDXD_DEV_IAX, + IDXD_DEV_NONE, +}; + +struct idxd_device_driver idxd_drv = { + .type = dev_types, + .probe = idxd_device_drv_probe, + .remove = idxd_device_drv_remove, + .name = "idxd", +}; diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 4bb5a65ec237..a356d227f755 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -58,6 +58,7 @@ struct idxd_device_driver { }; extern struct idxd_device_driver dsa_drv; +extern struct idxd_device_driver idxd_drv; struct idxd_irq_entry { struct idxd_device *idxd; @@ -501,6 +502,8 @@ void idxd_mask_msix_vector(struct idxd_device *idxd, int vec_id); void idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id); /* device control */ +int idxd_register_idxd_drv(void); +void idxd_unregister_idxd_drv(void); int idxd_device_drv_probe(struct idxd_dev *idxd_dev); void idxd_device_drv_remove(struct idxd_dev *idxd_dev); int drv_enable_wq(struct idxd_wq *wq); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 544ff7137292..c19b03c17ab9 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -840,6 +840,10 @@ static int __init idxd_init_module(void) if (err < 0) return err; + err = idxd_driver_register(&idxd_drv); + if (err < 0) + goto err_idxd_driver_register; + err = idxd_driver_register(&dsa_drv); if (err < 0) goto err_dsa_driver_register; @@ -859,6 +863,8 @@ err_pci_register: err_cdev_register: idxd_driver_unregister(&dsa_drv); err_dsa_driver_register: + idxd_driver_unregister(&idxd_drv); +err_idxd_driver_register: idxd_unregister_bus_type(); return err; } @@ -866,6 +872,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { + idxd_driver_unregister(&idxd_drv); idxd_driver_unregister(&dsa_drv); pci_unregister_driver(&idxd_pci_driver); idxd_cdev_remove(); -- cgit v1.2.3-70-g09d2 From 0cda4f6986a3824cac500f66326ff267bf37110f Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:30 -0700 Subject: dmaengine: idxd: create dmaengine driver for wq 'device' The original architecture of /sys/bus/dsa invented a scheme whereby a single entry in the list of bus drivers, /sys/bus/drivers/dsa, handled all device types and internally routed them to different drivers. Those internal drivers were invisible to userspace. Now, as /sys/bus/dsa wants to grow support for alternate drivers for a given device, for example vfio-mdev instead of kernel-internal-dmaengine, a proper bus device-driver model is needed. The first step in that process is separating the existing omnibus/implicit "dsa" driver into proper individual drivers registered on /sys/bus/dsa. Establish the idxd_dmaengine_drv driver that controls the enabling and disabling of the wq and also register and unregister the dma channel. idxd_wq_alloc_resources() and idxd_wq_free_resources() also get moved to the dmaengine driver. The resources (dma descriptors allocation and setup) are only used by the dmaengine driver and should only happen when it loads. The char dev driver (cdev) related bits are left in the __drv_enable_wq() and __drv_disable_wq() calls to be moved when we split out the char dev driver just like how the dmaengine driver is split out. WQ autoload support is not expected currently. With the amount of configuration needed for the device, the wq is always expected to be enabled by a tool (or via sysfs) rather than auto enabled at driver load. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637467033.744545.12330636655625405394.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 40 +++--------------------- drivers/dma/idxd/dma.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/idxd.h | 3 ++ drivers/dma/idxd/init.c | 7 +++++ 4 files changed, 92 insertions(+), 35 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 12ae3f1639f1..4dcc9431ae3d 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1130,7 +1130,7 @@ int idxd_device_load_config(struct idxd_device *idxd) return 0; } -static int __drv_enable_wq(struct idxd_wq *wq) +int __drv_enable_wq(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; struct device *dev = &idxd->pdev->dev; @@ -1178,12 +1178,7 @@ static int __drv_enable_wq(struct idxd_wq *wq) } } - rc = idxd_wq_alloc_resources(wq); - if (rc < 0) { - dev_dbg(dev, "wq resource alloc failed\n"); - goto err; - } - + rc = 0; spin_lock_irqsave(&idxd->dev_lock, flags); if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) rc = idxd_device_config(idxd); @@ -1207,21 +1202,7 @@ static int __drv_enable_wq(struct idxd_wq *wq) wq->client_count = 0; - if (wq->type == IDXD_WQT_KERNEL) { - rc = idxd_wq_init_percpu_ref(wq); - if (rc < 0) { - dev_dbg(dev, "wq %d percpu_ref setup failed\n", wq->id); - goto err_cpu_ref; - } - } - - if (is_idxd_wq_dmaengine(wq)) { - rc = idxd_register_dma_channel(wq); - if (rc < 0) { - dev_dbg(dev, "wq %d DMA channel register failed\n", wq->id); - goto err_client; - } - } else if (is_idxd_wq_cdev(wq)) { + if (is_idxd_wq_cdev(wq)) { rc = idxd_wq_add_cdev(wq); if (rc < 0) { dev_dbg(dev, "wq %d cdev creation failed\n", wq->id); @@ -1229,12 +1210,9 @@ static int __drv_enable_wq(struct idxd_wq *wq) } } - dev_info(dev, "wq %s enabled\n", dev_name(wq_confdev(wq))); return 0; err_client: - idxd_wq_quiesce(wq); -err_cpu_ref: idxd_wq_unmap_portal(wq); err_map_portal: rc = idxd_wq_disable(wq, false); @@ -1254,19 +1232,14 @@ int drv_enable_wq(struct idxd_wq *wq) return rc; } -static void __drv_disable_wq(struct idxd_wq *wq) +void __drv_disable_wq(struct idxd_wq *wq) { struct idxd_device *idxd = wq->idxd; struct device *dev = &idxd->pdev->dev; lockdep_assert_held(&wq->wq_lock); - if (wq->type == IDXD_WQT_KERNEL) - idxd_wq_quiesce(wq); - - if (is_idxd_wq_dmaengine(wq)) - idxd_unregister_dma_channel(wq); - else if (is_idxd_wq_cdev(wq)) + if (is_idxd_wq_cdev(wq)) idxd_wq_del_cdev(wq); if (idxd_wq_refcount(wq)) @@ -1278,10 +1251,7 @@ static void __drv_disable_wq(struct idxd_wq *wq) idxd_wq_drain(wq); idxd_wq_reset(wq); - idxd_wq_free_resources(wq); wq->client_count = 0; - - dev_info(dev, "wq %s disabled\n", dev_name(wq_confdev(wq))); } void drv_disable_wq(struct idxd_wq *wq) diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index 2e52f9a50519..7e3281700183 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -262,3 +262,80 @@ void idxd_unregister_dma_channel(struct idxd_wq *wq) wq->idxd_chan = NULL; put_device(wq_confdev(wq)); } + +static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev) +{ + struct device *dev = &idxd_dev->conf_dev; + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); + struct idxd_device *idxd = wq->idxd; + int rc; + + if (idxd->state != IDXD_DEV_ENABLED) + return -ENXIO; + + mutex_lock(&wq->wq_lock); + wq->type = IDXD_WQT_KERNEL; + rc = __drv_enable_wq(wq); + if (rc < 0) { + dev_dbg(dev, "Enable wq %d failed: %d\n", wq->id, rc); + rc = -ENXIO; + goto err; + } + + rc = idxd_wq_alloc_resources(wq); + if (rc < 0) { + dev_dbg(dev, "WQ resource alloc failed\n"); + goto err_res_alloc; + } + + rc = idxd_wq_init_percpu_ref(wq); + if (rc < 0) { + dev_dbg(dev, "percpu_ref setup failed\n"); + goto err_ref; + } + + rc = idxd_register_dma_channel(wq); + if (rc < 0) { + dev_dbg(dev, "Failed to register dma channel\n"); + goto err_dma; + } + + mutex_unlock(&wq->wq_lock); + return 0; + +err_dma: + idxd_wq_quiesce(wq); +err_ref: + idxd_wq_free_resources(wq); +err_res_alloc: + __drv_disable_wq(wq); +err: + wq->type = IDXD_WQT_NONE; + mutex_unlock(&wq->wq_lock); + return rc; +} + +static void idxd_dmaengine_drv_remove(struct idxd_dev *idxd_dev) +{ + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); + + mutex_lock(&wq->wq_lock); + idxd_wq_quiesce(wq); + idxd_unregister_dma_channel(wq); + __drv_disable_wq(wq); + idxd_wq_free_resources(wq); + wq->type = IDXD_WQT_NONE; + mutex_unlock(&wq->wq_lock); +} + +static enum idxd_dev_type dev_types[] = { + IDXD_DEV_WQ, + IDXD_DEV_NONE, +}; + +struct idxd_device_driver idxd_dmaengine_drv = { + .probe = idxd_dmaengine_drv_probe, + .remove = idxd_dmaengine_drv_remove, + .name = "dmaengine", + .type = dev_types, +}; diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index a356d227f755..a840c328bec9 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -59,6 +59,7 @@ struct idxd_device_driver { extern struct idxd_device_driver dsa_drv; extern struct idxd_device_driver idxd_drv; +extern struct idxd_device_driver idxd_dmaengine_drv; struct idxd_irq_entry { struct idxd_device *idxd; @@ -507,7 +508,9 @@ void idxd_unregister_idxd_drv(void); int idxd_device_drv_probe(struct idxd_dev *idxd_dev); void idxd_device_drv_remove(struct idxd_dev *idxd_dev); int drv_enable_wq(struct idxd_wq *wq); +int __drv_enable_wq(struct idxd_wq *wq); void drv_disable_wq(struct idxd_wq *wq); +void __drv_disable_wq(struct idxd_wq *wq); int idxd_device_init_reset(struct idxd_device *idxd); int idxd_device_enable(struct idxd_device *idxd); int idxd_device_disable(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index c19b03c17ab9..6f38128ce400 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -844,6 +844,10 @@ static int __init idxd_init_module(void) if (err < 0) goto err_idxd_driver_register; + err = idxd_driver_register(&idxd_dmaengine_drv); + if (err < 0) + goto err_idxd_dmaengine_driver_register; + err = idxd_driver_register(&dsa_drv); if (err < 0) goto err_dsa_driver_register; @@ -863,6 +867,8 @@ err_pci_register: err_cdev_register: idxd_driver_unregister(&dsa_drv); err_dsa_driver_register: + idxd_driver_unregister(&idxd_dmaengine_drv); +err_idxd_dmaengine_driver_register: idxd_driver_unregister(&idxd_drv); err_idxd_driver_register: idxd_unregister_bus_type(); @@ -872,6 +878,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { + idxd_driver_unregister(&idxd_dmaengine_drv); idxd_driver_unregister(&idxd_drv); idxd_driver_unregister(&dsa_drv); pci_unregister_driver(&idxd_pci_driver); -- cgit v1.2.3-70-g09d2 From 448c3de8ac8353fc4447738ae3c56c4eb6c2131d Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:35 -0700 Subject: dmaengine: idxd: create user driver for wq 'device' The original architecture of /sys/bus/dsa invented a scheme whereby a single entry in the list of bus drivers, /sys/bus/drivers/dsa, handled all device types and internally routed them to different drivers. Those internal drivers were invisible to userspace. Now, as /sys/bus/dsa wants to grow support for alternate drivers for a given device, for example vfio-mdev instead of kernel-internal-dmaengine, a proper bus device-driver model is needed. The first step in that process is separating the existing omnibus/implicit "dsa" driver into proper individual drivers registered on /sys/bus/dsa. Establish the idxd_user_drv driver that controls the enabling and disabling of the wq and also register and unregister a char device to allow user space to mmap the descriptor submission portal. The cdev related bits are moved to the cdev driver probe/remove and out of the drv_enabe/disable_wq() calls. These bits are exclusive to the cdev operation and not part of the generic enable/disable of the wq device. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637467578.744545.10203997610072341376.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/cdev.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/device.c | 14 ------------- drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/init.c | 7 +++++++ 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index 18a003b93812..b67bbf24242a 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -304,6 +304,59 @@ void idxd_wq_del_cdev(struct idxd_wq *wq) put_device(cdev_dev(idxd_cdev)); } +static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) +{ + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); + struct idxd_device *idxd = wq->idxd; + int rc; + + if (idxd->state != IDXD_DEV_ENABLED) + return -ENXIO; + + mutex_lock(&wq->wq_lock); + wq->type = IDXD_WQT_USER; + rc = __drv_enable_wq(wq); + if (rc < 0) + goto err; + + rc = idxd_wq_add_cdev(wq); + if (rc < 0) + goto err_cdev; + + mutex_unlock(&wq->wq_lock); + return 0; + +err_cdev: + __drv_disable_wq(wq); +err: + wq->type = IDXD_WQT_NONE; + mutex_unlock(&wq->wq_lock); + return rc; +} + +static void idxd_user_drv_remove(struct idxd_dev *idxd_dev) +{ + struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); + + mutex_lock(&wq->wq_lock); + idxd_wq_del_cdev(wq); + __drv_disable_wq(wq); + wq->type = IDXD_WQT_NONE; + mutex_unlock(&wq->wq_lock); +} + +static enum idxd_dev_type dev_types[] = { + IDXD_DEV_WQ, + IDXD_DEV_NONE, +}; + +struct idxd_device_driver idxd_user_drv = { + .probe = idxd_user_drv_probe, + .remove = idxd_user_drv_remove, + .name = "user", + .type = dev_types, +}; + int idxd_cdev_register(void) { int rc, i; diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 4dcc9431ae3d..9bbc28d9a9eb 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1201,19 +1201,8 @@ int __drv_enable_wq(struct idxd_wq *wq) } wq->client_count = 0; - - if (is_idxd_wq_cdev(wq)) { - rc = idxd_wq_add_cdev(wq); - if (rc < 0) { - dev_dbg(dev, "wq %d cdev creation failed\n", wq->id); - goto err_client; - } - } - return 0; -err_client: - idxd_wq_unmap_portal(wq); err_map_portal: rc = idxd_wq_disable(wq, false); if (rc < 0) @@ -1239,9 +1228,6 @@ void __drv_disable_wq(struct idxd_wq *wq) lockdep_assert_held(&wq->wq_lock); - if (is_idxd_wq_cdev(wq)) - idxd_wq_del_cdev(wq); - if (idxd_wq_refcount(wq)) dev_warn(dev, "Clients has claim on wq %d: %d\n", wq->id, idxd_wq_refcount(wq)); diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index a840c328bec9..bacec9b93a7e 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -60,6 +60,7 @@ struct idxd_device_driver { extern struct idxd_device_driver dsa_drv; extern struct idxd_device_driver idxd_drv; extern struct idxd_device_driver idxd_dmaengine_drv; +extern struct idxd_device_driver idxd_user_drv; struct idxd_irq_entry { struct idxd_device *idxd; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 6f38128ce400..33a80f700ff8 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -848,6 +848,10 @@ static int __init idxd_init_module(void) if (err < 0) goto err_idxd_dmaengine_driver_register; + err = idxd_driver_register(&idxd_user_drv); + if (err < 0) + goto err_idxd_user_driver_register; + err = idxd_driver_register(&dsa_drv); if (err < 0) goto err_dsa_driver_register; @@ -867,6 +871,8 @@ err_pci_register: err_cdev_register: idxd_driver_unregister(&dsa_drv); err_dsa_driver_register: + idxd_driver_unregister(&idxd_user_drv); +err_idxd_user_driver_register: idxd_driver_unregister(&idxd_dmaengine_drv); err_idxd_dmaengine_driver_register: idxd_driver_unregister(&idxd_drv); @@ -878,6 +884,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { + idxd_driver_unregister(&idxd_user_drv); idxd_driver_unregister(&idxd_dmaengine_drv); idxd_driver_unregister(&idxd_drv); idxd_driver_unregister(&dsa_drv); -- cgit v1.2.3-70-g09d2 From d9e5481fca74f870cf2fc2f90a0e77e85c0b5b86 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:41 -0700 Subject: dmaengine: dsa: move dsa_bus_type out of idxd driver to standalone In preparation for dsa_drv compat support to be built-in, move the bus code to its own compilation unit. A follow-on patch adds the compat implementation. Recall that the compat implementation allows for the deprecated / omnibus dsa_drv binding scheme rather than the idiomatic organization of a full fledged bus driver per driver type. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637468142.744545.2811632736881720857.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 4 +++ drivers/dma/Makefile | 2 +- drivers/dma/idxd/Makefile | 5 +++ drivers/dma/idxd/bus.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/init.c | 30 +--------------- drivers/dma/idxd/sysfs.c | 43 ---------------------- 6 files changed, 103 insertions(+), 73 deletions(-) create mode 100644 drivers/dma/idxd/bus.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index f450e4231db7..d7101bff1772 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -277,6 +277,10 @@ config INTEL_IDMA64 Enable DMA support for Intel Low Power Subsystem such as found on Intel Skylake PCH. +config INTEL_IDXD_BUS + tristate + default INTEL_IDXD + config INTEL_IDXD tristate "Intel Data Accelerators support" depends on PCI && X86_64 && !UML diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index aa69094e3547..13b5258d04ea 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -41,7 +41,7 @@ obj-$(CONFIG_IMX_DMA) += imx-dma.o obj-$(CONFIG_IMX_SDMA) += imx-sdma.o obj-$(CONFIG_INTEL_IDMA64) += idma64.o obj-$(CONFIG_INTEL_IOATDMA) += ioat/ -obj-$(CONFIG_INTEL_IDXD) += idxd/ +obj-y += idxd/ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o obj-$(CONFIG_K3_DMA) += k3dma.o obj-$(CONFIG_LPC18XX_DMAMUX) += lpc18xx-dmamux.o diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile index 6d11558756f8..8c29ed4d48c3 100644 --- a/drivers/dma/idxd/Makefile +++ b/drivers/dma/idxd/Makefile @@ -1,4 +1,9 @@ +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD + obj-$(CONFIG_INTEL_IDXD) += idxd.o idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o + +obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o +idxd_bus-y := bus.o diff --git a/drivers/dma/idxd/bus.c b/drivers/dma/idxd/bus.c new file mode 100644 index 000000000000..02837f0fb3e4 --- /dev/null +++ b/drivers/dma/idxd/bus.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */ +#include +#include +#include +#include +#include "idxd.h" + + +int __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *owner, + const char *mod_name) +{ + struct device_driver *drv = &idxd_drv->drv; + + if (!idxd_drv->type) { + pr_debug("driver type not set (%ps)\n", __builtin_return_address(0)); + return -EINVAL; + } + + drv->name = idxd_drv->name; + drv->bus = &dsa_bus_type; + drv->owner = owner; + drv->mod_name = mod_name; + + return driver_register(drv); +} +EXPORT_SYMBOL_GPL(__idxd_driver_register); + +void idxd_driver_unregister(struct idxd_device_driver *idxd_drv) +{ + driver_unregister(&idxd_drv->drv); +} +EXPORT_SYMBOL_GPL(idxd_driver_unregister); + +static int idxd_config_bus_match(struct device *dev, + struct device_driver *drv) +{ + struct idxd_device_driver *idxd_drv = + container_of(drv, struct idxd_device_driver, drv); + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + int i = 0; + + while (idxd_drv->type[i] != IDXD_DEV_NONE) { + if (idxd_dev->type == idxd_drv->type[i]) + return 1; + i++; + } + + return 0; +} + +static int idxd_config_bus_probe(struct device *dev) +{ + struct idxd_device_driver *idxd_drv = + container_of(dev->driver, struct idxd_device_driver, drv); + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + return idxd_drv->probe(idxd_dev); +} + +static int idxd_config_bus_remove(struct device *dev) +{ + struct idxd_device_driver *idxd_drv = + container_of(dev->driver, struct idxd_device_driver, drv); + struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); + + idxd_drv->remove(idxd_dev); + return 0; +} + +struct bus_type dsa_bus_type = { + .name = "dsa", + .match = idxd_config_bus_match, + .probe = idxd_config_bus_probe, + .remove = idxd_config_bus_remove, +}; +EXPORT_SYMBOL_GPL(dsa_bus_type); + +static int __init dsa_bus_init(void) +{ + return bus_register(&dsa_bus_type); +} +module_init(dsa_bus_init); + +static void __exit dsa_bus_exit(void) +{ + bus_unregister(&dsa_bus_type); +} +module_exit(dsa_bus_exit); + +MODULE_DESCRIPTION("IDXD driver dsa_bus_type driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 33a80f700ff8..9b797fcdfd7b 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -26,6 +26,7 @@ MODULE_VERSION(IDXD_DRIVER_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Intel Corporation"); +MODULE_IMPORT_NS(IDXD); static bool sva = true; module_param(sva, bool, 0644); @@ -836,10 +837,6 @@ static int __init idxd_init_module(void) perfmon_init(); - err = idxd_register_bus_type(); - if (err < 0) - return err; - err = idxd_driver_register(&idxd_drv); if (err < 0) goto err_idxd_driver_register; @@ -877,7 +874,6 @@ err_idxd_user_driver_register: err_idxd_dmaengine_driver_register: idxd_driver_unregister(&idxd_drv); err_idxd_driver_register: - idxd_unregister_bus_type(); return err; } module_init(idxd_init_module); @@ -890,30 +886,6 @@ static void __exit idxd_exit_module(void) idxd_driver_unregister(&dsa_drv); pci_unregister_driver(&idxd_pci_driver); idxd_cdev_remove(); - idxd_unregister_bus_type(); perfmon_exit(); } module_exit(idxd_exit_module); - -int __idxd_driver_register(struct idxd_device_driver *idxd_drv, struct module *owner, - const char *mod_name) -{ - struct device_driver *drv = &idxd_drv->drv; - - if (!idxd_drv->type) { - pr_debug("driver type not set (%ps)\n", __builtin_return_address(0)); - return -EINVAL; - } - - drv->name = idxd_drv->name; - drv->bus = &dsa_bus_type; - drv->owner = owner; - drv->mod_name = mod_name; - - return driver_register(drv); -} - -void idxd_driver_unregister(struct idxd_device_driver *idxd_drv) -{ - driver_unregister(&idxd_drv->drv); -} diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 8d48903df131..633f4947ed32 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -16,49 +16,6 @@ static char *idxd_wq_type_names[] = { [IDXD_WQT_USER] = "user", }; -static int idxd_config_bus_match(struct device *dev, - struct device_driver *drv) -{ - struct idxd_device_driver *idxd_drv = - container_of(drv, struct idxd_device_driver, drv); - struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - int i = 0; - - while (idxd_drv->type[i] != IDXD_DEV_NONE) { - if (idxd_dev->type == idxd_drv->type[i]) - return 1; - i++; - } - - return 0; -} - -static int idxd_config_bus_probe(struct device *dev) -{ - struct idxd_device_driver *idxd_drv = - container_of(dev->driver, struct idxd_device_driver, drv); - struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - - return idxd_drv->probe(idxd_dev); -} - -static int idxd_config_bus_remove(struct device *dev) -{ - struct idxd_device_driver *idxd_drv = - container_of(dev->driver, struct idxd_device_driver, drv); - struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev); - - idxd_drv->remove(idxd_dev); - return 0; -} - -struct bus_type dsa_bus_type = { - .name = "dsa", - .match = idxd_config_bus_match, - .probe = idxd_config_bus_probe, - .remove = idxd_config_bus_remove, -}; - static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) { if (is_idxd_dev(idxd_dev)) -- cgit v1.2.3-70-g09d2 From 6e7f3ee97bbe2c7d7a53b7dbd7a08a579e03c8c9 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 15 Jul 2021 11:44:47 -0700 Subject: dmaengine: idxd: move dsa_drv support to compatible mode The original architecture of /sys/bus/dsa invented a scheme whereby a single entry in the list of bus drivers, /sys/bus/drivers/dsa, handled all device types and internally routed them to different different drivers. Those internal drivers were invisible to userspace. With the idxd driver transitioned to a proper bus device-driver model, the legacy behavior needs to be preserved due to it being exposed to user space via sysfs. Create a compat driver to provide the legacy behavior for /sys/bus/dsa/drivers/dsa. This should satisfy user tool accel-config v3.2 or ealier where this behavior is expected. If the distro has a newer accel-config then the legacy mode does not need to be enabled. When the compat driver binds the device (i.e. dsa0) to the dsa driver, it will be bound to the new idxd_drv. The wq device (i.e. wq0.0) will be bound to either the dmaengine_drv or the user_drv. The dsa_drv becomes a routing mechansim for the new drivers. It will not support additional external drivers that are implemented later. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162637468705.744545.4399080971745974435.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 17 +++++++ drivers/dma/idxd/Makefile | 3 ++ drivers/dma/idxd/cdev.c | 1 + drivers/dma/idxd/compat.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/idxd/device.c | 1 + drivers/dma/idxd/dma.c | 1 + drivers/dma/idxd/idxd.h | 10 +++- drivers/dma/idxd/init.c | 7 --- drivers/dma/idxd/sysfs.c | 40 ---------------- 9 files changed, 146 insertions(+), 48 deletions(-) create mode 100644 drivers/dma/idxd/compat.c diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index d7101bff1772..ceb41be0505e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -295,6 +295,23 @@ config INTEL_IDXD If unsure, say N. +config INTEL_IDXD_COMPAT + bool "Legacy behavior for idxd driver" + depends on PCI && X86_64 + select INTEL_IDXD_BUS + help + Compatible driver to support old /sys/bus/dsa/drivers/dsa behavior. + The old behavior performed driver bind/unbind for device and wq + devices all under the dsa driver. The compat driver will emulate + the legacy behavior in order to allow existing support apps (i.e. + accel-config) to continue function. It is expected that accel-config + v3.2 and earlier will need the compat mode. A distro with later + accel-config version can disable this compat config. + + Say Y if you have old applications that require such behavior. + + If unsure, say N. + # Config symbol that collects all the dependencies that's necessary to # support shared virtual memory for the devices supported by idxd. config INTEL_IDXD_SVM diff --git a/drivers/dma/idxd/Makefile b/drivers/dma/idxd/Makefile index 8c29ed4d48c3..a1e9f2b3a37c 100644 --- a/drivers/dma/idxd/Makefile +++ b/drivers/dma/idxd/Makefile @@ -7,3 +7,6 @@ idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o obj-$(CONFIG_INTEL_IDXD_BUS) += idxd_bus.o idxd_bus-y := bus.o + +obj-$(CONFIG_INTEL_IDXD_COMPAT) += idxd_compat.o +idxd_compat-y := compat.o diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index b67bbf24242a..f6a4603517ba 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -356,6 +356,7 @@ struct idxd_device_driver idxd_user_drv = { .name = "user", .type = dev_types, }; +EXPORT_SYMBOL_GPL(idxd_user_drv); int idxd_cdev_register(void) { diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c new file mode 100644 index 000000000000..d67746ee0c1a --- /dev/null +++ b/drivers/dma/idxd/compat.c @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */ +#include +#include +#include +#include +#include +#include "idxd.h" + +extern int device_driver_attach(struct device_driver *drv, struct device *dev); +extern void device_driver_detach(struct device *dev); + +#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ + struct driver_attribute driver_attr_##_name = \ + __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) + +static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t count) +{ + struct bus_type *bus = drv->bus; + struct device *dev; + int rc = -ENODEV; + + dev = bus_find_device_by_name(bus, NULL, buf); + if (dev && dev->driver) { + device_driver_detach(dev); + rc = count; + } + + return rc; +} +static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); + +static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t count) +{ + struct bus_type *bus = drv->bus; + struct device *dev; + struct device_driver *alt_drv; + int rc = -ENODEV; + struct idxd_dev *idxd_dev; + + dev = bus_find_device_by_name(bus, NULL, buf); + if (!dev || dev->driver || drv != &dsa_drv.drv) + return -ENODEV; + + idxd_dev = confdev_to_idxd_dev(dev); + if (is_idxd_dev(idxd_dev)) { + alt_drv = driver_find("idxd", bus); + if (!alt_drv) + return -ENODEV; + } else if (is_idxd_wq_dev(idxd_dev)) { + struct idxd_wq *wq = confdev_to_wq(dev); + + if (is_idxd_wq_kernel(wq)) { + alt_drv = driver_find("dmaengine", bus); + if (!alt_drv) + return -ENODEV; + } else if (is_idxd_wq_user(wq)) { + alt_drv = driver_find("user", bus); + if (!alt_drv) + return -ENODEV; + } else { + return -ENODEV; + } + } + + rc = device_driver_attach(alt_drv, dev); + if (rc < 0) + return rc; + + return count; +} +static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); + +static struct attribute *dsa_drv_compat_attrs[] = { + &driver_attr_bind.attr, + &driver_attr_unbind.attr, + NULL, +}; + +static const struct attribute_group dsa_drv_compat_attr_group = { + .attrs = dsa_drv_compat_attrs, +}; + +static const struct attribute_group *dsa_drv_compat_groups[] = { + &dsa_drv_compat_attr_group, + NULL, +}; + +static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) +{ + return -ENODEV; +} + +static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) +{ +} + +static enum idxd_dev_type dev_types[] = { + IDXD_DEV_NONE, +}; + +struct idxd_device_driver dsa_drv = { + .name = "dsa", + .probe = idxd_dsa_drv_probe, + .remove = idxd_dsa_drv_remove, + .type = dev_types, + .drv = { + .suppress_bind_attrs = true, + .groups = dsa_drv_compat_groups, + }, +}; + +module_idxd_driver(dsa_drv); +MODULE_IMPORT_NS(IDXD); diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 9bbc28d9a9eb..99350ac9a292 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1318,3 +1318,4 @@ struct idxd_device_driver idxd_drv = { .remove = idxd_device_drv_remove, .name = "idxd", }; +EXPORT_SYMBOL_GPL(idxd_drv); diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index 7e3281700183..2fd7ec29a08f 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -339,3 +339,4 @@ struct idxd_device_driver idxd_dmaengine_drv = { .name = "dmaengine", .type = dev_types, }; +EXPORT_SYMBOL_GPL(idxd_dmaengine_drv); diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index bacec9b93a7e..d0874d8877d9 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -416,11 +416,16 @@ static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq) return false; } -static inline bool is_idxd_wq_cdev(struct idxd_wq *wq) +static inline bool is_idxd_wq_user(struct idxd_wq *wq) { return wq->type == IDXD_WQT_USER; } +static inline bool is_idxd_wq_kernel(struct idxd_wq *wq) +{ + return wq->type == IDXD_WQT_KERNEL; +} + static inline bool wq_dedicated(struct idxd_wq *wq) { return test_bit(WQ_FLAG_DEDICATED, &wq->flags); @@ -484,6 +489,9 @@ int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, void idxd_driver_unregister(struct idxd_device_driver *idxd_drv); +#define module_idxd_driver(__idxd_driver) \ + module_driver(__idxd_driver, idxd_driver_register, idxd_driver_unregister) + int idxd_register_bus_type(void); void idxd_unregister_bus_type(void); int idxd_register_devices(struct idxd_device *idxd); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 9b797fcdfd7b..8db56f98059f 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -849,10 +849,6 @@ static int __init idxd_init_module(void) if (err < 0) goto err_idxd_user_driver_register; - err = idxd_driver_register(&dsa_drv); - if (err < 0) - goto err_dsa_driver_register; - err = idxd_cdev_register(); if (err) goto err_cdev_register; @@ -866,8 +862,6 @@ static int __init idxd_init_module(void) err_pci_register: idxd_cdev_remove(); err_cdev_register: - idxd_driver_unregister(&dsa_drv); -err_dsa_driver_register: idxd_driver_unregister(&idxd_user_drv); err_idxd_user_driver_register: idxd_driver_unregister(&idxd_dmaengine_drv); @@ -883,7 +877,6 @@ static void __exit idxd_exit_module(void) idxd_driver_unregister(&idxd_user_drv); idxd_driver_unregister(&idxd_dmaengine_drv); idxd_driver_unregister(&idxd_drv); - idxd_driver_unregister(&dsa_drv); pci_unregister_driver(&idxd_pci_driver); idxd_cdev_remove(); perfmon_exit(); diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 633f4947ed32..b883e9f16e7f 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -16,46 +16,6 @@ static char *idxd_wq_type_names[] = { [IDXD_WQT_USER] = "user", }; -static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) -{ - if (is_idxd_dev(idxd_dev)) - return idxd_device_drv_probe(idxd_dev); - - if (is_idxd_wq_dev(idxd_dev)) { - struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); - - return drv_enable_wq(wq); - } - - return -ENODEV; -} - -static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) -{ - if (is_idxd_dev(idxd_dev)) { - idxd_device_drv_remove(idxd_dev); - return; - } - - if (is_idxd_wq_dev(idxd_dev)) { - struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev); - - drv_disable_wq(wq); - return; - } -} - -static enum idxd_dev_type dev_types[] = { - IDXD_DEV_NONE, -}; - -struct idxd_device_driver dsa_drv = { - .name = "dsa", - .probe = idxd_dsa_drv_probe, - .remove = idxd_dsa_drv_remove, - .type = dev_types, -}; - /* IDXD engine attributes */ static ssize_t engine_group_id_show(struct device *dev, struct device_attribute *attr, char *buf) -- cgit v1.2.3-70-g09d2 From 0e96454ca26cc5c594ec792f7e5168cce726f7cf Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 14 Jul 2021 16:25:00 -0700 Subject: dmaengine: idxd: remove fault processing code Kernel memory are pinned and will not cause faults. Since the driver does not support interrupts for user descriptors, no fault errors are expected to come through the misc interrupt. Remove dead code. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162630502789.631986.10591230961790023856.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/irq.c | 95 +++----------------------------------------------- 1 file changed, 4 insertions(+), 91 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index be65d55e1fc4..e018459b534f 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -23,10 +23,8 @@ struct idxd_fault { }; static int irq_process_work_list(struct idxd_irq_entry *irq_entry, - enum irq_work_type wtype, int *processed, u64 data); static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, - enum irq_work_type wtype, int *processed, u64 data); static void idxd_device_reinit(struct work_struct *work) @@ -62,46 +60,6 @@ static void idxd_device_reinit(struct work_struct *work) idxd_device_clear_state(idxd); } -static void idxd_device_fault_work(struct work_struct *work) -{ - struct idxd_fault *fault = container_of(work, struct idxd_fault, work); - struct idxd_irq_entry *ie; - int i; - int processed; - int irqcnt = fault->idxd->num_wq_irqs + 1; - - for (i = 1; i < irqcnt; i++) { - ie = &fault->idxd->irq_entries[i]; - irq_process_work_list(ie, IRQ_WORK_PROCESS_FAULT, - &processed, fault->addr); - if (processed) - break; - - irq_process_pending_llist(ie, IRQ_WORK_PROCESS_FAULT, - &processed, fault->addr); - if (processed) - break; - } - - kfree(fault); -} - -static int idxd_device_schedule_fault_process(struct idxd_device *idxd, - u64 fault_addr) -{ - struct idxd_fault *fault; - - fault = kmalloc(sizeof(*fault), GFP_ATOMIC); - if (!fault) - return -ENOMEM; - - fault->addr = fault_addr; - fault->idxd = idxd; - INIT_WORK(&fault->work, idxd_device_fault_work); - queue_work(idxd->wq, &fault->work); - return 0; -} - static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) { struct device *dev = &idxd->pdev->dev; @@ -168,15 +126,6 @@ static int process_misc_interrupts(struct idxd_device *idxd, u32 cause) if (!err) return 0; - /* - * This case should rarely happen and typically is due to software - * programming error by the driver. - */ - if (idxd->sw_err.valid && - idxd->sw_err.desc_valid && - idxd->sw_err.fault_addr) - idxd_device_schedule_fault_process(idxd, idxd->sw_err.fault_addr); - gensts.bits = ioread32(idxd->reg_base + IDXD_GENSTATS_OFFSET); if (gensts.state == IDXD_DEVICE_STATE_HALT) { idxd->state = IDXD_DEV_HALTED; @@ -228,43 +177,19 @@ irqreturn_t idxd_misc_thread(int vec, void *data) return IRQ_HANDLED; } -static inline bool match_fault(struct idxd_desc *desc, u64 fault_addr) -{ - /* - * Completion address can be bad as well. Check fault address match for descriptor - * and completion address. - */ - if ((u64)desc->hw == fault_addr || (u64)desc->completion == fault_addr) { - struct idxd_device *idxd = desc->wq->idxd; - struct device *dev = &idxd->pdev->dev; - - dev_warn(dev, "desc with fault address: %#llx\n", fault_addr); - return true; - } - - return false; -} - static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, - enum irq_work_type wtype, int *processed, u64 data) { struct idxd_desc *desc, *t; struct llist_node *head; int queued = 0; unsigned long flags; - enum idxd_complete_type reason; *processed = 0; head = llist_del_all(&irq_entry->pending_llist); if (!head) goto out; - if (wtype == IRQ_WORK_NORMAL) - reason = IDXD_COMPLETE_NORMAL; - else - reason = IDXD_COMPLETE_DEV_FAIL; - llist_for_each_entry_safe(desc, t, head, llnode) { u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; @@ -275,9 +200,7 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, continue; } - if (unlikely(status != DSA_COMP_SUCCESS)) - match_fault(desc, data); - complete_desc(desc, reason); + complete_desc(desc, IDXD_COMPLETE_NORMAL); (*processed)++; } else { spin_lock_irqsave(&irq_entry->list_lock, flags); @@ -293,20 +216,14 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, } static int irq_process_work_list(struct idxd_irq_entry *irq_entry, - enum irq_work_type wtype, int *processed, u64 data) { int queued = 0; unsigned long flags; LIST_HEAD(flist); struct idxd_desc *desc, *n; - enum idxd_complete_type reason; *processed = 0; - if (wtype == IRQ_WORK_NORMAL) - reason = IDXD_COMPLETE_NORMAL; - else - reason = IDXD_COMPLETE_DEV_FAIL; /* * This lock protects list corruption from access of list outside of the irq handler @@ -338,9 +255,7 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, continue; } - if (unlikely(status != DSA_COMP_SUCCESS)) - match_fault(desc, data); - complete_desc(desc, reason); + complete_desc(desc, IDXD_COMPLETE_NORMAL); } return queued; @@ -370,14 +285,12 @@ static int idxd_desc_process(struct idxd_irq_entry *irq_entry) * 5. Repeat until no more descriptors. */ do { - rc = irq_process_work_list(irq_entry, IRQ_WORK_NORMAL, - &processed, 0); + rc = irq_process_work_list(irq_entry, &processed, 0); total += processed; if (rc != 0) continue; - rc = irq_process_pending_llist(irq_entry, IRQ_WORK_NORMAL, - &processed, 0); + rc = irq_process_pending_llist(irq_entry, &processed, 0); total += processed; } while (rc != 0); -- cgit v1.2.3-70-g09d2 From 7d3370e506ec5cd781ef6b938cf29c046eb77585 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 20 Jul 2021 21:48:35 -0700 Subject: Revert "Input: serio - make write method mandatory" This reverts commit 81c7c0a350bfe9306ad9fb10356534ede8f4ab31. The idea to make write method mandatory was flawed as several client drivers (such as atkbd) check for presence of write() method to adjust behavior of the driver. Reported-by: Nathan Chancellor Reported-by: Michael Kelley Signed-off-by: Dmitry Torokhov --- drivers/input/serio/ams_delta_serio.c | 6 ------ drivers/input/serio/serio.c | 5 ----- include/linux/serio.h | 5 ++++- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index a1c314897951..1c0be299f179 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -89,11 +89,6 @@ static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int ams_delta_serio_write(struct serio *serio, u8 data) -{ - return -EINVAL; -} - static int ams_delta_serio_open(struct serio *serio) { struct ams_delta_serio *priv = serio->port_data; @@ -162,7 +157,6 @@ static int ams_delta_serio_init(struct platform_device *pdev) priv->serio = serio; serio->id.type = SERIO_8042; - serio->write = ams_delta_serio_write; serio->open = ams_delta_serio_open; serio->close = ams_delta_serio_close; strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name)); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 8d229a11bb6b..29f491082926 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -694,11 +694,6 @@ EXPORT_SYMBOL(serio_reconnect); */ void __serio_register_port(struct serio *serio, struct module *owner) { - if (!serio->write) { - pr_err("%s: refusing to register %s without write method\n", - __func__, serio->name); - return; - } serio_init_port(serio); serio_queue_event(serio, owner, SERIO_REGISTER_PORT); } diff --git a/include/linux/serio.h b/include/linux/serio.h index 075f1b8d76fa..6c27d413da92 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -121,7 +121,10 @@ void serio_unregister_driver(struct serio_driver *drv); static inline int serio_write(struct serio *serio, unsigned char data) { - return serio->write(serio, data); + if (serio->write) + return serio->write(serio, data); + else + return -1; } static inline void serio_drv_write_wakeup(struct serio *serio) -- cgit v1.2.3-70-g09d2 From dcb7c0b9461c2a30f6616262736daac6f01ecb09 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 20 Jul 2021 14:54:17 -0700 Subject: hardening: Clarify Kconfig text for auto-var-init Clarify the details around the automatic variable initialization modes available. Specifically this details the values used for pattern init and expands on the rationale for zero init safety. Additionally makes zero init the default when available. Cc: glider@google.com Cc: Nathan Chancellor Cc: Nick Desaulniers Cc: linux-security-module@vger.kernel.org Cc: clang-built-linux@googlegroups.com Signed-off-by: Kees Cook Acked-by: Gustavo A. R. Silva --- security/Kconfig.hardening | 52 ++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index 023aea5e117c..90cbaff86e13 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -29,6 +29,7 @@ choice prompt "Initialize kernel stack variables at function entry" default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS default INIT_STACK_ALL_PATTERN if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT_PATTERN + default INIT_STACK_ALL_ZERO if CC_HAS_AUTO_VAR_INIT_PATTERN default INIT_STACK_NONE help This option enables initialization of stack variables at @@ -39,11 +40,11 @@ choice syscalls. This chooses the level of coverage over classes of potentially - uninitialized variables. The selected class will be + uninitialized variables. The selected class of variable will be initialized before use in a function. config INIT_STACK_NONE - bool "no automatic initialization (weakest)" + bool "no automatic stack variable initialization (weakest)" help Disable automatic stack variable initialization. This leaves the kernel vulnerable to the standard @@ -80,7 +81,7 @@ choice and is disallowed. config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL - bool "zero-init anything passed by reference (very strong)" + bool "zero-init everything passed by reference (very strong)" depends on GCC_PLUGINS depends on !(KASAN && KASAN_STACK) select GCC_PLUGIN_STRUCTLEAK @@ -91,33 +92,44 @@ choice of uninitialized stack variable exploits and information exposures. + As a side-effect, this keeps a lot of variables on the + stack that can otherwise be optimized out, so combining + this with CONFIG_KASAN_STACK can lead to a stack overflow + and is disallowed. + config INIT_STACK_ALL_PATTERN - bool "0xAA-init everything on the stack (strongest)" + bool "pattern-init everything (strongest)" depends on CC_HAS_AUTO_VAR_INIT_PATTERN help - Initializes everything on the stack with a 0xAA - pattern. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures, even variables that were warned to have been - left uninitialized. + Initializes everything on the stack (including padding) + with a specific debug value. This is intended to eliminate + all classes of uninitialized stack variable exploits and + information exposures, even variables that were warned about + having been left uninitialized. Pattern initialization is known to provoke many existing bugs related to uninitialized locals, e.g. pointers receive - non-NULL values, buffer sizes and indices are very big. + non-NULL values, buffer sizes and indices are very big. The + pattern is situation-specific; Clang on 64-bit uses 0xAA + repeating for all types and padding except float and double + which use 0xFF repeating (-NaN). Clang on 32-bit uses 0xFF + repeating for all types and padding. config INIT_STACK_ALL_ZERO - bool "zero-init everything on the stack (strongest and safest)" + bool "zero-init everything (strongest and safest)" depends on CC_HAS_AUTO_VAR_INIT_ZERO help - Initializes everything on the stack with a zero - value. This is intended to eliminate all classes - of uninitialized stack variable exploits and information - exposures, even variables that were warned to have been - left uninitialized. - - Zero initialization provides safe defaults for strings, - pointers, indices and sizes, and is therefore - more suitable as a security mitigation measure. + Initializes everything on the stack (including padding) + with a zero value. This is intended to eliminate all + classes of uninitialized stack variable exploits and + information exposures, even variables that were warned + about having been left uninitialized. + + Zero initialization provides safe defaults for strings + (immediately NUL-terminated), pointers (NULL), indices + (index 0), and sizes (0 length), so it is therefore more + suitable as a production security mitigation than pattern + initialization. endchoice -- cgit v1.2.3-70-g09d2 From 17ce60b2e4f87262eedd693021224130d720c00c Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Mon, 5 Jul 2021 00:43:59 +0000 Subject: Documentation: gpio: driver.rst: Remove gpiochip_irqchip_add mention This function was removed in commit f1f37abbe6fc ("gpio: Retire the explicit gpio irqchip code") but this mention was left behind. Also, mention that .set_type() only has to set a line handler if the chip is cascaded, as opposed to hierarchical. Signed-off-by: Vincent Pelletier Signed-off-by: Bartosz Golaszewski --- Documentation/driver-api/gpio/driver.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index d6b0d779859b..bbc53920d4dd 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -547,13 +547,10 @@ To use the helpers please keep the following in mind: the irqchip can initialize. E.g. .dev and .can_sleep shall be set up properly. -- Nominally set all handlers to handle_bad_irq() in the setup call and pass - handle_bad_irq() as flow handler parameter in gpiochip_irqchip_add() if it is - expected for GPIO driver that irqchip .set_type() callback will be called - before using/enabling each GPIO IRQ. Then set the handler to - handle_level_irq() and/or handle_edge_irq() in the irqchip .set_type() - callback depending on what your controller supports and what is requested - by the consumer. +- Nominally set gpio_irq_chip.handler to handle_bad_irq. Then, if your irqchip + is cascaded, set the handler to handle_level_irq() and/or handle_edge_irq() + in the irqchip .set_type() callback depending on what your controller + supports and what is requested by the consumer. Locking IRQ usage -- cgit v1.2.3-70-g09d2 From f3f1017a98f91355671feb0e741391999a43b55d Mon Sep 17 00:00:00 2001 From: Hannu Hartikainen Date: Thu, 8 Jul 2021 18:20:54 +0300 Subject: docs: gpio: explain GPIOD_OUT_* values and toggling active low I was confused about the gpiod_flags values and thought that GPIOD_OUT_LOW and GPIOD_OUT_HIGH set the line to be active low / active high. This is not true, but I got the misconception because the flags GPIOD_OUT_*_OPEN_DRAIN do change line configuration and there's a subchapter about *active low* and *open drain* semantics. Add an explicit mention that the initial value is a logical value (and not the line configuration or physical line level). Also add a mention of the function gpiod_toggle_active_low which was previously missing from this document. Signed-off-by: Hannu Hartikainen Signed-off-by: Bartosz Golaszewski --- Documentation/driver-api/gpio/consumer.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst index 3366a991b4aa..47869ca8ccf0 100644 --- a/Documentation/driver-api/gpio/consumer.rst +++ b/Documentation/driver-api/gpio/consumer.rst @@ -72,6 +72,10 @@ for the GPIO. Values can be: * GPIOD_OUT_HIGH_OPEN_DRAIN same as GPIOD_OUT_HIGH but also enforce the line to be electrically used with open drain. +Note that the initial value is *logical* and the physical line level depends on +whether the line is configured active high or active low (see +:ref:`active_low_semantics`). + The two last flags are used for use cases where open drain is mandatory, such as I2C: if the line is not already configured as open drain in the mappings (see board.txt), then open drain will be enforced anyway and a warning will be @@ -252,6 +256,8 @@ that can't be accessed from hardIRQ handlers, these calls act the same as the spinlock-safe calls. +.. _active_low_semantics: + The active low and open drain semantics --------------------------------------- As a consumer should not have to care about the physical line level, all of the @@ -309,9 +315,11 @@ work on the raw line value:: void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value) int gpiod_direction_output_raw(struct gpio_desc *desc, int value) -The active low state of a GPIO can also be queried using the following call:: +The active low state of a GPIO can also be queried and toggled using the +following calls:: int gpiod_is_active_low(const struct gpio_desc *desc) + void gpiod_toggle_active_low(struct gpio_desc *desc) Note that these functions should only be used with great moderation; a driver should not have to care about the physical line level or open drain semantics. -- cgit v1.2.3-70-g09d2 From daa37361518bf2d1f591bbdaa7c68b2a43d7af48 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 15 Jul 2021 13:36:36 +0200 Subject: backlight: ktd253: Stabilize backlight Remove interrupt disablement during backlight setting. It is way to dangerous and makes platforms instable by having it miss vblank IRQs leading to the graphics derailing. The code is using ndelay() which is not available on platforms such as ARM and will result in 32 * udelay(1) which is substantial. Add some code to detect if an interrupt occurs during the tight loop and in that case just redo it from the top. Fixes: 5317f37e48b9 ("backlight: Add Kinetic KTD253 backlight driver") Cc: Stephan Gerhold Reported-by: newbyte@disroot.org Reviewed-by: Daniel Thompson Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/video/backlight/ktd253-backlight.c | 75 ++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/drivers/video/backlight/ktd253-backlight.c b/drivers/video/backlight/ktd253-backlight.c index a7df5bcca9da..37aa5a669530 100644 --- a/drivers/video/backlight/ktd253-backlight.c +++ b/drivers/video/backlight/ktd253-backlight.c @@ -25,6 +25,7 @@ #define KTD253_T_LOW_NS (200 + 10) /* Additional 10ns as safety factor */ #define KTD253_T_HIGH_NS (200 + 10) /* Additional 10ns as safety factor */ +#define KTD253_T_OFF_CRIT_NS 100000 /* 100 us, now it doesn't look good */ #define KTD253_T_OFF_MS 3 struct ktd253_backlight { @@ -34,13 +35,50 @@ struct ktd253_backlight { u16 ratio; }; +static void ktd253_backlight_set_max_ratio(struct ktd253_backlight *ktd253) +{ + gpiod_set_value_cansleep(ktd253->gpiod, 1); + ndelay(KTD253_T_HIGH_NS); + /* We always fall back to this when we power on */ +} + +static int ktd253_backlight_stepdown(struct ktd253_backlight *ktd253) +{ + /* + * These GPIO operations absolutely can NOT sleep so no _cansleep + * suffixes, and no using GPIO expanders on slow buses for this! + * + * The maximum number of cycles of the loop is 32 so the time taken + * should nominally be: + * (T_LOW_NS + T_HIGH_NS + loop_time) * 32 + * + * Architectures do not always support ndelay() and we will get a few us + * instead. If we get to a critical time limit an interrupt has likely + * occured in the low part of the loop and we need to restart from the + * top so we have the backlight in a known state. + */ + u64 ns; + + ns = ktime_get_ns(); + gpiod_set_value(ktd253->gpiod, 0); + ndelay(KTD253_T_LOW_NS); + gpiod_set_value(ktd253->gpiod, 1); + ns = ktime_get_ns() - ns; + if (ns >= KTD253_T_OFF_CRIT_NS) { + dev_err(ktd253->dev, "PCM on backlight took too long (%llu ns)\n", ns); + return -EAGAIN; + } + ndelay(KTD253_T_HIGH_NS); + return 0; +} + static int ktd253_backlight_update_status(struct backlight_device *bl) { struct ktd253_backlight *ktd253 = bl_get_data(bl); int brightness = backlight_get_brightness(bl); u16 target_ratio; u16 current_ratio = ktd253->ratio; - unsigned long flags; + int ret; dev_dbg(ktd253->dev, "new brightness/ratio: %d/32\n", brightness); @@ -62,37 +100,34 @@ static int ktd253_backlight_update_status(struct backlight_device *bl) } if (current_ratio == 0) { - gpiod_set_value_cansleep(ktd253->gpiod, 1); - ndelay(KTD253_T_HIGH_NS); - /* We always fall back to this when we power on */ + ktd253_backlight_set_max_ratio(ktd253); current_ratio = KTD253_MAX_RATIO; } - /* - * WARNING: - * The loop to set the correct current level is performed - * with interrupts disabled as it is timing critical. - * The maximum number of cycles of the loop is 32 - * so the time taken will be (T_LOW_NS + T_HIGH_NS + loop_time) * 32, - */ - local_irq_save(flags); while (current_ratio != target_ratio) { /* * These GPIO operations absolutely can NOT sleep so no * _cansleep suffixes, and no using GPIO expanders on * slow buses for this! */ - gpiod_set_value(ktd253->gpiod, 0); - ndelay(KTD253_T_LOW_NS); - gpiod_set_value(ktd253->gpiod, 1); - ndelay(KTD253_T_HIGH_NS); - /* After 1/32 we loop back to 32/32 */ - if (current_ratio == KTD253_MIN_RATIO) + ret = ktd253_backlight_stepdown(ktd253); + if (ret == -EAGAIN) { + /* + * Something disturbed the backlight setting code when + * running so we need to bring the PWM back to a known + * state. This shouldn't happen too much. + */ + gpiod_set_value_cansleep(ktd253->gpiod, 0); + msleep(KTD253_T_OFF_MS); + ktd253_backlight_set_max_ratio(ktd253); + current_ratio = KTD253_MAX_RATIO; + } else if (current_ratio == KTD253_MIN_RATIO) { + /* After 1/32 we loop back to 32/32 */ current_ratio = KTD253_MAX_RATIO; - else + } else { current_ratio--; + } } - local_irq_restore(flags); ktd253->ratio = current_ratio; dev_dbg(ktd253->dev, "new ratio set to %d/32\n", target_ratio); -- cgit v1.2.3-70-g09d2 From f591a2e0548da88130c7b1c79f1f735273adc683 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Sun, 4 Jul 2021 09:54:01 +0200 Subject: scsi: core: Add new flag BLIST_IGN_MEDIA_CHANGE Add a new flag for devices that erroneously establish MEDIUM MAY HAVE CHANGED unit attentions. Drivers can set this flag to make the SCSI layer ignore media change events during resume. [mkp: add "ignore" and add corresponding flag to struct scsi_device] Link: https://lore.kernel.org/r/20210704075403.147114-2-martin.kepplinger@puri.sm Reviewed-by: Bart Van Assche Signed-off-by: Martin Kepplinger Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_scan.c | 3 +++ include/scsi/scsi_device.h | 1 + include/scsi/scsi_devinfo.h | 6 +++--- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index b059bf2b61d4..3faedf4970ec 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -973,6 +973,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_UNMAP_LIMIT_WS) sdev->unmap_limit_for_ws = 1; + if (*bflags & BLIST_IGN_MEDIA_CHANGE) + sdev->ignore_media_change = 1; + sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; if (*bflags & BLIST_TRY_VPD_PAGES) diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index ac6ab16abee7..d1de21f799f4 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -205,6 +205,7 @@ struct scsi_device { unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */ unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device * creation time */ + unsigned ignore_media_change:1; /* Ignore MEDIA CHANGE on resume */ bool offline_already; /* Device offline message logged */ diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index 3fdb322d4c4b..5d14adae21c7 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -28,7 +28,8 @@ #define BLIST_LARGELUN ((__force blist_flags_t)(1ULL << 9)) /* override additional length field */ #define BLIST_INQUIRY_36 ((__force blist_flags_t)(1ULL << 10)) -#define __BLIST_UNUSED_11 ((__force blist_flags_t)(1ULL << 11)) +/* ignore MEDIA CHANGE unit attention after resuming from runtime suspend */ +#define BLIST_IGN_MEDIA_CHANGE ((__force blist_flags_t)(1ULL << 11)) /* do not do automatic start on add */ #define BLIST_NOSTARTONADD ((__force blist_flags_t)(1ULL << 12)) #define __BLIST_UNUSED_13 ((__force blist_flags_t)(1ULL << 13)) @@ -73,8 +74,7 @@ #define __BLIST_HIGH_UNUSED (~(__BLIST_LAST_USED | \ (__force blist_flags_t) \ ((__force __u64)__BLIST_LAST_USED - 1ULL))) -#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_11 | \ - __BLIST_UNUSED_13 | \ +#define __BLIST_UNUSED_MASK (__BLIST_UNUSED_13 | \ __BLIST_UNUSED_14 | \ __BLIST_UNUSED_15 | \ __BLIST_UNUSED_16 | \ -- cgit v1.2.3-70-g09d2 From ed4246d37f3b94e429d020cac692434a00bae4cc Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Sun, 4 Jul 2021 09:54:02 +0200 Subject: scsi: sd: REQUEST SENSE for BLIST_IGN_MEDIA_CHANGE devices in runtime_resume() For SD card reader devices that have the BLIST_IGN_MEDIA_CHANGE flag set, a MEDIUM MAY HAVE CHANGED unit attention is established after resuming from runtime suspend. Send a REQUEST SENSE to consume the UA. The "downside" is that for these devices we now rely on users to not change the medium (SD card) *during* a runtime suspend/resume cycle, i.e. when not unmounting. To enable runtime PM for an SD cardreader (device number 0:0:0:0), do: echo 0 > /sys/module/block/parameters/events_dfl_poll_msecs echo 1000 > /sys/bus/scsi/devices/0:0:0:0/power/autosuspend_delay_ms echo auto > /sys/bus/scsi/devices/0:0:0:0/power/control [mkp: use scsi_device flag instead of poking at BLIST] Link: https://lore.kernel.org/r/20210704075403.147114-3-martin.kepplinger@puri.sm Reviewed-by: Bart Van Assche Signed-off-by: Martin Kepplinger Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b8d55af763f9..e7ef4728d5eb 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -110,6 +110,7 @@ static void sd_shutdown(struct device *); static int sd_suspend_system(struct device *); static int sd_suspend_runtime(struct device *); static int sd_resume(struct device *); +static int sd_resume_runtime(struct device *); static void sd_rescan(struct device *); static blk_status_t sd_init_command(struct scsi_cmnd *SCpnt); static void sd_uninit_command(struct scsi_cmnd *SCpnt); @@ -604,7 +605,7 @@ static const struct dev_pm_ops sd_pm_ops = { .poweroff = sd_suspend_system, .restore = sd_resume, .runtime_suspend = sd_suspend_runtime, - .runtime_resume = sd_resume, + .runtime_resume = sd_resume_runtime, }; static struct scsi_driver sd_template = { @@ -3716,6 +3717,25 @@ static int sd_resume(struct device *dev) return ret; } +static int sd_resume_runtime(struct device *dev) +{ + struct scsi_disk *sdkp = dev_get_drvdata(dev); + struct scsi_device *sdp = sdkp->device; + + if (sdp->ignore_media_change) { + /* clear the device's sense data */ + static const u8 cmd[10] = { REQUEST_SENSE }; + + if (scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, + NULL, sdp->request_queue->rq_timeout, 1, 0, + RQF_PM, NULL)) + sd_printk(KERN_NOTICE, sdkp, + "Failed to clear sense data\n"); + } + + return sd_resume(dev); +} + /** * init_sd - entry point for this driver (both when built in or when * a module). -- cgit v1.2.3-70-g09d2 From 9abe677951d15a099964b909010daaf92307bd4b Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Sun, 4 Jul 2021 09:54:03 +0200 Subject: scsi: core: Add BLIST_IGN_MEDIA_CHANGE for Ultra HS-SD/MMC USB card readers Ultra HS-SD/MMC card reader devices establish a MEDIUM MAY HAVE CHANGED unit attention not only when the medium changes but also when resuming from suspend. Setting the BLIST_IGN_MEDIA_CHANGE flag permits using runtime PM for these readers. [mkp: renamed flag] Link: https://lore.kernel.org/r/20210704075403.147114-4-martin.kepplinger@puri.sm Reviewed-by: Bart Van Assche Signed-off-by: Martin Kepplinger Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index d33355ab6e14..c7080454aea9 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -171,6 +171,7 @@ static struct { {"FUJITSU", "ETERNUS_DXM", "*", BLIST_RETRY_ASC_C1}, {"Generic", "USB SD Reader", "1.00", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"Generic", "USB Storage-SMC", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, /* FW: 0180 and 0207 */ + {"Generic", "Ultra HS-SD/MMC", "2.09", BLIST_IGN_MEDIA_CHANGE | BLIST_INQUIRY_36}, {"HITACHI", "DF400", "*", BLIST_REPORTLUN2}, {"HITACHI", "DF500", "*", BLIST_REPORTLUN2}, {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, -- cgit v1.2.3-70-g09d2 From b7d2be48cc08a9d42e347d944efa9f37ab9b83d2 Mon Sep 17 00:00:00 2001 From: Chen Lifu Date: Tue, 29 Jun 2021 10:34:54 +0800 Subject: riscv: kprobes: implement the auipc instruction This has been tested by probing a module that contains an auipc instruction. Signed-off-by: Chen Lifu [Palmer: commit message] Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/probes/decode-insn.c | 2 +- arch/riscv/kernel/probes/simulate-insn.c | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c index 0ed043acc882..5eb03fb61450 100644 --- a/arch/riscv/kernel/probes/decode-insn.c +++ b/arch/riscv/kernel/probes/decode-insn.c @@ -38,11 +38,11 @@ riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api) RISCV_INSN_REJECTED(c_ebreak, insn); #endif - RISCV_INSN_REJECTED(auipc, insn); RISCV_INSN_REJECTED(branch, insn); RISCV_INSN_SET_SIMULATE(jal, insn); RISCV_INSN_SET_SIMULATE(jalr, insn); + RISCV_INSN_SET_SIMULATE(auipc, insn); return INSN_GOOD; } diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c index 2519ce26377d..b81719522d5c 100644 --- a/arch/riscv/kernel/probes/simulate-insn.c +++ b/arch/riscv/kernel/probes/simulate-insn.c @@ -83,3 +83,37 @@ bool __kprobes simulate_jalr(u32 opcode, unsigned long addr, struct pt_regs *reg return ret; } + +#define auipc_rd_idx(opcode) \ + ((opcode >> 7) & 0x1f) + +#define auipc_imm(opcode) \ + ((((opcode) >> 12) & 0xfffff) << 12) + +#if __riscv_xlen == 64 +#define auipc_offset(opcode) sign_extend64(auipc_imm(opcode), 31) +#elif __riscv_xlen == 32 +#define auipc_offset(opcode) auipc_imm(opcode) +#else +#error "Unexpected __riscv_xlen" +#endif + +bool __kprobes simulate_auipc(u32 opcode, unsigned long addr, struct pt_regs *regs) +{ + /* + * auipc instruction: + * 31 12 11 7 6 0 + * | imm[31:12] | rd | opcode | + * 20 5 7 + */ + + u32 rd_idx = auipc_rd_idx(opcode); + unsigned long rd_val = addr + auipc_offset(opcode); + + if (!rv_insn_reg_set_val(regs, rd_idx, rd_val)) + return false; + + instruction_pointer_set(regs, addr + 4); + + return true; +} -- cgit v1.2.3-70-g09d2 From 67979e927dd053bde3b71128495f651256b3161c Mon Sep 17 00:00:00 2001 From: Chen Lifu Date: Tue, 29 Jun 2021 10:34:55 +0800 Subject: riscv: kprobes: implement the branch instructions This has been tested by probing a module that contains each of the flavors of branches we have. Signed-off-by: Chen Lifu [Palmer: commit message, fix kconfig errors] Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/probes/decode-insn.c | 3 +- arch/riscv/kernel/probes/simulate-insn.c | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c index 5eb03fb61450..64f6183b4717 100644 --- a/arch/riscv/kernel/probes/decode-insn.c +++ b/arch/riscv/kernel/probes/decode-insn.c @@ -38,11 +38,10 @@ riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api) RISCV_INSN_REJECTED(c_ebreak, insn); #endif - RISCV_INSN_REJECTED(branch, insn); - RISCV_INSN_SET_SIMULATE(jal, insn); RISCV_INSN_SET_SIMULATE(jalr, insn); RISCV_INSN_SET_SIMULATE(auipc, insn); + RISCV_INSN_SET_SIMULATE(branch, insn); return INSN_GOOD; } diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c index b81719522d5c..d73e96f6ed7c 100644 --- a/arch/riscv/kernel/probes/simulate-insn.c +++ b/arch/riscv/kernel/probes/simulate-insn.c @@ -117,3 +117,81 @@ bool __kprobes simulate_auipc(u32 opcode, unsigned long addr, struct pt_regs *re return true; } + +#define branch_rs1_idx(opcode) \ + (((opcode) >> 15) & 0x1f) + +#define branch_rs2_idx(opcode) \ + (((opcode) >> 20) & 0x1f) + +#define branch_funct3(opcode) \ + (((opcode) >> 12) & 0x7) + +#define branch_imm(opcode) \ + (((((opcode) >> 8) & 0xf ) << 1) | \ + ((((opcode) >> 25) & 0x3f) << 5) | \ + ((((opcode) >> 7) & 0x1 ) << 11) | \ + ((((opcode) >> 31) & 0x1 ) << 12)) + +#define branch_offset(opcode) \ + sign_extend32((branch_imm(opcode)), 12) + +#define BRANCH_BEQ 0x0 +#define BRANCH_BNE 0x1 +#define BRANCH_BLT 0x4 +#define BRANCH_BGE 0x5 +#define BRANCH_BLTU 0x6 +#define BRANCH_BGEU 0x7 + +bool __kprobes simulate_branch(u32 opcode, unsigned long addr, struct pt_regs *regs) +{ + /* + * branch instructions: + * 31 30 25 24 20 19 15 14 12 11 8 7 6 0 + * | imm[12] | imm[10:5] | rs2 | rs1 | funct3 | imm[4:1] | imm[11] | opcode | + * 1 6 5 5 3 4 1 7 + * imm[12|10:5] rs2 rs1 000 imm[4:1|11] 1100011 BEQ + * imm[12|10:5] rs2 rs1 001 imm[4:1|11] 1100011 BNE + * imm[12|10:5] rs2 rs1 100 imm[4:1|11] 1100011 BLT + * imm[12|10:5] rs2 rs1 101 imm[4:1|11] 1100011 BGE + * imm[12|10:5] rs2 rs1 110 imm[4:1|11] 1100011 BLTU + * imm[12|10:5] rs2 rs1 111 imm[4:1|11] 1100011 BGEU + */ + + s32 offset; + s32 offset_tmp; + unsigned long rs1_val; + unsigned long rs2_val; + + if (!rv_insn_reg_get_val(regs, branch_rs1_idx(opcode), &rs1_val) || + !rv_insn_reg_get_val(regs, branch_rs2_idx(opcode), &rs2_val)) + return false; + + offset_tmp = branch_offset(opcode); + switch (branch_funct3(opcode)) { + case BRANCH_BEQ: + offset = (rs1_val == rs2_val) ? offset_tmp : 4; + break; + case BRANCH_BNE: + offset = (rs1_val != rs2_val) ? offset_tmp : 4; + break; + case BRANCH_BLT: + offset = ((long)rs1_val < (long)rs2_val) ? offset_tmp : 4; + break; + case BRANCH_BGE: + offset = ((long)rs1_val >= (long)rs2_val) ? offset_tmp : 4; + break; + case BRANCH_BLTU: + offset = (rs1_val < rs2_val) ? offset_tmp : 4; + break; + case BRANCH_BGEU: + offset = (rs1_val >= rs2_val) ? offset_tmp : 4; + break; + default: + return false; + } + + instruction_pointer_set(regs, addr + offset); + + return true; +} -- cgit v1.2.3-70-g09d2 From faff43da31ae469ff28d71af4aa47f0c08b0b26c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 19 Jul 2021 21:16:17 -0700 Subject: mips: cavium-octeon: clean up kernel-doc in cvmx-interrupt-decodes.c Fix kernel-doc warnings reported by kernel test robot: arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c:49: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c:230: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c:271: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c:301: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c:340: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Aditya Srivastava Cc: David Daney Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- .../cavium-octeon/executive/cvmx-interrupt-decodes.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c index 2f415d9d0f3c..67d6da21d49f 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c +++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c @@ -46,7 +46,9 @@ /** - * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t + * __cvmx_interrupt_gmxx_rxx_int_en_enable - enable all interrupt bits in cvmx_gmxx_rxx_int_en_t + * @index: interrupt register offset + * @block: interrupt register block_id */ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) { @@ -227,7 +229,9 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64); } /** - * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t + * __cvmx_interrupt_pcsx_intx_en_reg_enable - enable all interrupt bits in cvmx_pcsx_intx_en_reg_t + * @index: interrupt register offset + * @block: interrupt register block_id */ void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block) { @@ -268,7 +272,8 @@ void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block) cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64); } /** - * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t + * __cvmx_interrupt_pcsxx_int_en_reg_enable - enable all interrupt bits in cvmx_pcsxx_int_en_reg_t + * @index: interrupt register block_id */ void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index) { @@ -298,7 +303,8 @@ void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index) } /** - * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t + * __cvmx_interrupt_spxx_int_msk_enable - enable all interrupt bits in cvmx_spxx_int_msk_t + * @index: interrupt register block_id */ void __cvmx_interrupt_spxx_int_msk_enable(int index) { @@ -337,7 +343,8 @@ void __cvmx_interrupt_spxx_int_msk_enable(int index) cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64); } /** - * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t + * __cvmx_interrupt_stxx_int_msk_enable - enable all interrupt bits in cvmx_stxx_int_msk_t + * @index: interrupt register block_id */ void __cvmx_interrupt_stxx_int_msk_enable(int index) { -- cgit v1.2.3-70-g09d2 From 73b9919f3c17851b4c1d90fb6c343d9c438c554c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 19 Jul 2021 21:34:32 -0700 Subject: mips: netlogic: fix kernel-doc complaints in fmn-config.c Clean up kernel-doc warnings in netlogic/xlr/fmn-config.c by using correct kernel-doc format. Fixes these warnings: arch/mips/netlogic/xlr/fmn-config.c:106: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Configure bucket size and credits for a device. 'size' is the size of arch/mips/netlogic/xlr/fmn-config.c:181: warning: expecting prototype for Setup the FMN details for each devices according to the device available(). Prototype was for xlr_board_info_setup() instead Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Ganesan Ramalingam Cc: John Crispin Cc: Aditya Srivastava Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- arch/mips/netlogic/xlr/fmn-config.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/mips/netlogic/xlr/fmn-config.c b/arch/mips/netlogic/xlr/fmn-config.c index c7622c6e5f67..15483537e8cf 100644 --- a/arch/mips/netlogic/xlr/fmn-config.c +++ b/arch/mips/netlogic/xlr/fmn-config.c @@ -103,18 +103,19 @@ static void check_credit_distribution(void) } /** - * Configure bucket size and credits for a device. 'size' is the size of - * the buckets for the device. This size is distributed among all the CPUs - * so that all of them can send messages to the device. - * - * The device is also given 'cpu_credits' to send messages to the CPUs - * + * setup_fmn_cc - Configure bucket size and credits for a device. * @dev_info: FMN information structure for each devices * @start_stn_id: Starting station id of dev_info * @end_stn_id: End station id of dev_info * @num_buckets: Total number of buckets for den_info * @cpu_credits: Allowed credits to cpu for each devices pointing by dev_info * @size: Size of the each buckets in the device station + * + * 'size' is the size of the buckets for the device. This size is + * distributed among all the CPUs + * so that all of them can send messages to the device. + * + * The device is also given 'cpu_credits' to send messages to the CPUs */ static void setup_fmn_cc(struct xlr_fmn_info *dev_info, int start_stn_id, int end_stn_id, int num_buckets, int cpu_credits, int size) @@ -174,6 +175,8 @@ static void setup_cpu_fmninfo(struct xlr_fmn_info *cpu, int num_core) } /** + * xlr_board_info_setup - Setup FMN details + * * Setup the FMN details for each devices according to the device available * in each variant of XLR/XLS processor */ -- cgit v1.2.3-70-g09d2 From d17eef2767d84b7dc4e1b8029be1eacb1d8679f6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 1 Apr 2021 00:06:56 +0900 Subject: mips: replace deprecated EXTRA_CFLAGS with ccflags-y As Documentation/kbuild/makefiles.rst says, EXTRA_CFLAGS is deprecated. Replace it with ccflags-y. Signed-off-by: Masahiro Yamada Signed-off-by: Thomas Bogendoerfer --- arch/mips/kvm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile index c67250a956b8..18c69eff1d3f 100644 --- a/arch/mips/kvm/Makefile +++ b/arch/mips/kvm/Makefile @@ -4,7 +4,7 @@ common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o eventfd.o binary_stats.o) -EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm +ccflags-y += -Ivirt/kvm -Iarch/mips/kvm common-objs-$(CONFIG_CPU_HAS_MSA) += msa.o -- cgit v1.2.3-70-g09d2 From d656132d2a2abc06917d822f7adcda86fd6dd192 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 1 Apr 2021 00:06:57 +0900 Subject: mips: clean up kvm Makefile You can use kvm-y instead of kvm-objs to create the composite module. kvm-$(CONFIG_...) looks cleaner. Signed-off-by: Masahiro Yamada Signed-off-by: Thomas Bogendoerfer --- arch/mips/kvm/Makefile | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile index 18c69eff1d3f..d3710959da55 100644 --- a/arch/mips/kvm/Makefile +++ b/arch/mips/kvm/Makefile @@ -2,21 +2,18 @@ # Makefile for KVM support for MIPS # -common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o eventfd.o binary_stats.o) - ccflags-y += -Ivirt/kvm -Iarch/mips/kvm -common-objs-$(CONFIG_CPU_HAS_MSA) += msa.o +kvm-y := $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o eventfd.o binary_stats.o) +kvm-$(CONFIG_CPU_HAS_MSA) += msa.o -kvm-objs := $(common-objs-y) mips.o emulate.o entry.o \ +kvm-y += mips.o emulate.o entry.o \ interrupt.o stats.o \ fpu.o -kvm-objs += hypcall.o -kvm-objs += mmu.o -ifdef CONFIG_CPU_LOONGSON64 -kvm-objs += loongson_ipi.o -endif +kvm-y += hypcall.o +kvm-y += mmu.o +kvm-$(CONFIG_CPU_LOONGSON64) += loongson_ipi.o -kvm-objs += vz.o +kvm-y += vz.o obj-$(CONFIG_KVM) += kvm.o obj-y += callback.o tlb.o -- cgit v1.2.3-70-g09d2 From d475653672b730a30bd1391f68c98f450afaf725 Mon Sep 17 00:00:00 2001 From: "Nícolas F. R. A. Prado" Date: Thu, 10 Jun 2021 14:56:13 -0300 Subject: dt-bindings: clk: Convert rockchip,rk3399-cru to DT schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the rockchip,rk3399-cru binding to DT schema format. Tested with ARCH=arm64 make dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml ARCH=arm64 make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210610175613.167601-1-nfraprado@collabora.com Signed-off-by: Heiko Stuebner --- .../bindings/clock/rockchip,rk3399-cru.txt | 68 ---------------- .../bindings/clock/rockchip,rk3399-cru.yaml | 92 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 68 deletions(-) delete mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt deleted file mode 100644 index 3bc56fae90ac..000000000000 --- a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt +++ /dev/null @@ -1,68 +0,0 @@ -* Rockchip RK3399 Clock and Reset Unit - -The RK3399 clock controller generates and supplies clock to various -controllers within the SoC and also implements a reset controller for SoC -peripherals. - -Required Properties: - -- compatible: PMU for CRU should be "rockchip,rk3399-pmucru" -- compatible: CRU should be "rockchip,rk3399-cru" -- reg: physical base address of the controller and length of memory mapped - region. -- #clock-cells: should be 1. -- #reset-cells: should be 1. - -Optional Properties: - -- rockchip,grf: phandle to the syscon managing the "general register files". - It is used for GRF muxes, if missing any muxes present in the GRF will not - be available. - -Each clock is assigned an identifier and client nodes can use this identifier -to specify the clock which they consume. All available clocks are defined as -preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be -used in device tree sources. Similar macros exist for the reset sources in -these files. - -External clocks: - -There are several clocks that are generated outside the SoC. It is expected -that they are defined using standard clock bindings with following -clock-output-names: - - "xin24m" - crystal input - required, - - "xin32k" - rtc clock - optional, - - "clkin_gmac" - external GMAC clock - optional, - - "clkin_i2s" - external I2S clock - optional, - - "pclkin_cif" - external ISP clock - optional, - - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 - - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 - -Example: Clock controller node: - - pmucru: pmu-clock-controller@ff750000 { - compatible = "rockchip,rk3399-pmucru"; - reg = <0x0 0xff750000 0x0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - cru: clock-controller@ff760000 { - compatible = "rockchip,rk3399-cru"; - reg = <0x0 0xff760000 0x0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - -Example: UART controller node that consumes the clock generated by the clock - controller: - - uart0: serial@ff1a0000 { - compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; - reg = <0x0 0xff180000 0x0 0x100>; - clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; - clock-names = "baudclk", "apb_pclk"; - interrupts = ; - reg-shift = <2>; - reg-io-width = <4>; - }; diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml new file mode 100644 index 000000000000..72b286a1beba --- /dev/null +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3399 Clock and Reset Unit + +maintainers: + - Xing Zheng + - Heiko Stuebner + +description: | + The RK3399 clock controller generates and supplies clock to various + controllers within the SoC and also implements a reset controller for SoC + peripherals. + Each clock is assigned an identifier and client nodes can use this identifier + to specify the clock which they consume. All available clocks are defined as + preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be + used in device tree sources. Similar macros exist for the reset sources in + these files. + There are several clocks that are generated outside the SoC. It is expected + that they are defined using standard clock bindings with following + clock-output-names: + - "xin24m" - crystal input - required, + - "xin32k" - rtc clock - optional, + - "clkin_gmac" - external GMAC clock - optional, + - "clkin_i2s" - external I2S clock - optional, + - "pclkin_cif" - external ISP clock - optional, + - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 + - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 + +properties: + compatible: + enum: + - rockchip,rk3399-pmucru + - rockchip,rk3399-cru + + reg: + maxItems: 1 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + + clocks: + minItems: 1 + + assigned-clocks: + minItems: 1 + maxItems: 64 + + assigned-clock-parents: + minItems: 1 + maxItems: 64 + + assigned-clock-rates: + minItems: 1 + maxItems: 64 + + rockchip,grf: + $ref: /schemas/types.yaml#/definitions/phandle + description: > + phandle to the syscon managing the "general register files". It is used + for GRF muxes, if missing any muxes present in the GRF will not be + available. + +required: + - compatible + - reg + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + pmucru: pmu-clock-controller@ff750000 { + compatible = "rockchip,rk3399-pmucru"; + reg = <0xff750000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + - | + cru: clock-controller@ff760000 { + compatible = "rockchip,rk3399-cru"; + reg = <0xff760000 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; -- cgit v1.2.3-70-g09d2 From a32ad90426a9c8eb3915eed26e08ce133bd9e0da Mon Sep 17 00:00:00 2001 From: Austin Kim Date: Tue, 29 Jun 2021 14:50:50 +0100 Subject: IMA: remove -Wmissing-prototypes warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With W=1 build, the compiler throws warning message as below: security/integrity/ima/ima_mok.c:24:12: warning: no previous prototype for ‘ima_mok_init’ [-Wmissing-prototypes] __init int ima_mok_init(void) Silence the warning by adding static keyword to ima_mok_init(). Signed-off-by: Austin Kim Fixes: 41c89b64d718 ("IMA: create machine owner and blacklist keyrings") Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar --- security/integrity/ima/ima_mok.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 1e5c01916173..95cc31525c57 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -21,7 +21,7 @@ struct key *ima_blacklist_keyring; /* * Allocate the IMA blacklist keyring */ -__init int ima_mok_init(void) +static __init int ima_mok_init(void) { struct key_restriction *restriction; -- cgit v1.2.3-70-g09d2 From 5d1ef2ce13a9098b4e0d31c50e4c79763a57b444 Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Fri, 23 Jul 2021 10:53:02 +0200 Subject: ima: Introduce ima_get_current_hash_algo() Buffer measurements, unlike file measurements, are not accessible after the measurement is done, as buffers are not suitable for use with the integrity_iint_cache structure (there is no index, for files it is the inode number). In the subsequent patches, the measurement (digest) will be returned directly by the functions that perform the buffer measurement, ima_measure_critical_data() and process_buffer_measurement(). A caller of those functions also needs to know the algorithm used to calculate the digest. Instead of adding the algorithm as a new parameter to the functions, this patch provides it separately with the new function ima_get_current_hash_algo(). Since the hash algorithm does not change after the IMA setup phase, there is no risk of races (obtaining a digest calculated with a different algorithm than the one returned). Signed-off-by: Roberto Sassu Reviewed-by: Lakshmi Ramasubramanian [zohar@linux.ibm.com: annotate ima_hash_algo as __ro_after_init] Signed-off-by: Mimi Zohar --- include/linux/ima.h | 7 +++++++ security/integrity/ima/ima_main.c | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 61d5723ec303..81e830d01ced 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -11,9 +11,11 @@ #include #include #include +#include struct linux_binprm; #ifdef CONFIG_IMA +extern enum hash_algo ima_get_current_hash_algo(void); extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_file_check(struct file *file, int mask); extern void ima_post_create_tmpfile(struct user_namespace *mnt_userns, @@ -64,6 +66,11 @@ static inline const char * const *arch_get_ima_policy(void) #endif #else +static inline enum hash_algo ima_get_current_hash_algo(void) +{ + return HASH_ALGO__LAST; +} + static inline int ima_bprm_check(struct linux_binprm *bprm) { return 0; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 287b90509006..634e4709d8af 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -35,7 +35,7 @@ int ima_appraise = IMA_APPRAISE_ENFORCE; int ima_appraise; #endif -int ima_hash_algo = HASH_ALGO_SHA1; +int __ro_after_init ima_hash_algo = HASH_ALGO_SHA1; static int hash_setup_done; static struct notifier_block ima_lsm_policy_notifier = { @@ -76,6 +76,11 @@ out: } __setup("ima_hash=", hash_setup); +enum hash_algo ima_get_current_hash_algo(void) +{ + return ima_hash_algo; +} + /* Prevent mmap'ing a file execute that is already mmap'ed write */ static int mmap_violation_check(enum ima_hooks func, struct file *file, char **pathbuf, const char **pathname, -- cgit v1.2.3-70-g09d2 From ce5bb5a86e5ebcd3c2e40e6dd1382027b5d43caf Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Fri, 23 Jul 2021 10:53:03 +0200 Subject: ima: Return int in the functions to measure a buffer ima_measure_critical_data() and process_buffer_measurement() currently don't return a result as, unlike appraisal-related functions, the result is not used by callers to deny an operation. Measurement-related functions instead rely on the audit subsystem to notify the system administrator when an error occurs. However, ima_measure_critical_data() and process_buffer_measurement() are a special case, as these are the only functions that can return a buffer measurement (for files, there is ima_file_hash()). In a subsequent patch, they will be modified to return the calculated digest. In preparation to return the result of the digest calculation, this patch modifies the return type from void to int, and returns 0 if the buffer has been successfully measured, a negative value otherwise. Given that the result of the measurement is still not necessary, this patch does not modify the behavior of existing callers by processing the returned value. For those, the return value is ignored. Signed-off-by: Roberto Sassu Reviewed-by: Lakshmi Ramasubramanian Acked-by: Paul Moore (for the SELinux bits) Signed-off-by: Mimi Zohar --- include/linux/ima.h | 15 +++++++++------ security/integrity/ima/ima.h | 10 +++++----- security/integrity/ima/ima_main.c | 40 ++++++++++++++++++++++----------------- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 81e830d01ced..60492263aa64 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -35,10 +35,10 @@ extern void ima_post_path_mknod(struct user_namespace *mnt_userns, extern int ima_file_hash(struct file *file, char *buf, size_t buf_size); extern int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size); extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size); -extern void ima_measure_critical_data(const char *event_label, - const char *event_name, - const void *buf, size_t buf_len, - bool hash); +extern int ima_measure_critical_data(const char *event_label, + const char *event_name, + const void *buf, size_t buf_len, + bool hash); #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM extern void ima_appraise_parse_cmdline(void); @@ -144,10 +144,13 @@ static inline int ima_inode_hash(struct inode *inode, char *buf, size_t buf_size static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) {} -static inline void ima_measure_critical_data(const char *event_label, +static inline int ima_measure_critical_data(const char *event_label, const char *event_name, const void *buf, size_t buf_len, - bool hash) {} + bool hash) +{ + return -ENOENT; +} #endif /* CONFIG_IMA */ diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index f0e448ed1f9f..03db221324c3 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -264,11 +264,11 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, struct evm_ima_xattr_data *xattr_value, int xattr_len, const struct modsig *modsig, int pcr, struct ima_template_desc *template_desc); -void process_buffer_measurement(struct user_namespace *mnt_userns, - struct inode *inode, const void *buf, int size, - const char *eventname, enum ima_hooks func, - int pcr, const char *func_data, - bool buf_hash); +int process_buffer_measurement(struct user_namespace *mnt_userns, + struct inode *inode, const void *buf, int size, + const char *eventname, enum ima_hooks func, + int pcr, const char *func_data, + bool buf_hash); void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename); int ima_alloc_init_template(struct ima_event_data *event_data, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 634e4709d8af..c814738caaca 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -827,7 +827,7 @@ int ima_post_load_data(char *buf, loff_t size, return 0; } -/* +/** * process_buffer_measurement - Measure the buffer or the buffer data hash * @mnt_userns: user namespace of the mount the inode was found from * @inode: inode associated with the object being measured (NULL for KEY_CHECK) @@ -840,12 +840,15 @@ int ima_post_load_data(char *buf, loff_t size, * @buf_hash: measure buffer data hash * * Based on policy, either the buffer data or buffer data hash is measured + * + * Return: 0 if the buffer has been successfully measured, a negative value + * otherwise. */ -void process_buffer_measurement(struct user_namespace *mnt_userns, - struct inode *inode, const void *buf, int size, - const char *eventname, enum ima_hooks func, - int pcr, const char *func_data, - bool buf_hash) +int process_buffer_measurement(struct user_namespace *mnt_userns, + struct inode *inode, const void *buf, int size, + const char *eventname, enum ima_hooks func, + int pcr, const char *func_data, + bool buf_hash) { int ret = 0; const char *audit_cause = "ENOMEM"; @@ -867,7 +870,7 @@ void process_buffer_measurement(struct user_namespace *mnt_userns, u32 secid; if (!ima_policy_flag) - return; + return -ENOENT; template = ima_template_desc_buf(); if (!template) { @@ -889,7 +892,7 @@ void process_buffer_measurement(struct user_namespace *mnt_userns, secid, 0, func, &pcr, &template, func_data); if (!(action & IMA_MEASURE)) - return; + return -ENOENT; } if (!pcr) @@ -937,7 +940,7 @@ out: func_measure_str(func), audit_cause, ret, 0, ret); - return; + return ret; } /** @@ -977,18 +980,21 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) * and extend the pcr. Examples of critical data could be various data * structures, policies, and states stored in kernel memory that can * impact the integrity of the system. + * + * Return: 0 if the buffer has been successfully measured, a negative value + * otherwise. */ -void ima_measure_critical_data(const char *event_label, - const char *event_name, - const void *buf, size_t buf_len, - bool hash) +int ima_measure_critical_data(const char *event_label, + const char *event_name, + const void *buf, size_t buf_len, + bool hash) { if (!event_name || !event_label || !buf || !buf_len) - return; + return -ENOPARAM; - process_buffer_measurement(&init_user_ns, NULL, buf, buf_len, event_name, - CRITICAL_DATA, 0, event_label, - hash); + return process_buffer_measurement(&init_user_ns, NULL, buf, buf_len, + event_name, CRITICAL_DATA, 0, + event_label, hash); } static int __init init_ima(void) -- cgit v1.2.3-70-g09d2 From ca3c9bdb101d9b9eb3ed8a85cc0fe55915ba49de Mon Sep 17 00:00:00 2001 From: Roberto Sassu Date: Fri, 23 Jul 2021 10:53:04 +0200 Subject: ima: Add digest and digest_len params to the functions to measure a buffer This patch performs the final modification necessary to pass the buffer measurement to callers, so that they provide a functionality similar to ima_file_hash(). It adds the 'digest' and 'digest_len' parameters to ima_measure_critical_data() and process_buffer_measurement(). These functions calculate the digest even if there is no suitable rule in the IMA policy and, in this case, they simply return 1 before generating a new measurement entry. Signed-off-by: Roberto Sassu Reviewed-by: Lakshmi Ramasubramanian Signed-off-by: Mimi Zohar --- include/linux/ima.h | 5 ++-- security/integrity/ima/ima.h | 2 +- security/integrity/ima/ima_appraise.c | 2 +- security/integrity/ima/ima_asymmetric_keys.c | 2 +- security/integrity/ima/ima_init.c | 3 ++- security/integrity/ima/ima_main.c | 36 ++++++++++++++++++++-------- security/integrity/ima/ima_queue_keys.c | 2 +- security/selinux/ima.c | 6 +++-- 8 files changed, 39 insertions(+), 19 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index 60492263aa64..b6ab66a546ae 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -38,7 +38,7 @@ extern void ima_kexec_cmdline(int kernel_fd, const void *buf, int size); extern int ima_measure_critical_data(const char *event_label, const char *event_name, const void *buf, size_t buf_len, - bool hash); + bool hash, u8 *digest, size_t digest_len); #ifdef CONFIG_IMA_APPRAISE_BOOTPARAM extern void ima_appraise_parse_cmdline(void); @@ -147,7 +147,8 @@ static inline void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) { static inline int ima_measure_critical_data(const char *event_label, const char *event_name, const void *buf, size_t buf_len, - bool hash) + bool hash, u8 *digest, + size_t digest_len) { return -ENOENT; } diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 03db221324c3..2f4c20b16ad7 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -268,7 +268,7 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, struct inode *inode, const void *buf, int size, const char *eventname, enum ima_hooks func, int pcr, const char *func_data, - bool buf_hash); + bool buf_hash, u8 *digest, size_t digest_len); void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename); int ima_alloc_init_template(struct ima_event_data *event_data, diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index ef9dcfce45d4..63bec42c353f 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -357,7 +357,7 @@ int ima_check_blacklist(struct integrity_iint_cache *iint, if ((rc == -EPERM) && (iint->flags & IMA_MEASURE)) process_buffer_measurement(&init_user_ns, NULL, digest, digestsize, "blacklisted-hash", NONE, - pcr, NULL, false); + pcr, NULL, false, NULL, 0); } return rc; diff --git a/security/integrity/ima/ima_asymmetric_keys.c b/security/integrity/ima/ima_asymmetric_keys.c index c985418698a4..f6aa0b47a772 100644 --- a/security/integrity/ima/ima_asymmetric_keys.c +++ b/security/integrity/ima/ima_asymmetric_keys.c @@ -62,5 +62,5 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key, */ process_buffer_measurement(&init_user_ns, NULL, payload, payload_len, keyring->description, KEY_CHECK, 0, - keyring->description, false); + keyring->description, false, NULL, 0); } diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 5076a7d9d23e..b26fa67476b4 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -154,7 +154,8 @@ int __init ima_init(void) ima_init_key_queue(); ima_measure_critical_data("kernel_info", "kernel_version", - UTS_RELEASE, strlen(UTS_RELEASE), false); + UTS_RELEASE, strlen(UTS_RELEASE), false, + NULL, 0); return rc; } diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index c814738caaca..1cba6beb5a60 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -838,17 +838,20 @@ int ima_post_load_data(char *buf, loff_t size, * @pcr: pcr to extend the measurement * @func_data: func specific data, may be NULL * @buf_hash: measure buffer data hash + * @digest: buffer digest will be written to + * @digest_len: buffer length * * Based on policy, either the buffer data or buffer data hash is measured * - * Return: 0 if the buffer has been successfully measured, a negative value - * otherwise. + * Return: 0 if the buffer has been successfully measured, 1 if the digest + * has been written to the passed location but not added to a measurement entry, + * a negative value otherwise. */ int process_buffer_measurement(struct user_namespace *mnt_userns, struct inode *inode, const void *buf, int size, const char *eventname, enum ima_hooks func, int pcr, const char *func_data, - bool buf_hash) + bool buf_hash, u8 *digest, size_t digest_len) { int ret = 0; const char *audit_cause = "ENOMEM"; @@ -869,7 +872,10 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, int action = 0; u32 secid; - if (!ima_policy_flag) + if (digest && digest_len < digest_hash_len) + return -EINVAL; + + if (!ima_policy_flag && !digest) return -ENOENT; template = ima_template_desc_buf(); @@ -891,7 +897,7 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, action = ima_get_action(mnt_userns, inode, current_cred(), secid, 0, func, &pcr, &template, func_data); - if (!(action & IMA_MEASURE)) + if (!(action & IMA_MEASURE) && !digest) return -ENOENT; } @@ -922,6 +928,12 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, event_data.buf_len = digest_hash_len; } + if (digest) + memcpy(digest, iint.ima_hash->digest, digest_hash_len); + + if (!ima_policy_flag || (func && !(action & IMA_MEASURE))) + return 1; + ret = ima_alloc_init_template(&event_data, &entry, template); if (ret < 0) { audit_cause = "alloc_entry"; @@ -964,7 +976,7 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) process_buffer_measurement(file_mnt_user_ns(f.file), file_inode(f.file), buf, size, "kexec-cmdline", KEXEC_CMDLINE, 0, - NULL, false); + NULL, false, NULL, 0); fdput(f); } @@ -975,26 +987,30 @@ void ima_kexec_cmdline(int kernel_fd, const void *buf, int size) * @buf: pointer to buffer data * @buf_len: length of buffer data (in bytes) * @hash: measure buffer data hash + * @digest: buffer digest will be written to + * @digest_len: buffer length * * Measure data critical to the integrity of the kernel into the IMA log * and extend the pcr. Examples of critical data could be various data * structures, policies, and states stored in kernel memory that can * impact the integrity of the system. * - * Return: 0 if the buffer has been successfully measured, a negative value - * otherwise. + * Return: 0 if the buffer has been successfully measured, 1 if the digest + * has been written to the passed location but not added to a measurement entry, + * a negative value otherwise. */ int ima_measure_critical_data(const char *event_label, const char *event_name, const void *buf, size_t buf_len, - bool hash) + bool hash, u8 *digest, size_t digest_len) { if (!event_name || !event_label || !buf || !buf_len) return -ENOPARAM; return process_buffer_measurement(&init_user_ns, NULL, buf, buf_len, event_name, CRITICAL_DATA, 0, - event_label, hash); + event_label, hash, digest, + digest_len); } static int __init init_ima(void) diff --git a/security/integrity/ima/ima_queue_keys.c b/security/integrity/ima/ima_queue_keys.c index 979ef6c71f3d..93056c03bf5a 100644 --- a/security/integrity/ima/ima_queue_keys.c +++ b/security/integrity/ima/ima_queue_keys.c @@ -165,7 +165,7 @@ void ima_process_queued_keys(void) entry->keyring_name, KEY_CHECK, 0, entry->keyring_name, - false); + false, NULL, 0); list_del(&entry->list); ima_free_key_entry(entry); } diff --git a/security/selinux/ima.c b/security/selinux/ima.c index 34d421861bfc..727c4e43219d 100644 --- a/security/selinux/ima.c +++ b/security/selinux/ima.c @@ -86,7 +86,8 @@ void selinux_ima_measure_state_locked(struct selinux_state *state) } ima_measure_critical_data("selinux", "selinux-state", - state_str, strlen(state_str), false); + state_str, strlen(state_str), false, + NULL, 0); kfree(state_str); @@ -103,7 +104,8 @@ void selinux_ima_measure_state_locked(struct selinux_state *state) } ima_measure_critical_data("selinux", "selinux-policy-hash", - policy, policy_len, true); + policy, policy_len, true, + NULL, 0); vfree(policy); } -- cgit v1.2.3-70-g09d2 From 9f1168cf263aab0474300f7118107f8ef73e7423 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 29 Jun 2021 15:20:45 +0200 Subject: PCI: controller: PCI_IXP4XX should depend on ARCH_IXP4XX The Intel IXP4xx PCI controller is only present on Intel IXP4xx XScale-based network processor SoCs. Add a dependency on ARCH_IXP4XX, to prevent asking the user about this driver when configuring a kernel without support for the XScale processor family. Link: https://lore.kernel.org/r/6a88e55fe58fc280f4ff1ca83c154e4895b6dcbf.1624972789.git.geert+renesas@glider.be Fixes: f7821b4934584824 ("PCI: ixp4xx: Add a new driver for IXP4xx") Signed-off-by: Geert Uytterhoeven [lorenzo.pieralisi@arm.com: commit log] Signed-off-by: Lorenzo Pieralisi Reviewed-by: Linus Walleij --- drivers/pci/controller/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 5e1e3796efa4..326f7d13024f 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -40,6 +40,7 @@ config PCI_FTPCI100 config PCI_IXP4XX bool "Intel IXP4xx PCI controller" depends on ARM && OF + depends on ARCH_IXP4XX || COMPILE_TEST default ARCH_IXP4XX help Say Y here if you want support for the PCI host controller found -- cgit v1.2.3-70-g09d2 From 6310a1526aa0b00b6d8a8205a753b5fcf2212eb2 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Sun, 4 Jul 2021 23:57:33 +0000 Subject: PCI: tegra: Remove unused struct tegra_pcie_bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following the code refactoring completed in the commit 1fd92928bab5 ("PCI: tegra: Refactor configuration space mapping code") there are no more known users of struct tegra_pcie_bus. Thus, remove declaration of struct tegra_pcie_bus as it's no longer needed and does not have any existing users left. Link: https://lore.kernel.org/r/20210704235733.2514131-1-kw@linux.com Signed-off-by: Krzysztof Wilczyński Signed-off-by: Lorenzo Pieralisi --- drivers/pci/controller/pci-tegra.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index c979229a6d0d..4aa103aaa366 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -372,11 +372,6 @@ struct tegra_pcie_port { struct gpio_desc *reset_gpio; }; -struct tegra_pcie_bus { - struct list_head list; - unsigned int nr; -}; - static inline void afi_writel(struct tegra_pcie *pcie, u32 value, unsigned long offset) { -- cgit v1.2.3-70-g09d2 From 832e6e3e9d498dea53f03e1e472779dcf4121689 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 24 Jun 2021 21:17:40 +0200 Subject: dt-bindings: pinctrl: qcom: Add bindings for MDM9607 Document the newly added MDM9607 pinctrl driver. Signed-off-by: Konrad Dybcio Reviewed-by: Rob Herring Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210624191743.617073-1-konrad.dybcio@somainline.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,mdm9607-pinctrl.yaml | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,mdm9607-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,mdm9607-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9607-pinctrl.yaml new file mode 100644 index 000000000000..3b02dc6626ed --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,mdm9607-pinctrl.yaml @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,mdm9607-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. MDM9607 TLMM block + +maintainers: + - Konrad Dybcio + +description: | + This binding describes the Top Level Mode Multiplexer block found in the + MDM9607 platform. + +allOf: + - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# + +properties: + compatible: + const: qcom,mdm9607-tlmm + + reg: + maxItems: 1 + + interrupts: true + interrupt-controller: true + '#interrupt-cells': true + gpio-controller: true + gpio-reserved-ranges: true + '#gpio-cells': true + gpio-ranges: true + wakeup-parent: true + +required: + - compatible + - reg + +additionalProperties: false + +patternProperties: + '-state$': + oneOf: + - $ref: "#/$defs/qcom-mdm9607-tlmm-state" + - patternProperties: + ".*": + $ref: "#/$defs/qcom-mdm9607-tlmm-state" + +'$defs': + qcom-mdm9607-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([1-9]|[1-7][0-9]|80)$" + - enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd, + sdc2_data, qdsd_cmd, qdsd_data0, qdsd_data1, qdsd_data2, + qdsd_data3 ] + minItems: 1 + maxItems: 16 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + + enum: [ adsp_ext, atest_bbrx0, atest_bbrx1, atest_char, atest_char0, + atest_char1, atest_char2, atest_char3, + atest_combodac_to_gpio_native, atest_gpsadc_dtest0_native, + atest_gpsadc_dtest1_native, atest_tsens, backlight_en_b, + bimc_dte0, bimc_dte1, blsp1_spi, blsp2_spi, blsp3_spi, + blsp_i2c1, blsp_i2c2, blsp_i2c3, blsp_i2c4, blsp_i2c5, + blsp_i2c6, blsp_spi1, blsp_spi2, blsp_spi3, blsp_spi4, + blsp_spi5, blsp_spi6, blsp_uart1, blsp_uart2, blsp_uart3, + blsp_uart4, blsp_uart5, blsp_uart6, blsp_uim1, blsp_uim2, + codec_int, codec_rst, coex_uart, cri_trng, cri_trng0, + cri_trng1, dbg_out, ebi0_wrcdc, ebi2_a, ebi2_a_d_8_b, + ebi2_lcd, ebi2_lcd_cs_n_b, ebi2_lcd_te_b, eth_irq, eth_rst, + gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a, gcc_gp2_clk_b, + gcc_gp3_clk_a, gcc_gp3_clk_b, gcc_plltest, gcc_tlmm, gmac_mdio, + gpio, gsm0_tx, lcd_rst, ldo_en, ldo_update, m_voc, modem_tsync, + nav_ptp_pps_in_a, nav_ptp_pps_in_b, nav_tsync_out_a, + nav_tsync_out_b, pa_indicator, pbs0, pbs1, pbs2, + pri_mi2s_data0_a, pri_mi2s_data1_a, pri_mi2s_mclk_a, + pri_mi2s_sck_a, pri_mi2s_ws_a, prng_rosc, ptp_pps_out_a, + ptp_pps_out_b, pwr_crypto_enabled_a, pwr_crypto_enabled_b, + pwr_modem_enabled_a, pwr_modem_enabled_b, pwr_nav_enabled_a, + pwr_nav_enabled_b, qdss_cti_trig_in_a0, qdss_cti_trig_in_a1, + qdss_cti_trig_in_b0, qdss_cti_trig_in_b1, qdss_cti_trig_out_a0, + qdss_cti_trig_out_a1, qdss_cti_trig_out_b0, qdss_cti_trig_out_b1, + qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a, + qdss_tracectl_b, qdss_tracedata_a, qdss_tracedata_b, rcm_marker1, + rcm_marker2, sd_write, sec_mi2s, sensor_en, sensor_int2, + sensor_int3, sensor_rst, ssbi1, ssbi2, touch_rst, ts_int, + uim1_clk, uim1_data, uim1_present, uim1_reset, uim2_clk, + uim2_data, uim2_present, uim2_reset, uim_batt, wlan_en1, ] + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + drive-strength: true + input-enable: true + output-high: true + output-low: true + + required: + - pins + - function + + additionalProperties: false + +examples: + - | + #include + tlmm: pinctrl@1000000 { + compatible = "qcom,mdm9607-tlmm"; + reg = <0x01000000 0x300000>; + interrupts = ; + gpio-controller; + gpio-ranges = <&msmgpio 0 0 80>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; -- cgit v1.2.3-70-g09d2 From 41353ae7a17ba63118ef364896309df3e3824390 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Thu, 24 Jun 2021 21:17:41 +0200 Subject: pinctrl: qcom: Add MDM9607 pinctrl driver Add a pinctrl driver to allow for managing SoC pins. Signed-off-by: Konrad Dybcio Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210624191743.617073-2-konrad.dybcio@somainline.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 8 + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-mdm9607.c | 1087 ++++++++++++++++++++++++++++++++ 3 files changed, 1096 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-mdm9607.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 2f51b4f99393..6a151f3c1e3b 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -88,6 +88,14 @@ config PINCTRL_MSM8960 This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm TLMM block found in the Qualcomm 8960 platform. +config PINCTRL_MDM9607 + tristate "Qualcomm 9607 pin controller driver" + depends on GPIOLIB && OF + depends on PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 9607 platform. + config PINCTRL_MDM9615 tristate "Qualcomm 9615 pin controller driver" depends on GPIOLIB && OF diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index d696fe2789bb..3337860b4860 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o obj-$(CONFIG_PINCTRL_MSM8998) += pinctrl-msm8998.o obj-$(CONFIG_PINCTRL_QCS404) += pinctrl-qcs404.o obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o +obj-$(CONFIG_PINCTRL_MDM9607) += pinctrl-mdm9607.o obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o diff --git a/drivers/pinctrl/qcom/pinctrl-mdm9607.c b/drivers/pinctrl/qcom/pinctrl-mdm9607.c new file mode 100644 index 000000000000..d622b3df0fe7 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-mdm9607.c @@ -0,0 +1,1087 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, Konrad Dybcio + * + * based on pinctrl-msm8916.c + */ + +#include +#include +#include +#include + +#include "pinctrl-msm.h" + +static const struct pinctrl_pin_desc mdm9607_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "SDC1_CLK"), + PINCTRL_PIN(81, "SDC1_CMD"), + PINCTRL_PIN(82, "SDC1_DATA"), + PINCTRL_PIN(83, "SDC2_CLK"), + PINCTRL_PIN(84, "SDC2_CMD"), + PINCTRL_PIN(85, "SDC2_DATA"), + PINCTRL_PIN(86, "QDSD_CLK"), + PINCTRL_PIN(87, "QDSD_CMD"), + PINCTRL_PIN(88, "QDSD_DATA0"), + PINCTRL_PIN(89, "QDSD_DATA1"), + PINCTRL_PIN(90, "QDSD_DATA2"), + PINCTRL_PIN(91, "QDSD_DATA3"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } + +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); + +static const unsigned int sdc1_clk_pins[] = { 80 }; +static const unsigned int sdc1_cmd_pins[] = { 81 }; +static const unsigned int sdc1_data_pins[] = { 82 }; +static const unsigned int sdc2_clk_pins[] = { 83 }; +static const unsigned int sdc2_cmd_pins[] = { 84 }; +static const unsigned int sdc2_data_pins[] = { 85 }; +static const unsigned int qdsd_clk_pins[] = { 86 }; +static const unsigned int qdsd_cmd_pins[] = { 87 }; +static const unsigned int qdsd_data0_pins[] = { 88 }; +static const unsigned int qdsd_data1_pins[] = { 89 }; +static const unsigned int qdsd_data2_pins[] = { 90 }; +static const unsigned int qdsd_data3_pins[] = { 91 }; + +#define FUNCTION(fname) \ + [msm_mux_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + msm_mux_gpio, \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9 \ + }, \ + .nfuncs = 10, \ + .ctl_reg = 0x1000 * id, \ + .io_reg = 0x4 + 0x1000 * id, \ + .intr_cfg_reg = 0x8 + 0x1000 * id, \ + .intr_status_reg = 0xc + 0x1000 * id, \ + .intr_target_reg = 0x8 + 0x1000 * id, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_target_bit = 5, \ + .intr_target_kpss_val = 4, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define SDC_PINGROUP(pg_name, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_target_kpss_val = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +enum mdm9607_functions { + msm_mux_adsp_ext, + msm_mux_atest_bbrx0, + msm_mux_atest_bbrx1, + msm_mux_atest_char, + msm_mux_atest_char0, + msm_mux_atest_char1, + msm_mux_atest_char2, + msm_mux_atest_char3, + msm_mux_atest_combodac_to_gpio_native, + msm_mux_atest_gpsadc_dtest0_native, + msm_mux_atest_gpsadc_dtest1_native, + msm_mux_atest_tsens, + msm_mux_backlight_en_b, + msm_mux_bimc_dte0, + msm_mux_bimc_dte1, + msm_mux_blsp1_spi, + msm_mux_blsp2_spi, + msm_mux_blsp3_spi, + msm_mux_blsp_i2c1, + msm_mux_blsp_i2c2, + msm_mux_blsp_i2c3, + msm_mux_blsp_i2c4, + msm_mux_blsp_i2c5, + msm_mux_blsp_i2c6, + msm_mux_blsp_spi1, + msm_mux_blsp_spi2, + msm_mux_blsp_spi3, + msm_mux_blsp_spi4, + msm_mux_blsp_spi5, + msm_mux_blsp_spi6, + msm_mux_blsp_uart1, + msm_mux_blsp_uart2, + msm_mux_blsp_uart3, + msm_mux_blsp_uart4, + msm_mux_blsp_uart5, + msm_mux_blsp_uart6, + msm_mux_blsp_uim1, + msm_mux_blsp_uim2, + msm_mux_codec_int, + msm_mux_codec_rst, + msm_mux_coex_uart, + msm_mux_cri_trng, + msm_mux_cri_trng0, + msm_mux_cri_trng1, + msm_mux_dbg_out, + msm_mux_ebi0_wrcdc, + msm_mux_ebi2_a, + msm_mux_ebi2_a_d_8_b, + msm_mux_ebi2_lcd, + msm_mux_ebi2_lcd_cs_n_b, + msm_mux_ebi2_lcd_te_b, + msm_mux_eth_irq, + msm_mux_eth_rst, + msm_mux_gcc_gp1_clk_a, + msm_mux_gcc_gp1_clk_b, + msm_mux_gcc_gp2_clk_a, + msm_mux_gcc_gp2_clk_b, + msm_mux_gcc_gp3_clk_a, + msm_mux_gcc_gp3_clk_b, + msm_mux_gcc_plltest, + msm_mux_gcc_tlmm, + msm_mux_gmac_mdio, + msm_mux_gpio, + msm_mux_gsm0_tx, + msm_mux_lcd_rst, + msm_mux_ldo_en, + msm_mux_ldo_update, + msm_mux_m_voc, + msm_mux_modem_tsync, + msm_mux_nav_ptp_pps_in_a, + msm_mux_nav_ptp_pps_in_b, + msm_mux_nav_tsync_out_a, + msm_mux_nav_tsync_out_b, + msm_mux_pa_indicator, + msm_mux_pbs0, + msm_mux_pbs1, + msm_mux_pbs2, + msm_mux_pri_mi2s_data0_a, + msm_mux_pri_mi2s_data1_a, + msm_mux_pri_mi2s_mclk_a, + msm_mux_pri_mi2s_sck_a, + msm_mux_pri_mi2s_ws_a, + msm_mux_prng_rosc, + msm_mux_ptp_pps_out_a, + msm_mux_ptp_pps_out_b, + msm_mux_pwr_crypto_enabled_a, + msm_mux_pwr_crypto_enabled_b, + msm_mux_pwr_modem_enabled_a, + msm_mux_pwr_modem_enabled_b, + msm_mux_pwr_nav_enabled_a, + msm_mux_pwr_nav_enabled_b, + msm_mux_qdss_cti_trig_in_a0, + msm_mux_qdss_cti_trig_in_a1, + msm_mux_qdss_cti_trig_in_b0, + msm_mux_qdss_cti_trig_in_b1, + msm_mux_qdss_cti_trig_out_a0, + msm_mux_qdss_cti_trig_out_a1, + msm_mux_qdss_cti_trig_out_b0, + msm_mux_qdss_cti_trig_out_b1, + msm_mux_qdss_traceclk_a, + msm_mux_qdss_traceclk_b, + msm_mux_qdss_tracectl_a, + msm_mux_qdss_tracectl_b, + msm_mux_qdss_tracedata_a, + msm_mux_qdss_tracedata_b, + msm_mux_rcm_marker1, + msm_mux_rcm_marker2, + msm_mux_sd_write, + msm_mux_sec_mi2s, + msm_mux_sensor_en, + msm_mux_sensor_int2, + msm_mux_sensor_int3, + msm_mux_sensor_rst, + msm_mux_ssbi1, + msm_mux_ssbi2, + msm_mux_touch_rst, + msm_mux_ts_int, + msm_mux_uim1_clk, + msm_mux_uim1_data, + msm_mux_uim1_present, + msm_mux_uim1_reset, + msm_mux_uim2_clk, + msm_mux_uim2_data, + msm_mux_uim2_present, + msm_mux_uim2_reset, + msm_mux_uim_batt, + msm_mux_wlan_en1, + msm_mux__, +}; + +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", +}; +static const char * const blsp_spi3_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; +static const char * const blsp_uart3_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; +static const char * const qdss_tracedata_a_groups[] = { + "gpio0", "gpio1", "gpio4", "gpio5", "gpio20", "gpio21", "gpio22", + "gpio23", "gpio24", "gpio25", "gpio26", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", +}; +static const char * const bimc_dte1_groups[] = { + "gpio1", "gpio24", +}; +static const char * const blsp_i2c3_groups[] = { + "gpio2", "gpio3", +}; +static const char * const qdss_traceclk_a_groups[] = { + "gpio2", +}; +static const char * const bimc_dte0_groups[] = { + "gpio2", "gpio15", +}; +static const char * const qdss_cti_trig_in_a1_groups[] = { + "gpio3", +}; +static const char * const blsp_spi2_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", +}; +static const char * const blsp_uart2_groups[] = { + "gpio4", "gpio5", "gpio6", "gpio7", +}; +static const char * const blsp_uim2_groups[] = { + "gpio4", "gpio5", +}; +static const char * const blsp_i2c2_groups[] = { + "gpio6", "gpio7", +}; +static const char * const qdss_tracectl_a_groups[] = { + "gpio6", +}; +static const char * const sensor_int2_groups[] = { + "gpio8", +}; +static const char * const blsp_spi5_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", +}; +static const char * const blsp_uart5_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", +}; +static const char * const ebi2_lcd_groups[] = { + "gpio8", "gpio11", "gpio74", "gpio78", +}; +static const char * const m_voc_groups[] = { + "gpio8", "gpio78", +}; +static const char * const sensor_int3_groups[] = { + "gpio9", +}; +static const char * const sensor_en_groups[] = { + "gpio10", +}; +static const char * const blsp_i2c5_groups[] = { + "gpio10", "gpio11", +}; +static const char * const ebi2_a_groups[] = { + "gpio10", +}; +static const char * const qdss_tracedata_b_groups[] = { + "gpio10", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43", "gpio46", + "gpio47", "gpio48", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", + "gpio58", "gpio59", +}; +static const char * const sensor_rst_groups[] = { + "gpio11", +}; +static const char * const blsp2_spi_groups[] = { + "gpio11", "gpio13", "gpio77", +}; +static const char * const blsp_spi1_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", +}; +static const char * const blsp_uart1_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", +}; +static const char * const blsp_uim1_groups[] = { + "gpio12", "gpio13", +}; +static const char * const blsp3_spi_groups[] = { + "gpio12", "gpio26", "gpio76", +}; +static const char * const gcc_gp2_clk_b_groups[] = { + "gpio12", +}; +static const char * const gcc_gp3_clk_b_groups[] = { + "gpio13", +}; +static const char * const blsp_i2c1_groups[] = { + "gpio14", "gpio15", +}; +static const char * const gcc_gp1_clk_b_groups[] = { + "gpio14", +}; +static const char * const blsp_spi4_groups[] = { + "gpio16", "gpio17", "gpio18", "gpio19", +}; +static const char * const blsp_uart4_groups[] = { + "gpio16", "gpio17", "gpio18", "gpio19", +}; +static const char * const rcm_marker1_groups[] = { + "gpio18", +}; +static const char * const blsp_i2c4_groups[] = { + "gpio18", "gpio19", +}; +static const char * const qdss_cti_trig_out_a1_groups[] = { + "gpio18", +}; +static const char * const rcm_marker2_groups[] = { + "gpio19", +}; +static const char * const qdss_cti_trig_out_a0_groups[] = { + "gpio19", +}; +static const char * const blsp_spi6_groups[] = { + "gpio20", "gpio21", "gpio22", "gpio23", +}; +static const char * const blsp_uart6_groups[] = { + "gpio20", "gpio21", "gpio22", "gpio23", +}; +static const char * const pri_mi2s_ws_a_groups[] = { + "gpio20", +}; +static const char * const ebi2_lcd_te_b_groups[] = { + "gpio20", +}; +static const char * const blsp1_spi_groups[] = { + "gpio20", "gpio21", "gpio78", +}; +static const char * const backlight_en_b_groups[] = { + "gpio21", +}; +static const char * const pri_mi2s_data0_a_groups[] = { + "gpio21", +}; +static const char * const pri_mi2s_data1_a_groups[] = { + "gpio22", +}; +static const char * const blsp_i2c6_groups[] = { + "gpio22", "gpio23", +}; +static const char * const ebi2_a_d_8_b_groups[] = { + "gpio22", +}; +static const char * const pri_mi2s_sck_a_groups[] = { + "gpio23", +}; +static const char * const ebi2_lcd_cs_n_b_groups[] = { + "gpio23", +}; +static const char * const touch_rst_groups[] = { + "gpio24", +}; +static const char * const pri_mi2s_mclk_a_groups[] = { + "gpio24", +}; +static const char * const pwr_nav_enabled_a_groups[] = { + "gpio24", +}; +static const char * const ts_int_groups[] = { + "gpio25", +}; +static const char * const sd_write_groups[] = { + "gpio25", +}; +static const char * const pwr_crypto_enabled_a_groups[] = { + "gpio25", +}; +static const char * const codec_rst_groups[] = { + "gpio26", +}; +static const char * const adsp_ext_groups[] = { + "gpio26", +}; +static const char * const atest_combodac_to_gpio_native_groups[] = { + "gpio26", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", + "gpio33", "gpio34", "gpio35", "gpio41", "gpio45", "gpio49", "gpio50", + "gpio51", "gpio52", "gpio54", "gpio55", "gpio57", "gpio59", +}; +static const char * const uim2_data_groups[] = { + "gpio27", +}; +static const char * const gmac_mdio_groups[] = { + "gpio27", "gpio28", +}; +static const char * const gcc_gp1_clk_a_groups[] = { + "gpio27", +}; +static const char * const uim2_clk_groups[] = { + "gpio28", +}; +static const char * const gcc_gp2_clk_a_groups[] = { + "gpio28", +}; +static const char * const eth_irq_groups[] = { + "gpio29", +}; +static const char * const uim2_reset_groups[] = { + "gpio29", +}; +static const char * const gcc_gp3_clk_a_groups[] = { + "gpio29", +}; +static const char * const eth_rst_groups[] = { + "gpio30", +}; +static const char * const uim2_present_groups[] = { + "gpio30", +}; +static const char * const prng_rosc_groups[] = { + "gpio30", +}; +static const char * const uim1_data_groups[] = { + "gpio31", +}; +static const char * const uim1_clk_groups[] = { + "gpio32", +}; +static const char * const uim1_reset_groups[] = { + "gpio33", +}; +static const char * const uim1_present_groups[] = { + "gpio34", +}; +static const char * const gcc_plltest_groups[] = { + "gpio34", "gpio35", +}; +static const char * const uim_batt_groups[] = { + "gpio35", +}; +static const char * const coex_uart_groups[] = { + "gpio36", "gpio37", +}; +static const char * const codec_int_groups[] = { + "gpio38", +}; +static const char * const qdss_cti_trig_in_a0_groups[] = { + "gpio38", +}; +static const char * const atest_bbrx1_groups[] = { + "gpio39", +}; +static const char * const cri_trng0_groups[] = { + "gpio40", +}; +static const char * const atest_bbrx0_groups[] = { + "gpio40", +}; +static const char * const cri_trng_groups[] = { + "gpio42", +}; +static const char * const qdss_cti_trig_in_b0_groups[] = { + "gpio44", +}; +static const char * const atest_gpsadc_dtest0_native_groups[] = { + "gpio44", +}; +static const char * const qdss_cti_trig_out_b0_groups[] = { + "gpio45", +}; +static const char * const qdss_tracectl_b_groups[] = { + "gpio49", +}; +static const char * const qdss_traceclk_b_groups[] = { + "gpio50", +}; +static const char * const pa_indicator_groups[] = { + "gpio51", +}; +static const char * const modem_tsync_groups[] = { + "gpio53", +}; +static const char * const nav_tsync_out_a_groups[] = { + "gpio53", +}; +static const char * const nav_ptp_pps_in_a_groups[] = { + "gpio53", +}; +static const char * const ptp_pps_out_a_groups[] = { + "gpio53", +}; +static const char * const gsm0_tx_groups[] = { + "gpio55", +}; +static const char * const qdss_cti_trig_in_b1_groups[] = { + "gpio56", +}; +static const char * const cri_trng1_groups[] = { + "gpio57", +}; +static const char * const qdss_cti_trig_out_b1_groups[] = { + "gpio57", +}; +static const char * const ssbi1_groups[] = { + "gpio58", +}; +static const char * const atest_gpsadc_dtest1_native_groups[] = { + "gpio58", +}; +static const char * const ssbi2_groups[] = { + "gpio59", +}; +static const char * const atest_char3_groups[] = { + "gpio60", +}; +static const char * const atest_char2_groups[] = { + "gpio61", +}; +static const char * const atest_char1_groups[] = { + "gpio62", +}; +static const char * const atest_char0_groups[] = { + "gpio63", +}; +static const char * const atest_char_groups[] = { + "gpio64", +}; +static const char * const ebi0_wrcdc_groups[] = { + "gpio70", +}; +static const char * const ldo_update_groups[] = { + "gpio72", +}; +static const char * const gcc_tlmm_groups[] = { + "gpio72", +}; +static const char * const ldo_en_groups[] = { + "gpio73", +}; +static const char * const dbg_out_groups[] = { + "gpio73", +}; +static const char * const atest_tsens_groups[] = { + "gpio73", +}; +static const char * const lcd_rst_groups[] = { + "gpio74", +}; +static const char * const wlan_en1_groups[] = { + "gpio75", +}; +static const char * const nav_tsync_out_b_groups[] = { + "gpio75", +}; +static const char * const nav_ptp_pps_in_b_groups[] = { + "gpio75", +}; +static const char * const ptp_pps_out_b_groups[] = { + "gpio75", +}; +static const char * const pbs0_groups[] = { + "gpio76", +}; +static const char * const sec_mi2s_groups[] = { + "gpio76", "gpio77", "gpio78", "gpio79", +}; +static const char * const pwr_modem_enabled_a_groups[] = { + "gpio76", +}; +static const char * const pbs1_groups[] = { + "gpio77", +}; +static const char * const pwr_modem_enabled_b_groups[] = { + "gpio77", +}; +static const char * const pbs2_groups[] = { + "gpio78", +}; +static const char * const pwr_nav_enabled_b_groups[] = { + "gpio78", +}; +static const char * const pwr_crypto_enabled_b_groups[] = { + "gpio79", +}; + +static const struct msm_function mdm9607_functions[] = { + FUNCTION(adsp_ext), + FUNCTION(atest_bbrx0), + FUNCTION(atest_bbrx1), + FUNCTION(atest_char), + FUNCTION(atest_char0), + FUNCTION(atest_char1), + FUNCTION(atest_char2), + FUNCTION(atest_char3), + FUNCTION(atest_combodac_to_gpio_native), + FUNCTION(atest_gpsadc_dtest0_native), + FUNCTION(atest_gpsadc_dtest1_native), + FUNCTION(atest_tsens), + FUNCTION(backlight_en_b), + FUNCTION(bimc_dte0), + FUNCTION(bimc_dte1), + FUNCTION(blsp1_spi), + FUNCTION(blsp2_spi), + FUNCTION(blsp3_spi), + FUNCTION(blsp_i2c1), + FUNCTION(blsp_i2c2), + FUNCTION(blsp_i2c3), + FUNCTION(blsp_i2c4), + FUNCTION(blsp_i2c5), + FUNCTION(blsp_i2c6), + FUNCTION(blsp_spi1), + FUNCTION(blsp_spi2), + FUNCTION(blsp_spi3), + FUNCTION(blsp_spi4), + FUNCTION(blsp_spi5), + FUNCTION(blsp_spi6), + FUNCTION(blsp_uart1), + FUNCTION(blsp_uart2), + FUNCTION(blsp_uart3), + FUNCTION(blsp_uart4), + FUNCTION(blsp_uart5), + FUNCTION(blsp_uart6), + FUNCTION(blsp_uim1), + FUNCTION(blsp_uim2), + FUNCTION(codec_int), + FUNCTION(codec_rst), + FUNCTION(coex_uart), + FUNCTION(cri_trng), + FUNCTION(cri_trng0), + FUNCTION(cri_trng1), + FUNCTION(dbg_out), + FUNCTION(ebi0_wrcdc), + FUNCTION(ebi2_a), + FUNCTION(ebi2_a_d_8_b), + FUNCTION(ebi2_lcd), + FUNCTION(ebi2_lcd_cs_n_b), + FUNCTION(ebi2_lcd_te_b), + FUNCTION(eth_irq), + FUNCTION(eth_rst), + FUNCTION(gcc_gp1_clk_a), + FUNCTION(gcc_gp1_clk_b), + FUNCTION(gcc_gp2_clk_a), + FUNCTION(gcc_gp2_clk_b), + FUNCTION(gcc_gp3_clk_a), + FUNCTION(gcc_gp3_clk_b), + FUNCTION(gcc_plltest), + FUNCTION(gcc_tlmm), + FUNCTION(gmac_mdio), + FUNCTION(gpio), + FUNCTION(gsm0_tx), + FUNCTION(lcd_rst), + FUNCTION(ldo_en), + FUNCTION(ldo_update), + FUNCTION(m_voc), + FUNCTION(modem_tsync), + FUNCTION(nav_ptp_pps_in_a), + FUNCTION(nav_ptp_pps_in_b), + FUNCTION(nav_tsync_out_a), + FUNCTION(nav_tsync_out_b), + FUNCTION(pa_indicator), + FUNCTION(pbs0), + FUNCTION(pbs1), + FUNCTION(pbs2), + FUNCTION(pri_mi2s_data0_a), + FUNCTION(pri_mi2s_data1_a), + FUNCTION(pri_mi2s_mclk_a), + FUNCTION(pri_mi2s_sck_a), + FUNCTION(pri_mi2s_ws_a), + FUNCTION(prng_rosc), + FUNCTION(ptp_pps_out_a), + FUNCTION(ptp_pps_out_b), + FUNCTION(pwr_crypto_enabled_a), + FUNCTION(pwr_crypto_enabled_b), + FUNCTION(pwr_modem_enabled_a), + FUNCTION(pwr_modem_enabled_b), + FUNCTION(pwr_nav_enabled_a), + FUNCTION(pwr_nav_enabled_b), + FUNCTION(qdss_cti_trig_in_a0), + FUNCTION(qdss_cti_trig_in_a1), + FUNCTION(qdss_cti_trig_in_b0), + FUNCTION(qdss_cti_trig_in_b1), + FUNCTION(qdss_cti_trig_out_a0), + FUNCTION(qdss_cti_trig_out_a1), + FUNCTION(qdss_cti_trig_out_b0), + FUNCTION(qdss_cti_trig_out_b1), + FUNCTION(qdss_traceclk_a), + FUNCTION(qdss_traceclk_b), + FUNCTION(qdss_tracectl_a), + FUNCTION(qdss_tracectl_b), + FUNCTION(qdss_tracedata_a), + FUNCTION(qdss_tracedata_b), + FUNCTION(rcm_marker1), + FUNCTION(rcm_marker2), + FUNCTION(sd_write), + FUNCTION(sec_mi2s), + FUNCTION(sensor_en), + FUNCTION(sensor_int2), + FUNCTION(sensor_int3), + FUNCTION(sensor_rst), + FUNCTION(ssbi1), + FUNCTION(ssbi2), + FUNCTION(touch_rst), + FUNCTION(ts_int), + FUNCTION(uim1_clk), + FUNCTION(uim1_data), + FUNCTION(uim1_present), + FUNCTION(uim1_reset), + FUNCTION(uim2_clk), + FUNCTION(uim2_data), + FUNCTION(uim2_present), + FUNCTION(uim2_reset), + FUNCTION(uim_batt), + FUNCTION(wlan_en1) +}; + +static const struct msm_pingroup mdm9607_groups[] = { + PINGROUP(0, blsp_uart3, blsp_spi3, _, _, _, _, _, qdss_tracedata_a, _), + PINGROUP(1, blsp_uart3, blsp_spi3, _, _, _, _, _, qdss_tracedata_a, bimc_dte1), + PINGROUP(2, blsp_uart3, blsp_i2c3, blsp_spi3, _, _, _, _, _, qdss_traceclk_a), + PINGROUP(3, blsp_uart3, blsp_i2c3, blsp_spi3, _, _, _, _, _, _), + PINGROUP(4, blsp_spi2, blsp_uart2, blsp_uim2, _, _, _, _, qdss_tracedata_a, _), + PINGROUP(5, blsp_spi2, blsp_uart2, blsp_uim2, _, _, _, _, qdss_tracedata_a, _), + PINGROUP(6, blsp_spi2, blsp_uart2, blsp_i2c2, _, _, _, _, _, _), + PINGROUP(7, blsp_spi2, blsp_uart2, blsp_i2c2, _, _, _, _, _, _), + PINGROUP(8, blsp_spi5, blsp_uart5, ebi2_lcd, m_voc, _, _, _, _, _), + PINGROUP(9, blsp_spi5, blsp_uart5, _, _, _, _, _, _, _), + PINGROUP(10, blsp_spi5, blsp_i2c5, blsp_uart5, ebi2_a, _, _, qdss_tracedata_b, _, _), + PINGROUP(11, blsp_spi5, blsp_i2c5, blsp_uart5, blsp2_spi, ebi2_lcd, _, _, _, _), + PINGROUP(12, blsp_spi1, blsp_uart1, blsp_uim1, blsp3_spi, gcc_gp2_clk_b, _, _, _, _), + PINGROUP(13, blsp_spi1, blsp_uart1, blsp_uim1, blsp2_spi, gcc_gp3_clk_b, _, _, _, _), + PINGROUP(14, blsp_spi1, blsp_uart1, blsp_i2c1, gcc_gp1_clk_b, _, _, _, _, _), + PINGROUP(15, blsp_spi1, blsp_uart1, blsp_i2c1, _, _, _, _, _, _), + PINGROUP(16, blsp_spi4, blsp_uart4, _, _, _, _, _, _, _), + PINGROUP(17, blsp_spi4, blsp_uart4, _, _, _, _, _, _, _), + PINGROUP(18, blsp_spi4, blsp_uart4, blsp_i2c4, _, _, _, _, _, _), + PINGROUP(19, blsp_spi4, blsp_uart4, blsp_i2c4, _, _, _, _, _, _), + PINGROUP(20, blsp_spi6, blsp_uart6, pri_mi2s_ws_a, ebi2_lcd_te_b, blsp1_spi, _, _, _, + qdss_tracedata_a), + PINGROUP(21, blsp_spi6, blsp_uart6, pri_mi2s_data0_a, blsp1_spi, _, _, _, _, _), + PINGROUP(22, blsp_spi6, blsp_uart6, pri_mi2s_data1_a, blsp_i2c6, ebi2_a_d_8_b, _, _, _, _), + PINGROUP(23, blsp_spi6, blsp_uart6, pri_mi2s_sck_a, blsp_i2c6, ebi2_lcd_cs_n_b, _, _, _, _), + PINGROUP(24, pri_mi2s_mclk_a, _, pwr_nav_enabled_a, _, _, _, _, qdss_tracedata_a, + bimc_dte1), + PINGROUP(25, sd_write, _, pwr_crypto_enabled_a, _, _, _, _, qdss_tracedata_a, _), + PINGROUP(26, blsp3_spi, adsp_ext, _, qdss_tracedata_a, _, atest_combodac_to_gpio_native, _, + _, _), + PINGROUP(27, uim2_data, gmac_mdio, gcc_gp1_clk_a, _, _, atest_combodac_to_gpio_native, _, _, + _), + PINGROUP(28, uim2_clk, gmac_mdio, gcc_gp2_clk_a, _, _, atest_combodac_to_gpio_native, _, _, + _), + PINGROUP(29, uim2_reset, gcc_gp3_clk_a, _, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(30, uim2_present, prng_rosc, _, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(31, uim1_data, _, _, atest_combodac_to_gpio_native, _, _, _, _, _), + PINGROUP(32, uim1_clk, _, _, atest_combodac_to_gpio_native, _, _, _, _, _), + PINGROUP(33, uim1_reset, _, _, atest_combodac_to_gpio_native, _, _, _, _, _), + PINGROUP(34, uim1_present, gcc_plltest, _, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(35, uim_batt, gcc_plltest, _, atest_combodac_to_gpio_native, _, _, _, _, _), + PINGROUP(36, coex_uart, _, _, _, _, _, _, _, _), + PINGROUP(37, coex_uart, _, _, _, _, _, _, _, _), + PINGROUP(38, _, _, _, qdss_cti_trig_in_a0, _, _, _, _, _), + PINGROUP(39, _, _, _, qdss_tracedata_b, _, atest_bbrx1, _, _, _), + PINGROUP(40, _, cri_trng0, _, _, _, _, qdss_tracedata_b, _, atest_bbrx0), + PINGROUP(41, _, _, _, _, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _), + PINGROUP(42, _, cri_trng, _, _, qdss_tracedata_b, _, _, _, _), + PINGROUP(43, _, _, _, _, qdss_tracedata_b, _, _, _, _), + PINGROUP(44, _, _, qdss_cti_trig_in_b0, _, atest_gpsadc_dtest0_native, _, _, _, _), + PINGROUP(45, _, _, qdss_cti_trig_out_b0, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(46, _, _, qdss_tracedata_b, _, _, _, _, _, _), + PINGROUP(47, _, _, qdss_tracedata_b, _, _, _, _, _, _), + PINGROUP(48, _, _, qdss_tracedata_b, _, _, _, _, _, _), + PINGROUP(49, _, _, qdss_tracectl_b, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(50, _, _, qdss_traceclk_b, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(51, _, pa_indicator, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _, _, + _), + PINGROUP(52, _, _, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _, _, _), + PINGROUP(53, _, modem_tsync, nav_tsync_out_a, nav_ptp_pps_in_a, ptp_pps_out_a, + qdss_tracedata_b, _, _, _), + PINGROUP(54, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _, _, _, _, _), + PINGROUP(55, gsm0_tx, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _, _, _, _), + PINGROUP(56, _, _, qdss_cti_trig_in_b1, _, _, _, _, _, _), + PINGROUP(57, _, cri_trng1, _, qdss_cti_trig_out_b1, _, atest_combodac_to_gpio_native, _, _, + _), + PINGROUP(58, _, ssbi1, _, qdss_tracedata_b, _, atest_gpsadc_dtest1_native, _, _, _), + PINGROUP(59, _, ssbi2, _, qdss_tracedata_b, _, atest_combodac_to_gpio_native, _, _, _), + PINGROUP(60, atest_char3, _, _, _, _, _, _, _, _), + PINGROUP(61, atest_char2, _, _, _, _, _, _, _, _), + PINGROUP(62, atest_char1, _, _, _, _, _, _, _, _), + PINGROUP(63, atest_char0, _, _, _, _, _, _, _, _), + PINGROUP(64, atest_char, _, _, _, _, _, _, _, _), + PINGROUP(65, _, _, _, _, _, _, _, _, _), + PINGROUP(66, _, _, _, _, _, _, _, _, _), + PINGROUP(67, _, _, _, _, _, _, _, _, _), + PINGROUP(68, _, _, _, _, _, _, _, _, _), + PINGROUP(69, _, _, _, _, _, _, _, _, _), + PINGROUP(70, _, _, ebi0_wrcdc, _, _, _, _, _, _), + PINGROUP(71, _, _, _, _, _, _, _, _, _), + PINGROUP(72, ldo_update, _, gcc_tlmm, _, _, _, _, _, _), + PINGROUP(73, ldo_en, dbg_out, _, _, _, atest_tsens, _, _, _), + PINGROUP(74, ebi2_lcd, _, _, _, _, _, _, _, _), + PINGROUP(75, nav_tsync_out_b, nav_ptp_pps_in_b, ptp_pps_out_b, _, qdss_tracedata_a, _, _, _, + _), + PINGROUP(76, pbs0, sec_mi2s, blsp3_spi, pwr_modem_enabled_a, _, qdss_tracedata_a, _, _, _), + PINGROUP(77, pbs1, sec_mi2s, blsp2_spi, pwr_modem_enabled_b, _, qdss_tracedata_a, _, _, _), + PINGROUP(78, pbs2, sec_mi2s, blsp1_spi, ebi2_lcd, m_voc, pwr_nav_enabled_b, _, + qdss_tracedata_a, _), + PINGROUP(79, sec_mi2s, _, pwr_crypto_enabled_b, _, qdss_tracedata_a, _, _, _, _), + SDC_PINGROUP(sdc1_clk, 0x10a000, 13, 6), + SDC_PINGROUP(sdc1_cmd, 0x10a000, 11, 3), + SDC_PINGROUP(sdc1_data, 0x10a000, 9, 0), + SDC_PINGROUP(sdc2_clk, 0x109000, 14, 6), + SDC_PINGROUP(sdc2_cmd, 0x109000, 11, 3), + SDC_PINGROUP(sdc2_data, 0x109000, 9, 0), + SDC_PINGROUP(qdsd_clk, 0x19c000, 3, 0), + SDC_PINGROUP(qdsd_cmd, 0x19c000, 8, 5), + SDC_PINGROUP(qdsd_data0, 0x19c000, 13, 10), + SDC_PINGROUP(qdsd_data1, 0x19c000, 18, 15), + SDC_PINGROUP(qdsd_data2, 0x19c000, 23, 20), + SDC_PINGROUP(qdsd_data3, 0x19c000, 28, 25), +}; + +static const struct msm_pinctrl_soc_data mdm9607_pinctrl = { + .pins = mdm9607_pins, + .npins = ARRAY_SIZE(mdm9607_pins), + .functions = mdm9607_functions, + .nfunctions = ARRAY_SIZE(mdm9607_functions), + .groups = mdm9607_groups, + .ngroups = ARRAY_SIZE(mdm9607_groups), + .ngpios = 80, +}; + +static int mdm9607_pinctrl_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &mdm9607_pinctrl); +} + +static const struct of_device_id mdm9607_pinctrl_of_match[] = { + { .compatible = "qcom,mdm9607-tlmm", }, + { } +}; + +static struct platform_driver mdm9607_pinctrl_driver = { + .driver = { + .name = "mdm9607-pinctrl", + .of_match_table = mdm9607_pinctrl_of_match, + }, + .probe = mdm9607_pinctrl_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init mdm9607_pinctrl_init(void) +{ + return platform_driver_register(&mdm9607_pinctrl_driver); +} +arch_initcall(mdm9607_pinctrl_init); + +static void __exit mdm9607_pinctrl_exit(void) +{ + platform_driver_unregister(&mdm9607_pinctrl_driver); +} +module_exit(mdm9607_pinctrl_exit); + +MODULE_DESCRIPTION("Qualcomm mdm9607 pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, mdm9607_pinctrl_of_match); -- cgit v1.2.3-70-g09d2 From 29d45a642d4ea8de7e89b57f856046df7c3b219f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 24 Jun 2021 14:49:13 +0800 Subject: pinctrl: bcm2835: Replace BUG with BUG_ON The if condition followed by BUG can be replaced to BUG_ON which is more compact and formal in linux source. Signed-off-by: Jason Wang Acked-by: Florian Fainelli Link: https://lore.kernel.org/r/20210624064913.41788-1-wangborong@cdjrlc.com Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 2c87af1180c4..8440c722f6f8 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -416,8 +416,7 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc) } } /* This should not happen, every IRQ has a bank */ - if (i == BCM2835_NUM_IRQS) - BUG(); + BUG_ON(i == BCM2835_NUM_IRQS); chained_irq_enter(host_chip, desc); -- cgit v1.2.3-70-g09d2 From baf8d6899b1e8906dc076ef26cc633e96a8bb0c3 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Mon, 19 Jul 2021 13:29:38 +0200 Subject: pinctrl: armada-37xx: Correct PWM pins definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PWM pins on North Bridge on Armada 37xx can be configured into PWM or GPIO functions. When in PWM function, each pin can also be configured to drive low on 0 and tri-state on 1 (LED mode). The current definitions handle this by declaring two pin groups for each pin: - group "pwmN" with functions "pwm" and "gpio" - group "ledN_od" ("od" for open drain) with functions "led" and "gpio" This is semantically incorrect. The correct definition for each pin should be one group with three functions: "pwm", "led" and "gpio". Change the "pwmN" groups to support "led" function. Remove "ledN_od" groups. This cannot break backwards compatibility with older device trees: no device tree uses it since there is no PWM driver for this SOC yet. Also "ledN_od" groups are not even documented. Fixes: b835d6953009 ("pinctrl: armada-37xx: swap polarity on LED group") Signed-off-by: Marek Behún Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210719112938.27594-1-kabel@kernel.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/marvell,armada-37xx-pinctrl.txt | 8 ++++---- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt index 38dc56a57760..ecec514b3155 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt @@ -43,19 +43,19 @@ group emmc_nb group pwm0 - pin 11 (GPIO1-11) - - functions pwm, gpio + - functions pwm, led, gpio group pwm1 - pin 12 - - functions pwm, gpio + - functions pwm, led, gpio group pwm2 - pin 13 - - functions pwm, gpio + - functions pwm, led, gpio group pwm3 - pin 14 - - functions pwm, gpio + - functions pwm, led, gpio group pmic1 - pin 7 diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 5a68e242f6b3..5cb018f98800 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -167,10 +167,14 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"), PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"), PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"), - PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"), - PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), - PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), - PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), + PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6), + "pwm", "led"), PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), @@ -184,10 +188,6 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), 18, 2, "gpio", "uart"), - PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), - PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), - PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), - PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), }; static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { -- cgit v1.2.3-70-g09d2 From 41af189bb38b2692ab5398222f54568719729198 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Mon, 7 Jun 2021 14:10:40 +0800 Subject: dt-bindings: pinctrl: imx8ulp: Add pinctrl binding Add pinctrl binding doc for i.MX8ULP Signed-off-by: Jacky Bai Reviewed-by: Rob Herring Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20210607061041.2654568-1-ping.bai@nxp.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/fsl,imx8ulp-pinctrl.yaml | 79 ++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx8ulp-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx8ulp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx8ulp-pinctrl.yaml new file mode 100644 index 000000000000..86622c4f374b --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx8ulp-pinctrl.yaml @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/fsl,imx8ulp-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale IMX8ULP IOMUX Controller + +maintainers: + - Jacky Bai + +description: + Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory + for common binding part and usage. + +properties: + compatible: + const: fsl,imx8ulp-iomuxc1 + + reg: + maxItems: 1 + +# Client device subnode's properties +patternProperties: + 'grp$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + + properties: + fsl,pins: + description: + each entry consists of 5 integers and represents the mux and config + setting for one pin. The first 4 integers are specified using a PIN_FUNC_ID macro, which can + be found in . The last + integer CONFIG is the pad setting value like pull-up on this pin. Please + refer to i.MX8ULP Reference Manual for detailed CONFIG settings. + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: | + "mux_config_reg" indicates the offset of mux register. + - description: | + "input_reg" indicates the offset of select input register. + - description: | + "mux_mode" indicates the mux value to be applied. + - description: | + "input_val" indicates the select input value to be applied. + - description: | + "pad_setting" indicates the pad configuration value to be applied. + + required: + - fsl,pins + + additionalProperties: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + # Pinmux controller node + - | + iomuxc: pinctrl@298c0000 { + compatible = "fsl,imx8ulp-iomuxc1"; + reg = <0x298c0000 0x10000>; + + pinctrl_lpuart5: lpuart5grp { + fsl,pins = + <0x0138 0x08F0 0x4 0x3 0x3>, + <0x013C 0x08EC 0x4 0x3 0x3>; + }; + }; + +... -- cgit v1.2.3-70-g09d2 From 16b343e8e0ef7de5ce451427fafc9e2ea42f548f Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 7 Jun 2021 14:10:41 +0800 Subject: pinctrl: imx8ulp: Add pinctrl driver support Add i.MX8ULP pinctrl driver support. Signed-off-by: Anson Huang Signed-off-by: Jacky Bai Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20210607061041.2654568-2-ping.bai@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/Kconfig | 7 + drivers/pinctrl/freescale/Makefile | 1 + drivers/pinctrl/freescale/pinctrl-imx8ulp.c | 274 ++++++++++++++++++++++++++++ 3 files changed, 282 insertions(+) create mode 100644 drivers/pinctrl/freescale/pinctrl-imx8ulp.c diff --git a/drivers/pinctrl/freescale/Kconfig b/drivers/pinctrl/freescale/Kconfig index f294336430cc..21fa21c6547b 100644 --- a/drivers/pinctrl/freescale/Kconfig +++ b/drivers/pinctrl/freescale/Kconfig @@ -166,6 +166,13 @@ config PINCTRL_IMX8DXL help Say Y here to enable the imx8dxl pinctrl driver +config PINCTRL_IMX8ULP + tristate "IMX8ULP pinctrl driver" + depends on ARCH_MXC + select PINCTRL_IMX + help + Say Y here to enable the imx8ulp pinctrl driver + config PINCTRL_VF610 bool "Freescale Vybrid VF610 pinctrl driver" depends on SOC_VF610 diff --git a/drivers/pinctrl/freescale/Makefile b/drivers/pinctrl/freescale/Makefile index e476cb671037..c44930b1b362 100644 --- a/drivers/pinctrl/freescale/Makefile +++ b/drivers/pinctrl/freescale/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_PINCTRL_IMX8MQ) += pinctrl-imx8mq.o obj-$(CONFIG_PINCTRL_IMX8QM) += pinctrl-imx8qm.o obj-$(CONFIG_PINCTRL_IMX8QXP) += pinctrl-imx8qxp.o obj-$(CONFIG_PINCTRL_IMX8DXL) += pinctrl-imx8dxl.o +obj-$(CONFIG_PINCTRL_IMX8ULP) += pinctrl-imx8ulp.o obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o diff --git a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c new file mode 100644 index 000000000000..c5db5dfcfcce --- /dev/null +++ b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2021 NXP + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-imx.h" + +enum imx8ulp_pads { + IMX8ULP_PAD_PTD0 = 0, + IMX8ULP_PAD_PTD1, + IMX8ULP_PAD_PTD2, + IMX8ULP_PAD_PTD3, + IMX8ULP_PAD_PTD4, + IMX8ULP_PAD_PTD5, + IMX8ULP_PAD_PTD6, + IMX8ULP_PAD_PTD7, + IMX8ULP_PAD_PTD8, + IMX8ULP_PAD_PTD9, + IMX8ULP_PAD_PTD10, + IMX8ULP_PAD_PTD11, + IMX8ULP_PAD_PTD12, + IMX8ULP_PAD_PTD13, + IMX8ULP_PAD_PTD14, + IMX8ULP_PAD_PTD15, + IMX8ULP_PAD_PTD16, + IMX8ULP_PAD_PTD17, + IMX8ULP_PAD_PTD18, + IMX8ULP_PAD_PTD19, + IMX8ULP_PAD_PTD20, + IMX8ULP_PAD_PTD21, + IMX8ULP_PAD_PTD22, + IMX8ULP_PAD_PTD23, + IMX8ULP_PAD_RESERVE0, + IMX8ULP_PAD_RESERVE1, + IMX8ULP_PAD_RESERVE2, + IMX8ULP_PAD_RESERVE3, + IMX8ULP_PAD_RESERVE4, + IMX8ULP_PAD_RESERVE5, + IMX8ULP_PAD_RESERVE6, + IMX8ULP_PAD_RESERVE7, + IMX8ULP_PAD_PTE0, + IMX8ULP_PAD_PTE1, + IMX8ULP_PAD_PTE2, + IMX8ULP_PAD_PTE3, + IMX8ULP_PAD_PTE4, + IMX8ULP_PAD_PTE5, + IMX8ULP_PAD_PTE6, + IMX8ULP_PAD_PTE7, + IMX8ULP_PAD_PTE8, + IMX8ULP_PAD_PTE9, + IMX8ULP_PAD_PTE10, + IMX8ULP_PAD_PTE11, + IMX8ULP_PAD_PTE12, + IMX8ULP_PAD_PTE13, + IMX8ULP_PAD_PTE14, + IMX8ULP_PAD_PTE15, + IMX8ULP_PAD_PTE16, + IMX8ULP_PAD_PTE17, + IMX8ULP_PAD_PTE18, + IMX8ULP_PAD_PTE19, + IMX8ULP_PAD_PTE20, + IMX8ULP_PAD_PTE21, + IMX8ULP_PAD_PTE22, + IMX8ULP_PAD_PTE23, + IMX8ULP_PAD_RESERVE8, + IMX8ULP_PAD_RESERVE9, + IMX8ULP_PAD_RESERVE10, + IMX8ULP_PAD_RESERVE11, + IMX8ULP_PAD_RESERVE12, + IMX8ULP_PAD_RESERVE13, + IMX8ULP_PAD_RESERVE14, + IMX8ULP_PAD_RESERVE15, + IMX8ULP_PAD_PTF0, + IMX8ULP_PAD_PTF1, + IMX8ULP_PAD_PTF2, + IMX8ULP_PAD_PTF3, + IMX8ULP_PAD_PTF4, + IMX8ULP_PAD_PTF5, + IMX8ULP_PAD_PTF6, + IMX8ULP_PAD_PTF7, + IMX8ULP_PAD_PTF8, + IMX8ULP_PAD_PTF9, + IMX8ULP_PAD_PTF10, + IMX8ULP_PAD_PTF11, + IMX8ULP_PAD_PTF12, + IMX8ULP_PAD_PTF13, + IMX8ULP_PAD_PTF14, + IMX8ULP_PAD_PTF15, + IMX8ULP_PAD_PTF16, + IMX8ULP_PAD_PTF17, + IMX8ULP_PAD_PTF18, + IMX8ULP_PAD_PTF19, + IMX8ULP_PAD_PTF20, + IMX8ULP_PAD_PTF21, + IMX8ULP_PAD_PTF22, + IMX8ULP_PAD_PTF23, + IMX8ULP_PAD_PTF24, + IMX8ULP_PAD_PTF25, + IMX8ULP_PAD_PTF26, + IMX8ULP_PAD_PTF27, + IMX8ULP_PAD_PTF28, + IMX8ULP_PAD_PTF29, + IMX8ULP_PAD_PTF30, + IMX8ULP_PAD_PTF31, +}; + +/* Pad names for the pinmux subsystem */ +static const struct pinctrl_pin_desc imx8ulp_pinctrl_pads[] = { + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD0), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD1), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD2), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD3), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD4), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD5), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD6), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD7), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD8), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD9), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD10), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD11), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD12), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD13), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD14), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD15), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD16), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD17), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD18), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD19), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD20), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD21), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD22), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD23), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE0), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE1), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE2), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE3), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE4), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE5), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE6), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE7), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE0), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE1), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE2), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE3), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE4), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE5), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE6), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE7), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE8), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE9), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE10), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE11), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE12), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE13), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE14), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE15), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE16), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE17), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE18), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE19), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE20), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE21), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE22), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE23), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE8), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE9), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE10), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE11), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE12), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE13), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE14), + IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE15), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF0), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF1), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF2), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF3), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF4), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF5), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF6), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF7), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF8), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF9), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF10), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF11), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF12), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF13), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF14), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF15), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF16), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF17), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF18), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF19), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF20), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF21), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF22), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF23), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF24), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF25), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF26), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF27), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF28), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF29), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF30), + IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF31), +}; + +#define BM_OBE_ENABLED BIT(17) +#define BM_IBE_ENABLED BIT(16) +#define BM_MUX_MODE 0xf00 +#define BP_MUX_MODE 8 + +static int imx8ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset, bool input) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pin_reg *pin_reg; + u32 reg; + + reg = readl(ipctl->base + pin_reg->mux_reg); + if (input) + reg = (reg & ~BM_OBE_ENABLED) | BM_IBE_ENABLED; + else + reg = (reg & ~BM_IBE_ENABLED) | BM_OBE_ENABLED; + writel(reg, ipctl->base + pin_reg->mux_reg); + + return 0; +} + +static const struct imx_pinctrl_soc_info imx8ulp_pinctrl_info = { + .pins = imx8ulp_pinctrl_pads, + .npins = ARRAY_SIZE(imx8ulp_pinctrl_pads), + .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG, + .gpio_set_direction = imx8ulp_pmx_gpio_set_direction, + .mux_mask = BM_MUX_MODE, + .mux_shift = BP_MUX_MODE, +}; + +static const struct of_device_id imx8ulp_pinctrl_of_match[] = { + { .compatible = "fsl,imx8ulp-iomuxc1", }, + { /* sentinel */ } +}; + +static int imx8ulp_pinctrl_probe(struct platform_device *pdev) +{ + return imx_pinctrl_probe(pdev, &imx8ulp_pinctrl_info); +} + +static struct platform_driver imx8ulp_pinctrl_driver = { + .driver = { + .name = "imx8ulp-pinctrl", + .of_match_table = imx8ulp_pinctrl_of_match, + .suppress_bind_attrs = true, + }, + .probe = imx8ulp_pinctrl_probe, +}; + +static int __init imx8ulp_pinctrl_init(void) +{ + return platform_driver_register(&imx8ulp_pinctrl_driver); +} +arch_initcall(imx8ulp_pinctrl_init); + +MODULE_AUTHOR("Jacky Bai "); +MODULE_DESCRIPTION("NXP i.MX8ULP pinctrl driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 1ac1f6459d1e4bddd541949019b871ccfb3f4e6e Mon Sep 17 00:00:00 2001 From: kernel test robot Date: Sat, 26 Jun 2021 13:15:50 +0800 Subject: pinctrl: mediatek: fix platform_no_drv_owner.cocci warnings drivers/pinctrl/mediatek/pinctrl-mt8365.c:488:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci Fixes: e94d8b6fb83a ("pinctrl: mediatek: add support for mt8365 SoC") CC: Fabien Parent Reported-by: kernel test robot Signed-off-by: kernel test robot Link: https://lore.kernel.org/r/20210626051550.GA37544@d0c207d51ce8 Signed-off-by: Linus Walleij --- drivers/pinctrl/mediatek/pinctrl-mt8365.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8365.c b/drivers/pinctrl/mediatek/pinctrl-mt8365.c index 22c33c3cb581..79b1fee5a1eb 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8365.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8365.c @@ -485,7 +485,6 @@ static struct platform_driver mtk_pinctrl_driver = { .probe = mtk_pinctrl_probe, .driver = { .name = "mediatek-mt8365-pinctrl", - .owner = THIS_MODULE, .of_match_table = mt8365_pctrl_match, .pm = &mtk_eint_pm_ops, }, -- cgit v1.2.3-70-g09d2 From ffdf4cecac07fd16459a82f605aeee8098e3161c Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 29 Jun 2021 18:04:04 +0530 Subject: dt-bindings: pinctrl: qcom,pmic-gpio: Arrange compatibles alphabetically Arrange the compatibles inside qcom-pmic gpio device tree bindings alphabetically. While at it, also make some minor cosmetic changes to allow future compatible addition to the bindings simpler. Cc: Linus Walleij Cc: Bjorn Andersson Reviewed-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Bhupesh Sharma Link: https://lore.kernel.org/r/20210629123407.82561-2-bhupesh.sharma@linaro.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 62 +++++++++++----------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 161216daf463..c9f02062774a 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -7,10 +7,21 @@ PMIC's from Qualcomm. Usage: required Value type: Definition: must be one of: + "qcom,pm660-gpio" + "qcom,pm660l-gpio" + "qcom,pm6150-gpio" + "qcom,pm6150l-gpio" + "qcom,pm7325-gpio" "qcom,pm8005-gpio" + "qcom,pm8008-gpio" "qcom,pm8018-gpio" "qcom,pm8038-gpio" "qcom,pm8058-gpio" + "qcom,pm8150-gpio" + "qcom,pm8150b-gpio" + "qcom,pm8350-gpio" + "qcom,pm8350b-gpio" + "qcom,pm8350c-gpio" "qcom,pm8916-gpio" "qcom,pm8917-gpio" "qcom,pm8921-gpio" @@ -22,21 +33,10 @@ PMIC's from Qualcomm. "qcom,pmi8950-gpio" "qcom,pmi8994-gpio" "qcom,pmi8998-gpio" - "qcom,pms405-gpio" - "qcom,pm660-gpio" - "qcom,pm660l-gpio" - "qcom,pm8150-gpio" - "qcom,pm8150b-gpio" - "qcom,pm8350-gpio" - "qcom,pm8350b-gpio" - "qcom,pm8350c-gpio" "qcom,pmk8350-gpio" - "qcom,pm7325-gpio" "qcom,pmr735a-gpio" "qcom,pmr735b-gpio" - "qcom,pm6150-gpio" - "qcom,pm6150l-gpio" - "qcom,pm8008-gpio" + "qcom,pms405-gpio" "qcom,pmx55-gpio" And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio" @@ -98,35 +98,35 @@ to specify in a pin configuration subnode: Value type: Definition: List of gpio pins affected by the properties specified in this subnode. Valid pins are: - gpio1-gpio4 for pm8005 - gpio1-gpio6 for pm8018 + gpio1-gpio10 for pm6150 + gpio1-gpio12 for pm6150l + gpio1-gpio10 for pm7325 + gpio1-gpio4 for pm8005 + gpio1-gpio2 for pm8008 + gpio1-gpio6 for pm8018 gpio1-gpio12 for pm8038 gpio1-gpio40 for pm8058 - gpio1-gpio4 for pm8916 + gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, gpio7 + and gpio8) + gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7) + gpio1-gpio12 for pm8150l (hole on gpio7) + gpio1-gpio10 for pm8350 + gpio1-gpio8 for pm8350b + gpio1-gpio9 for pm8350c + gpio1-gpio4 for pm8916 gpio1-gpio38 for pm8917 gpio1-gpio44 for pm8921 gpio1-gpio36 for pm8941 - gpio1-gpio8 for pm8950 (hole on gpio3) + gpio1-gpio8 for pm8950 (hole on gpio3) gpio1-gpio22 for pm8994 gpio1-gpio26 for pm8998 gpio1-gpio22 for pma8084 - gpio1-gpio2 for pmi8950 + gpio1-gpio2 for pmi8950 gpio1-gpio10 for pmi8994 + gpio1-gpio4 for pmk8350 + gpio1-gpio4 for pmr735a + gpio1-gpio4 for pmr735b gpio1-gpio12 for pms405 (holes on gpio1, gpio9 and gpio10) - gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, gpio7 - and gpio8) - gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7) - gpio1-gpio12 for pm8150l (hole on gpio7) - gpio1-gpio10 for pm8350 - gpio1-gpio8 for pm8350b - gpio1-gpio9 for pm8350c - gpio1-gpio4 for pmk8350 - gpio1-gpio10 for pm7325 - gpio1-gpio4 for pmr735a - gpio1-gpio4 for pmr735b - gpio1-gpio10 for pm6150 - gpio1-gpio12 for pm6150l - gpio1-gpio2 for pm8008 gpio1-gpio11 for pmx55 (holes on gpio3, gpio7, gpio10 and gpio11) -- cgit v1.2.3-70-g09d2 From 0ac2c2aebf824809e37fe480b7bcf659f3f295d2 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 29 Jun 2021 18:04:05 +0530 Subject: dt-bindings: pinctrl: qcom,pmic-gpio: Add compatible for SA8155p-adp Add pmic-gpio compatible string for pmm8155au pmic found on the SA8155p-adp board. Cc: Linus Walleij Cc: Bjorn Andersson Reviewed-by: Bjorn Andersson Acked-by: Rob Herring Signed-off-by: Bhupesh Sharma Link: https://lore.kernel.org/r/20210629123407.82561-3-bhupesh.sharma@linaro.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index c9f02062774a..261a1d114253 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -34,6 +34,7 @@ PMIC's from Qualcomm. "qcom,pmi8994-gpio" "qcom,pmi8998-gpio" "qcom,pmk8350-gpio" + "qcom,pmm8155au-gpio" "qcom,pmr735a-gpio" "qcom,pmr735b-gpio" "qcom,pms405-gpio" @@ -124,6 +125,7 @@ to specify in a pin configuration subnode: gpio1-gpio2 for pmi8950 gpio1-gpio10 for pmi8994 gpio1-gpio4 for pmk8350 + gpio1-gpio10 for pmm8155au gpio1-gpio4 for pmr735a gpio1-gpio4 for pmr735b gpio1-gpio12 for pms405 (holes on gpio1, gpio9 and gpio10) -- cgit v1.2.3-70-g09d2 From 4afc2a0c62a372a923cfb06182af387425489b7c Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 29 Jun 2021 18:04:06 +0530 Subject: pinctrl: qcom/pinctrl-spmi-gpio: Arrange compatibles alphabetically Arrange the compatibles inside qcom pinctrl-spmi gpio driver alphabetically. Cc: Linus Walleij Cc: Bjorn Andersson Reviewed-by: Bjorn Andersson Signed-off-by: Bhupesh Sharma Link: https://lore.kernel.org/r/20210629123407.82561-4-bhupesh.sharma@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index a89d24a040af..5246ea09c295 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1104,23 +1104,15 @@ static int pmic_gpio_remove(struct platform_device *pdev) } static const struct of_device_id pmic_gpio_of_match[] = { - { .compatible = "qcom,pm8005-gpio", .data = (void *) 4 }, - { .compatible = "qcom,pm8916-gpio", .data = (void *) 4 }, - { .compatible = "qcom,pm8941-gpio", .data = (void *) 36 }, - /* pm8950 has 8 GPIOs with holes on 3 */ - { .compatible = "qcom,pm8950-gpio", .data = (void *) 8 }, - { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, - { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, - { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, - { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, - { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, - { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, - /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ - { .compatible = "qcom,pms405-gpio", .data = (void *) 12 }, /* pm660 has 13 GPIOs with holes on 1, 5, 6, 7, 8 and 10 */ { .compatible = "qcom,pm660-gpio", .data = (void *) 13 }, /* pm660l has 12 GPIOs with holes on 1, 2, 10, 11 and 12 */ { .compatible = "qcom,pm660l-gpio", .data = (void *) 12 }, + { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, + { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pm8005-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pm8008-gpio", .data = (void *) 2 }, /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */ { .compatible = "qcom,pm8150-gpio", .data = (void *) 10 }, /* pm8150b has 12 GPIOs with holes on 3, r and 7 */ @@ -1130,13 +1122,21 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8350-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm8350b-gpio", .data = (void *) 8 }, { .compatible = "qcom,pm8350c-gpio", .data = (void *) 9 }, + { .compatible = "qcom,pm8916-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pm8941-gpio", .data = (void *) 36 }, + /* pm8950 has 8 GPIOs with holes on 3 */ + { .compatible = "qcom,pm8950-gpio", .data = (void *) 8 }, + { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, + { .compatible = "qcom,pm8998-gpio", .data = (void *) 26 }, + { .compatible = "qcom,pma8084-gpio", .data = (void *) 22 }, + { .compatible = "qcom,pmi8950-gpio", .data = (void *) 2 }, + { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, - { .compatible = "qcom,pm7325-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmr735a-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmr735b-gpio", .data = (void *) 4 }, - { .compatible = "qcom,pm6150-gpio", .data = (void *) 10 }, - { .compatible = "qcom,pm6150l-gpio", .data = (void *) 12 }, - { .compatible = "qcom,pm8008-gpio", .data = (void *) 2 }, + /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ + { .compatible = "qcom,pms405-gpio", .data = (void *) 12 }, /* pmx55 has 11 GPIOs with holes on 3, 7, 10, 11 */ { .compatible = "qcom,pmx55-gpio", .data = (void *) 11 }, { }, -- cgit v1.2.3-70-g09d2 From 79e2311c876c276566e3fb84ba33682eb540874b Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Tue, 29 Jun 2021 18:04:07 +0530 Subject: pinctrl: qcom/pinctrl-spmi-gpio: Add compatible for pmic-gpio on SA8155p-adp SA8155p-adp PMIC (PMM8155AU) exposes 10 GPIOs. Add support for the same in the pinctrl driver. Cc: Linus Walleij Cc: Bjorn Andersson Reviewed-by: Bjorn Andersson Signed-off-by: Bhupesh Sharma Link: https://lore.kernel.org/r/20210629123407.82561-5-bhupesh.sharma@linaro.org Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index 5246ea09c295..bbea3499178e 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1133,6 +1133,7 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 }, { .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 }, + { .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 }, { .compatible = "qcom,pmr735a-gpio", .data = (void *) 4 }, { .compatible = "qcom,pmr735b-gpio", .data = (void *) 4 }, /* pms405 has 12 GPIOs with holes on 1, 9, and 10 */ -- cgit v1.2.3-70-g09d2 From da5e96ffd5a938b11c430d023109a19ba3b6d71d Mon Sep 17 00:00:00 2001 From: satya priya Date: Fri, 23 Jul 2021 12:12:37 -0700 Subject: dt-bindings: power: reset: Change 'additionalProperties' to true Change 'additionalProperties' to true as this is a generic binding. Signed-off-by: satya priya Acked-by: Rob Herring Reviewed-by: Sebastian Reichel Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/1620800053-26405-4-git-send-email-skakit@codeaurora.org Signed-off-by: Dmitry Torokhov --- Documentation/devicetree/bindings/power/reset/reboot-mode.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/power/reset/reboot-mode.yaml b/Documentation/devicetree/bindings/power/reset/reboot-mode.yaml index 9c6fda6b1dd9..ad0a0b95cec1 100644 --- a/Documentation/devicetree/bindings/power/reset/reboot-mode.yaml +++ b/Documentation/devicetree/bindings/power/reset/reboot-mode.yaml @@ -36,7 +36,7 @@ patternProperties: "^mode-.*$": $ref: /schemas/types.yaml#/definitions/uint32 -additionalProperties: false +additionalProperties: true examples: - | -- cgit v1.2.3-70-g09d2 From 400793bc351b83c11ce28210d86039e905c8ff32 Mon Sep 17 00:00:00 2001 From: satya priya Date: Fri, 23 Jul 2021 12:12:52 -0700 Subject: dt-bindings: input: pm8941-pwrkey: Convert pm8941 power key binding to yaml Convert qcom pm8941 power key binding from .txt to .yaml format. The example has been removed in favour of full example being available in the qcom,pon.yaml binding. Signed-off-by: satya priya Reviewed-by: Rob Herring Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/1620800053-26405-5-git-send-email-skakit@codeaurora.org Signed-off-by: Dmitry Torokhov --- .../bindings/input/qcom,pm8941-pwrkey.txt | 55 ---------------------- .../bindings/input/qcom,pm8941-pwrkey.yaml | 51 ++++++++++++++++++++ 2 files changed, 51 insertions(+), 55 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt deleted file mode 100644 index 6cd08bca2c66..000000000000 --- a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt +++ /dev/null @@ -1,55 +0,0 @@ -Qualcomm PM8941 PMIC Power Key - -PROPERTIES - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,pm8941-pwrkey" - "qcom,pm8941-resin" - "qcom,pmk8350-pwrkey" - "qcom,pmk8350-resin" - -- reg: - Usage: required - Value type: - Definition: base address of registers for block - -- interrupts: - Usage: required - Value type: - Definition: key change interrupt; The format of the specifier is - defined by the binding document describing the node's - interrupt parent. - -- debounce: - Usage: optional - Value type: - Definition: time in microseconds that key must be pressed or released - for state change interrupt to trigger. - -- bias-pull-up: - Usage: optional - Value type: - Definition: presence of this property indicates that the KPDPWR_N pin - should be configured for pull up. - -- linux,code: - Usage: optional - Value type: - Definition: The input key-code associated with the power key. - Use the linux event codes defined in - include/dt-bindings/input/linux-event-codes.h - When property is omitted KEY_POWER is assumed. - -EXAMPLE - - pwrkey@800 { - compatible = "qcom,pm8941-pwrkey"; - reg = <0x800>; - interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; - debounce = <15625>; - bias-pull-up; - linux,code = ; - }; diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml new file mode 100644 index 000000000000..62314a5fdce5 --- /dev/null +++ b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/qcom,pm8941-pwrkey.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm PM8941 PMIC Power Key + +maintainers: + - Courtney Cavin + - Vinod Koul + +allOf: + - $ref: input.yaml# + +properties: + compatible: + enum: + - qcom,pm8941-pwrkey + - qcom,pm8941-resin + - qcom,pmk8350-pwrkey + - qcom,pmk8350-resin + + interrupts: + maxItems: 1 + + debounce: + description: | + Time in microseconds that key must be pressed or + released for state change interrupt to trigger. + $ref: /schemas/types.yaml#/definitions/uint32 + + bias-pull-up: + description: | + Presence of this property indicates that the KPDPWR_N + pin should be configured for pull up. + $ref: /schemas/types.yaml#/definitions/flag + + linux,code: + description: | + The input key-code associated with the power key. + Use the linux event codes defined in + include/dt-bindings/input/linux-event-codes.h + When property is omitted KEY_POWER is assumed. + +required: + - compatible + - interrupts + +unevaluatedProperties: false +... -- cgit v1.2.3-70-g09d2 From 76ba1900cb67390d963e07457ebf679c56c59094 Mon Sep 17 00:00:00 2001 From: satya priya Date: Fri, 23 Jul 2021 12:13:03 -0700 Subject: dt-bindings: power: reset: qcom-pon: Convert qcom PON binding to yaml Convert qcom PON binding from .txt to .yaml format. Signed-off-by: satya priya Reviewed-by: Rob Herring Reviewed-by: Sebastian Reichel Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/1620800053-26405-6-git-send-email-skakit@codeaurora.org Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/power/reset/qcom,pon.txt | 49 ------------- .../devicetree/bindings/power/reset/qcom,pon.yaml | 80 ++++++++++++++++++++++ 2 files changed, 80 insertions(+), 49 deletions(-) delete mode 100644 Documentation/devicetree/bindings/power/reset/qcom,pon.txt create mode 100644 Documentation/devicetree/bindings/power/reset/qcom,pon.yaml diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.txt b/Documentation/devicetree/bindings/power/reset/qcom,pon.txt deleted file mode 100644 index 0c0dc3a1e693..000000000000 --- a/Documentation/devicetree/bindings/power/reset/qcom,pon.txt +++ /dev/null @@ -1,49 +0,0 @@ -Qualcomm PON Device - -The Power On device for Qualcomm PM8xxx is MFD supporting pwrkey -and resin along with the Android reboot-mode. - -This DT node has pwrkey and resin as sub nodes. - -Required Properties: --compatible: Must be one of: - "qcom,pm8916-pon" - "qcom,pms405-pon" - "qcom,pm8998-pon" - --reg: Specifies the physical address of the pon register - -Optional subnode: --pwrkey: Specifies the subnode pwrkey and should follow the - qcom,pm8941-pwrkey.txt description. --resin: Specifies the subnode resin and should follow the - qcom,pm8xxx-pwrkey.txt description. - -The rest of the properties should follow the generic reboot-mode description -found in reboot-mode.txt - -Example: - - pon@800 { - compatible = "qcom,pm8916-pon"; - - reg = <0x800>; - mode-bootloader = <0x2>; - mode-recovery = <0x1>; - - pwrkey { - compatible = "qcom,pm8941-pwrkey"; - interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; - debounce = <15625>; - bias-pull-up; - linux,code = ; - }; - - resin { - compatible = "qcom,pm8941-resin"; - interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; - debounce = <15625>; - bias-pull-up; - linux,code = ; - }; - }; diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml new file mode 100644 index 000000000000..353f155df0f4 --- /dev/null +++ b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/reset/qcom,pon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm PON Device + +maintainers: + - Vinod Koul + +description: | + The Power On device for Qualcomm PM8xxx is MFD supporting pwrkey + and resin along with the Android reboot-mode. + + This DT node has pwrkey and resin as sub nodes. + +allOf: + - $ref: reboot-mode.yaml# + +properties: + compatible: + enum: + - qcom,pm8916-pon + - qcom,pms405-pon + - qcom,pm8998-pon + + reg: + maxItems: 1 + + pwrkey: + type: object + $ref: "../../input/qcom,pm8941-pwrkey.yaml#" + + resin: + type: object + $ref: "../../input/qcom,pm8941-pwrkey.yaml#" + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + spmi_bus: spmi@c440000 { + reg = <0x0c440000 0x1100>; + #address-cells = <2>; + #size-cells = <0>; + pmk8350: pmic@0 { + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + pmk8350_pon: pon_hlos@1300 { + reg = <0x1300>; + compatible = "qcom,pm8998-pon"; + + pwrkey { + compatible = "qcom,pm8941-pwrkey"; + interrupts = < 0x0 0x8 0 IRQ_TYPE_EDGE_BOTH >; + debounce = <15625>; + bias-pull-up; + linux,code = ; + }; + + resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + linux,code = ; + }; + }; + }; + }; +... -- cgit v1.2.3-70-g09d2 From af0ca06f8781499bd889658b47df75ee2da8ca8f Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 23 Jul 2021 17:32:42 -0300 Subject: pinctrl: imx8ulp: Initialize pin_reg The initialization of pin_reg is missing, causing the following build warning: drivers/pinctrl/freescale/pinctrl-imx8ulp.c:228:35: warning: 'pin_reg' is used uninitialized in this function [-Wuninitialized] Initialize pin_reg the same way as it is done on vf610 and imx7ulp to fix the problem. Fixes: 16b343e8e0ef ("pinctrl: imx8ulp: Add pinctrl driver support") Reported-by: kernel test robot Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210723203242.88845-1-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx8ulp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c index c5db5dfcfcce..f8572597a54e 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8ulp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8ulp.c @@ -225,6 +225,10 @@ static int imx8ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, const struct imx_pin_reg *pin_reg; u32 reg; + pin_reg = &ipctl->pin_regs[offset]; + if (pin_reg->mux_reg == -1) + return -EINVAL; + reg = readl(ipctl->base + pin_reg->mux_reg); if (input) reg = (reg & ~BM_OBE_ENABLED) | BM_IBE_ENABLED; -- cgit v1.2.3-70-g09d2 From 85044eb08d0a37b1b6bcb3504bfd660a85ba5b7b Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 20 Jul 2021 14:38:23 +0100 Subject: of: Return success from of_dma_set_restricted_buffer() when !OF_ADDRESS When CONFIG_OF_ADDRESS=n, of_dma_set_restricted_buffer() returns -ENODEV and breaks the boot for sparc[64] machines. Return 0 instead, since the function is essentially a glorified NOP in this configuration. Cc: Claire Chang Cc: Konrad Rzeszutek Wilk Reported-by: Guenter Roeck Suggested-by: Robin Murphy Tested-by: Guenter Roeck Tested-by: Claire Chang Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20210702030807.GA2685166@roeck-us.net Fixes: fec9b625095f ("of: Add plumbing for restricted DMA pool") Signed-off-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- drivers/of/of_private.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 376462798f7e..f557bd22b0cf 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -173,7 +173,8 @@ static inline int of_dma_get_range(struct device_node *np, static inline int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) { - return -ENODEV; + /* Do nothing, successfully. */ + return 0; } #endif -- cgit v1.2.3-70-g09d2 From 463e862ac63ef27fca423782536f6465abc3f180 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 20 Jul 2021 14:38:24 +0100 Subject: swiotlb: Convert io_default_tlb_mem to static allocation Since commit 69031f500865 ("swiotlb: Set dev->dma_io_tlb_mem to the swiotlb pool used"), 'struct device' may hold a copy of the global 'io_default_tlb_mem' pointer if the device is using swiotlb for DMA. A subsequent call to swiotlb_exit() will therefore leave dangling pointers behind in these device structures, resulting in KASAN splats such as: | BUG: KASAN: use-after-free in __iommu_dma_unmap_swiotlb+0x64/0xb0 | Read of size 8 at addr ffff8881d7830000 by task swapper/0/0 | | CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.12.0-rc3-debug #1 | Hardware name: HP HP Desktop M01-F1xxx/87D6, BIOS F.12 12/17/2020 | Call Trace: | | dump_stack+0x9c/0xcf | print_address_description.constprop.0+0x18/0x130 | kasan_report.cold+0x7f/0x111 | __iommu_dma_unmap_swiotlb+0x64/0xb0 | nvme_pci_complete_rq+0x73/0x130 | blk_complete_reqs+0x6f/0x80 | __do_softirq+0xfc/0x3be Convert 'io_default_tlb_mem' to a static structure, so that the per-device pointers remain valid after swiotlb_exit() has been invoked. All users are updated to reference the static structure directly, using the 'nslabs' field to determine whether swiotlb has been initialised. The 'slots' array is still allocated dynamically and referenced via a pointer rather than a flexible array member. Cc: Claire Chang Cc: Christoph Hellwig Cc: Robin Murphy Cc: Konrad Rzeszutek Wilk Fixes: 69031f500865 ("swiotlb: Set dev->dma_io_tlb_mem to the swiotlb pool used") Reported-by: Nathan Chancellor Tested-by: Nathan Chancellor Tested-by: Claire Chang Reviewed-by: Christoph Hellwig Signed-off-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- drivers/base/core.c | 2 +- drivers/xen/swiotlb-xen.c | 4 +-- include/linux/swiotlb.h | 4 +-- kernel/dma/swiotlb.c | 66 ++++++++++++++++++++++++++--------------------- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index ea5b85354526..b49824001cfa 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2848,7 +2848,7 @@ void device_initialize(struct device *dev) dev->dma_coherent = dma_default_coherent; #endif #ifdef CONFIG_SWIOTLB - dev->dma_io_tlb_mem = io_tlb_default_mem; + dev->dma_io_tlb_mem = &io_tlb_default_mem; #endif } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 785ec7e8be01..f06d9b4f1e0f 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -164,7 +164,7 @@ int __ref xen_swiotlb_init(void) int rc = -ENOMEM; char *start; - if (io_tlb_default_mem != NULL) { + if (io_tlb_default_mem.nslabs) { pr_warn("swiotlb buffer already initialized\n"); return -EEXIST; } @@ -547,7 +547,7 @@ xen_swiotlb_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, static int xen_swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return xen_phys_to_dma(hwdev, io_tlb_default_mem->end - 1) <= mask; + return xen_phys_to_dma(hwdev, io_tlb_default_mem.end - 1) <= mask; } const struct dma_map_ops xen_swiotlb_dma_ops = { diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 39284ff2a6cd..b0cb2a9973f4 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -103,9 +103,9 @@ struct io_tlb_mem { phys_addr_t orig_addr; size_t alloc_size; unsigned int list; - } slots[]; + } *slots; }; -extern struct io_tlb_mem *io_tlb_default_mem; +extern struct io_tlb_mem io_tlb_default_mem; static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) { diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index f1a9ae7fad8f..7948f274f9bb 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -70,7 +70,7 @@ enum swiotlb_force swiotlb_force; -struct io_tlb_mem *io_tlb_default_mem; +struct io_tlb_mem io_tlb_default_mem; /* * Max segment that we can provide which (if pages are contingous) will @@ -101,7 +101,7 @@ early_param("swiotlb", setup_io_tlb_npages); unsigned int swiotlb_max_segment(void) { - return io_tlb_default_mem ? max_segment : 0; + return io_tlb_default_mem.nslabs ? max_segment : 0; } EXPORT_SYMBOL_GPL(swiotlb_max_segment); @@ -134,9 +134,9 @@ void __init swiotlb_adjust_size(unsigned long size) void swiotlb_print_info(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; - if (!mem) { + if (!mem->nslabs) { pr_warn("No low mem\n"); return; } @@ -163,11 +163,11 @@ static inline unsigned long nr_slots(u64 val) */ void __init swiotlb_update_mem_attributes(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; void *vaddr; unsigned long bytes; - if (!mem || mem->late_alloc) + if (!mem->nslabs || mem->late_alloc) return; vaddr = phys_to_virt(mem->start); bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT); @@ -201,25 +201,24 @@ static void swiotlb_init_io_tlb_mem(struct io_tlb_mem *mem, phys_addr_t start, int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) { - struct io_tlb_mem *mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; size_t alloc_size; if (swiotlb_force == SWIOTLB_NO_FORCE) return 0; /* protect against double initialization */ - if (WARN_ON_ONCE(io_tlb_default_mem)) + if (WARN_ON_ONCE(mem->nslabs)) return -ENOMEM; - alloc_size = PAGE_ALIGN(struct_size(mem, slots, nslabs)); - mem = memblock_alloc(alloc_size, PAGE_SIZE); - if (!mem) + alloc_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), nslabs)); + mem->slots = memblock_alloc(alloc_size, PAGE_SIZE); + if (!mem->slots) panic("%s: Failed to allocate %zu bytes align=0x%lx\n", __func__, alloc_size, PAGE_SIZE); swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, false); - io_tlb_default_mem = mem; if (verbose) swiotlb_print_info(); swiotlb_set_max_segment(mem->nslabs << IO_TLB_SHIFT); @@ -304,26 +303,24 @@ swiotlb_late_init_with_default_size(size_t default_size) int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) { - struct io_tlb_mem *mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; unsigned long bytes = nslabs << IO_TLB_SHIFT; if (swiotlb_force == SWIOTLB_NO_FORCE) return 0; /* protect against double initialization */ - if (WARN_ON_ONCE(io_tlb_default_mem)) + if (WARN_ON_ONCE(mem->nslabs)) return -ENOMEM; - mem = (void *)__get_free_pages(GFP_KERNEL, - get_order(struct_size(mem, slots, nslabs))); - if (!mem) + mem->slots = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(array_size(sizeof(*mem->slots), nslabs))); + if (!mem->slots) return -ENOMEM; - memset(mem, 0, sizeof(*mem)); set_memory_decrypted((unsigned long)tlb, bytes >> PAGE_SHIFT); swiotlb_init_io_tlb_mem(mem, virt_to_phys(tlb), nslabs, true); - io_tlb_default_mem = mem; swiotlb_print_info(); swiotlb_set_max_segment(mem->nslabs << IO_TLB_SHIFT); return 0; @@ -331,18 +328,18 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) void __init swiotlb_exit(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; size_t size; + struct io_tlb_mem *mem = &io_tlb_default_mem; - if (!mem) + if (!mem->nslabs) return; - size = struct_size(mem, slots, mem->nslabs); + size = array_size(sizeof(*mem->slots), mem->nslabs); if (mem->late_alloc) - free_pages((unsigned long)mem, get_order(size)); + free_pages((unsigned long)mem->slots, get_order(size)); else - memblock_free_late(__pa(mem), PAGE_ALIGN(size)); - io_tlb_default_mem = NULL; + memblock_free_late(__pa(mem->slots), PAGE_ALIGN(size)); + memset(mem, 0, sizeof(*mem)); } /* @@ -696,7 +693,9 @@ size_t swiotlb_max_mapping_size(struct device *dev) bool is_swiotlb_active(struct device *dev) { - return dev->dma_io_tlb_mem != NULL; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; + + return mem && mem->nslabs; } EXPORT_SYMBOL_GPL(is_swiotlb_active); @@ -711,10 +710,10 @@ static void swiotlb_create_debugfs_files(struct io_tlb_mem *mem) static int __init swiotlb_create_default_debugfs(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; debugfs_dir = debugfs_create_dir("swiotlb", NULL); - if (mem) { + if (mem->nslabs) { mem->debugfs = debugfs_dir; swiotlb_create_debugfs_files(mem); } @@ -783,10 +782,17 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem, * to it. */ if (!mem) { - mem = kzalloc(struct_size(mem, slots, nslabs), GFP_KERNEL); + mem = kzalloc(sizeof(*mem), GFP_KERNEL); if (!mem) return -ENOMEM; + mem->slots = kzalloc(array_size(sizeof(*mem->slots), nslabs), + GFP_KERNEL); + if (!mem->slots) { + kfree(mem); + return -ENOMEM; + } + set_memory_decrypted((unsigned long)phys_to_virt(rmem->base), rmem->size >> PAGE_SHIFT); swiotlb_init_io_tlb_mem(mem, rmem->base, nslabs, false); @@ -806,7 +812,7 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem, static void rmem_swiotlb_device_release(struct reserved_mem *rmem, struct device *dev) { - dev->dma_io_tlb_mem = io_tlb_default_mem; + dev->dma_io_tlb_mem = &io_tlb_default_mem; } static const struct reserved_mem_ops rmem_swiotlb_ops = { -- cgit v1.2.3-70-g09d2 From 1efd3fc0ccf52e1aa5f0bf5b0d82847180d20951 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 20 Jul 2021 14:38:25 +0100 Subject: swiotlb: Emit diagnostic in swiotlb_exit() A recent debugging session would have been made a little bit easier if we had noticed sooner that swiotlb_exit() was being called during boot. Add a simple diagnostic message to swiotlb_exit() to complement the one from swiotlb_print_info() during initialisation. Cc: Claire Chang Cc: Christoph Hellwig Cc: Robin Murphy Link: https://lore.kernel.org/r/20210705190352.GA19461@willie-the-truck Suggested-by: Konrad Rzeszutek Wilk Tested-by: Nathan Chancellor Tested-by: Claire Chang Reviewed-by: Christoph Hellwig Signed-off-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 7948f274f9bb..b3c793ed9e64 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -334,6 +334,7 @@ void __init swiotlb_exit(void) if (!mem->nslabs) return; + pr_info("tearing down default memory pool\n"); size = array_size(sizeof(*mem->slots), mem->nslabs); if (mem->late_alloc) free_pages((unsigned long)mem->slots, get_order(size)); -- cgit v1.2.3-70-g09d2 From ad6c00283163cb7ad52cdf97d2850547446f7d98 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 20 Jul 2021 14:38:26 +0100 Subject: swiotlb: Free tbl memory in swiotlb_exit() Although swiotlb_exit() frees the 'slots' metadata array referenced by 'io_tlb_default_mem', it leaves the underlying buffer pages allocated despite no longer being usable. Extend swiotlb_exit() to free the buffer pages as well as the slots array. Cc: Claire Chang Cc: Christoph Hellwig Cc: Robin Murphy Cc: Konrad Rzeszutek Wilk Tested-by: Nathan Chancellor Tested-by: Claire Chang Reviewed-by: Christoph Hellwig Signed-off-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- kernel/dma/swiotlb.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index b3c793ed9e64..87c40517e822 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -328,18 +328,27 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs) void __init swiotlb_exit(void) { - size_t size; struct io_tlb_mem *mem = &io_tlb_default_mem; + unsigned long tbl_vaddr; + size_t tbl_size, slots_size; if (!mem->nslabs) return; pr_info("tearing down default memory pool\n"); - size = array_size(sizeof(*mem->slots), mem->nslabs); - if (mem->late_alloc) - free_pages((unsigned long)mem->slots, get_order(size)); - else - memblock_free_late(__pa(mem->slots), PAGE_ALIGN(size)); + tbl_vaddr = (unsigned long)phys_to_virt(mem->start); + tbl_size = PAGE_ALIGN(mem->end - mem->start); + slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs)); + + set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT); + if (mem->late_alloc) { + free_pages(tbl_vaddr, get_order(tbl_size)); + free_pages((unsigned long)mem->slots, get_order(slots_size)); + } else { + memblock_free_late(mem->start, tbl_size); + memblock_free_late(__pa(mem->slots), slots_size); + } + memset(mem, 0, sizeof(*mem)); } -- cgit v1.2.3-70-g09d2 From 93ebb6828723b8aef114415c4dc3518342f7dcad Mon Sep 17 00:00:00 2001 From: Halil Pasic Date: Sat, 24 Jul 2021 01:17:46 +0200 Subject: s390/pv: fix the forcing of the swiotlb Since commit 903cd0f315fe ("swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing") if code sets swiotlb_force it needs to do so before the swiotlb is initialised. Otherwise io_tlb_default_mem->force_bounce will not get set to true, and devices that use (the default) swiotlb will not bounce despite switolb_force having the value of SWIOTLB_FORCE. Let us restore swiotlb functionality for PV by fulfilling this new requirement. This change addresses what turned out to be a fragility in commit 64e1f0c531d1 ("s390/mm: force swiotlb for protected virtualization"), which ain't exactly broken in its original context, but could give us some more headache if people backport the broken change and forget this fix. Signed-off-by: Halil Pasic Tested-by: Christian Borntraeger Reviewed-by: Christian Borntraeger Fixes: 903cd0f315fe ("swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing") Fixes: 64e1f0c531d1 ("s390/mm: force swiotlb for protected virtualization") Cc: stable@vger.kernel.org #5.3+ Signed-off-by: Konrad Rzeszutek Wilk --- arch/s390/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 8ac710de1ab1..07bbee9b7320 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -186,9 +186,9 @@ static void pv_init(void) return; /* make sure bounce buffers are shared */ + swiotlb_force = SWIOTLB_FORCE; swiotlb_init(1); swiotlb_update_mem_attributes(); - swiotlb_force = SWIOTLB_FORCE; } void __init mem_init(void) -- cgit v1.2.3-70-g09d2 From 5af9f79b41b2ac58cc1d7c08945d7dbe26ee694a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 23 Jul 2021 17:33:24 -0700 Subject: Input: pm8941-pwrkey - fix comma vs semicolon issue There is absolutely no reason to use comma operator in this code, 2 separate statements make much more sense. Reviewed-by: Stephen Boyd Link: https://lore.kernel.org/r/YPsa1qCBn/SAmE5x@google.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/pm8941-pwrkey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c index 10e3fc0eac6e..33609603245d 100644 --- a/drivers/input/misc/pm8941-pwrkey.c +++ b/drivers/input/misc/pm8941-pwrkey.c @@ -284,7 +284,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev) } if (pwrkey->data->supports_ps_hold_poff_config) { - pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify, + pwrkey->reboot_notifier.notifier_call = pm8941_reboot_notify; error = register_reboot_notifier(&pwrkey->reboot_notifier); if (error) { dev_err(&pdev->dev, "failed to register reboot notifier: %d\n", -- cgit v1.2.3-70-g09d2 From 04647773d6481885447dc263673144053d3ec561 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 23 Jul 2021 17:34:07 -0700 Subject: dt-bindings: input: Convert ChipOne ICN8318 binding to a schema The ChipOne ICN8318 Touchscreen Controller is supported by Linux thanks to its device tree binding. Now that we have the DT validation in place, let's convert the device tree bindings for that driver over to a YAML schema. Signed-off-by: Maxime Ripard Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210721140424.725744-17-maxime@cerno.tech Signed-off-by: Dmitry Torokhov --- .../input/touchscreen/chipone,icn8318.yaml | 62 ++++++++++++++++++++++ .../bindings/input/touchscreen/chipone_icn8318.txt | 44 --------------- 2 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/chipone,icn8318.yaml delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt diff --git a/Documentation/devicetree/bindings/input/touchscreen/chipone,icn8318.yaml b/Documentation/devicetree/bindings/input/touchscreen/chipone,icn8318.yaml new file mode 100644 index 000000000000..9df685bdc5db --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/chipone,icn8318.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/chipone,icn8318.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ChipOne ICN8318 Touchscreen Controller Device Tree Bindings + +maintainers: + - Dmitry Torokhov + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: + const: chipone,icn8318 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + wake-gpios: + maxItems: 1 + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - wake-gpios + - touchscreen-size-x + - touchscreen-size-y + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@40 { + compatible = "chipone,icn8318"; + reg = <0x40>; + interrupt-parent = <&pio>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */ + pinctrl-names = "default"; + pinctrl-0 = <&ts_wake_pin_p66>; + wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */ + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-inverted-x; + touchscreen-swapped-x-y; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt b/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt deleted file mode 100644 index 38b0603f65f3..000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/chipone_icn8318.txt +++ /dev/null @@ -1,44 +0,0 @@ -* ChipOne icn8318 I2C touchscreen controller - -Required properties: - - compatible : "chipone,icn8318" - - reg : I2C slave address of the chip (0x40) - - interrupts : interrupt specification for the icn8318 interrupt - - wake-gpios : GPIO specification for the WAKE input - - touchscreen-size-x : horizontal resolution of touchscreen (in pixels) - - touchscreen-size-y : vertical resolution of touchscreen (in pixels) - -Optional properties: - - pinctrl-names : should be "default" - - pinctrl-0: : a phandle pointing to the pin settings for the - control gpios - - touchscreen-fuzz-x : horizontal noise value of the absolute input - device (in pixels) - - touchscreen-fuzz-y : vertical noise value of the absolute input - device (in pixels) - - touchscreen-inverted-x : X axis is inverted (boolean) - - touchscreen-inverted-y : Y axis is inverted (boolean) - - touchscreen-swapped-x-y : X and Y axis are swapped (boolean) - Swapping is done after inverting the axis - -Example: - -i2c@00000000 { - /* ... */ - - chipone_icn8318@40 { - compatible = "chipone,icn8318"; - reg = <0x40>; - interrupt-parent = <&pio>; - interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* EINT9 (PG9) */ - pinctrl-names = "default"; - pinctrl-0 = <&ts_wake_pin_p66>; - wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */ - touchscreen-size-x = <800>; - touchscreen-size-y = <480>; - touchscreen-inverted-x; - touchscreen-swapped-x-y; - }; - - /* ... */ -}; -- cgit v1.2.3-70-g09d2 From 187acd8c148a5f6ffed70776ca7f02efca0342fb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 23 Jul 2021 17:34:20 -0700 Subject: dt-bindings: input: Convert Pixcir Touchscreen binding to a schema The Pixcir Touchscreen Controller is supported by Linux thanks to its device tree binding. Now that we have the DT validation in place, let's convert the device tree bindings for that driver over to a YAML schema. Signed-off-by: Maxime Ripard Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210721140424.725744-18-maxime@cerno.tech Signed-off-by: Dmitry Torokhov --- .../input/touchscreen/pixcir,pixcir_ts.yaml | 68 ++++++++++++++++++++++ .../bindings/input/touchscreen/pixcir_i2c_ts.txt | 31 ---------- 2 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir,pixcir_ts.yaml delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir,pixcir_ts.yaml b/Documentation/devicetree/bindings/input/touchscreen/pixcir,pixcir_ts.yaml new file mode 100644 index 000000000000..f9998edbff70 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/pixcir,pixcir_ts.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/pixcir,pixcir_ts.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Pixcir Touchscreen Controller Device Tree Bindings + +maintainers: + - Dmitry Torokhov + +allOf: + - $ref: touchscreen.yaml# + +properties: + compatible: + enum: + - pixcir,pixcir_ts + - pixcir,pixcir_tangoc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + attb-gpio: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + enable-gpios: + maxItems: 1 + + wake-gpios: + maxItems: 1 + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - attb-gpio + - touchscreen-size-x + - touchscreen-size-y + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@5c { + compatible = "pixcir,pixcir_ts"; + reg = <0x5c>; + interrupts = <2 0>; + attb-gpio = <&gpf 2 0 2>; + touchscreen-size-x = <800>; + touchscreen-size-y = <600>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt deleted file mode 100644 index 697a3e7831e7..000000000000 --- a/Documentation/devicetree/bindings/input/touchscreen/pixcir_i2c_ts.txt +++ /dev/null @@ -1,31 +0,0 @@ -* Pixcir I2C touchscreen controllers - -Required properties: -- compatible: must be "pixcir,pixcir_ts" or "pixcir,pixcir_tangoc" -- reg: I2C address of the chip -- interrupts: interrupt to which the chip is connected -- attb-gpio: GPIO connected to the ATTB line of the chip -- touchscreen-size-x: horizontal resolution of touchscreen (in pixels) -- touchscreen-size-y: vertical resolution of touchscreen (in pixels) - -Optional properties: -- reset-gpios: GPIO connected to the RESET line of the chip -- enable-gpios: GPIO connected to the ENABLE line of the chip -- wake-gpios: GPIO connected to the WAKE line of the chip - -Example: - - i2c@00000000 { - /* ... */ - - pixcir_ts@5c { - compatible = "pixcir,pixcir_ts"; - reg = <0x5c>; - interrupts = <2 0>; - attb-gpio = <&gpf 2 0 2>; - touchscreen-size-x = <800>; - touchscreen-size-y = <600>; - }; - - /* ... */ - }; -- cgit v1.2.3-70-g09d2 From cc3d15a51717b8f5850444aa437bf5535e80d263 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 23 Jul 2021 17:34:36 -0700 Subject: dt-bindings: input: Convert Regulator Haptic binding to a schema The Haptic feedback based on a regulator is supported by Linux thanks to its device tree binding. Now that we have the DT validation in place, let's convert the device tree bindings for that driver over to a YAML schema. Signed-off-by: Maxime Ripard Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210721140424.725744-19-maxime@cerno.tech Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/regulator-haptic.txt | 21 ----------- .../bindings/input/regulator-haptic.yaml | 43 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 21 deletions(-) delete mode 100644 Documentation/devicetree/bindings/input/regulator-haptic.txt create mode 100644 Documentation/devicetree/bindings/input/regulator-haptic.yaml diff --git a/Documentation/devicetree/bindings/input/regulator-haptic.txt b/Documentation/devicetree/bindings/input/regulator-haptic.txt deleted file mode 100644 index 3ed1c7eb2f97..000000000000 --- a/Documentation/devicetree/bindings/input/regulator-haptic.txt +++ /dev/null @@ -1,21 +0,0 @@ -* Regulator Haptic Device Tree Bindings - -Required Properties: - - compatible : Should be "regulator-haptic" - - haptic-supply : Power supply to the haptic motor. - [*] refer Documentation/devicetree/bindings/regulator/regulator.txt - - - max-microvolt : The maximum voltage value supplied to the haptic motor. - [The unit of the voltage is a micro] - - - min-microvolt : The minimum voltage value supplied to the haptic motor. - [The unit of the voltage is a micro] - -Example: - - haptics { - compatible = "regulator-haptic"; - haptic-supply = <&motor_regulator>; - max-microvolt = <2700000>; - min-microvolt = <1100000>; - }; diff --git a/Documentation/devicetree/bindings/input/regulator-haptic.yaml b/Documentation/devicetree/bindings/input/regulator-haptic.yaml new file mode 100644 index 000000000000..b1ae72f9cd2d --- /dev/null +++ b/Documentation/devicetree/bindings/input/regulator-haptic.yaml @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/input/regulator-haptic.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Regulator Haptic Device Tree Bindings + +maintainers: + - Jaewon Kim + +properties: + compatible: + const: regulator-haptic + + haptic-supply: + description: > + Power supply to the haptic motor + + max-microvolt: + description: > + The maximum voltage value supplied to the haptic motor + + min-microvolt: + description: > + The minimum voltage value supplied to the haptic motor + +required: + - compatible + - haptic-supply + - max-microvolt + - min-microvolt + +additionalProperties: false + +examples: + - | + haptics { + compatible = "regulator-haptic"; + haptic-supply = <&motor_regulator>; + max-microvolt = <2700000>; + min-microvolt = <1100000>; + }; -- cgit v1.2.3-70-g09d2 From a5b84e4e4f57cceceb206fd8b1c828c81b7e63a6 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 23 Jul 2021 17:34:57 -0700 Subject: dt-bindings: input: sun4i-lradc: Add wakeup-source The LRADC can be a wakeup source and is listed as such in some DT already. Let's make sure we allow that property in the binding. Signed-off-by: Maxime Ripard Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210721140424.725744-21-maxime@cerno.tech Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml index cffd02028d02..d74f2002409e 100644 --- a/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml +++ b/Documentation/devicetree/bindings/input/allwinner,sun4i-a10-lradc-keys.yaml @@ -29,6 +29,8 @@ properties: description: Regulator for the LRADC reference voltage + wakeup-source: true + patternProperties: "^button-[0-9]+$": type: object -- cgit v1.2.3-70-g09d2 From 3e679dc78c17825a55e6f2cdb9078e375c945b15 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 16 Jul 2021 09:39:11 -0500 Subject: f2fs: make f2fs_write_failed() take struct inode Make f2fs_write_failed() take a 'struct inode' directly rather than a 'struct address_space', as this simplifies it slightly. Signed-off-by: Eric Biggers Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index ba120d55e9b1..1803c68fa269 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3178,9 +3178,8 @@ static int f2fs_write_data_pages(struct address_space *mapping, FS_CP_DATA_IO : FS_DATA_IO); } -static void f2fs_write_failed(struct address_space *mapping, loff_t to) +static void f2fs_write_failed(struct inode *inode, loff_t to) { - struct inode *inode = mapping->host; loff_t i_size = i_size_read(inode); if (IS_NOQUOTA(inode)) @@ -3412,7 +3411,7 @@ repeat: fail: f2fs_put_page(page, 1); - f2fs_write_failed(mapping, pos + len); + f2fs_write_failed(inode, pos + len); if (drop_atomic) f2fs_drop_inmem_pages_all(sbi, false); return err; @@ -3602,7 +3601,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) f2fs_update_iostat(F2FS_I_SB(inode), APP_DIRECT_IO, count - iov_iter_count(iter)); } else if (err < 0) { - f2fs_write_failed(mapping, offset + count); + f2fs_write_failed(inode, offset + count); } } else { if (err > 0) -- cgit v1.2.3-70-g09d2 From 6de8687ccdefed40d617492f4e1b3962eb577b6b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 16 Jul 2021 09:39:12 -0500 Subject: f2fs: remove allow_outplace_dio() We can just check f2fs_lfs_mode() directly. The block_unaligned_IO() check is redundant because in LFS mode, f2fs doesn't do direct I/O writes that aren't block-aligned (due to f2fs_force_buffered_io() returning true in this case, triggering the fallback to buffered I/O). Signed-off-by: Eric Biggers Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 2 +- fs/f2fs/f2fs.h | 10 ---------- fs/f2fs/file.c | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 1803c68fa269..28ad1f533c2a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3553,7 +3553,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if (f2fs_force_buffered_io(inode, iocb, iter)) return 0; - do_opu = allow_outplace_dio(inode, iocb, iter); + do_opu = rw == WRITE && f2fs_lfs_mode(sbi); trace_f2fs_direct_IO_enter(inode, offset, count, rw); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 867f2c5d9559..8459b6d5a2f8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4311,16 +4311,6 @@ static inline int block_unaligned_IO(struct inode *inode, return align & blocksize_mask; } -static inline int allow_outplace_dio(struct inode *inode, - struct kiocb *iocb, struct iov_iter *iter) -{ - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - int rw = iov_iter_rw(iter); - - return (f2fs_lfs_mode(sbi) && (rw == WRITE) && - !block_unaligned_IO(inode, iocb, iter)); -} - static inline bool f2fs_force_buffered_io(struct inode *inode, struct kiocb *iocb, struct iov_iter *iter) { diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 6afd4562335f..b1cb5b50faac 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -4292,7 +4292,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) * back to buffered IO. */ if (!f2fs_force_buffered_io(inode, iocb, from) && - allow_outplace_dio(inode, iocb, from)) + f2fs_lfs_mode(F2FS_I_SB(inode))) goto write; } preallocated = true; -- cgit v1.2.3-70-g09d2 From 2eeb0dce728a7eac3e4dfe355d98af40d61f7a26 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 22 Jul 2021 10:30:58 -0700 Subject: f2fs: don't sleep while grabing nat_tree_lock This tries to fix priority inversion in the below condition resulting in long checkpoint delay. f2fs_get_node_info() - nat_tree_lock -> sleep to grab journal_rwsem by contention checkpoint - waiting for nat_tree_lock In order to let checkpoint go, let's release nat_tree_lock, if there's a journal_rwsem contention. Signed-off-by: Daeho Jeong Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 0be9e2d7120e..c945a9730f3c 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -552,7 +552,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, int i; ni->nid = nid; - +retry: /* Check nat cache */ down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); @@ -564,10 +564,19 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, return 0; } - memset(&ne, 0, sizeof(struct f2fs_nat_entry)); + /* + * Check current segment summary by trying to grab journal_rwsem first. + * This sem is on the critical path on the checkpoint requiring the above + * nat_tree_lock. Therefore, we should retry, if we failed to grab here + * while not bothering checkpoint. + */ + if (!rwsem_is_locked(&sbi->cp_global_sem)) { + down_read(&curseg->journal_rwsem); + } else if (!down_read_trylock(&curseg->journal_rwsem)) { + up_read(&nm_i->nat_tree_lock); + goto retry; + } - /* Check current segment summary */ - down_read(&curseg->journal_rwsem); i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0); if (i >= 0) { ne = nat_in_journal(journal, i); -- cgit v1.2.3-70-g09d2 From 0a03801ca8bddfbf634d3b42d57a0864d6b3c1ec Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Sat, 24 Jul 2021 21:06:11 +0800 Subject: docs/zh_CN: reformat zh_CN/dev-tools/testing-overview Reorganise several long lines in order to satisfy the kernel coding style. Signed-off-by: Hu Haowen Reviewed-by: Yanteng Si Link: https://lore.kernel.org/r/20210724130611.4231-1-src.res@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/dev-tools/testing-overview.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Documentation/translations/zh_CN/dev-tools/testing-overview.rst b/Documentation/translations/zh_CN/dev-tools/testing-overview.rst index 8206d5b477e2..b7a1d13da6c6 100644 --- a/Documentation/translations/zh_CN/dev-tools/testing-overview.rst +++ b/Documentation/translations/zh_CN/dev-tools/testing-overview.rst @@ -70,13 +70,14 @@ kselftest也因此非常适合于全部功能的测试,因为这些功能会 确切函数或代码行。这有助于决定内核被测试了多少,或用来查找合适的测试 中没有覆盖到的极端情况。 -Documentation/translations/zh_CN/dev-tools/gcov.rst 是GCC的覆盖率测试工具,能用于获取内核的全局或每个模块的 -覆盖率。与KCOV不同的是,这个工具不记录每个任务的覆盖率。覆盖率数据可 -以通过debugfs读取,并通过常规的gcov工具进行解释。 - -Documentation/dev-tools/kcov.rst 是能够构建在内核之中,用于在每个任务的层面捕捉覆盖率的一 -个功能。因此,它对于模糊测试和关于代码执行期间信息的其它情况非常有用, -比如在一个单一系统调用里使用它就很有用。 +Documentation/translations/zh_CN/dev-tools/gcov.rst 是GCC的覆盖率测试 +工具,能用于获取内核的全局或每个模块的覆盖率。与KCOV不同的是,这个工具 +不记录每个任务的覆盖率。覆盖率数据可以通过debugfs读取,并通过常规的 +gcov工具进行解释。 + +Documentation/dev-tools/kcov.rst 是能够构建在内核之中,用于在每个任务 +的层面捕捉覆盖率的一个功能。因此,它对于模糊测试和关于代码执行期间信 +息的其它情况非常有用,比如在一个单一系统调用里使用它就很有用。 动态分析工具 ============ -- cgit v1.2.3-70-g09d2 From 6ab0493dfc6255a99eb5f157e012eeafd75f5b56 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 23 Jul 2021 13:05:26 -0700 Subject: deprecated.rst: Include details on "no_hash_pointers" Linus decided a debug toggle for %p was tolerable, so update the %p deprecation documentation. Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20210723200526.3424128-1-keescook@chromium.org Signed-off-by: Jonathan Corbet --- Documentation/process/deprecated.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst index 9d83b8db8874..8ced754a5a0f 100644 --- a/Documentation/process/deprecated.rst +++ b/Documentation/process/deprecated.rst @@ -164,7 +164,9 @@ Paraphrasing Linus's current `guidance `_. +If you are debugging something where "%p" hashing is causing problems, +you can temporarily boot with the debug flag "`no_hash_pointers +`_". Variable Length Arrays (VLAs) ----------------------------- -- cgit v1.2.3-70-g09d2 From 5b42d0bfb73d21bc31917c4fcab4def8a398aa0d Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 22 Jul 2021 13:03:53 +0300 Subject: docs: printk-formats: fix build warning Add an empty line after the '::' starting the code block so that the following lines are properly interpreted. Without this, the following build warnings are visible. Documentation/core-api/printk-formats.rst:136: WARNING: Unexpected indentation. Documentation/core-api/printk-formats.rst:137: WARNING: Block quote ends without a blank line; unexpected unindent. Fixes: 9294523e3768 ("module: add printk formats to add module build ID to stacktraces") Signed-off-by: Ioana Ciornei Reviewed-by: Stephen Boyd Acked-by: Petr Mladek Link: https://lore.kernel.org/r/20210722100356.635078-2-ciorneiioana@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/core-api/printk-formats.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index d941717a191b..e08bbe9b0cbf 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -130,6 +130,7 @@ printed after the symbol name with an extra ``b`` appended to the end of the specifier. :: + %pS versatile_init+0x0/0x110 [module_name] %pSb versatile_init+0x0/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e] %pSRb versatile_init+0x9/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e] -- cgit v1.2.3-70-g09d2 From 8b9671643d2f6f567669aa54f15b8a2791d324d5 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 22 Jul 2021 13:03:54 +0300 Subject: docs: kvm: fix build warnings Fix some small build warnings. The title underline was too short in some cases and a code block was not indented. Documentation/virt/kvm/api.rst:7216: WARNING: Title underline too short. Fixes: 6dba94035203 ("KVM: x86: Introduce KVM_GET_SREGS2 / KVM_SET_SREGS2") Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20210722100356.635078-3-ciorneiioana@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/virt/kvm/api.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index c7b165ca70b6..535ac0efd1b0 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5077,7 +5077,7 @@ of bytes successfully copied is returned. If the call completes successfully then ``length`` is returned. 4.131 KVM_GET_SREGS2 ------------------- +-------------------- :Capability: KVM_CAP_SREGS2 :Architectures: x86 @@ -5090,17 +5090,17 @@ This ioctl (when supported) replaces the KVM_GET_SREGS. :: -struct kvm_sregs2 { - /* out (KVM_GET_SREGS2) / in (KVM_SET_SREGS2) */ - struct kvm_segment cs, ds, es, fs, gs, ss; - struct kvm_segment tr, ldt; - struct kvm_dtable gdt, idt; - __u64 cr0, cr2, cr3, cr4, cr8; - __u64 efer; - __u64 apic_base; - __u64 flags; - __u64 pdptrs[4]; -}; + struct kvm_sregs2 { + /* out (KVM_GET_SREGS2) / in (KVM_SET_SREGS2) */ + struct kvm_segment cs, ds, es, fs, gs, ss; + struct kvm_segment tr, ldt; + struct kvm_dtable gdt, idt; + __u64 cr0, cr2, cr3, cr4, cr8; + __u64 efer; + __u64 apic_base; + __u64 flags; + __u64 pdptrs[4]; + }; flags values for ``kvm_sregs2``: @@ -5110,7 +5110,7 @@ flags values for ``kvm_sregs2``: 4.132 KVM_SET_SREGS2 ------------------- +-------------------- :Capability: KVM_CAP_SREGS2 :Architectures: x86 @@ -7213,7 +7213,7 @@ supported in the host. A VMM can check whether the service is available to the guest on migration. 8.33 KVM_CAP_HYPERV_ENFORCE_CPUID ------------------------------ +--------------------------------- Architectures: x86 -- cgit v1.2.3-70-g09d2 From a9fd134be7b94622fe487ae6db48bf9514ad1a53 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 22 Jul 2021 13:03:55 +0300 Subject: docs: kvm: properly format code blocks and lists Add a '::' so that a code block is interpreted properly and also add a blank line before the start of a list. Fixes: fdc09ddd4064 ("KVM: stats: Add documentation for binary statistics interface") Signed-off-by: Ioana Ciornei Reviewed-by: Jing Zhang Link: https://lore.kernel.org/r/20210722100356.635078-4-ciorneiioana@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/virt/kvm/api.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 535ac0efd1b0..c8225466f379 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5201,6 +5201,7 @@ trailing ``'\0'``, is indicated by the ``name_size`` field in the header. The descriptors block is only needed to be read once for the lifetime of the file descriptor contains a sequence of ``struct kvm_stats_desc``, each followed by a string of size ``name_size``. +:: #define KVM_STATS_TYPE_SHIFT 0 #define KVM_STATS_TYPE_MASK (0xF << KVM_STATS_TYPE_SHIFT) @@ -5234,6 +5235,7 @@ by this descriptor. Its endianness is CPU native. The following flags are supported: Bits 0-3 of ``flags`` encode the type: + * ``KVM_STATS_TYPE_CUMULATIVE`` The statistics data is cumulative. The value of data can only be increased. Most of the counters used in KVM are of this type. @@ -5252,6 +5254,7 @@ Bits 0-3 of ``flags`` encode the type: The corresponding ``size`` field for this type is always 1. Bits 4-7 of ``flags`` encode the unit: + * ``KVM_STATS_UNIT_NONE`` There is no unit for the value of statistics data. This usually means that the value is a simple counter of an event. @@ -5266,6 +5269,7 @@ Bits 4-7 of ``flags`` encode the unit: Bits 8-11 of ``flags``, together with ``exponent``, encode the scale of the unit: + * ``KVM_STATS_BASE_POW10`` The scale is based on power of 10. It is used for measurement of time and CPU clock cycles. For example, an exponent of -9 can be used with -- cgit v1.2.3-70-g09d2 From 662fa3d6099374c4615bf64d06895e3573b935b2 Mon Sep 17 00:00:00 2001 From: Ioana Ciornei Date: Thu, 22 Jul 2021 13:03:56 +0300 Subject: docs: networking: dpaa2: fix chapter title format Fix the DPAA2 DPIO driver chapter title by adding the necessary overline. Without this, the index page of the DPAA2 documentation doesn't display properly. Fixes: d8e516bac73f ("soc: fsl: dpio: Convert DPIO documentation to .rst") Signed-off-by: Ioana Ciornei Link: https://lore.kernel.org/r/20210722100356.635078-5-ciorneiioana@gmail.com Signed-off-by: Jonathan Corbet --- .../networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver.rst b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver.rst index c50fd46631e0..e4ebfe62a183 100644 --- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver.rst +++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver.rst @@ -1,5 +1,6 @@ .. include:: +=================================== DPAA2 DPIO (Data Path I/O) Overview =================================== -- cgit v1.2.3-70-g09d2 From f3fd34fe0e71cb58ffa16d26fc887c6eb73fb1c0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Jul 2021 11:50:01 +0200 Subject: docs: sound: kernel-api: writing-an-alsa-driver.rst: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+00a0 (' '): NO-BREAK SPACE as it can cause lines being truncated on PDF output Reviewed-by: Takashi Iwai Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/21abe5fa495a05ac1f998ed66184a77e19ac89cc.1626947264.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/sound/kernel-api/writing-an-alsa-driver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst index 01d59b8aea92..6da9c887a48b 100644 --- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst +++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst @@ -3368,7 +3368,7 @@ This ensures that the device can be closed and the driver unloaded without losing data. This callback is optional. If you do not set ``drain`` in the struct -snd_rawmidi_ops structure, ALSA will simply wait for 50 milliseconds +snd_rawmidi_ops structure, ALSA will simply wait for 50 milliseconds instead. Miscellaneous Devices -- cgit v1.2.3-70-g09d2 From dc9c31c3ffc803b5362ca9d6ff1426ccb738f77e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Jul 2021 11:50:02 +0200 Subject: docs: firmware-guide: acpi: dsd: graph.rst: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+00a0 (' '): NO-BREAK SPACE as it can cause lines being truncated on PDF output Acked-by: Rafael J. Wysocki Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/a65b04a5cf341cff02d4b514dd4889b4fa4f94b8.1626947264.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/firmware-guide/acpi/dsd/graph.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/firmware-guide/acpi/dsd/graph.rst b/Documentation/firmware-guide/acpi/dsd/graph.rst index 4341299aa937..0ced07cb1be3 100644 --- a/Documentation/firmware-guide/acpi/dsd/graph.rst +++ b/Documentation/firmware-guide/acpi/dsd/graph.rst @@ -159,7 +159,7 @@ References [2] Devicetree. https://www.devicetree.org, referenced 2016-10-03. -[3] Documentation/devicetree/bindings/graph.txt +[3] Documentation/devicetree/bindings/graph.txt [4] Device Properties UUID For _DSD. https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf, -- cgit v1.2.3-70-g09d2 From b426d9d78efb39800dabaed447a0bfc959038930 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Jul 2021 11:50:03 +0200 Subject: docs: virt: kvm: api.rst: replace some characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conversion tools used during DocBook/LaTeX/html/Markdown->ReST conversion and some cut-and-pasted text contain some characters that aren't easily reachable on standard keyboards and/or could cause troubles when parsed by the documentation build system. Replace the occurences of the following characters: - U+00a0 (' '): NO-BREAK SPACE as it can cause lines being truncated on PDF output Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/ff70cb42d63f3a1da66af1b21b8d038418ed5189.1626947264.git.mchehab+huawei@kernel.org Signed-off-by: Jonathan Corbet --- Documentation/virt/kvm/api.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index c8225466f379..7152268c580d 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -855,7 +855,7 @@ in-kernel irqchip (GIC), and for in-kernel irqchip can tell the GIC to use PPIs designated for specific cpus. The irq field is interpreted like this:: -  bits: | 31 ... 28 | 27 ... 24 | 23 ... 16 | 15 ... 0 | + bits: | 31 ... 28 | 27 ... 24 | 23 ... 16 | 15 ... 0 | field: | vcpu2_index | irq_type | vcpu_index | irq_id | The irq_type field has the following values: @@ -2149,10 +2149,10 @@ prior to calling the KVM_RUN ioctl. Errors: ====== ============================================================ -  ENOENT   no such register -  EINVAL   invalid register ID, or no such register or used with VMs in + ENOENT no such register + EINVAL invalid register ID, or no such register or used with VMs in protected virtualization mode on s390 -  EPERM    (arm64) register access not allowed before vcpu finalization + EPERM (arm64) register access not allowed before vcpu finalization ====== ============================================================ (These error codes are indicative only: do not rely on a specific error @@ -2590,10 +2590,10 @@ following id bit patterns:: Errors include: ======== ============================================================ -  ENOENT   no such register -  EINVAL   invalid register ID, or no such register or used with VMs in + ENOENT no such register + EINVAL invalid register ID, or no such register or used with VMs in protected virtualization mode on s390 -  EPERM    (arm64) register access not allowed before vcpu finalization + EPERM (arm64) register access not allowed before vcpu finalization ======== ============================================================ (These error codes are indicative only: do not rely on a specific error @@ -3112,13 +3112,13 @@ current state. "addr" is ignored. Errors: ====== ================================================================= -  EINVAL    the target is unknown, or the combination of features is invalid. -  ENOENT    a features bit specified is unknown. + EINVAL the target is unknown, or the combination of features is invalid. + ENOENT a features bit specified is unknown. ====== ================================================================= This tells KVM what type of CPU to present to the guest, and what -optional features it should have.  This will cause a reset of the cpu -registers to their initial values.  If this is not called, KVM_RUN will +optional features it should have. This will cause a reset of the cpu +registers to their initial values. If this is not called, KVM_RUN will return ENOEXEC for that vcpu. The initial values are defined as: @@ -3239,8 +3239,8 @@ VCPU matching underlying host. Errors: ===== ============================================================== -  E2BIG     the reg index list is too big to fit in the array specified by -             the user (the number required will be written into n). + E2BIG the reg index list is too big to fit in the array specified by + the user (the number required will be written into n). ===== ============================================================== :: @@ -3288,7 +3288,7 @@ specific device. ARM/arm64 divides the id field into two parts, a device id and an address type id specific to the individual device:: -  bits: | 63 ... 32 | 31 ... 16 | 15 ... 0 | + bits: | 63 ... 32 | 31 ... 16 | 15 ... 0 | field: | 0x00000000 | device id | addr type id | ARM/arm64 currently only require this when using the in-kernel GIC -- cgit v1.2.3-70-g09d2 From ce48ee81a1930b2218bea23490adb6673c88bf70 Mon Sep 17 00:00:00 2001 From: "Fabio M. De Francesco" Date: Wed, 21 Jul 2021 21:02:50 +0200 Subject: admin-guide/hw-vuln: Rephrase a section of core-scheduling.rst Rephrase the "For MDS" section in core-scheduling.rst for the purpose of making it clearer what is meant by "kernel memory is still considered untrusted". Suggested-by: Vineeth Pillai Signed-off-by: Fabio M. De Francesco Reviewed-by: Joel Fernandes (Google) Link: https://lore.kernel.org/r/20210721190250.26095-1-fmdefrancesco@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/hw-vuln/core-scheduling.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/admin-guide/hw-vuln/core-scheduling.rst b/Documentation/admin-guide/hw-vuln/core-scheduling.rst index 7b410aef9c5c..0febe458597c 100644 --- a/Documentation/admin-guide/hw-vuln/core-scheduling.rst +++ b/Documentation/admin-guide/hw-vuln/core-scheduling.rst @@ -181,10 +181,12 @@ Open cross-HT issues that core scheduling does not solve -------------------------------------------------------- 1. For MDS ~~~~~~~~~~ -Core scheduling cannot protect against MDS attacks between an HT running in -user mode and another running in kernel mode. Even though both HTs run tasks -which trust each other, kernel memory is still considered untrusted. Such -attacks are possible for any combination of sibling CPU modes (host or guest mode). +Core scheduling cannot protect against MDS attacks between the siblings +running in user mode and the others running in kernel mode. Even though all +siblings run tasks which trust each other, when the kernel is executing +code on behalf of a task, it cannot trust the code running in the +sibling. Such attacks are possible for any combination of sibling CPU modes +(host or guest mode). 2. For L1TF ~~~~~~~~~~~ -- cgit v1.2.3-70-g09d2 From d5caec394a78617cbc0eea0870da22aa019c346d Mon Sep 17 00:00:00 2001 From: Yang Xu Date: Wed, 23 Jun 2021 09:37:48 +0800 Subject: admin-guide/cputopology.rst: Remove non-existed cpu-hotplug.txt Since kernel commit ff58fa7f556c ("Documentation: Update CPU hotplug and move it to core-api"), cpu_hotplug.txt has been removed. We should update it in here. Signed-off-by: Yang Xu Link: https://lore.kernel.org/r/1624412269-13155-1-git-send-email-xuyang2018.jy@fujitsu.com Signed-off-by: Jonathan Corbet --- Documentation/admin-guide/cputopology.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/cputopology.rst b/Documentation/admin-guide/cputopology.rst index 8632a1db36e4..b085dbac60a5 100644 --- a/Documentation/admin-guide/cputopology.rst +++ b/Documentation/admin-guide/cputopology.rst @@ -58,9 +58,9 @@ source for the output is in brackets ("[]"). [NR_CPUS-1] offline: CPUs that are not online because they have been - HOTPLUGGED off (see cpu-hotplug.txt) or exceed the limit - of CPUs allowed by the kernel configuration (kernel_max - above). [~cpu_online_mask + cpus >= NR_CPUS] + HOTPLUGGED off or exceed the limit of CPUs allowed by the + kernel configuration (kernel_max above). + [~cpu_online_mask + cpus >= NR_CPUS] online: CPUs that are online and being scheduled [cpu_online_mask] @@ -96,5 +96,5 @@ online.):: possible: 0-127 present: 0-3 -See cpu-hotplug.txt for the possible_cpus=NUM kernel start parameter -as well as more information on the various cpumasks. +See Documentation/core-api/cpu_hotplug.rst for the possible_cpus=NUM +kernel start parameter as well as more information on the various cpumasks. -- cgit v1.2.3-70-g09d2 From 77167b966b7e671d8ab308b1e31ebfed97986402 Mon Sep 17 00:00:00 2001 From: Hannu Hartikainen Date: Wed, 7 Jul 2021 16:36:35 +0300 Subject: docs: submitting-patches: clarify the role of LKML The documentation previously stated that LKML should be used as *last resort*. However, scripts/get_maintainer.pl always suggests it and in a discussion about changing that[0] it turned out that LKML should in fact receive all patches. Update documentation to make it clear that all patches should be sent to LKML by default, in addition to any subsystem-specific lists. [0]: https://lore.kernel.org/lkml/19a701a8d5837088aa7d8ba594c228c0e040e747.camel@perches.com/ Signed-off-by: Hannu Hartikainen Link: https://lore.kernel.org/r/20210707133634.286840-1-hannu@hrtk.in Signed-off-by: Jonathan Corbet --- Documentation/process/submitting-patches.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 0852bcf73630..8ad6b93f91e6 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -216,11 +216,11 @@ cannot find a maintainer for the subsystem you are working on, Andrew Morton (akpm@linux-foundation.org) serves as a maintainer of last resort. You should also normally choose at least one mailing list to receive a copy -of your patch set. linux-kernel@vger.kernel.org functions as a list of -last resort, but the volume on that list has caused a number of developers -to tune it out. Look in the MAINTAINERS file for a subsystem-specific -list; your patch will probably get more attention there. Please do not -spam unrelated lists, though. +of your patch set. linux-kernel@vger.kernel.org should be used by default +for all patches, but the volume on that list has caused a number of +developers to tune it out. Look in the MAINTAINERS file for a +subsystem-specific list; your patch will probably get more attention there. +Please do not spam unrelated lists, though. Many kernel-related lists are hosted on vger.kernel.org; you can find a list of them at http://vger.kernel.org/vger-lists.html. There are -- cgit v1.2.3-70-g09d2 From 4a52225d61017c0cb9133b624d5790bf86abf608 Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Tue, 8 Jun 2021 15:52:07 +0800 Subject: docs/zh_CN: add a translation for index The original file has added a former intro in commit b51208d41c6a4e7fc2f0 ("docs: Tweak the top-level Sphinx page") and hence update the Chinese version for it. Signed-off-by: Hu Haowen Link: https://lore.kernel.org/r/20210608075207.77812-1-src.res@email.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst index 1f953d3439a5..e0d51a167032 100644 --- a/Documentation/translations/zh_CN/index.rst +++ b/Documentation/translations/zh_CN/index.rst @@ -17,6 +17,11 @@ **翻译计划:** 内核中文文档欢迎任何翻译投稿,特别是关于内核用户和管理员指南部分。 +这是中文内核文档树的顶级目录。内核文档,就像内核本身一样,在很大程度上是一 +项正在进行的工作;当我们努力将许多分散的文件整合成一个连贯的整体时尤其如此。 +另外,随时欢迎您对内核文档进行改进;如果您想提供帮助,请加入vger.kernel.org +上的linux-doc邮件列表。 + 许可证文档 ---------- -- cgit v1.2.3-70-g09d2 From 374c15594c4ee0dfcceb38852bd43be09070f402 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:42 -0700 Subject: iommu/io-pgtable: Introduce unmap_pages() as a page table op The io-pgtable code expects to operate on a single block or granule of memory that is supported by the IOMMU hardware when unmapping memory. This means that when a large buffer that consists of multiple such blocks is unmapped, the io-pgtable code will walk the page tables to the correct level to unmap each block, even for blocks that are virtually contiguous and at the same level, which can incur an overhead in performance. Introduce the unmap_pages() page table op to express to the io-pgtable code that it should unmap a number of blocks of the same size, instead of a single block. Doing so allows multiple blocks to be unmapped in one call to the io-pgtable code, reducing the number of page table walks, and indirect calls. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Will Deacon Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-2-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- include/linux/io-pgtable.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 4d40dfa75b55..9391c5fa71e6 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -144,6 +144,7 @@ struct io_pgtable_cfg { * * @map: Map a physically contiguous memory region. * @unmap: Unmap a physically contiguous memory region. + * @unmap_pages: Unmap a range of virtually contiguous pages of the same size. * @iova_to_phys: Translate iova to physical address. * * These functions map directly onto the iommu_ops member functions with @@ -154,6 +155,9 @@ struct io_pgtable_ops { phys_addr_t paddr, size_t size, int prot, gfp_t gfp); size_t (*unmap)(struct io_pgtable_ops *ops, unsigned long iova, size_t size, struct iommu_iotlb_gather *gather); + size_t (*unmap_pages)(struct io_pgtable_ops *ops, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather); phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops, unsigned long iova); }; -- cgit v1.2.3-70-g09d2 From cacffb7f7b45ba7649eedea4c196c6e9f1863bf3 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:43 -0700 Subject: iommu: Add an unmap_pages() op for IOMMU drivers Add a callback for IOMMU drivers to provide a path for the IOMMU framework to call into an IOMMU driver, which can call into the io-pgtable code, to unmap a virtually contiguous range of pages of the same size. For IOMMU drivers that do not specify an unmap_pages() callback, the existing logic of unmapping memory one page block at a time will be used. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Will Deacon Acked-by: Lu Baolu Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-3-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- include/linux/iommu.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 32d448050bf7..25a844121be5 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -181,6 +181,7 @@ struct iommu_iotlb_gather { * @detach_dev: detach device from an iommu domain * @map: map a physically contiguous memory region to an iommu domain * @unmap: unmap a physically contiguous memory region from an iommu domain + * @unmap_pages: unmap a number of pages of the same size from an iommu domain * @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain * @iotlb_sync_map: Sync mappings created recently using @map to the hardware * @iotlb_sync: Flush all queued ranges from the hardware TLBs and empty flush @@ -231,6 +232,9 @@ struct iommu_ops { phys_addr_t paddr, size_t size, int prot, gfp_t gfp); size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather); + size_t (*unmap_pages)(struct iommu_domain *domain, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *iotlb_gather); void (*flush_iotlb_all)(struct iommu_domain *domain); void (*iotlb_sync_map)(struct iommu_domain *domain, unsigned long iova, size_t size); -- cgit v1.2.3-70-g09d2 From ca073b55d16a83ba7e73cd313312abc68f07f293 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:44 -0700 Subject: iommu/io-pgtable: Introduce map_pages() as a page table op Mapping memory into io-pgtables follows the same semantics that unmapping memory used to follow (i.e. a buffer will be mapped one page block per call to the io-pgtable code). This means that it can be optimized in the same way that unmapping memory was, so add a map_pages() callback to the io-pgtable ops structure, so that a range of pages of the same size can be mapped within the same call. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-4-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- include/linux/io-pgtable.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 9391c5fa71e6..c43f3b899d2a 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -143,6 +143,7 @@ struct io_pgtable_cfg { * struct io_pgtable_ops - Page table manipulation API for IOMMU drivers. * * @map: Map a physically contiguous memory region. + * @map_pages: Map a physically contiguous range of pages of the same size. * @unmap: Unmap a physically contiguous memory region. * @unmap_pages: Unmap a range of virtually contiguous pages of the same size. * @iova_to_phys: Translate iova to physical address. @@ -153,6 +154,9 @@ struct io_pgtable_cfg { struct io_pgtable_ops { int (*map)(struct io_pgtable_ops *ops, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp); + int (*map_pages)(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped); size_t (*unmap)(struct io_pgtable_ops *ops, unsigned long iova, size_t size, struct iommu_iotlb_gather *gather); size_t (*unmap_pages)(struct io_pgtable_ops *ops, unsigned long iova, -- cgit v1.2.3-70-g09d2 From 910c4406ccc9613de0a54abf910edc4bf8a575c0 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:45 -0700 Subject: iommu: Add a map_pages() op for IOMMU drivers Add a callback for IOMMU drivers to provide a path for the IOMMU framework to call into an IOMMU driver, which can call into the io-pgtable code, to map a physically contiguous rnage of pages of the same size. For IOMMU drivers that do not specify a map_pages() callback, the existing logic of mapping memory one page block at a time will be used. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Acked-by: Lu Baolu Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-5-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- include/linux/iommu.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 25a844121be5..d7989d4a7404 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -180,6 +180,8 @@ struct iommu_iotlb_gather { * @attach_dev: attach device to an iommu domain * @detach_dev: detach device from an iommu domain * @map: map a physically contiguous memory region to an iommu domain + * @map_pages: map a physically contiguous set of pages of the same size to + * an iommu domain. * @unmap: unmap a physically contiguous memory region from an iommu domain * @unmap_pages: unmap a number of pages of the same size from an iommu domain * @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain @@ -230,6 +232,9 @@ struct iommu_ops { void (*detach_dev)(struct iommu_domain *domain, struct device *dev); int (*map)(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp); + int (*map_pages)(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped); size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather); size_t (*unmap_pages)(struct iommu_domain *domain, unsigned long iova, -- cgit v1.2.3-70-g09d2 From e7d6fff6b3d34230bac1b2c2607646d7b8638cb7 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 16 Jun 2021 06:38:46 -0700 Subject: iommu: Use bitmap to calculate page size in iommu_pgsize() Avoid the potential for shifting values by amounts greater than the width of their type by using a bitmap to compute page size in iommu_pgsize(). Signed-off-by: Will Deacon Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1623850736-389584-6-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 5419c4b9f27a..80e471ada358 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -2378,30 +2379,22 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long addr_merge, size_t size) { unsigned int pgsize_idx; + unsigned long pgsizes; size_t pgsize; - /* Max page size that still fits into 'size' */ - pgsize_idx = __fls(size); + /* Page sizes supported by the hardware and small enough for @size */ + pgsizes = domain->pgsize_bitmap & GENMASK(__fls(size), 0); - /* need to consider alignment requirements ? */ - if (likely(addr_merge)) { - /* Max page size allowed by address */ - unsigned int align_pgsize_idx = __ffs(addr_merge); - pgsize_idx = min(pgsize_idx, align_pgsize_idx); - } - - /* build a mask of acceptable page sizes */ - pgsize = (1UL << (pgsize_idx + 1)) - 1; - - /* throw away page sizes not supported by the hardware */ - pgsize &= domain->pgsize_bitmap; + /* Constrain the page sizes further based on the maximum alignment */ + if (likely(addr_merge)) + pgsizes &= GENMASK(__ffs(addr_merge), 0); - /* make sure we're still sane */ - BUG_ON(!pgsize); + /* Make sure we have at least one suitable page size */ + BUG_ON(!pgsizes); - /* pick the biggest page */ - pgsize_idx = __fls(pgsize); - pgsize = 1UL << pgsize_idx; + /* Pick the biggest page size remaining */ + pgsize_idx = __fls(pgsizes); + pgsize = BIT(pgsize_idx); return pgsize; } -- cgit v1.2.3-70-g09d2 From 89d5b9601f70b72f524fdb7bc6cf1b1e8e20e867 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 16 Jun 2021 06:38:47 -0700 Subject: iommu: Split 'addr_merge' argument to iommu_pgsize() into separate parts The 'addr_merge' parameter to iommu_pgsize() is a fabricated address intended to describe the alignment requirements to consider when choosing an appropriate page size. On the iommu_map() path, this address is the logical OR of the virtual and physical addresses. Subsequent improvements to iommu_pgsize() will need to check the alignment of the virtual and physical components of 'addr_merge' independently, so pass them in as separate parameters and reconstruct 'addr_merge' locally. No functional change. Signed-off-by: Will Deacon Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1623850736-389584-7-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 80e471ada358..80e14c139d40 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2375,12 +2375,13 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) } EXPORT_SYMBOL_GPL(iommu_iova_to_phys); -static size_t iommu_pgsize(struct iommu_domain *domain, - unsigned long addr_merge, size_t size) +static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size) { unsigned int pgsize_idx; unsigned long pgsizes; size_t pgsize; + unsigned long addr_merge = paddr | iova; /* Page sizes supported by the hardware and small enough for @size */ pgsizes = domain->pgsize_bitmap & GENMASK(__fls(size), 0); @@ -2433,7 +2434,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, pr_debug("map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); while (size) { - size_t pgsize = iommu_pgsize(domain, iova | paddr, size); + size_t pgsize = iommu_pgsize(domain, iova, paddr, size); pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", iova, &paddr, pgsize); @@ -2521,8 +2522,9 @@ static size_t __iommu_unmap(struct iommu_domain *domain, * or we hit an area that isn't mapped. */ while (unmapped < size) { - size_t pgsize = iommu_pgsize(domain, iova, size - unmapped); + size_t pgsize; + pgsize = iommu_pgsize(domain, iova, iova, size - unmapped); unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather); if (!unmapped_page) break; -- cgit v1.2.3-70-g09d2 From b1d99dc5f983b4ae8ab9841981c5dbd5530f6344 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 16 Jun 2021 06:38:48 -0700 Subject: iommu: Hook up '->unmap_pages' driver callback Extend iommu_pgsize() to populate an optional 'count' parameter so that we can direct unmapping operation to the ->unmap_pages callback if it has been provided by the driver. Signed-off-by: Will Deacon Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1623850736-389584-8-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 59 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 80e14c139d40..725622c7e603 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2376,11 +2376,11 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) EXPORT_SYMBOL_GPL(iommu_iova_to_phys); static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size) + phys_addr_t paddr, size_t size, size_t *count) { - unsigned int pgsize_idx; + unsigned int pgsize_idx, pgsize_idx_next; unsigned long pgsizes; - size_t pgsize; + size_t offset, pgsize, pgsize_next; unsigned long addr_merge = paddr | iova; /* Page sizes supported by the hardware and small enough for @size */ @@ -2396,7 +2396,36 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova, /* Pick the biggest page size remaining */ pgsize_idx = __fls(pgsizes); pgsize = BIT(pgsize_idx); + if (!count) + return pgsize; + /* Find the next biggest support page size, if it exists */ + pgsizes = domain->pgsize_bitmap & ~GENMASK(pgsize_idx, 0); + if (!pgsizes) + goto out_set_count; + + pgsize_idx_next = __ffs(pgsizes); + pgsize_next = BIT(pgsize_idx_next); + + /* + * There's no point trying a bigger page size unless the virtual + * and physical addresses are similarly offset within the larger page. + */ + if ((iova ^ paddr) & (pgsize_next - 1)) + goto out_set_count; + + /* Calculate the offset to the next page size alignment boundary */ + offset = pgsize_next - (addr_merge & (pgsize_next - 1)); + + /* + * If size is big enough to accommodate the larger page, reduce + * the number of smaller pages. + */ + if (offset + pgsize_next <= size) + size = offset; + +out_set_count: + *count = size >> pgsize_idx; return pgsize; } @@ -2434,7 +2463,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, pr_debug("map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); while (size) { - size_t pgsize = iommu_pgsize(domain, iova, paddr, size); + size_t pgsize = iommu_pgsize(domain, iova, paddr, size, NULL); pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", iova, &paddr, pgsize); @@ -2485,6 +2514,19 @@ int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova, } EXPORT_SYMBOL_GPL(iommu_map_atomic); +static size_t __iommu_unmap_pages(struct iommu_domain *domain, + unsigned long iova, size_t size, + struct iommu_iotlb_gather *iotlb_gather) +{ + const struct iommu_ops *ops = domain->ops; + size_t pgsize, count; + + pgsize = iommu_pgsize(domain, iova, iova, size, &count); + return ops->unmap_pages ? + ops->unmap_pages(domain, iova, pgsize, count, iotlb_gather) : + ops->unmap(domain, iova, pgsize, iotlb_gather); +} + static size_t __iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather) @@ -2494,7 +2536,7 @@ static size_t __iommu_unmap(struct iommu_domain *domain, unsigned long orig_iova = iova; unsigned int min_pagesz; - if (unlikely(ops->unmap == NULL || + if (unlikely(!(ops->unmap || ops->unmap_pages) || domain->pgsize_bitmap == 0UL)) return 0; @@ -2522,10 +2564,9 @@ static size_t __iommu_unmap(struct iommu_domain *domain, * or we hit an area that isn't mapped. */ while (unmapped < size) { - size_t pgsize; - - pgsize = iommu_pgsize(domain, iova, iova, size - unmapped); - unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather); + unmapped_page = __iommu_unmap_pages(domain, iova, + size - unmapped, + iotlb_gather); if (!unmapped_page) break; -- cgit v1.2.3-70-g09d2 From 647c57764b37c0ddfa6bf775b03d5e5cc407086b Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:49 -0700 Subject: iommu: Add support for the map_pages() callback Since iommu_pgsize can calculate how many pages of the same size can be mapped/unmapped before the next largest page size boundary, add support for invoking an IOMMU driver's map_pages() callback, if it provides one. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1623850736-389584-9-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 725622c7e603..70a729ce88b1 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2429,6 +2429,30 @@ out_set_count: return pgsize; } +static int __iommu_map_pages(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot, + gfp_t gfp, size_t *mapped) +{ + const struct iommu_ops *ops = domain->ops; + size_t pgsize, count; + int ret; + + pgsize = iommu_pgsize(domain, iova, paddr, size, &count); + + pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx count %zu\n", + iova, &paddr, pgsize, count); + + if (ops->map_pages) { + ret = ops->map_pages(domain, iova, paddr, pgsize, count, prot, + gfp, mapped); + } else { + ret = ops->map(domain, iova, paddr, pgsize, prot, gfp); + *mapped = ret ? 0 : pgsize; + } + + return ret; +} + static int __iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { @@ -2439,7 +2463,7 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t orig_paddr = paddr; int ret = 0; - if (unlikely(ops->map == NULL || + if (unlikely(!(ops->map || ops->map_pages) || domain->pgsize_bitmap == 0UL)) return -ENODEV; @@ -2463,18 +2487,21 @@ static int __iommu_map(struct iommu_domain *domain, unsigned long iova, pr_debug("map: iova 0x%lx pa %pa size 0x%zx\n", iova, &paddr, size); while (size) { - size_t pgsize = iommu_pgsize(domain, iova, paddr, size, NULL); + size_t mapped = 0; - pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", - iova, &paddr, pgsize); - ret = ops->map(domain, iova, paddr, pgsize, prot, gfp); + ret = __iommu_map_pages(domain, iova, paddr, size, prot, gfp, + &mapped); + /* + * Some pages may have been mapped, even if an error occurred, + * so we should account for those so they can be unmapped. + */ + size -= mapped; if (ret) break; - iova += pgsize; - paddr += pgsize; - size -= pgsize; + iova += mapped; + paddr += mapped; } /* unroll mapping in case something went wrong */ -- cgit v1.2.3-70-g09d2 From 41e1eb2546e9c8200d32f11e4b47d86d156a5a97 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:50 -0700 Subject: iommu/io-pgtable-arm: Prepare PTE methods for handling multiple entries The PTE methods currently operate on a single entry. In preparation for manipulating multiple PTEs in one map or unmap call, allow them to handle multiple PTEs. Signed-off-by: Isaac J. Manjarres Suggested-by: Robin Murphy Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-10-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm.c | 78 ++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 87def58e79b5..ea66b10c04c4 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -232,20 +232,23 @@ static void __arm_lpae_free_pages(void *pages, size_t size, free_pages((unsigned long)pages, get_order(size)); } -static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, +static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries, struct io_pgtable_cfg *cfg) { dma_sync_single_for_device(cfg->iommu_dev, __arm_lpae_dma_addr(ptep), - sizeof(*ptep), DMA_TO_DEVICE); + sizeof(*ptep) * num_entries, DMA_TO_DEVICE); } static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte, - struct io_pgtable_cfg *cfg) + int num_entries, struct io_pgtable_cfg *cfg) { - *ptep = pte; + int i; + + for (i = 0; i < num_entries; i++) + ptep[i] = pte; if (!cfg->coherent_walk) - __arm_lpae_sync_pte(ptep, cfg); + __arm_lpae_sync_pte(ptep, num_entries, cfg); } static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, @@ -255,47 +258,54 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, phys_addr_t paddr, arm_lpae_iopte prot, - int lvl, arm_lpae_iopte *ptep) + int lvl, int num_entries, arm_lpae_iopte *ptep) { arm_lpae_iopte pte = prot; + struct io_pgtable_cfg *cfg = &data->iop.cfg; + size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data); + int i; if (data->iop.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1) pte |= ARM_LPAE_PTE_TYPE_PAGE; else pte |= ARM_LPAE_PTE_TYPE_BLOCK; - pte |= paddr_to_iopte(paddr, data); + for (i = 0; i < num_entries; i++) + ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data); - __arm_lpae_set_pte(ptep, pte, &data->iop.cfg); + if (!cfg->coherent_walk) + __arm_lpae_sync_pte(ptep, num_entries, cfg); } static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, unsigned long iova, phys_addr_t paddr, - arm_lpae_iopte prot, int lvl, + arm_lpae_iopte prot, int lvl, int num_entries, arm_lpae_iopte *ptep) { - arm_lpae_iopte pte = *ptep; - - if (iopte_leaf(pte, lvl, data->iop.fmt)) { - /* We require an unmap first */ - WARN_ON(!selftest_running); - return -EEXIST; - } else if (iopte_type(pte) == ARM_LPAE_PTE_TYPE_TABLE) { - /* - * We need to unmap and free the old table before - * overwriting it with a block entry. - */ - arm_lpae_iopte *tblp; - size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data); - - tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data); - if (__arm_lpae_unmap(data, NULL, iova, sz, lvl, tblp) != sz) { - WARN_ON(1); - return -EINVAL; + int i; + + for (i = 0; i < num_entries; i++) + if (iopte_leaf(ptep[i], lvl, data->iop.fmt)) { + /* We require an unmap first */ + WARN_ON(!selftest_running); + return -EEXIST; + } else if (iopte_type(ptep[i]) == ARM_LPAE_PTE_TYPE_TABLE) { + /* + * We need to unmap and free the old table before + * overwriting it with a block entry. + */ + arm_lpae_iopte *tblp; + size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data); + + tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data); + if (__arm_lpae_unmap(data, NULL, iova + i * sz, sz, + lvl, tblp) != sz) { + WARN_ON(1); + return -EINVAL; + } } - } - __arm_lpae_init_pte(data, paddr, prot, lvl, ptep); + __arm_lpae_init_pte(data, paddr, prot, lvl, num_entries, ptep); return 0; } @@ -323,7 +333,7 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, return old; /* Even if it's not ours, there's no point waiting; just kick it */ - __arm_lpae_sync_pte(ptep, cfg); + __arm_lpae_sync_pte(ptep, 1, cfg); if (old == curr) WRITE_ONCE(*ptep, new | ARM_LPAE_PTE_SW_SYNC); @@ -344,7 +354,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, /* If we can install a leaf entry at this level, then do so */ if (size == block_size) - return arm_lpae_init_pte(data, iova, paddr, prot, lvl, ptep); + return arm_lpae_init_pte(data, iova, paddr, prot, lvl, 1, ptep); /* We can't allocate tables at the final level */ if (WARN_ON(lvl >= ARM_LPAE_MAX_LEVELS - 1)) @@ -361,7 +371,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, if (pte) __arm_lpae_free_pages(cptep, tblsz, cfg); } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { - __arm_lpae_sync_pte(ptep, cfg); + __arm_lpae_sync_pte(ptep, 1, cfg); } if (pte && !iopte_leaf(pte, lvl, data->iop.fmt)) { @@ -543,7 +553,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, if (i == unmap_idx) continue; - __arm_lpae_init_pte(data, blk_paddr, pte, lvl, &tablep[i]); + __arm_lpae_init_pte(data, blk_paddr, pte, lvl, 1, &tablep[i]); } pte = arm_lpae_install_table(tablep, ptep, blk_pte, cfg); @@ -585,7 +595,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, /* If the size matches this level, we're in the right place */ if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) { - __arm_lpae_set_pte(ptep, 0, &iop->cfg); + __arm_lpae_set_pte(ptep, 0, 1, &iop->cfg); if (!iopte_leaf(pte, lvl, iop->fmt)) { /* Also flush any partial walks */ -- cgit v1.2.3-70-g09d2 From 1fe27be5ffec20637a8fe17ec7c1e88f3aaf62f0 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:51 -0700 Subject: iommu/io-pgtable-arm: Implement arm_lpae_unmap_pages() Implement the unmap_pages() callback for the ARM LPAE io-pgtable format. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-11-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm.c | 120 +++++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 46 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index ea66b10c04c4..fe8fa0ee9c98 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -46,6 +46,9 @@ #define ARM_LPAE_PGD_SIZE(d) \ (sizeof(arm_lpae_iopte) << (d)->pgd_bits) +#define ARM_LPAE_PTES_PER_TABLE(d) \ + (ARM_LPAE_GRANULE(d) >> ilog2(sizeof(arm_lpae_iopte))) + /* * Calculate the index at level l used to map virtual address a using the * pagetable in d. @@ -239,22 +242,19 @@ static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, int num_entries, sizeof(*ptep) * num_entries, DMA_TO_DEVICE); } -static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte, - int num_entries, struct io_pgtable_cfg *cfg) +static void __arm_lpae_clear_pte(arm_lpae_iopte *ptep, struct io_pgtable_cfg *cfg) { - int i; - for (i = 0; i < num_entries; i++) - ptep[i] = pte; + *ptep = 0; if (!cfg->coherent_walk) - __arm_lpae_sync_pte(ptep, num_entries, cfg); + __arm_lpae_sync_pte(ptep, 1, cfg); } static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, struct iommu_iotlb_gather *gather, - unsigned long iova, size_t size, int lvl, - arm_lpae_iopte *ptep); + unsigned long iova, size_t size, size_t pgcount, + int lvl, arm_lpae_iopte *ptep); static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, phys_addr_t paddr, arm_lpae_iopte prot, @@ -298,7 +298,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data); tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data); - if (__arm_lpae_unmap(data, NULL, iova + i * sz, sz, + if (__arm_lpae_unmap(data, NULL, iova + i * sz, sz, 1, lvl, tblp) != sz) { WARN_ON(1); return -EINVAL; @@ -526,14 +526,15 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, struct iommu_iotlb_gather *gather, unsigned long iova, size_t size, arm_lpae_iopte blk_pte, int lvl, - arm_lpae_iopte *ptep) + arm_lpae_iopte *ptep, size_t pgcount) { struct io_pgtable_cfg *cfg = &data->iop.cfg; arm_lpae_iopte pte, *tablep; phys_addr_t blk_paddr; size_t tablesz = ARM_LPAE_GRANULE(data); size_t split_sz = ARM_LPAE_BLOCK_SIZE(lvl, data); - int i, unmap_idx = -1; + int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data); + int i, unmap_idx_start = -1, num_entries = 0, max_entries; if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS)) return 0; @@ -542,15 +543,18 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, if (!tablep) return 0; /* Bytes unmapped */ - if (size == split_sz) - unmap_idx = ARM_LPAE_LVL_IDX(iova, lvl, data); + if (size == split_sz) { + unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data); + max_entries = ptes_per_table - unmap_idx_start; + num_entries = min_t(int, pgcount, max_entries); + } blk_paddr = iopte_to_paddr(blk_pte, data); pte = iopte_prot(blk_pte); - for (i = 0; i < tablesz / sizeof(pte); i++, blk_paddr += split_sz) { + for (i = 0; i < ptes_per_table; i++, blk_paddr += split_sz) { /* Unmap! */ - if (i == unmap_idx) + if (i >= unmap_idx_start && i < (unmap_idx_start + num_entries)) continue; __arm_lpae_init_pte(data, blk_paddr, pte, lvl, 1, &tablep[i]); @@ -568,76 +572,92 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, return 0; tablep = iopte_deref(pte, data); - } else if (unmap_idx >= 0) { - io_pgtable_tlb_add_page(&data->iop, gather, iova, size); - return size; + } else if (unmap_idx_start >= 0) { + for (i = 0; i < num_entries; i++) + io_pgtable_tlb_add_page(&data->iop, gather, iova + i * size, size); + + return num_entries * size; } - return __arm_lpae_unmap(data, gather, iova, size, lvl, tablep); + return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl, tablep); } static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data, struct iommu_iotlb_gather *gather, - unsigned long iova, size_t size, int lvl, - arm_lpae_iopte *ptep) + unsigned long iova, size_t size, size_t pgcount, + int lvl, arm_lpae_iopte *ptep) { arm_lpae_iopte pte; struct io_pgtable *iop = &data->iop; + int i = 0, num_entries, max_entries, unmap_idx_start; /* Something went horribly wrong and we ran out of page table */ if (WARN_ON(lvl == ARM_LPAE_MAX_LEVELS)) return 0; - ptep += ARM_LPAE_LVL_IDX(iova, lvl, data); + unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data); + ptep += unmap_idx_start; pte = READ_ONCE(*ptep); if (WARN_ON(!pte)) return 0; /* If the size matches this level, we're in the right place */ if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) { - __arm_lpae_set_pte(ptep, 0, 1, &iop->cfg); - - if (!iopte_leaf(pte, lvl, iop->fmt)) { - /* Also flush any partial walks */ - io_pgtable_tlb_flush_walk(iop, iova, size, - ARM_LPAE_GRANULE(data)); - ptep = iopte_deref(pte, data); - __arm_lpae_free_pgtable(data, lvl + 1, ptep); - } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) { - /* - * Order the PTE update against queueing the IOVA, to - * guarantee that a flush callback from a different CPU - * has observed it before the TLBIALL can be issued. - */ - smp_wmb(); - } else { - io_pgtable_tlb_add_page(iop, gather, iova, size); + max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start; + num_entries = min_t(int, pgcount, max_entries); + + while (i < num_entries) { + pte = READ_ONCE(*ptep); + if (WARN_ON(!pte)) + break; + + __arm_lpae_clear_pte(ptep, &iop->cfg); + + if (!iopte_leaf(pte, lvl, iop->fmt)) { + /* Also flush any partial walks */ + io_pgtable_tlb_flush_walk(iop, iova + i * size, size, + ARM_LPAE_GRANULE(data)); + __arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data)); + } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) { + /* + * Order the PTE update against queueing the IOVA, to + * guarantee that a flush callback from a different CPU + * has observed it before the TLBIALL can be issued. + */ + smp_wmb(); + } else { + io_pgtable_tlb_add_page(iop, gather, iova + i * size, size); + } + + ptep++; + i++; } - return size; + return i * size; } else if (iopte_leaf(pte, lvl, iop->fmt)) { /* * Insert a table at the next level to map the old region, * minus the part we want to unmap */ return arm_lpae_split_blk_unmap(data, gather, iova, size, pte, - lvl + 1, ptep); + lvl + 1, ptep, pgcount); } /* Keep on walkin' */ ptep = iopte_deref(pte, data); - return __arm_lpae_unmap(data, gather, iova, size, lvl + 1, ptep); + return __arm_lpae_unmap(data, gather, iova, size, pgcount, lvl + 1, ptep); } -static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, - size_t size, struct iommu_iotlb_gather *gather) +static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather) { struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); struct io_pgtable_cfg *cfg = &data->iop.cfg; arm_lpae_iopte *ptep = data->pgd; long iaext = (s64)iova >> cfg->ias; - if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) + if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize || !pgcount)) return 0; if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) @@ -645,7 +665,14 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, if (WARN_ON(iaext)) return 0; - return __arm_lpae_unmap(data, gather, iova, size, data->start_level, ptep); + return __arm_lpae_unmap(data, gather, iova, pgsize, pgcount, + data->start_level, ptep); +} + +static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, + size_t size, struct iommu_iotlb_gather *gather) +{ + return arm_lpae_unmap_pages(ops, iova, size, 1, gather); } static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, @@ -761,6 +788,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg) data->iop.ops = (struct io_pgtable_ops) { .map = arm_lpae_map, .unmap = arm_lpae_unmap, + .unmap_pages = arm_lpae_unmap_pages, .iova_to_phys = arm_lpae_iova_to_phys, }; -- cgit v1.2.3-70-g09d2 From 4a77b12deb253bd0d56bab6e9f5ad09cef754c36 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:52 -0700 Subject: iommu/io-pgtable-arm: Implement arm_lpae_map_pages() Implement the map_pages() callback for the ARM LPAE io-pgtable format. Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-12-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index fe8fa0ee9c98..053df4048a29 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -341,20 +341,30 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, } static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, - phys_addr_t paddr, size_t size, arm_lpae_iopte prot, - int lvl, arm_lpae_iopte *ptep, gfp_t gfp) + phys_addr_t paddr, size_t size, size_t pgcount, + arm_lpae_iopte prot, int lvl, arm_lpae_iopte *ptep, + gfp_t gfp, size_t *mapped) { arm_lpae_iopte *cptep, pte; size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data); size_t tblsz = ARM_LPAE_GRANULE(data); struct io_pgtable_cfg *cfg = &data->iop.cfg; + int ret = 0, num_entries, max_entries, map_idx_start; /* Find our entry at the current level */ - ptep += ARM_LPAE_LVL_IDX(iova, lvl, data); + map_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data); + ptep += map_idx_start; /* If we can install a leaf entry at this level, then do so */ - if (size == block_size) - return arm_lpae_init_pte(data, iova, paddr, prot, lvl, 1, ptep); + if (size == block_size) { + max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start; + num_entries = min_t(int, pgcount, max_entries); + ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep); + if (!ret && mapped) + *mapped += num_entries * size; + + return ret; + } /* We can't allocate tables at the final level */ if (WARN_ON(lvl >= ARM_LPAE_MAX_LEVELS - 1)) @@ -383,7 +393,8 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, } /* Rinse, repeat */ - return __arm_lpae_map(data, iova, paddr, size, prot, lvl + 1, cptep, gfp); + return __arm_lpae_map(data, iova, paddr, size, pgcount, prot, lvl + 1, + cptep, gfp, mapped); } static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, @@ -450,8 +461,9 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, return pte; } -static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, - phys_addr_t paddr, size_t size, int iommu_prot, gfp_t gfp) +static int arm_lpae_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int iommu_prot, gfp_t gfp, size_t *mapped) { struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); struct io_pgtable_cfg *cfg = &data->iop.cfg; @@ -460,7 +472,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, arm_lpae_iopte prot; long iaext = (s64)iova >> cfg->ias; - if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) + if (WARN_ON(!pgsize || (pgsize & cfg->pgsize_bitmap) != pgsize)) return -EINVAL; if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1) @@ -473,7 +485,8 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, return 0; prot = arm_lpae_prot_to_pte(data, iommu_prot); - ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep, gfp); + ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl, + ptep, gfp, mapped); /* * Synchronise all PTE updates for the new mapping before there's * a chance for anything to kick off a table walk for the new iova. @@ -483,6 +496,13 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, return ret; } +static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t size, int iommu_prot, gfp_t gfp) +{ + return arm_lpae_map_pages(ops, iova, paddr, size, 1, iommu_prot, gfp, + NULL); +} + static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl, arm_lpae_iopte *ptep) { @@ -787,6 +807,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg) data->iop.ops = (struct io_pgtable_ops) { .map = arm_lpae_map, + .map_pages = arm_lpae_map_pages, .unmap = arm_lpae_unmap, .unmap_pages = arm_lpae_unmap_pages, .iova_to_phys = arm_lpae_iova_to_phys, -- cgit v1.2.3-70-g09d2 From f13eabcf9dfad938333c0b6cc6bf4c05cc25eb4f Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:53 -0700 Subject: iommu/io-pgtable-arm-v7s: Implement arm_v7s_unmap_pages() Implement the unmap_pages() callback for the ARM v7s io-pgtable format. Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-13-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm-v7s.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index d4004bcf333a..1af060686985 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -710,15 +710,32 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data, return __arm_v7s_unmap(data, gather, iova, size, lvl + 1, ptep); } -static size_t arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova, - size_t size, struct iommu_iotlb_gather *gather) +static size_t arm_v7s_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather) { struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops); + size_t unmapped = 0, ret; if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias))) return 0; - return __arm_v7s_unmap(data, gather, iova, size, 1, data->pgd); + while (pgcount--) { + ret = __arm_v7s_unmap(data, gather, iova, pgsize, 1, data->pgd); + if (!ret) + break; + + unmapped += pgsize; + iova += pgsize; + } + + return unmapped; +} + +static size_t arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova, + size_t size, struct iommu_iotlb_gather *gather) +{ + return arm_v7s_unmap_pages(ops, iova, size, 1, gather); } static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops, @@ -781,6 +798,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, data->iop.ops = (struct io_pgtable_ops) { .map = arm_v7s_map, .unmap = arm_v7s_unmap, + .unmap_pages = arm_v7s_unmap_pages, .iova_to_phys = arm_v7s_iova_to_phys, }; -- cgit v1.2.3-70-g09d2 From 23c30bed9c3c9062774488dc5223aa1ee850e028 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:54 -0700 Subject: iommu/io-pgtable-arm-v7s: Implement arm_v7s_map_pages() Implement the map_pages() callback for the ARM v7s io-pgtable format. Signed-off-by: Isaac J. Manjarres Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-14-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm-v7s.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index 1af060686985..5db90d7ce2ec 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -519,11 +519,12 @@ static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, unsigned long iova, return __arm_v7s_map(data, iova, paddr, size, prot, lvl + 1, cptep, gfp); } -static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, - phys_addr_t paddr, size_t size, int prot, gfp_t gfp) +static int arm_v7s_map_pages(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped) { struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops); - int ret; + int ret = -EINVAL; if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) || paddr >= (1ULL << data->iop.cfg.oas))) @@ -533,7 +534,17 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, if (!(prot & (IOMMU_READ | IOMMU_WRITE))) return 0; - ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd, gfp); + while (pgcount--) { + ret = __arm_v7s_map(data, iova, paddr, pgsize, prot, 1, data->pgd, + gfp); + if (ret) + break; + + iova += pgsize; + paddr += pgsize; + if (mapped) + *mapped += pgsize; + } /* * Synchronise all PTE updates for the new mapping before there's * a chance for anything to kick off a table walk for the new iova. @@ -543,6 +554,12 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, return ret; } +static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova, + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) +{ + return arm_v7s_map_pages(ops, iova, paddr, size, 1, prot, gfp, NULL); +} + static void arm_v7s_free_pgtable(struct io_pgtable *iop) { struct arm_v7s_io_pgtable *data = io_pgtable_to_data(iop); @@ -797,6 +814,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, data->iop.ops = (struct io_pgtable_ops) { .map = arm_v7s_map, + .map_pages = arm_v7s_map_pages, .unmap = arm_v7s_unmap, .unmap_pages = arm_v7s_unmap_pages, .iova_to_phys = arm_v7s_iova_to_phys, -- cgit v1.2.3-70-g09d2 From 9ea1a2c4944851aae4d821b3a6c99ade2bc3bbe6 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:55 -0700 Subject: iommu/arm-smmu: Implement the unmap_pages() IOMMU driver callback Implement the unmap_pages() callback for the ARM SMMU driver to allow calls from iommu_unmap to unmap multiple pages of the same size in one call. Also, remove the unmap() callback for the SMMU driver, as it will no longer be used. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-15-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index f22dbeb1e510..9a0c49060bf3 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1215,8 +1215,9 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, return ret; } -static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, - size_t size, struct iommu_iotlb_gather *gather) +static size_t arm_smmu_unmap_pages(struct iommu_domain *domain, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *iotlb_gather) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; @@ -1226,7 +1227,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, return 0; arm_smmu_rpm_get(smmu); - ret = ops->unmap(ops, iova, size, gather); + ret = ops->unmap_pages(ops, iova, pgsize, pgcount, iotlb_gather); arm_smmu_rpm_put(smmu); return ret; @@ -1583,7 +1584,7 @@ static struct iommu_ops arm_smmu_ops = { .domain_free = arm_smmu_domain_free, .attach_dev = arm_smmu_attach_dev, .map = arm_smmu_map, - .unmap = arm_smmu_unmap, + .unmap_pages = arm_smmu_unmap_pages, .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, .iova_to_phys = arm_smmu_iova_to_phys, -- cgit v1.2.3-70-g09d2 From 808035317b22e2dd8d2cfef2083ad1743ac0c0e2 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 16 Jun 2021 06:38:56 -0700 Subject: iommu/arm-smmu: Implement the map_pages() IOMMU driver callback Implement the map_pages() callback for the ARM SMMU driver to allow calls from iommu_map to map multiple pages of the same size in one call. Also, remove the map() callback for the ARM SMMU driver, as it will no longer be used. Signed-off-by: Isaac J. Manjarres Suggested-by: Will Deacon Signed-off-by: Georgi Djakov Link: https://lore.kernel.org/r/1623850736-389584-16-git-send-email-quic_c_gdjako@quicinc.com Signed-off-by: Joerg Roedel --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 9a0c49060bf3..5ed4408d4b28 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1198,8 +1198,9 @@ rpm_put: return ret; } -static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot, gfp_t gfp) +static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; @@ -1209,7 +1210,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, return -ENODEV; arm_smmu_rpm_get(smmu); - ret = ops->map(ops, iova, paddr, size, prot, gfp); + ret = ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, gfp, mapped); arm_smmu_rpm_put(smmu); return ret; @@ -1583,7 +1584,7 @@ static struct iommu_ops arm_smmu_ops = { .domain_alloc = arm_smmu_domain_alloc, .domain_free = arm_smmu_domain_free, .attach_dev = arm_smmu_attach_dev, - .map = arm_smmu_map, + .map_pages = arm_smmu_map_pages, .unmap_pages = arm_smmu_unmap_pages, .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, -- cgit v1.2.3-70-g09d2 From 8119cefd9a29b71997e62b762932d23499ba4896 Mon Sep 17 00:00:00 2001 From: Hari Bathini Date: Wed, 14 Jul 2021 18:17:58 +0530 Subject: powerpc/kexec: blacklist functions called in real mode for kprobe As kprobe does not handle events happening in real mode, blacklist the functions that only get called in real mode or in kexec sequence with MMU turned off. Signed-off-by: Hari Bathini Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/162626687834.155313.4692863392927831843.stgit@hbathini-workstation.ibm.com --- arch/powerpc/kernel/head_64.S | 2 ++ arch/powerpc/kexec/core_64.c | 6 ++++-- arch/powerpc/mm/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/pgtable.c | 4 ++-- arch/powerpc/mm/book3s64/radix_pgtable.c | 3 ++- arch/powerpc/platforms/ps3/htab.c | 3 ++- arch/powerpc/platforms/ps3/mm.c | 8 ++++++-- arch/powerpc/platforms/pseries/lpar.c | 9 ++++++--- 8 files changed, 25 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 79930b0bc781..f17ae2083733 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -712,6 +712,8 @@ _GLOBAL(copy_and_flush) isync blr +_ASM_NOKPROBE_SYMBOL(copy_and_flush); /* Called in real mode */ + .align 8 copy_to_here: diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c index 8a449b2d8715..84618d3c8013 100644 --- a/arch/powerpc/kexec/core_64.c +++ b/arch/powerpc/kexec/core_64.c @@ -72,7 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image) return 0; } -static void copy_segments(unsigned long ind) +/* Called during kexec sequence with MMU off */ +static notrace void copy_segments(unsigned long ind) { unsigned long entry; unsigned long *ptr; @@ -105,7 +106,8 @@ static void copy_segments(unsigned long ind) } } -void kexec_copy_flush(struct kimage *image) +/* Called during kexec sequence with MMU off */ +notrace void kexec_copy_flush(struct kimage *image) { long i, nr_segments = image->nr_segments; struct kexec_segment ranges[KEXEC_SEGMENT_MAX]; diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index 52e170bd95ae..d8279bfe68ea 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -787,7 +787,7 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, * TODO: add batching support when enabled. remember, no dynamic memory here, * although there is the control page available... */ -static void native_hpte_clear(void) +static notrace void native_hpte_clear(void) { unsigned long vpn = 0; unsigned long slot, slots; diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index 9ffa65074cb0..300099de553b 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -172,8 +172,8 @@ pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) } #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -/* For use by kexec */ -void mmu_cleanup_all(void) +/* For use by kexec, called with MMU off */ +notrace void mmu_cleanup_all(void) { if (radix_enabled()) radix__mmu_cleanup_all(); diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index e50ddf129c15..ae20add7954a 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -679,7 +679,8 @@ void radix__early_init_mmu_secondary(void) mtspr(SPRN_UAMOR, 0); } -void radix__mmu_cleanup_all(void) +/* Called during kexec sequence with MMU off */ +notrace void radix__mmu_cleanup_all(void) { unsigned long lpcr; diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c index 7ddc7ec6a7c0..ef710a715903 100644 --- a/arch/powerpc/platforms/ps3/htab.c +++ b/arch/powerpc/platforms/ps3/htab.c @@ -169,7 +169,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn, spin_unlock_irqrestore(&ps3_htab_lock, flags); } -static void ps3_hpte_clear(void) +/* Called during kexec sequence with MMU off */ +static notrace void ps3_hpte_clear(void) { unsigned long hpte_count = (1UL << ppc64_pft_size) >> 4; u64 i; diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index a81eac35d900..9c44f335c0b9 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -195,9 +195,11 @@ fail: /** * ps3_mm_vas_destroy - + * + * called during kexec sequence with MMU off. */ -void ps3_mm_vas_destroy(void) +notrace void ps3_mm_vas_destroy(void) { int result; @@ -1243,9 +1245,11 @@ void __init ps3_mm_init(void) /** * ps3_mm_shutdown - final cleanup of address space + * + * called during kexec sequence with MMU off. */ -void ps3_mm_shutdown(void) +notrace void ps3_mm_shutdown(void) { ps3_mm_region_destroy(&map.r1); } diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index dab356e3ff87..869ef638698a 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -801,7 +801,8 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group) return -1; } -static void manual_hpte_clear_all(void) +/* Called during kexec sequence with MMU off */ +static notrace void manual_hpte_clear_all(void) { unsigned long size_bytes = 1UL << ppc64_pft_size; unsigned long hpte_count = size_bytes >> 4; @@ -834,7 +835,8 @@ static void manual_hpte_clear_all(void) } } -static int hcall_hpte_clear_all(void) +/* Called during kexec sequence with MMU off */ +static notrace int hcall_hpte_clear_all(void) { int rc; @@ -845,7 +847,8 @@ static int hcall_hpte_clear_all(void) return rc; } -static void pseries_hpte_clear_all(void) +/* Called during kexec sequence with MMU off */ +static notrace void pseries_hpte_clear_all(void) { int rc; -- cgit v1.2.3-70-g09d2 From d453ceb6549af8798913de6a20444cb7200fdb69 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Thu, 13 May 2021 17:57:33 -0700 Subject: platform/chrome: sensorhub: Add trace events for sample Add trace event to report samples and their timestamp coming from the EC. It allows to check if the timestamps are correct and the filter is working correctly without introducing too much latency. To enable these events: cd /sys/kernel/debug/tracing/ echo 1 > events/cros_ec/enable echo 0 > events/cros_ec/cros_ec_request_start/enable echo 0 > events/cros_ec/cros_ec_request_done/enable echo 1 > tracing_on cat trace_pipe Observe event flowing: irq/105-chromeo-95 [000] .... 613.659758: cros_ec_sensorhub_timestamp: ... irq/105-chromeo-95 [000] .... 613.665219: cros_ec_sensorhub_filter: dx: ... Signed-off-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/Makefile | 2 +- drivers/platform/chrome/cros_ec_sensorhub_ring.c | 14 ++++ drivers/platform/chrome/cros_ec_trace.h | 94 ++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index 41baccba033f..f901d2e43166 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_chardev.o obj-$(CONFIG_CROS_EC_LIGHTBAR) += cros_ec_lightbar.o obj-$(CONFIG_CROS_EC_VBC) += cros_ec_vbc.o obj-$(CONFIG_CROS_EC_DEBUGFS) += cros_ec_debugfs.o -cros-ec-sensorhub-objs := cros_ec_sensorhub.o cros_ec_sensorhub_ring.o +cros-ec-sensorhub-objs := cros_ec_sensorhub.o cros_ec_sensorhub_ring.o cros_ec_trace.o obj-$(CONFIG_CROS_EC_SENSORHUB) += cros-ec-sensorhub.o obj-$(CONFIG_CROS_EC_SYSFS) += cros_ec_sysfs.o obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o diff --git a/drivers/platform/chrome/cros_ec_sensorhub_ring.c b/drivers/platform/chrome/cros_ec_sensorhub_ring.c index 8921f24e83ba..98e37080f760 100644 --- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c +++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c @@ -17,6 +17,8 @@ #include #include +#include "cros_ec_trace.h" + /* Precision of fixed point for the m values from the filter */ #define M_PRECISION BIT(23) @@ -291,6 +293,7 @@ cros_ec_sensor_ring_ts_filter_update(struct cros_ec_sensors_ts_filter_state state->median_m = 0; state->median_error = 0; } + trace_cros_ec_sensorhub_filter(state, dx, dy); } /** @@ -427,6 +430,11 @@ cros_ec_sensor_ring_process_event(struct cros_ec_sensorhub *sensorhub, if (new_timestamp - *current_timestamp > 0) *current_timestamp = new_timestamp; } + trace_cros_ec_sensorhub_timestamp(in->timestamp, + fifo_info->timestamp, + fifo_timestamp, + *current_timestamp, + now); } if (in->flags & MOTIONSENSE_SENSOR_FLAG_ODR) { @@ -460,6 +468,12 @@ cros_ec_sensor_ring_process_event(struct cros_ec_sensorhub *sensorhub, /* Regular sample */ out->sensor_id = in->sensor_num; + trace_cros_ec_sensorhub_data(in->sensor_num, + fifo_info->timestamp, + fifo_timestamp, + *current_timestamp, + now); + if (*current_timestamp - now > 0) { /* * This fix is needed to overcome the timestamp filter putting diff --git a/drivers/platform/chrome/cros_ec_trace.h b/drivers/platform/chrome/cros_ec_trace.h index f744b21bc655..f50b9f9b8610 100644 --- a/drivers/platform/chrome/cros_ec_trace.h +++ b/drivers/platform/chrome/cros_ec_trace.h @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -70,6 +71,99 @@ TRACE_EVENT(cros_ec_request_done, __entry->retval) ); +TRACE_EVENT(cros_ec_sensorhub_timestamp, + TP_PROTO(u32 ec_sample_timestamp, u32 ec_fifo_timestamp, s64 fifo_timestamp, + s64 current_timestamp, s64 current_time), + TP_ARGS(ec_sample_timestamp, ec_fifo_timestamp, fifo_timestamp, current_timestamp, + current_time), + TP_STRUCT__entry( + __field(u32, ec_sample_timestamp) + __field(u32, ec_fifo_timestamp) + __field(s64, fifo_timestamp) + __field(s64, current_timestamp) + __field(s64, current_time) + __field(s64, delta) + ), + TP_fast_assign( + __entry->ec_sample_timestamp = ec_sample_timestamp; + __entry->ec_fifo_timestamp = ec_fifo_timestamp; + __entry->fifo_timestamp = fifo_timestamp; + __entry->current_timestamp = current_timestamp; + __entry->current_time = current_time; + __entry->delta = current_timestamp - current_time; + ), + TP_printk("ec_ts: %12lld, ec_fifo_ts: %12lld, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", + __entry->ec_sample_timestamp, + __entry->ec_fifo_timestamp, + __entry->fifo_timestamp, + __entry->current_timestamp, + __entry->current_time, + __entry->delta + ) +); + +TRACE_EVENT(cros_ec_sensorhub_data, + TP_PROTO(u32 ec_sensor_num, u32 ec_fifo_timestamp, s64 fifo_timestamp, + s64 current_timestamp, s64 current_time), + TP_ARGS(ec_sensor_num, ec_fifo_timestamp, fifo_timestamp, current_timestamp, current_time), + TP_STRUCT__entry( + __field(u32, ec_sensor_num) + __field(u32, ec_fifo_timestamp) + __field(s64, fifo_timestamp) + __field(s64, current_timestamp) + __field(s64, current_time) + __field(s64, delta) + ), + TP_fast_assign( + __entry->ec_sensor_num = ec_sensor_num; + __entry->ec_fifo_timestamp = ec_fifo_timestamp; + __entry->fifo_timestamp = fifo_timestamp; + __entry->current_timestamp = current_timestamp; + __entry->current_time = current_time; + __entry->delta = current_timestamp - current_time; + ), + TP_printk("ec_num: %4d, ec_fifo_ts: %12lld, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", + __entry->ec_sensor_num, + __entry->ec_fifo_timestamp, + __entry->fifo_timestamp, + __entry->current_timestamp, + __entry->current_time, + __entry->delta + ) +); + +TRACE_EVENT(cros_ec_sensorhub_filter, + TP_PROTO(struct cros_ec_sensors_ts_filter_state *state, s64 dx, s64 dy), + TP_ARGS(state, dx, dy), + TP_STRUCT__entry( + __field(s64, dx) + __field(s64, dy) + __field(s64, median_m) + __field(s64, median_error) + __field(s64, history_len) + __field(s64, x) + __field(s64, y) + ), + TP_fast_assign( + __entry->dx = dx; + __entry->dy = dy; + __entry->median_m = state->median_m; + __entry->median_error = state->median_error; + __entry->history_len = state->history_len; + __entry->x = state->x_offset; + __entry->y = state->y_offset; + ), + TP_printk("dx: %12lld. dy: %12lld median_m: %12lld median_error: %12lld len: %d x: %12lld y: %12lld", + __entry->dx, + __entry->dy, + __entry->median_m, + __entry->median_error, + __entry->history_len, + __entry->x, + __entry->y + ) +); + #endif /* _CROS_EC_TRACE_H_ */ -- cgit v1.2.3-70-g09d2 From 1d479f160c500249d8fa4d21e7d2b7aaffc04daf Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 12 Jul 2021 19:12:15 +0800 Subject: iommu: Deprecate Intel and AMD cmdline methods to enable strict mode Now that the x86 drivers support iommu.strict, deprecate the custom methods. Signed-off-by: John Garry Acked-by: Robin Murphy Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1626088340-5838-2-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- Documentation/admin-guide/kernel-parameters.txt | 9 ++------- drivers/iommu/amd/init.c | 4 +++- drivers/iommu/intel/iommu.c | 1 + 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index bdb22006f713..a04d2748c99a 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -290,10 +290,7 @@ amd_iommu= [HW,X86-64] Pass parameters to the AMD IOMMU driver in the system. Possible values are: - fullflush - enable flushing of IO/TLB entries when - they are unmapped. Otherwise they are - flushed before they will be reused, which - is a lot of faster + fullflush - Deprecated, equivalent to iommu.strict=1 off - do not initialize any AMD IOMMU found in the system force_isolation - Force device isolation for all @@ -1944,9 +1941,7 @@ this case, gfx device will use physical address for DMA. strict [Default Off] - With this option on every unmap_single operation will - result in a hardware IOTLB flush operation as opposed - to batching them for performance. + Deprecated, equivalent to iommu.strict=1. sp_off [Default Off] By default, super page will be supported if Intel IOMMU has the capability. With this option, super page will diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 46280e6e1535..3a2fb805f11e 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -3098,8 +3098,10 @@ static int __init parse_amd_iommu_intr(char *str) static int __init parse_amd_iommu_options(char *str) { for (; *str; ++str) { - if (strncmp(str, "fullflush", 9) == 0) + if (strncmp(str, "fullflush", 9) == 0) { + pr_warn("amd_iommu=fullflush deprecated; use iommu.strict=1 instead\n"); amd_iommu_unmap_flush = true; + } if (strncmp(str, "force_enable", 12) == 0) amd_iommu_force_enable = true; if (strncmp(str, "off", 3) == 0) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index dd22fc7d5176..c6da5dadd12e 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -454,6 +454,7 @@ static int __init intel_iommu_setup(char *str) pr_warn("intel_iommu=forcedac deprecated; use iommu.forcedac instead\n"); iommu_dma_forcedac = true; } else if (!strncmp(str, "strict", 6)) { + pr_warn("intel_iommu=strict deprecated; use iommu.strict=1 instead\n"); pr_info("Disable batched IOTLB flush\n"); intel_iommu_strict = 1; } else if (!strncmp(str, "sp_off", 6)) { -- cgit v1.2.3-70-g09d2 From d8577d2e331dc06f5871afa6b76035dd8b74c903 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 12 Jul 2021 19:12:16 +0800 Subject: iommu: Print strict or lazy mode at init time As well as the default domain type, it's useful to know whether strict or lazy for DMA domains, so add this info in a separate print. The (stict/lazy) mode may be also set via iommu.strict earlyparm, but this will be processed prior to iommu_subsys_init(), so that print will be accurate for drivers which don't set the mode via custom means. For the drivers which set the mode via custom means - AMD and Intel drivers - they maintain prints to inform a change in policy or that custom cmdline methods to change policy are deprecated. Signed-off-by: John Garry Reviewed-by: Robin Murphy Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1626088340-5838-3-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 70a729ce88b1..69d7d4865668 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -139,6 +139,11 @@ static int __init iommu_subsys_init(void) (iommu_cmd_line & IOMMU_CMD_LINE_DMA_API) ? "(set via kernel command line)" : ""); + pr_info("DMA domain TLB invalidation policy: %s mode %s\n", + iommu_dma_strict ? "strict" : "lazy", + (iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ? + "(set via kernel command line)" : ""); + return 0; } subsys_initcall(iommu_subsys_init); -- cgit v1.2.3-70-g09d2 From 712d8f205835c1d170e85d7811da3d9f36d8fab7 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 12 Jul 2021 19:12:17 +0800 Subject: iommu: Enhance IOMMU default DMA mode build options First, add build options IOMMU_DEFAULT_{LAZY|STRICT}, so that we have the opportunity to set {lazy|strict} mode as default at build time. Then put the two config options in an choice, as they are mutually exclusive. [jpg: Make choice between strict and lazy only (and not passthrough)] Signed-off-by: Zhen Lei Signed-off-by: John Garry Reviewed-by: Robin Murphy Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1626088340-5838-4-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- Documentation/admin-guide/kernel-parameters.txt | 3 +- drivers/iommu/Kconfig | 40 +++++++++++++++++++++++++ drivers/iommu/iommu.c | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index a04d2748c99a..90b525cf0ec2 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2042,9 +2042,10 @@ throughput at the cost of reduced device isolation. Will fall back to strict mode if not supported by the relevant IOMMU driver. - 1 - Strict mode (default). + 1 - Strict mode. DMA unmap operations invalidate IOMMU hardware TLBs synchronously. + unset - Use value of CONFIG_IOMMU_DEFAULT_{LAZY,STRICT}. Note: on x86, the default behaviour depends on the equivalent driver-specific parameters, but a strict mode explicitly specified by either method takes diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 07b7c25cbed8..9cd5d7afc766 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -90,6 +90,46 @@ config IOMMU_DEFAULT_PASSTHROUGH If unsure, say N here. +choice + prompt "IOMMU default DMA IOTLB invalidation mode" + depends on IOMMU_DMA + + default IOMMU_DEFAULT_STRICT + help + This option allows an IOMMU DMA IOTLB invalidation mode to be + chosen at build time, to override the default mode of each ARCH, + removing the need to pass in kernel parameters through command line. + It is still possible to provide common boot params to override this + config. + + If unsure, keep the default. + +config IOMMU_DEFAULT_STRICT + bool "strict" + help + For every IOMMU DMA unmap operation, the flush operation of IOTLB and + the free operation of IOVA are guaranteed to be done in the unmap + function. + +config IOMMU_DEFAULT_LAZY + bool "lazy" + help + Support lazy mode, where for every IOMMU DMA unmap operation, the + flush operation of IOTLB and the free operation of IOVA are deferred. + They are only guaranteed to be done before the related IOVA will be + reused. + + The isolation provided in this mode is not as secure as STRICT mode, + such that a vulnerable time window may be created between the DMA + unmap and the mappings cached in the IOMMU IOTLB or device TLB + finally being invalidated, where the device could still access the + memory which has already been unmapped by the device driver. + However this mode may provide better performance in high throughput + scenarios, and is still considerably more secure than passthrough + mode or no IOMMU. + +endchoice + config OF_IOMMU def_bool y depends on OF && IOMMU_API diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 69d7d4865668..bd9ccce387c5 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -30,7 +30,7 @@ static struct kset *iommu_group_kset; static DEFINE_IDA(iommu_group_ida); static unsigned int iommu_def_domain_type __read_mostly; -static bool iommu_dma_strict __read_mostly = true; +static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_STRICT); static u32 iommu_cmd_line __read_mostly; struct iommu_group { -- cgit v1.2.3-70-g09d2 From d0e108b8e962e0aae65dc74ffda63b93b6ef32f4 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 12 Jul 2021 19:12:18 +0800 Subject: iommu/vt-d: Add support for IOMMU default DMA mode build options Make IOMMU_DEFAULT_LAZY default for when INTEL_IOMMU config is set, as is current behaviour. Also delete global flag intel_iommu_strict: - In intel_iommu_setup(), call iommu_set_dma_strict(true) directly. Also remove the print, as iommu_subsys_init() prints the mode and we have already marked this param as deprecated. - For cap_caching_mode() check in intel_iommu_setup(), call iommu_set_dma_strict(true) directly; also reword the accompanying print with a level downgrade and also add the missing '\n'. - For Ironlake GPU, again call iommu_set_dma_strict(true) directly and keep the accompanying print. [jpg: Remove intel_iommu_strict] Signed-off-by: Zhen Lei Signed-off-by: John Garry Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1626088340-5838-5-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 1 + drivers/iommu/intel/iommu.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 9cd5d7afc766..265d7a6c9d3a 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -94,6 +94,7 @@ choice prompt "IOMMU default DMA IOTLB invalidation mode" depends on IOMMU_DMA + default IOMMU_DEFAULT_LAZY if INTEL_IOMMU default IOMMU_DEFAULT_STRICT help This option allows an IOMMU DMA IOTLB invalidation mode to be diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index c6da5dadd12e..6fd004a1a66d 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -361,7 +361,6 @@ int intel_iommu_enabled = 0; EXPORT_SYMBOL_GPL(intel_iommu_enabled); static int dmar_map_gfx = 1; -static int intel_iommu_strict; static int intel_iommu_superpage = 1; static int iommu_identity_mapping; static int iommu_skip_te_disable; @@ -455,8 +454,7 @@ static int __init intel_iommu_setup(char *str) iommu_dma_forcedac = true; } else if (!strncmp(str, "strict", 6)) { pr_warn("intel_iommu=strict deprecated; use iommu.strict=1 instead\n"); - pr_info("Disable batched IOTLB flush\n"); - intel_iommu_strict = 1; + iommu_set_dma_strict(true); } else if (!strncmp(str, "sp_off", 6)) { pr_info("Disable supported super page\n"); intel_iommu_superpage = 0; @@ -4394,9 +4392,9 @@ int __init intel_iommu_init(void) * is likely to be much lower than the overhead of synchronizing * the virtual and physical IOMMU page-tables. */ - if (!intel_iommu_strict && cap_caching_mode(iommu->cap)) { - pr_warn("IOMMU batching is disabled due to virtualization"); - intel_iommu_strict = 1; + if (cap_caching_mode(iommu->cap)) { + pr_info_once("IOMMU batching disallowed due to virtualization\n"); + iommu_set_dma_strict(true); } iommu_device_sysfs_add(&iommu->iommu, NULL, intel_iommu_groups, @@ -4405,7 +4403,6 @@ int __init intel_iommu_init(void) } up_read(&dmar_global_lock); - iommu_set_dma_strict(intel_iommu_strict); bus_set_iommu(&pci_bus_type, &intel_iommu_ops); if (si_domain && !hw_pass_through) register_memory_notifier(&intel_iommu_memory_nb); @@ -5715,8 +5712,8 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) } else if (dmar_map_gfx) { /* we have to ensure the gfx device is idle before we flush */ pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n"); - intel_iommu_strict = 1; - } + iommu_set_dma_strict(true); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt); -- cgit v1.2.3-70-g09d2 From 02252b3bfe9f98770a8d902925711676ff5bd766 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Mon, 12 Jul 2021 19:12:19 +0800 Subject: iommu/amd: Add support for IOMMU default DMA mode build options Make IOMMU_DEFAULT_LAZY default for when AMD_IOMMU config is set, which matches current behaviour. For "fullflush" param, just call iommu_set_dma_strict(true) directly. Since we get a strict vs lazy mode print already in iommu_subsys_init(), and maintain a deprecation print when "fullflush" param is passed, drop the prints in amd_iommu_init_dma_ops(). Finally drop global flag amd_iommu_unmap_flush, as it has no longer has any purpose. [jpg: Rebase for relocated file and drop amd_iommu_unmap_flush] Signed-off-by: Zhen Lei Signed-off-by: John Garry Link: https://lore.kernel.org/r/1626088340-5838-6-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 2 +- drivers/iommu/amd/amd_iommu_types.h | 6 ------ drivers/iommu/amd/init.c | 3 +-- drivers/iommu/amd/iommu.c | 6 ------ 4 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 265d7a6c9d3a..c84da8205be7 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -94,7 +94,7 @@ choice prompt "IOMMU default DMA IOTLB invalidation mode" depends on IOMMU_DMA - default IOMMU_DEFAULT_LAZY if INTEL_IOMMU + default IOMMU_DEFAULT_LAZY if (AMD_IOMMU || INTEL_IOMMU) default IOMMU_DEFAULT_STRICT help This option allows an IOMMU DMA IOTLB invalidation mode to be diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h index 94c1a7a9876d..8dbe61e2b3c1 100644 --- a/drivers/iommu/amd/amd_iommu_types.h +++ b/drivers/iommu/amd/amd_iommu_types.h @@ -779,12 +779,6 @@ extern u16 amd_iommu_last_bdf; /* allocation bitmap for domain ids */ extern unsigned long *amd_iommu_pd_alloc_bitmap; -/* - * If true, the addresses will be flushed on unmap time, not when - * they are reused - */ -extern bool amd_iommu_unmap_flush; - /* Smallest max PASID supported by any IOMMU in the system */ extern u32 amd_iommu_max_pasid; diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 3a2fb805f11e..1e641cb6dddc 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -161,7 +161,6 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have to handle */ LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings we find in ACPI */ -bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the system */ @@ -3100,7 +3099,7 @@ static int __init parse_amd_iommu_options(char *str) for (; *str; ++str) { if (strncmp(str, "fullflush", 9) == 0) { pr_warn("amd_iommu=fullflush deprecated; use iommu.strict=1 instead\n"); - amd_iommu_unmap_flush = true; + iommu_set_dma_strict(true); } if (strncmp(str, "force_enable", 12) == 0) amd_iommu_force_enable = true; diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 811a49a95d04..52fe2326042a 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1775,12 +1775,6 @@ void amd_iommu_domain_update(struct protection_domain *domain) static void __init amd_iommu_init_dma_ops(void) { swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; - - if (amd_iommu_unmap_flush) - pr_info("IO/TLB flush on unmap enabled\n"); - else - pr_info("Lazy IO/TLB flushing enabled\n"); - iommu_set_dma_strict(amd_iommu_unmap_flush); } int __init amd_iommu_init_api(void) -- cgit v1.2.3-70-g09d2 From 308723e3580027f0cd7c86a5edfe6b5acb6863d2 Mon Sep 17 00:00:00 2001 From: John Garry Date: Mon, 12 Jul 2021 19:12:20 +0800 Subject: iommu: Remove mode argument from iommu_set_dma_strict() We only ever now set strict mode enabled in iommu_set_dma_strict(), so just remove the argument. Signed-off-by: John Garry Reviewed-by: Robin Murphy Reviewed-by: Lu Baolu Link: https://lore.kernel.org/r/1626088340-5838-7-git-send-email-john.garry@huawei.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/init.c | 2 +- drivers/iommu/intel/iommu.c | 6 +++--- drivers/iommu/iommu.c | 5 ++--- include/linux/iommu.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 1e641cb6dddc..6e12a615117b 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -3099,7 +3099,7 @@ static int __init parse_amd_iommu_options(char *str) for (; *str; ++str) { if (strncmp(str, "fullflush", 9) == 0) { pr_warn("amd_iommu=fullflush deprecated; use iommu.strict=1 instead\n"); - iommu_set_dma_strict(true); + iommu_set_dma_strict(); } if (strncmp(str, "force_enable", 12) == 0) amd_iommu_force_enable = true; diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 6fd004a1a66d..da9afa730df1 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -454,7 +454,7 @@ static int __init intel_iommu_setup(char *str) iommu_dma_forcedac = true; } else if (!strncmp(str, "strict", 6)) { pr_warn("intel_iommu=strict deprecated; use iommu.strict=1 instead\n"); - iommu_set_dma_strict(true); + iommu_set_dma_strict(); } else if (!strncmp(str, "sp_off", 6)) { pr_info("Disable supported super page\n"); intel_iommu_superpage = 0; @@ -4394,7 +4394,7 @@ int __init intel_iommu_init(void) */ if (cap_caching_mode(iommu->cap)) { pr_info_once("IOMMU batching disallowed due to virtualization\n"); - iommu_set_dma_strict(true); + iommu_set_dma_strict(); } iommu_device_sysfs_add(&iommu->iommu, NULL, intel_iommu_groups, @@ -5712,7 +5712,7 @@ static void quirk_calpella_no_shadow_gtt(struct pci_dev *dev) } else if (dmar_map_gfx) { /* we have to ensure the gfx device is idle before we flush */ pci_info(dev, "Disabling batched IOTLB flush on Ironlake\n"); - iommu_set_dma_strict(true); + iommu_set_dma_strict(); } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index bd9ccce387c5..eeea5e5c4d10 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -350,10 +350,9 @@ static int __init iommu_dma_setup(char *str) } early_param("iommu.strict", iommu_dma_setup); -void iommu_set_dma_strict(bool strict) +void iommu_set_dma_strict(void) { - if (strict || !(iommu_cmd_line & IOMMU_CMD_LINE_STRICT)) - iommu_dma_strict = strict; + iommu_dma_strict = true; } bool iommu_get_dma_strict(struct iommu_domain *domain) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index d7989d4a7404..4997c78e2670 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -485,7 +485,7 @@ int iommu_enable_nesting(struct iommu_domain *domain); int iommu_set_pgtable_quirks(struct iommu_domain *domain, unsigned long quirks); -void iommu_set_dma_strict(bool val); +void iommu_set_dma_strict(void); bool iommu_get_dma_strict(struct iommu_domain *domain); extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev, -- cgit v1.2.3-70-g09d2 From 13b6eb6e1c98c47f7e0d6c74e8b22cfe189a84dd Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 15 Jul 2021 14:04:24 +0100 Subject: iommu: Streamline iommu_iova_to_phys() If people are going to insist on calling iommu_iova_to_phys() pointlessly and expecting it to work, we can at least do ourselves a favour by handling those cases in the core code, rather than repeatedly across an inconsistent handful of drivers. Since all the existing drivers implement the internal callback, and any future ones are likely to want to work with iommu-dma which relies on iova_to_phys a fair bit, we may as well remove that currently-redundant check as well and consider it mandatory. Reviewed-by: Lu Baolu Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/f564f3f6ff731b898ff7a898919bf871c2c7745a.1626354264.git.robin.murphy@arm.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/io_pgtable.c | 3 --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 3 --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 3 --- drivers/iommu/iommu.c | 5 ++++- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c index bb0ee5c9fde7..182c93a43efd 100644 --- a/drivers/iommu/amd/io_pgtable.c +++ b/drivers/iommu/amd/io_pgtable.c @@ -493,9 +493,6 @@ static phys_addr_t iommu_v1_iova_to_phys(struct io_pgtable_ops *ops, unsigned lo unsigned long offset_mask, pte_pgsize; u64 *pte, __pte; - if (pgtable->mode == PAGE_MODE_NONE) - return iova; - pte = fetch_pte(pgtable, iova, &pte_pgsize); if (!pte || !IOMMU_PTE_PRESENT(*pte)) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 235f9bdaeaf2..6346f21726f4 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2488,9 +2488,6 @@ arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; - if (domain->type == IOMMU_DOMAIN_IDENTITY) - return iova; - if (!ops) return 0; diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 5ed4408d4b28..ac21170fa208 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1322,9 +1322,6 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops; - if (domain->type == IOMMU_DOMAIN_IDENTITY) - return iova; - if (!ops) return 0; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index eeea5e5c4d10..f2cda9950bd5 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2372,7 +2372,10 @@ EXPORT_SYMBOL_GPL(iommu_detach_group); phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { - if (unlikely(domain->ops->iova_to_phys == NULL)) + if (domain->type == IOMMU_DOMAIN_IDENTITY) + return iova; + + if (domain->type == IOMMU_DOMAIN_BLOCKED) return 0; return domain->ops->iova_to_phys(domain, iova); -- cgit v1.2.3-70-g09d2 From 8bc54824da4e8fcf0ed679cf09ac32f23d83254a Mon Sep 17 00:00:00 2001 From: Xiyu Yang via iommu Date: Mon, 19 Jul 2021 16:32:58 +0800 Subject: iommu/amd: Convert from atomic_t to refcount_t on pasid_state->count refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Reviewed-by: Suravee Suthikulpanit Link: https://lore.kernel.org/r/1626683578-64214-1-git-send-email-xiyuyang19@fudan.edu.cn Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu_v2.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c index f8d4ad421e07..a9e568276c99 100644 --- a/drivers/iommu/amd/iommu_v2.c +++ b/drivers/iommu/amd/iommu_v2.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) "AMD-Vi: " fmt +#include #include #include #include @@ -33,7 +34,7 @@ struct pri_queue { struct pasid_state { struct list_head list; /* For global state-list */ - atomic_t count; /* Reference count */ + refcount_t count; /* Reference count */ unsigned mmu_notifier_count; /* Counting nested mmu_notifier calls */ struct mm_struct *mm; /* mm_struct for the faults */ @@ -242,7 +243,7 @@ static struct pasid_state *get_pasid_state(struct device_state *dev_state, ret = *ptr; if (ret) - atomic_inc(&ret->count); + refcount_inc(&ret->count); out_unlock: spin_unlock_irqrestore(&dev_state->lock, flags); @@ -257,14 +258,14 @@ static void free_pasid_state(struct pasid_state *pasid_state) static void put_pasid_state(struct pasid_state *pasid_state) { - if (atomic_dec_and_test(&pasid_state->count)) + if (refcount_dec_and_test(&pasid_state->count)) wake_up(&pasid_state->wq); } static void put_pasid_state_wait(struct pasid_state *pasid_state) { - atomic_dec(&pasid_state->count); - wait_event(pasid_state->wq, !atomic_read(&pasid_state->count)); + refcount_dec(&pasid_state->count); + wait_event(pasid_state->wq, !refcount_read(&pasid_state->count)); free_pasid_state(pasid_state); } @@ -624,7 +625,7 @@ int amd_iommu_bind_pasid(struct pci_dev *pdev, u32 pasid, goto out; - atomic_set(&pasid_state->count, 1); + refcount_set(&pasid_state->count, 1); init_waitqueue_head(&pasid_state->wq); spin_lock_init(&pasid_state->lock); -- cgit v1.2.3-70-g09d2 From a886d5a7e67bc403b8e51ab50c10324bcdbb686f Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 20 Jul 2021 10:06:13 +0800 Subject: iommu/vt-d: Report real pgsize bitmap to iommu core The pgsize bitmap is used to advertise the page sizes our hardware supports to the IOMMU core, which will then use this information to split physically contiguous memory regions it is mapping into page sizes that we support. Traditionally the IOMMU core just handed us the mappings directly, after making sure the size is an order of a 4KiB page and that the mapping has natural alignment. To retain this behavior, we currently advertise that we support all page sizes that are an order of 4KiB. We are about to utilize the new IOMMU map/unmap_pages APIs. We could change this to advertise the real page sizes we support. Signed-off-by: Lu Baolu Link: https://lore.kernel.org/r/20210720020615.4144323-2-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel --- drivers/iommu/intel/iommu.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index da9afa730df1..4984cba8c00f 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -85,24 +85,6 @@ #define LEVEL_STRIDE (9) #define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) -/* - * This bitmap is used to advertise the page sizes our hardware support - * to the IOMMU core, which will then use this information to split - * physically contiguous memory regions it is mapping into page sizes - * that we support. - * - * Traditionally the IOMMU core just handed us the mappings directly, - * after making sure the size is an order of a 4KiB page and that the - * mapping has natural alignment. - * - * To retain this behavior, we currently advertise that we support - * all page sizes that are an order of 4KiB. - * - * If at some point we'd like to utilize the IOMMU core's new behavior, - * we could change this to advertise the real page sizes we support. - */ -#define INTEL_IOMMU_PGSIZES (~0xFFFUL) - static inline int agaw_to_level(int agaw) { return agaw + 2; @@ -735,6 +717,23 @@ static int domain_update_device_node(struct dmar_domain *domain) static void domain_update_iotlb(struct dmar_domain *domain); +/* Return the super pagesize bitmap if supported. */ +static unsigned long domain_super_pgsize_bitmap(struct dmar_domain *domain) +{ + unsigned long bitmap = 0; + + /* + * 1-level super page supports page size of 2MiB, 2-level super page + * supports page size of both 2MiB and 1GiB. + */ + if (domain->iommu_superpage == 1) + bitmap |= SZ_2M; + else if (domain->iommu_superpage == 2) + bitmap |= SZ_2M | SZ_1G; + + return bitmap; +} + /* Some capabilities may be different across iommus */ static void domain_update_iommu_cap(struct dmar_domain *domain) { @@ -761,6 +760,7 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) else domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw); + domain->domain.pgsize_bitmap |= domain_super_pgsize_bitmap(domain); domain_update_iotlb(domain); } @@ -5609,7 +5609,7 @@ const struct iommu_ops intel_iommu_ops = { .dev_disable_feat = intel_iommu_dev_disable_feat, .is_attach_deferred = intel_iommu_is_attach_deferred, .def_domain_type = device_def_domain_type, - .pgsize_bitmap = INTEL_IOMMU_PGSIZES, + .pgsize_bitmap = SZ_4K, #ifdef CONFIG_INTEL_IOMMU_SVM .cache_invalidate = intel_iommu_sva_invalidate, .sva_bind_gpasid = intel_svm_bind_gpasid, -- cgit v1.2.3-70-g09d2 From 3f34f125977685e591def32984c77e23a86075b0 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 20 Jul 2021 10:06:14 +0800 Subject: iommu/vt-d: Implement map/unmap_pages() iommu_ops callback Implement the map_pages() and unmap_pages() callback for the Intel IOMMU driver to allow calls from iommu core to map and unmap multiple pages of the same size in one call. With map/unmap_pages() implemented, the prior map/unmap callbacks are deprecated. Signed-off-by: Lu Baolu Link: https://lore.kernel.org/r/20210720020615.4144323-3-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel --- drivers/iommu/intel/iommu.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 4984cba8c00f..e4c74296b34a 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -5065,6 +5065,28 @@ static int intel_iommu_map(struct iommu_domain *domain, hpa >> VTD_PAGE_SHIFT, size, prot); } +static int intel_iommu_map_pages(struct iommu_domain *domain, + unsigned long iova, phys_addr_t paddr, + size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped) +{ + unsigned long pgshift = __ffs(pgsize); + size_t size = pgcount << pgshift; + int ret; + + if (pgsize != SZ_4K && pgsize != SZ_2M && pgsize != SZ_1G) + return -EINVAL; + + if (!IS_ALIGNED(iova | paddr, pgsize)) + return -EINVAL; + + ret = intel_iommu_map(domain, iova, paddr, size, prot, gfp); + if (!ret && mapped) + *mapped = size; + + return ret; +} + static size_t intel_iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *gather) @@ -5094,6 +5116,17 @@ static size_t intel_iommu_unmap(struct iommu_domain *domain, return size; } +static size_t intel_iommu_unmap_pages(struct iommu_domain *domain, + unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather) +{ + unsigned long pgshift = __ffs(pgsize); + size_t size = pgcount << pgshift; + + return intel_iommu_unmap(domain, iova, size, gather); +} + static void intel_iommu_tlb_sync(struct iommu_domain *domain, struct iommu_iotlb_gather *gather) { @@ -5591,9 +5624,9 @@ const struct iommu_ops intel_iommu_ops = { .aux_attach_dev = intel_iommu_aux_attach_device, .aux_detach_dev = intel_iommu_aux_detach_device, .aux_get_pasid = intel_iommu_aux_get_pasid, - .map = intel_iommu_map, + .map_pages = intel_iommu_map_pages, + .unmap_pages = intel_iommu_unmap_pages, .iotlb_sync_map = intel_iommu_iotlb_sync_map, - .unmap = intel_iommu_unmap, .flush_iotlb_all = intel_flush_iotlb_all, .iotlb_sync = intel_iommu_tlb_sync, .iova_to_phys = intel_iommu_iova_to_phys, -- cgit v1.2.3-70-g09d2 From 75cc1018a9e1e57d4ae43a101fc08a070894d439 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Tue, 20 Jul 2021 10:06:15 +0800 Subject: iommu/vt-d: Move clflush'es from iotlb_sync_map() to map_pages() As the Intel VT-d driver has switched to use the iommu_ops.map_pages() callback, multiple pages of the same size will be mapped in a call. There's no need to put the clflush'es in iotlb_sync_map() callback. Move them back into __domain_mapping() to simplify the code. Signed-off-by: Lu Baolu Link: https://lore.kernel.org/r/20210720020615.4144323-4-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel --- drivers/iommu/intel/iommu.c | 48 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index e4c74296b34a..c12cc955389a 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2333,9 +2333,9 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, unsigned long phys_pfn, unsigned long nr_pages, int prot) { + struct dma_pte *first_pte = NULL, *pte = NULL; unsigned int largepage_lvl = 0; unsigned long lvl_pages = 0; - struct dma_pte *pte = NULL; phys_addr_t pteval; u64 attr; @@ -2368,6 +2368,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, pte = pfn_to_dma_pte(domain, iov_pfn, &largepage_lvl); if (!pte) return -ENOMEM; + first_pte = pte; + /* It is large page*/ if (largepage_lvl > 1) { unsigned long end_pfn; @@ -2415,14 +2417,14 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, * recalculate 'pte' and switch back to smaller pages for the * end of the mapping, if the trailing size is not enough to * use another superpage (i.e. nr_pages < lvl_pages). - * - * We leave clflush for the leaf pte changes to iotlb_sync_map() - * callback. */ pte++; if (!nr_pages || first_pte_in_page(pte) || - (largepage_lvl > 1 && nr_pages < lvl_pages)) + (largepage_lvl > 1 && nr_pages < lvl_pages)) { + domain_flush_cache(domain, first_pte, + (void *)pte - (void *)first_pte); pte = NULL; + } } return 0; @@ -5563,39 +5565,6 @@ static bool risky_device(struct pci_dev *pdev) return false; } -static void clflush_sync_map(struct dmar_domain *domain, unsigned long clf_pfn, - unsigned long clf_pages) -{ - struct dma_pte *first_pte = NULL, *pte = NULL; - unsigned long lvl_pages = 0; - int level = 0; - - while (clf_pages > 0) { - if (!pte) { - level = 0; - pte = pfn_to_dma_pte(domain, clf_pfn, &level); - if (WARN_ON(!pte)) - return; - first_pte = pte; - lvl_pages = lvl_to_nr_pages(level); - } - - if (WARN_ON(!lvl_pages || clf_pages < lvl_pages)) - return; - - clf_pages -= lvl_pages; - clf_pfn += lvl_pages; - pte++; - - if (!clf_pages || first_pte_in_page(pte) || - (level > 1 && clf_pages < lvl_pages)) { - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - pte = NULL; - } - } -} - static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain, unsigned long iova, size_t size) { @@ -5605,9 +5574,6 @@ static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain, struct intel_iommu *iommu; int iommu_id; - if (!dmar_domain->iommu_coherency) - clflush_sync_map(dmar_domain, pfn, pages); - for_each_domain_iommu(iommu_id, dmar_domain) { iommu = g_iommus[iommu_id]; __mapping_notify_one(iommu, dmar_domain, pfn, pages); -- cgit v1.2.3-70-g09d2 From d28b1e03dc8d1070538ca3ea3f4e6732109ddf42 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 19 Jul 2021 15:38:10 +0100 Subject: clk: renesas: r9a07g044: Add entry for fixed clock P0_DIV2 Add entry for fixed core clock P0_DIV2 and assign LAST_DT_CORE_CLK to R9A07G044_CLK_P0_DIV2. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Link: https://lore.kernel.org/r/20210719143811.2135-5-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a07g044-cpg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c index 9e9e8fb6d00d..4c94b94c4125 100644 --- a/drivers/clk/renesas/r9a07g044-cpg.c +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -16,7 +16,7 @@ enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A07G044_OSCCLK, + LAST_DT_CORE_CLK = R9A07G044_CLK_P0_DIV2, /* External Input Clocks */ CLK_EXTAL, @@ -77,6 +77,7 @@ static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1), DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), + DEF_FIXED("P0_DIV2", R9A07G044_CLK_P0_DIV2, R9A07G044_CLK_P0, 1, 2), DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV2_4, DIVPL3B, dtable_1_32, CLK_DIVIDER_HIWORD_MASK), -- cgit v1.2.3-70-g09d2 From ee974d9625c405977ef5d9aedc476be1d0362ebf Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 21 Jul 2021 16:44:53 +0300 Subject: iommu/amd: Fix printing of IOMMU events when rate limiting kicks in For the printing of RMP_HW_ERROR / RMP_PAGE_FAULT / IO_PAGE_FAULT events, the AMD IOMMU code uses such logic: if (pdev) dev_data = dev_iommu_priv_get(&pdev->dev); if (dev_data && __ratelimit(&dev_data->rs)) { pci_err(pdev, ... } else { printk_ratelimit() / pr_err{,_ratelimited}(... } This means that if we receive an event for a PCI devid which actually does have a struct pci_dev and an attached struct iommu_dev_data, but rate limiting kicks in, we'll fall back to the non-PCI branch of the test, and print the event in a different format. Fix this by changing the logic to: if (dev_data) { if (__ratelimit(&dev_data->rs)) { pci_err(pdev, ... } } else { pr_err_ratelimited(... } Suggested-by: Suravee Suthikulpanit Signed-off-by: Lennert Buytenhek Reviewed-by: Suravee Suthikulpanit Link: https://lore.kernel.org/r/YPgk1dD1gPMhJXgY@wantstofly.org Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 811a49a95d04..a7d6d78147b7 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -425,9 +425,11 @@ static void amd_iommu_report_rmp_hw_error(volatile u32 *event) if (pdev) dev_data = dev_iommu_priv_get(&pdev->dev); - if (dev_data && __ratelimit(&dev_data->rs)) { - pci_err(pdev, "Event logged [RMP_HW_ERROR vmg_tag=0x%04x, spa=0x%llx, flags=0x%04x]\n", - vmg_tag, spa, flags); + if (dev_data) { + if (__ratelimit(&dev_data->rs)) { + pci_err(pdev, "Event logged [RMP_HW_ERROR vmg_tag=0x%04x, spa=0x%llx, flags=0x%04x]\n", + vmg_tag, spa, flags); + } } else { pr_err_ratelimited("Event logged [RMP_HW_ERROR device=%02x:%02x.%x, vmg_tag=0x%04x, spa=0x%llx, flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), @@ -456,9 +458,11 @@ static void amd_iommu_report_rmp_fault(volatile u32 *event) if (pdev) dev_data = dev_iommu_priv_get(&pdev->dev); - if (dev_data && __ratelimit(&dev_data->rs)) { - pci_err(pdev, "Event logged [RMP_PAGE_FAULT vmg_tag=0x%04x, gpa=0x%llx, flags_rmp=0x%04x, flags=0x%04x]\n", - vmg_tag, gpa, flags_rmp, flags); + if (dev_data) { + if (__ratelimit(&dev_data->rs)) { + pci_err(pdev, "Event logged [RMP_PAGE_FAULT vmg_tag=0x%04x, gpa=0x%llx, flags_rmp=0x%04x, flags=0x%04x]\n", + vmg_tag, gpa, flags_rmp, flags); + } } else { pr_err_ratelimited("Event logged [RMP_PAGE_FAULT device=%02x:%02x.%x, vmg_tag=0x%04x, gpa=0x%llx, flags_rmp=0x%04x, flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), @@ -480,11 +484,13 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id, if (pdev) dev_data = dev_iommu_priv_get(&pdev->dev); - if (dev_data && __ratelimit(&dev_data->rs)) { - pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n", - domain_id, address, flags); - } else if (printk_ratelimit()) { - pr_err("Event logged [IO_PAGE_FAULT device=%02x:%02x.%x domain=0x%04x address=0x%llx flags=0x%04x]\n", + if (dev_data) { + if (__ratelimit(&dev_data->rs)) { + pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n", + domain_id, address, flags); + } + } else { + pr_err_ratelimited("Event logged [IO_PAGE_FAULT device=%02x:%02x.%x domain=0x%04x address=0x%llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), domain_id, address, flags); } -- cgit v1.2.3-70-g09d2 From b8da302e2955fe4d41eb9d48199242674d77dbe0 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Thu, 24 Jun 2021 19:14:17 +0200 Subject: PCI: Call Max Payload Size-related fixup quirks early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_device_add() calls HEADER fixups after pci_configure_device(), which configures Max Payload Size. Convert MPS-related fixups to EARLY fixups so pci_configure_mps() takes them into account. Fixes: 27d868b5e6cfa ("PCI: Set MPS to match upstream bridge") Link: https://lore.kernel.org/r/20210624171418.27194-1-kabel@kernel.org Signed-off-by: Marek Behún Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org --- drivers/pci/quirks.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6d74386eadc2..c8a7f8d7123a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3234,12 +3234,12 @@ static void fixup_mpss_256(struct pci_dev *dev) { dev->pcie_mpss = 1; /* 256 bytes */ } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); /* * Intel 5000 and 5100 Memory controllers have an erratum with read completion -- cgit v1.2.3-70-g09d2 From b12d93e9958e028856cbcb061b6e64728ca07755 Mon Sep 17 00:00:00 2001 From: Marek Behún Date: Thu, 24 Jun 2021 19:14:18 +0200 Subject: PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ASMedia ASM1062 SATA controller advertises Max_Payload_Size_Supported of 512, but in fact it cannot handle incoming TLPs with payload size of 512. We discovered this issue on PCIe controllers capable of MPS = 512 (Aardvark and DesignWare), where the issue presents itself as an External Abort. Bjorn Helgaas says: Probably ASM1062 reports a Malformed TLP error when it receives a data payload of 512 bytes, and Aardvark, DesignWare, etc convert this to an arm64 External Abort. [1] To avoid this problem, limit the ASM1062 Max Payload Size Supported to 256 bytes, so we set the Max Payload Size of devices that may send TLPs to the ASM1062 to 256 or less. [1] https://lore.kernel.org/linux-pci/20210601170907.GA1949035@bjorn-Precision-5520/ BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212695 Link: https://lore.kernel.org/r/20210624171418.27194-2-kabel@kernel.org Reported-by: Rötti Signed-off-by: Marek Behún Signed-off-by: Bjorn Helgaas Reviewed-by: Krzysztof Wilczyński Reviewed-by: Pali Rohár Cc: stable@vger.kernel.org --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c8a7f8d7123a..664233c2ef29 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3240,6 +3240,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x0612, fixup_mpss_256); /* * Intel 5000 and 5100 Memory controllers have an erratum with read completion -- cgit v1.2.3-70-g09d2 From f9398f15605a50110bf570aaa361163a85113dd1 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 23 Jul 2021 15:19:31 -0700 Subject: lib/test_stackinit: Fix static initializer test The static initializer test got accidentally converted to a dynamic initializer. Fix this and retain the giant padding hole without using an aligned struct member. Fixes: 50ceaa95ea09 ("lib: Introduce test_stackinit module") Cc: Ard Biesheuvel Cc: stable@vger.kernel.org Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20210723221933.3431999-2-keescook@chromium.org --- lib/test_stackinit.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/lib/test_stackinit.c b/lib/test_stackinit.c index f93b1e145ada..16b1d3a3a497 100644 --- a/lib/test_stackinit.c +++ b/lib/test_stackinit.c @@ -67,10 +67,10 @@ static bool range_contains(char *haystack_start, size_t haystack_size, #define INIT_STRUCT_none /**/ #define INIT_STRUCT_zero = { } #define INIT_STRUCT_static_partial = { .two = 0, } -#define INIT_STRUCT_static_all = { .one = arg->one, \ - .two = arg->two, \ - .three = arg->three, \ - .four = arg->four, \ +#define INIT_STRUCT_static_all = { .one = 0, \ + .two = 0, \ + .three = 0, \ + .four = 0, \ } #define INIT_STRUCT_dynamic_partial = { .two = arg->two, } #define INIT_STRUCT_dynamic_all = { .one = arg->one, \ @@ -84,8 +84,7 @@ static bool range_contains(char *haystack_start, size_t haystack_size, var.one = 0; \ var.two = 0; \ var.three = 0; \ - memset(&var.four, 0, \ - sizeof(var.four)) + var.four = 0 /* * @name: unique string name for the test @@ -210,18 +209,13 @@ struct test_small_hole { unsigned long four; }; -/* Try to trigger unhandled padding in a structure. */ -struct test_aligned { - u32 internal1; - u64 internal2; -} __aligned(64); - +/* Trigger unhandled padding in a structure. */ struct test_big_hole { u8 one; u8 two; u8 three; /* 61 byte padding hole here. */ - struct test_aligned four; + u8 four __aligned(64); } __aligned(64); struct test_trailing_hole { -- cgit v1.2.3-70-g09d2 From 3abc16af57c9939724df92fcbda296b25cc95168 Mon Sep 17 00:00:00 2001 From: Patryk Duda Date: Tue, 18 May 2021 16:07:58 +0200 Subject: platform/chrome: cros_ec_proto: Send command again when timeout occurs Sometimes kernel is trying to probe Fingerprint MCU (FPMCU) when it hasn't initialized SPI yet. This can happen because FPMCU is restarted during system boot and kernel can send message in short window eg. between sysjump to RW and SPI initialization. Cc: # 4.4+ Signed-off-by: Patryk Duda Link: https://lore.kernel.org/r/20210518140758.29318-1-pdk@semihalf.com Signed-off-by: Benson Leung --- drivers/platform/chrome/cros_ec_proto.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index aa7f7aa77297..a7404d69b2d3 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -279,6 +279,15 @@ static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev, msg->insize = sizeof(struct ec_response_get_protocol_info); ret = send_command(ec_dev, msg); + /* + * Send command once again when timeout occurred. + * Fingerprint MCU (FPMCU) is restarted during system boot which + * introduces small window in which FPMCU won't respond for any + * messages sent by kernel. There is no need to wait before next + * attempt because we waited at least EC_MSG_DEADLINE_MS. + */ + if (ret == -ETIMEDOUT) + ret = send_command(ec_dev, msg); if (ret < 0) { dev_dbg(ec_dev->dev, -- cgit v1.2.3-70-g09d2 From 9d563236cca43fc4fe190b3be173444bd48e2a3b Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 13 Jul 2021 09:46:19 -0500 Subject: clk: socfpga: agilex: fix the parents of the psi_ref_clk The psi_ref_clk comes from the C2 node of the main_pll and periph_pll, not the C3. Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin Signed-off-by: Dinh Nguyen Link: https://lore.kernel.org/r/20210713144621.605140-1-dinguyen@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/socfpga/clk-agilex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index 1cb21ea79c64..9dffe9ba0e74 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -107,10 +107,10 @@ static const struct clk_parent_data gpio_db_free_mux[] = { }; static const struct clk_parent_data psi_ref_free_mux[] = { - { .fw_name = "main_pll_c3", - .name = "main_pll_c3", }, - { .fw_name = "peri_pll_c3", - .name = "peri_pll_c3", }, + { .fw_name = "main_pll_c2", + .name = "main_pll_c2", }, + { .fw_name = "peri_pll_c2", + .name = "peri_pll_c2", }, { .fw_name = "osc1", .name = "osc1", }, { .fw_name = "cb-intosc-hs-div2-clk", -- cgit v1.2.3-70-g09d2 From f817c132db679d492d96c60993fa2f2c67ab18d0 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 13 Jul 2021 09:46:20 -0500 Subject: clk: socfpga: agilex: fix up s2f_user0_clk representation Correct the s2f_user0_mux clock representation. Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin Signed-off-by: Dinh Nguyen Link: https://lore.kernel.org/r/20210713144621.605140-2-dinguyen@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/socfpga/clk-agilex.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index 9dffe9ba0e74..7baaa16dea7b 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -195,6 +195,13 @@ static const struct clk_parent_data sdmmc_mux[] = { .name = "boot_clk", }, }; +static const struct clk_parent_data s2f_user0_mux[] = { + { .fw_name = "s2f_user0_free_clk", + .name = "s2f_user0_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + static const struct clk_parent_data s2f_user1_mux[] = { { .fw_name = "s2f_user1_free_clk", .name = "s2f_user1_free_clk", }, @@ -319,6 +326,8 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { 4, 0x98, 0, 16, 0x88, 3, 0}, { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C, 5, 0, 0, 0, 0x88, 4, 4}, + { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux, ARRAY_SIZE(s2f_user0_mux), 0, 0x24, + 6, 0, 0, 0, 0x30, 2, 0}, { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0}, { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C, -- cgit v1.2.3-70-g09d2 From d17929eb1066d1c1653aae9bb4396a9f1d6602ac Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Tue, 13 Jul 2021 09:46:21 -0500 Subject: clk: socfpga: agilex: add the bypass register for s2f_usr0 clock Add the bypass register for the s2f_user0_clk. Fixes: 80c6b7a0894f ("clk: socfpga: agilex: add clock driver for the Agilex platform") Cc: stable@vger.kernel.org Signed-off-by: Kris Chaplin Signed-off-by: Dinh Nguyen Link: https://lore.kernel.org/r/20210713144621.605140-3-dinguyen@kernel.org Signed-off-by: Stephen Boyd --- drivers/clk/socfpga/clk-agilex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index 7baaa16dea7b..242e94c0cf8a 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -280,7 +280,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0}, { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, - ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, + ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30, 2}, { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88, 5}, { AGILEX_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux, -- cgit v1.2.3-70-g09d2 From f449a3d7a1530db44e7bba1a875f522115e99ab5 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:16 -0700 Subject: scsi: lpfc: Add PCI ID support for LPe37000/LPe38000 series adapters Update supported pci_device_id table to include the values for the G7+ ASIC Device ID utilized by LPe37xxx and LPe38xxx series of adapters. The default reporting string will be "LPe38000". Link: https://lore.kernel.org/r/20210722221721.74388-2-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw.h | 1 + drivers/scsi/lpfc/lpfc_ids.h | 2 ++ drivers/scsi/lpfc/lpfc_init.c | 3 +++ 3 files changed, 6 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 4a5a85ed42ec..476d17708157 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1694,6 +1694,7 @@ struct lpfc_fdmi_reg_portattr { #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268 #define PCI_DEVICE_ID_LANCER_G6_FC 0xe300 #define PCI_DEVICE_ID_LANCER_G7_FC 0xf400 +#define PCI_DEVICE_ID_LANCER_G7P_FC 0xf500 #define PCI_DEVICE_ID_SAT_SMB 0xf011 #define PCI_DEVICE_ID_SAT_MID 0xf015 #define PCI_DEVICE_ID_RFLY 0xf095 diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h index d48414e295a0..72ad9ecb87ab 100644 --- a/drivers/scsi/lpfc/lpfc_ids.h +++ b/drivers/scsi/lpfc/lpfc_ids.h @@ -118,6 +118,8 @@ const struct pci_device_id lpfc_id_table[] = { PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC, PCI_ANY_ID, PCI_ANY_ID, }, + {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7P_FC, + PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK, PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF, diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 65a7c564f1d6..f08129c67a2e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2599,6 +2599,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) case PCI_DEVICE_ID_LANCER_G7_FC: m = (typeof(m)){"LPe36000", "PCIe", "Fibre Channel Adapter"}; break; + case PCI_DEVICE_ID_LANCER_G7P_FC: + m = (typeof(m)){"LPe38000", "PCIe", "Fibre Channel Adapter"}; + break; case PCI_DEVICE_ID_SKYHAWK: case PCI_DEVICE_ID_SKYHAWK_VF: oneConnect = 1; -- cgit v1.2.3-70-g09d2 From df3d78c3eb4eba13b3ef9740a8c664508ee644ae Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:17 -0700 Subject: scsi: lpfc: Fix cq_id truncation in rq create On the newer hardware, CQ_ID values can be larger than seen on previous generations. This exposed an issue in the driver where its definition of cq_id in the RQ Create mailbox cmd was too small, thus the cq_id was truncated, causing the command to fail. Revise the RQ_CREATE CQ_ID field to its proper size (16 bits). Link: https://lore.kernel.org/r/20210722221721.74388-3-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 4d9233de9ead..c31a0cbcc208 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1561,7 +1561,7 @@ struct rq_context { #define lpfc_rq_context_hdr_size_WORD word1 uint32_t word2; #define lpfc_rq_context_cq_id_SHIFT 16 -#define lpfc_rq_context_cq_id_MASK 0x000003FF +#define lpfc_rq_context_cq_id_MASK 0x0000FFFF #define lpfc_rq_context_cq_id_WORD word2 #define lpfc_rq_context_buf_size_SHIFT 0 #define lpfc_rq_context_buf_size_MASK 0x0000FFFF -- cgit v1.2.3-70-g09d2 From f6c5e6c4561d2a94a8eb39e6d4cb87a715bbd3de Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:18 -0700 Subject: scsi: lpfc: Revise Topology and RAS support checks for new adapters Support for Topology and RAS logging capabilities were qualified by PCIe device ID checks necessitating additional driver changes for new device IDs. Reduce reliance on specific PCIe device IDs by substituting checks for SLI family information. This automatically picks up support on the newest hardware. Link: https://lore.kernel.org/r/20210722221721.74388-4-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 14 +++++++++----- drivers/scsi/lpfc/lpfc_hw4.h | 4 ++++ drivers/scsi/lpfc/lpfc_init.c | 34 ++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_mbox.c | 5 +++-- drivers/scsi/lpfc/lpfc_scsi.c | 8 ++------ 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 457989cfc0b7..a5154856bc0f 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4038,6 +4038,7 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, const char *val_buf = buf; int err; uint32_t prev_val; + u8 sli_family, if_type; if (!strncmp(buf, "nolip ", strlen("nolip "))) { nolip = 1; @@ -4061,13 +4062,16 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, /* * The 'topology' is not a configurable parameter if : * - persistent topology enabled - * - G7/G6 with no private loop support + * - ASIC_GEN_NUM >= 0xC, with no private loop support */ - + sli_family = bf_get(lpfc_sli_intf_sli_family, + &phba->sli4_hba.sli_intf); + if_type = bf_get(lpfc_sli_intf_if_type, + &phba->sli4_hba.sli_intf); if ((phba->hba_flag & HBA_PERSISTENT_TOPO || - (!phba->sli4_hba.pc_sli4_params.pls && - (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || - phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) && + (!phba->sli4_hba.pc_sli4_params.pls && + (sli_family == LPFC_SLI_INTF_FAMILY_G6 || + if_type == LPFC_SLI_INTF_IF_TYPE_6))) && val == 4) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "3114 Loop mode not supported\n"); diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index c31a0cbcc208..aadbb0de629d 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -94,6 +94,9 @@ struct lpfc_sli_intf { #define LPFC_SLI_INTF_FAMILY_BE3 0x1 #define LPFC_SLI_INTF_FAMILY_LNCR_A0 0xa #define LPFC_SLI_INTF_FAMILY_LNCR_B0 0xb +#define LPFC_SLI_INTF_FAMILY_G6 0xc +#define LPFC_SLI_INTF_FAMILY_G7 0xd +#define LPFC_SLI_INTF_FAMILY_G7P 0xe #define lpfc_sli_intf_slirev_SHIFT 4 #define lpfc_sli_intf_slirev_MASK 0x0000000F #define lpfc_sli_intf_slirev_WORD word0 @@ -4719,6 +4722,7 @@ union lpfc_wqe128 { #define MAGIC_NUMBER_G6 0xFEAA0003 #define MAGIC_NUMBER_G7 0xFEAA0005 +#define MAGIC_NUMBER_G7P 0xFEAA0020 struct lpfc_grp_hdr { uint32_t size; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f08129c67a2e..ead8e91e8625 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -8550,9 +8550,12 @@ lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) } /* FW supports persistent topology - override module parameter value */ phba->hba_flag |= HBA_PERSISTENT_TOPO; - switch (phba->pcidev->device) { - case PCI_DEVICE_ID_LANCER_G7_FC: - case PCI_DEVICE_ID_LANCER_G6_FC: + + /* if ASIC_GEN_NUM >= 0xC) */ + if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_IF_TYPE_6) || + (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_FAMILY_G6)) { if (!tf) { phba->cfg_topology = ((pt == LINK_FLAGS_LOOP) ? FLAGS_TOPOLOGY_MODE_LOOP @@ -8560,8 +8563,7 @@ lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) } else { phba->hba_flag &= ~HBA_PERSISTENT_TOPO; } - break; - default: /* G5 */ + } else { /* G5 */ if (tf) { /* If topology failover set - pt is '0' or '1' */ phba->cfg_topology = (pt ? FLAGS_TOPOLOGY_MODE_PT_LOOP : @@ -8571,7 +8573,6 @@ lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) ? FLAGS_TOPOLOGY_MODE_PT_PT : FLAGS_TOPOLOGY_MODE_LOOP); } - break; } if (phba->hba_flag & HBA_PERSISTENT_TOPO) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -12991,7 +12992,9 @@ lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset, const struct firmware *fw) { int rc; + u8 sli_family; + sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf); /* Three cases: (1) FW was not supported on the detected adapter. * (2) FW update has been locked out administratively. * (3) Some other error during FW update. @@ -12999,10 +13002,12 @@ lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset, * for admin diagnosis. */ if (offset == ADD_STATUS_FW_NOT_SUPPORTED || - (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC && + (sli_family == LPFC_SLI_INTF_FAMILY_G6 && magic_number != MAGIC_NUMBER_G6) || - (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC && - magic_number != MAGIC_NUMBER_G7)) { + (sli_family == LPFC_SLI_INTF_FAMILY_G7 && + magic_number != MAGIC_NUMBER_G7) || + (sli_family == LPFC_SLI_INTF_FAMILY_G7P && + magic_number != MAGIC_NUMBER_G7P)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3030 This firmware version is not supported on" " this HBA model. Device:%x Magic:%x Type:%x " @@ -14053,17 +14058,18 @@ lpfc_sli4_oas_verify(struct lpfc_hba *phba) void lpfc_sli4_ras_init(struct lpfc_hba *phba) { - switch (phba->pcidev->device) { - case PCI_DEVICE_ID_LANCER_G6_FC: - case PCI_DEVICE_ID_LANCER_G7_FC: + /* if ASIC_GEN_NUM >= 0xC) */ + if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_IF_TYPE_6) || + (bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_FAMILY_G6)) { phba->ras_fwlog.ras_hwsupport = true; if (phba->cfg_ras_fwlog_func == PCI_FUNC(phba->pcidev->devfn) && phba->cfg_ras_fwlog_buffsize) phba->ras_fwlog.ras_enabled = true; else phba->ras_fwlog.ras_enabled = false; - break; - default: + } else { phba->ras_fwlog.ras_hwsupport = false; } } diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 84bc373190d8..6c754ee96bee 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -513,8 +513,9 @@ lpfc_init_link(struct lpfc_hba * phba, break; } - if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || - phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && + /* Topology handling for ASIC_GEN_NUM 0xC and later */ + if ((phba->sli4_hba.pc_sli4_params.sli_family == LPFC_SLI_INTF_FAMILY_G6 || + phba->sli4_hba.pc_sli4_params.if_type == LPFC_SLI_INTF_IF_TYPE_6) && !(phba->sli4_hba.pc_sli4_params.pls) && mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) { mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 10002a13c5c6..ee4ff4855866 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5029,12 +5029,8 @@ lpfc_check_pci_resettable(struct lpfc_hba *phba) } /* Check for valid Emulex Device ID */ - switch (ptr->device) { - case PCI_DEVICE_ID_LANCER_FC: - case PCI_DEVICE_ID_LANCER_G6_FC: - case PCI_DEVICE_ID_LANCER_G7_FC: - break; - default: + if (phba->sli_rev != LPFC_SLI_REV4 || + phba->hba_flag & HBA_FCOE_MODE) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "8347 Incapable PCI reset device: " "0x%04x\n", ptr->device); -- cgit v1.2.3-70-g09d2 From bfc477854a42c3de6c2f34c7e8f7ef9917ef53ca Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:19 -0700 Subject: scsi: lpfc: Add 256 Gb link speed support Update routines to support 256 Gb link speed for LPe37000/LPe38000 adapters. 256 Gb speeds can be seen on trunk links. Link: https://lore.kernel.org/r/20210722221721.74388-5-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 3 +++ drivers/scsi/lpfc/lpfc_ct.c | 5 +++++ drivers/scsi/lpfc/lpfc_els.c | 8 ++++++++ drivers/scsi/lpfc/lpfc_hbadisc.c | 1 + drivers/scsi/lpfc/lpfc_init.c | 5 +++++ drivers/scsi/lpfc/lpfc_scsi.h | 4 ++++ 6 files changed, 26 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index a5154856bc0f..869c2b6f1515 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -6745,6 +6745,9 @@ lpfc_get_host_speed(struct Scsi_Host *shost) case LPFC_LINK_SPEED_128GHZ: fc_host_speed(shost) = FC_PORTSPEED_128GBIT; break; + case LPFC_LINK_SPEED_256GHZ: + fc_host_speed(shost) = FC_PORTSPEED_256GBIT; + break; default: fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 1acb8820a08e..a1c85fa135a9 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -2846,6 +2846,8 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, ae->un.AttrInt = 0; if (!(phba->hba_flag & HBA_FCOE_MODE)) { + if (phba->lmt & LMT_256Gb) + ae->un.AttrInt |= HBA_PORTSPEED_256GFC; if (phba->lmt & LMT_128Gb) ae->un.AttrInt |= HBA_PORTSPEED_128GFC; if (phba->lmt & LMT_64Gb) @@ -2927,6 +2929,9 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, case LPFC_LINK_SPEED_128GHZ: ae->un.AttrInt = HBA_PORTSPEED_128GFC; break; + case LPFC_LINK_SPEED_256GHZ: + ae->un.AttrInt = HBA_PORTSPEED_256GFC; + break; default: ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; break; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 342c7e28ee95..08ae2b12b92c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6105,6 +6105,12 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) case LPFC_LINK_SPEED_64GHZ: rdp_speed = RDP_PS_64GB; break; + case LPFC_LINK_SPEED_128GHZ: + rdp_speed = RDP_PS_128GB; + break; + case LPFC_LINK_SPEED_256GHZ: + rdp_speed = RDP_PS_256GB; + break; default: rdp_speed = RDP_PS_UNKNOWN; break; @@ -6112,6 +6118,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) desc->info.port_speed.speed = cpu_to_be16(rdp_speed); + if (phba->lmt & LMT_256Gb) + rdp_cap |= RDP_PS_256GB; if (phba->lmt & LMT_128Gb) rdp_cap |= RDP_PS_128GB; if (phba->lmt & LMT_64Gb) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 32fb3be42b26..6da2daf7d9e3 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3331,6 +3331,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) case LPFC_LINK_SPEED_32GHZ: case LPFC_LINK_SPEED_64GHZ: case LPFC_LINK_SPEED_128GHZ: + case LPFC_LINK_SPEED_256GHZ: break; default: phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index ead8e91e8625..2c0aaa0a301d 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -4679,6 +4679,8 @@ static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost) if (phba->hba_flag & HBA_FCOE_MODE) return; + if (phba->lmt & LMT_256Gb) + fc_host_supported_speeds(shost) |= FC_PORTSPEED_256GBIT; if (phba->lmt & LMT_128Gb) fc_host_supported_speeds(shost) |= FC_PORTSPEED_128GBIT; if (phba->lmt & LMT_64Gb) @@ -5087,6 +5089,9 @@ lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code, case LPFC_FC_LA_SPEED_128G: port_speed = 128000; break; + case LPFC_FC_LA_SPEED_256G: + port_speed = 256000; + break; default: port_speed = 0; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index f76667b7da7b..46989532c23d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h @@ -142,6 +142,10 @@ struct lpfc_scsicmd_bkt { #define FC_PORTSPEED_128GBIT 0x2000 #endif +#ifndef FC_PORTSPEED_256GBIT +#define FC_PORTSPEED_256GBIT 0x4000 +#endif + #define TXRDY_PAYLOAD_LEN 12 /* For sysfs/debugfs tmp string max len */ -- cgit v1.2.3-70-g09d2 From 95518cabe1193e1746c77be6d8233d76dcf1969e Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:20 -0700 Subject: scsi: lpfc: Update lpfc version to 14.0.0.0 Update lpfc version to 14.0.0.0. Link: https://lore.kernel.org/r/20210722221721.74388-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 63b2690ab49f..73a5b3bbdacd 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "12.8.0.11" +#define LPFC_DRIVER_VERSION "14.0.0.0" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- cgit v1.2.3-70-g09d2 From 45e524d61ec4dd600f4d34360301398d52594a44 Mon Sep 17 00:00:00 2001 From: James Smart Date: Thu, 22 Jul 2021 15:17:21 -0700 Subject: scsi: lpfc: Copyright updates for 14.0.0.0 patches Update copyrights to 2021 for files modified in the 14.0.0.0 patch set. Link: https://lore.kernel.org/r/20210722221721.74388-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hw.h | 2 +- drivers/scsi/lpfc/lpfc_ids.h | 2 +- drivers/scsi/lpfc/lpfc_scsi.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index 476d17708157..4083764916a5 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h index 72ad9ecb87ab..6a90e6e53d09 100644 --- a/drivers/scsi/lpfc/lpfc_ids.h +++ b/drivers/scsi/lpfc/lpfc_ids.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 46989532c23d..3836d7f6a575 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * -- cgit v1.2.3-70-g09d2 From ff2d86d04d2614e33e122eb9a43ae9fd2a7274af Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 21 Jul 2021 10:53:50 +0100 Subject: scsi: lpfc: Remove redundant assignment to pointer pcmd The pointer pcmd is being initialized with a value that is never read, the assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210721095350.41564-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/lpfc/lpfc_sli.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index c34240819d92..47dd13719901 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10129,8 +10129,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0); bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp, phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); - pcmd = (uint32_t *) (((struct lpfc_dmabuf *) - iocbq->context2)->virt); if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) { bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1); bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, -- cgit v1.2.3-70-g09d2 From 8f13142ac2eb04642e1c451b4475743d77e9c86c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 21 Jul 2021 11:15:19 +0100 Subject: scsi: target: Remove redundant assignment to variable ret The variable ret is being initialized with a value that is never read, the assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210721101519.42299-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/target/iscsi/cxgbit/cxgbit_ddp.c | 2 +- drivers/target/loopback/tcm_loop.c | 4 ++-- drivers/target/target_core_iblock.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/target/iscsi/cxgbit/cxgbit_ddp.c b/drivers/target/iscsi/cxgbit/cxgbit_ddp.c index b044999ad002..072afd070f3e 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_ddp.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_ddp.c @@ -234,7 +234,7 @@ cxgbit_get_r2t_ttt(struct iscsi_conn *conn, struct iscsi_cmd *cmd, struct cxgbit_device *cdev = csk->com.cdev; struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd); struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo; - int ret = -EINVAL; + int ret; if ((!ccmd->setup_ddp) || (!test_bit(CSK_DDP_ENABLE, &csk->com.flags))) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 6d0b0e67e79e..fdc36274cb39 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -241,7 +241,7 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; struct tcm_loop_tpg *tl_tpg; - int ret = FAILED; + int ret; /* * Locate the tcm_loop_hba_t pointer @@ -261,7 +261,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) { struct tcm_loop_hba *tl_hba; struct tcm_loop_tpg *tl_tpg; - int ret = FAILED; + int ret; /* * Locate the tcm_loop_hba_t pointer diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 44d9d028f716..4069a1edcfa3 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -83,7 +83,7 @@ static int iblock_configure_device(struct se_device *dev) struct blk_integrity *bi; fmode_t mode; unsigned int max_write_zeroes_sectors; - int ret = -ENOMEM; + int ret; if (!(ib_dev->ibd_flags & IBDF_HAS_UDEV_PATH)) { pr_err("Missing udev_path= parameters for IBLOCK\n"); -- cgit v1.2.3-70-g09d2 From 0525265e434ba6c24f4a2c468114c4b21e48cb7a Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Fri, 23 Jul 2021 16:46:24 +0800 Subject: scsi: libsas: Drop BLK_DEV_BSGLIB selection SCSI_SAS_ATTRS already selects BLK_DEV_BSGLIB in drivers/scsi/Kconfig. Remove selection in libsas/Kconfig. Link: https://lore.kernel.org/r/20210723084624.2596297-1-guoqing.jiang@linux.dev Signed-off-by: Guoqing Jiang Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig index 052ee3a26f6e..c640535d1ac0 100644 --- a/drivers/scsi/libsas/Kconfig +++ b/drivers/scsi/libsas/Kconfig @@ -10,7 +10,6 @@ config SCSI_SAS_LIBSAS tristate "SAS Domain Transport Attributes" depends on SCSI select SCSI_SAS_ATTRS - select BLK_DEV_BSGLIB help This provides transport specific helpers for SAS drivers which use the domain device construct (like the aic94xxx). -- cgit v1.2.3-70-g09d2 From cb51bcd5c34b0558ba2bb04963bcb1053375a8e4 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 26 Jul 2021 13:19:24 -0700 Subject: scsi: qla2xxx: Remove unused variable 'status' Fix the clang build warning: drivers/scsi/qla2xxx/qla_nx.c:2209:6: error: variable 'status' set but not used [-Werror,-Wunused-but-set-variable] int status = 0; Link: https://lore.kernel.org/r/20210726201924.3202278-4-morbo@google.com Reviewed-by: Nathan Chancellor Signed-off-by: Bill Wendling Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 615e44af1ca6..11aad97dfca8 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -2166,7 +2166,6 @@ qla82xx_poll(int irq, void *dev_id) struct qla_hw_data *ha; struct rsp_que *rsp; struct device_reg_82xx __iomem *reg; - int status = 0; uint32_t stat; uint32_t host_int = 0; uint16_t mb[8]; @@ -2195,7 +2194,6 @@ qla82xx_poll(int irq, void *dev_id) case 0x10: case 0x11: qla82xx_mbx_completion(vha, MSW(stat)); - status |= MBX_INTERRUPT; break; case 0x12: mb[0] = MSW(stat); -- cgit v1.2.3-70-g09d2 From 7ebb336e45ef1ce23462c3bbd03779929008901f Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:25:56 -0700 Subject: scsi: qla2xxx: edif: Add start + stop bsgs Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. Add two new BSG calls: - QL_VND_SC_APP_START: Application will announce its presence to driver with this call. Driver will restart all connections to see if remote device supports security or not. - QL_VND_SC_APP_STOP: Application announces it is in the process of exiting. Driver will restart all connections to revert back to non-secure. Provided the remote device is willing to allow a non-secure connection. Link: https://lore.kernel.org/r/20210624052606.21613-2-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/Makefile | 3 +- drivers/scsi/qla2xxx/qla_bsg.c | 3 + drivers/scsi/qla2xxx/qla_bsg.h | 3 + drivers/scsi/qla2xxx/qla_dbg.h | 1 + drivers/scsi/qla2xxx/qla_def.h | 70 ++++--- drivers/scsi/qla2xxx/qla_edif.c | 356 ++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_edif.h | 33 ++++ drivers/scsi/qla2xxx/qla_edif_bsg.h | 220 ++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 4 + 9 files changed, 669 insertions(+), 24 deletions(-) create mode 100644 drivers/scsi/qla2xxx/qla_edif.c create mode 100644 drivers/scsi/qla2xxx/qla_edif.h create mode 100644 drivers/scsi/qla2xxx/qla_edif_bsg.h diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index 17d5bc1cc56b..cbc1303e761e 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ - qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o + qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \ + qla_edif.o obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index d42b2ad84049..e6cccbcc7a1b 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2840,6 +2840,9 @@ qla2x00_process_vendor_specific(struct bsg_job *bsg_job) case QL_VND_DPORT_DIAGNOSTICS: return qla2x00_do_dport_diagnostics(bsg_job); + case QL_VND_EDIF_MGMT: + return qla_edif_app_mgmt(bsg_job); + case QL_VND_SS_GET_FLASH_IMAGE_STATUS: return qla2x00_get_flash_image_status(bsg_job); diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index 0274e99e4a12..dd793cf8bc1e 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h @@ -31,6 +31,7 @@ #define QL_VND_DPORT_DIAGNOSTICS 0x19 #define QL_VND_GET_PRIV_STATS_EX 0x1A #define QL_VND_SS_GET_FLASH_IMAGE_STATUS 0x1E +#define QL_VND_EDIF_MGMT 0X1F #define QL_VND_MANAGE_HOST_STATS 0x23 #define QL_VND_GET_HOST_STATS 0x24 #define QL_VND_GET_TGT_STATS 0x25 @@ -294,4 +295,6 @@ struct qla_active_regions { uint8_t reserved[32]; } __packed; +#include "qla_edif_bsg.h" + #endif diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 9eb708e5e22e..f1f6c740bdcd 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -367,6 +367,7 @@ ql_log_qp(uint32_t, struct qla_qpair *, int32_t, const char *fmt, ...); #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ #define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */ +#define ql_dbg_edif 0x00000400 /* edif and purex debug */ extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, uint32_t, void **); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 2f67ec1df3e6..0d28328722b2 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -49,6 +49,28 @@ typedef struct { uint8_t domain; } le_id_t; +/* + * 24 bit port ID type definition. + */ +typedef union { + uint32_t b24 : 24; + struct { +#ifdef __BIG_ENDIAN + uint8_t domain; + uint8_t area; + uint8_t al_pa; +#elif defined(__LITTLE_ENDIAN) + uint8_t al_pa; + uint8_t area; + uint8_t domain; +#else +#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" +#endif + uint8_t rsvd_1; + } b; +} port_id_t; +#define INVALID_PORT_ID 0xFFFFFF + #include "qla_bsg.h" #include "qla_dsd.h" #include "qla_nx.h" @@ -345,6 +367,8 @@ struct name_list_extended { #define FW_MAX_EXCHANGES_CNT (32 * 1024) #define REDUCE_EXCHANGES_CNT (8 * 1024) +#define SET_DID_STATUS(stat_var, status) (stat_var = status << 16) + struct req_que; struct qla_tgt_sess; @@ -373,29 +397,6 @@ struct srb_cmd { /* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */ #define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID) - -/* - * 24 bit port ID type definition. - */ -typedef union { - uint32_t b24 : 24; - - struct { -#ifdef __BIG_ENDIAN - uint8_t domain; - uint8_t area; - uint8_t al_pa; -#elif defined(__LITTLE_ENDIAN) - uint8_t al_pa; - uint8_t area; - uint8_t domain; -#else -#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" -#endif - uint8_t rsvd_1; - } b; -} port_id_t; -#define INVALID_PORT_ID 0xFFFFFF #define ISP_REG16_DISCONNECT 0xFFFF static inline le_id_t be_id_to_le(be_id_t id) @@ -2424,6 +2425,7 @@ enum discovery_state { DSC_LOGIN_COMPLETE, DSC_ADISC, DSC_DELETE_PEND, + DSC_LOGIN_AUTH_PEND, }; enum login_state { /* FW control Target side */ @@ -2563,6 +2565,22 @@ typedef struct fc_port { u64 tgt_short_link_down_cnt; u64 tgt_link_down_time; u64 dev_loss_tmo; + /* + * EDIF parameters for encryption. + */ + struct { + uint32_t enable:1; /* device is edif enabled/req'd */ + uint32_t app_stop:2; + uint32_t app_started:1; + uint32_t secured_login:1; + uint32_t app_sess_online:1; + uint32_t tx_rekey_cnt; + uint32_t rx_rekey_cnt; + /* delayed rx delete data structure list */ + uint64_t tx_bytes; + uint64_t rx_bytes; + uint8_t non_secured_login; + } edif; } fc_port_t; enum { @@ -2616,6 +2634,7 @@ static const char * const port_dstate_str[] = { #define FCF_ASYNC_SENT BIT_3 #define FCF_CONF_COMP_SUPPORTED BIT_4 #define FCF_ASYNC_ACTIVE BIT_5 +#define FCF_FCSP_DEVICE BIT_6 /* No loop ID flag. */ #define FC_NO_LOOP_ID 0x1000 @@ -3935,6 +3954,7 @@ struct qla_hw_data { uint32_t scm_supported_f:1; /* Enabled in Driver */ uint32_t scm_enabled:1; + uint32_t edif_enabled:1; uint32_t max_req_queue_warned:1; uint32_t plogi_template_valid:1; uint32_t port_isolated:1; @@ -4659,6 +4679,8 @@ struct purex_item { } iocb; }; +#include "qla_edif.h" + #define SCM_FLAG_RDF_REJECT 0x00 #define SCM_FLAG_RDF_COMPLETED 0x01 @@ -4888,6 +4910,8 @@ typedef struct scsi_qla_host { u64 reset_cmd_err_cnt; u64 link_down_time; u64 short_link_down_cnt; + struct edif_dbell e_dbell; + struct pur_core pur_cinfo; } scsi_qla_host_t; struct qla27xx_image_status { diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c new file mode 100644 index 000000000000..b0194ea1a32d --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Marvell Fibre Channel HBA Driver + * Copyright (c) 2021 Marvell + */ +#include "qla_def.h" +#include "qla_edif.h" + +#include +#include +#include +#include + +static void +qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port *fcport) +{ + ql_dbg(ql_dbg_edif, vha, 0x2058, + "Init SA_CTL List for fcport - nn %8phN pn %8phN portid=%02x%02x%02x.\n", + fcport->node_name, fcport->port_name, + fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa); + + fcport->edif.tx_rekey_cnt = 0; + fcport->edif.rx_rekey_cnt = 0; + + fcport->edif.tx_bytes = 0; + fcport->edif.rx_bytes = 0; +} + +/** + * qla_edif_app_check(): check for valid application id. + * @vha: host adapter pointer + * @appid: application id + * Return: false = fail, true = pass + */ +static bool +qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid) +{ + /* check that the app is allow/known to the driver */ + + if (appid.app_vid == EDIF_APP_ID) { + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, "%s app id ok\n", __func__); + return true; + } + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)", + __func__, appid.app_vid); + + return false; +} + +static void qla_edif_reset_auth_wait(struct fc_port *fcport, int state, + int waitonly) +{ + int cnt, max_cnt = 200; + bool traced = false; + + fcport->keep_nport_handle = 1; + + if (!waitonly) { + qla2x00_set_fcport_disc_state(fcport, state); + qlt_schedule_sess_for_deletion(fcport); + } else { + qla2x00_set_fcport_disc_state(fcport, state); + } + + ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, + "%s: waiting for session, max_cnt=%u\n", + __func__, max_cnt); + + cnt = 0; + + if (waitonly) { + /* Marker wait min 10 msecs. */ + msleep(50); + cnt += 50; + } + while (1) { + if (!traced) { + ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, + "%s: session sleep.\n", + __func__); + traced = true; + } + msleep(20); + cnt++; + if (waitonly && (fcport->disc_state == state || + fcport->disc_state == DSC_LOGIN_COMPLETE)) + break; + if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) + break; + if (cnt > max_cnt) + break; + } + + if (!waitonly) { + ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, + "%s: waited for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n", + __func__, fcport->port_name, fcport->loop_id, + fcport->d_id.b24, fcport, fcport->disc_state, cnt); + } else { + ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, + "%s: waited ONLY for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n", + __func__, fcport->port_name, fcport->loop_id, + fcport->d_id.b24, fcport, fcport->disc_state, cnt); + } +} + +/** + * qla_edif_app_start: application has announce its present + * @vha: host adapter pointer + * @bsg_job: user request + * + * Set/activate doorbell. Reset current sessions and re-login with + * secure flag. + */ +static int +qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct app_start appstart; + struct app_start_reply appreply; + struct fc_port *fcport, *tf; + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app start\n", __func__); + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &appstart, + sizeof(struct app_start)); + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app_vid=%x app_start_flags %x\n", + __func__, appstart.app_info.app_vid, appstart.app_start_flags); + + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + /* mark doorbell as active since an app is now present */ + vha->e_dbell.db_flags = EDB_ACTIVE; + } else { + ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n", + __func__); + } + + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { + if ((fcport->flags & FCF_FCSP_DEVICE)) { + ql_dbg(ql_dbg_edif, vha, 0xf084, + "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n", + __func__, fcport, fcport->port_name, + fcport->loop_id, fcport->d_id.b24, + fcport->logout_on_delete); + + if (atomic_read(&vha->loop_state) == LOOP_DOWN) + break; + + if (!fcport->edif.secured_login) + continue; + + fcport->edif.app_started = 1; + if (fcport->edif.app_stop || + (fcport->disc_state != DSC_LOGIN_COMPLETE && + fcport->disc_state != DSC_LOGIN_PEND && + fcport->disc_state != DSC_DELETED)) { + /* no activity */ + fcport->edif.app_stop = 0; + + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", + __func__, fcport->port_name); + fcport->edif.app_sess_online = 1; + qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); + } + qla_edif_sa_ctl_init(vha, fcport); + } + } + + if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) { + /* mark as active since an app is now present */ + vha->pur_cinfo.enode_flags = ENODE_ACTIVE; + } else { + ql_dbg(ql_dbg_edif, vha, 0x911f, "%s enode already active\n", + __func__); + } + + appreply.host_support_edif = vha->hw->flags.edif_enabled; + appreply.edif_enode_active = vha->pur_cinfo.enode_flags; + appreply.edif_edb_active = vha->e_dbell.db_flags; + + bsg_job->reply_len = sizeof(struct fc_bsg_reply) + + sizeof(struct app_start_reply); + + SET_DID_STATUS(bsg_reply->result, DID_OK); + + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, &appreply, + sizeof(struct app_start_reply)); + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s app start completed with 0x%x\n", + __func__, rval); + + return rval; +} + +/** + * qla_edif_app_stop - app has announced it's exiting. + * @vha: host adapter pointer + * @bsg_job: user space command pointer + * + * Free any in flight messages, clear all doorbell events + * to application. Reject any message relate to security. + */ +static int +qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + struct app_stop appstop; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct fc_port *fcport, *tf; + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &appstop, + sizeof(struct app_stop)); + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s Stopping APP: app_vid=%x\n", + __func__, appstop.app_info.app_vid); + + /* Call db stop and enode stop functions */ + + /* if we leave this running short waits are operational < 16 secs */ + qla_enode_stop(vha); /* stop enode */ + qla_edb_stop(vha); /* stop db */ + + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { + if (fcport->edif.non_secured_login) + continue; + + if (fcport->flags & FCF_FCSP_DEVICE) { + ql_dbg(ql_dbg_edif, vha, 0xf084, + "%s: sess %p from port %8phC lid %#04x s_id %06x logout %d keep %d els_logo %d\n", + __func__, fcport, + fcport->port_name, fcport->loop_id, fcport->d_id.b24, + fcport->logout_on_delete, fcport->keep_nport_handle, + fcport->send_els_logo); + + if (atomic_read(&vha->loop_state) == LOOP_DOWN) + break; + + fcport->edif.app_stop = 1; + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", + __func__, fcport->port_name); + + fcport->send_els_logo = 1; + qlt_schedule_sess_for_deletion(fcport); + + /* qla_edif_flush_sa_ctl_lists(fcport); */ + fcport->edif.app_started = 0; + } + } + + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + SET_DID_STATUS(bsg_reply->result, DID_OK); + + /* no return interface to app - it assumes we cleaned up ok */ + + return rval; +} + +int32_t +qla_edif_app_mgmt(struct bsg_job *bsg_job) +{ + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); + scsi_qla_host_t *vha = shost_priv(host); + struct app_id appcheck; + bool done = true; + int32_t rval = 0; + uint32_t vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s vnd subcmd=%x\n", + __func__, vnd_sc); + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &appcheck, + sizeof(struct app_id)); + + if (!vha->hw->flags.edif_enabled || + test_bit(VPORT_DELETE, &vha->dpc_flags)) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s edif not enabled or vp delete. bsg ptr done %p\n", + __func__, bsg_job); + + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + } + + if (!qla_edif_app_check(vha, appcheck)) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s app checked failed.\n", + __func__); + + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + } + + switch (vnd_sc) { + case QL_VND_SC_APP_START: + rval = qla_edif_app_start(vha, bsg_job); + break; + case QL_VND_SC_APP_STOP: + rval = qla_edif_app_stop(vha, bsg_job); + break; + default: + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", + __func__, + bsg_request->rqst_data.h_vendor.vendor_cmd[1]); + rval = EXT_STATUS_INVALID_PARAM; + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + break; + } + +done: + if (done) { + ql_dbg(ql_dbg_user, vha, 0x7009, + "%s: %d bsg ptr done %p\n", __func__, __LINE__, bsg_job); + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); + } + + return rval; +} + +void +qla_enode_stop(scsi_qla_host_t *vha) +{ + if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) { + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s enode not active\n", __func__); + return; + } +} + +/* function called when app is stopping */ + +void +qla_edb_stop(scsi_qla_host_t *vha) +{ + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s doorbell not enabled\n", __func__); + return; + } +} diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h new file mode 100644 index 000000000000..d7d1433295c7 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Marvell Fibre Channel HBA Driver + * Copyright (c) 2021 Marvell + */ +#ifndef __QLA_EDIF_H +#define __QLA_EDIF_H + +struct qla_scsi_host; +#define EDIF_APP_ID 0x73730001 + +enum enode_flags_t { + ENODE_ACTIVE = 0x1, +}; + +struct pur_core { + enum enode_flags_t enode_flags; + spinlock_t pur_lock; + struct list_head head; +}; + +enum db_flags_t { + EDB_ACTIVE = 0x1, +}; + +struct edif_dbell { + enum db_flags_t db_flags; + spinlock_t db_lock; + struct list_head head; + struct completion dbell; +}; + +#endif /* __QLA_EDIF_H */ diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h new file mode 100644 index 000000000000..58b718d35d19 --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Marvell Fibre Channel HBA Driver + * Copyright (C) 2018- Marvell + * + */ +#ifndef __QLA_EDIF_BSG_H +#define __QLA_EDIF_BSG_H + +/* BSG Vendor specific commands */ +#define ELS_MAX_PAYLOAD 1024 +#ifndef WWN_SIZE +#define WWN_SIZE 8 +#endif +#define VND_CMD_APP_RESERVED_SIZE 32 + +enum auth_els_sub_cmd { + SEND_ELS = 0, + SEND_ELS_REPLY, + PULL_ELS, +}; + +struct extra_auth_els { + enum auth_els_sub_cmd sub_cmd; + uint32_t extra_rx_xchg_address; + uint8_t extra_control_flags; +#define BSG_CTL_FLAG_INIT 0 +#define BSG_CTL_FLAG_LS_ACC 1 +#define BSG_CTL_FLAG_LS_RJT 2 +#define BSG_CTL_FLAG_TRM 3 + uint8_t extra_rsvd[3]; +} __packed; + +struct qla_bsg_auth_els_request { + struct fc_bsg_request r; + struct extra_auth_els e; +}; + +struct qla_bsg_auth_els_reply { + struct fc_bsg_reply r; + uint32_t rx_xchg_address; +}; + +struct app_id { + int app_vid; + uint8_t app_key[32]; +} __packed; + +struct app_start_reply { + uint32_t host_support_edif; + uint32_t edif_enode_active; + uint32_t edif_edb_active; + uint32_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +struct app_start { + struct app_id app_info; + uint32_t prli_to; + uint32_t key_shred; + uint8_t app_start_flags; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE - 1]; +} __packed; + +struct app_stop { + struct app_id app_info; + char buf[16]; +} __packed; + +struct app_plogi_reply { + uint32_t prli_status; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +#define RECFG_TIME 1 +#define RECFG_BYTES 2 + +struct app_rekey_cfg { + struct app_id app_info; + uint8_t rekey_mode; + port_id_t d_id; + uint8_t force; + union { + int64_t bytes; + int64_t time; + } rky_units; + + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +struct app_pinfo_req { + struct app_id app_info; + uint8_t num_ports; + port_id_t remote_pid; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +struct app_pinfo { + port_id_t remote_pid; + uint8_t remote_wwpn[WWN_SIZE]; + uint8_t remote_type; +#define VND_CMD_RTYPE_UNKNOWN 0 +#define VND_CMD_RTYPE_TARGET 1 +#define VND_CMD_RTYPE_INITIATOR 2 + uint8_t remote_state; + uint8_t auth_state; + uint8_t rekey_mode; + int64_t rekey_count; + int64_t rekey_config_value; + int64_t rekey_consumed_value; + + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +/* AUTH States */ +#define VND_CMD_AUTH_STATE_UNDEF 0 +#define VND_CMD_AUTH_STATE_SESSION_SHUTDOWN 1 +#define VND_CMD_AUTH_STATE_NEEDED 2 +#define VND_CMD_AUTH_STATE_ELS_RCVD 3 +#define VND_CMD_AUTH_STATE_SAUPDATE_COMPL 4 + +struct app_pinfo_reply { + uint8_t port_count; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; + struct app_pinfo ports[0]; +} __packed; + +struct app_sinfo_req { + struct app_id app_info; + uint8_t num_ports; + uint8_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +struct app_sinfo { + uint8_t remote_wwpn[WWN_SIZE]; + int64_t rekey_count; + uint8_t rekey_mode; + int64_t tx_bytes; + int64_t rx_bytes; +} __packed; + +struct app_stats_reply { + uint8_t elem_count; + struct app_sinfo elem[0]; +} __packed; + +struct qla_sa_update_frame { + struct app_id app_info; + uint16_t flags; +#define SAU_FLG_INV 0x01 /* delete key */ +#define SAU_FLG_TX 0x02 /* 1=tx, 0 = rx */ +#define SAU_FLG_FORCE_DELETE 0x08 +#define SAU_FLG_GMAC_MODE 0x20 /* + * GMAC mode is cleartext for the IO + * (i.e. NULL encryption) + */ +#define SAU_FLG_KEY128 0x40 +#define SAU_FLG_KEY256 0x80 + uint16_t fast_sa_index:10, + reserved:6; + uint32_t salt; + uint32_t spi; + uint8_t sa_key[32]; + uint8_t node_name[WWN_SIZE]; + uint8_t port_name[WWN_SIZE]; + port_id_t port_id; +} __packed; + +// used for edif mgmt bsg interface +#define QL_VND_SC_UNDEF 0 +#define QL_VND_SC_SA_UPDATE 1 +#define QL_VND_SC_APP_START 2 +#define QL_VND_SC_APP_STOP 3 +#define QL_VND_SC_AUTH_OK 4 +#define QL_VND_SC_AUTH_FAIL 5 +#define QL_VND_SC_REKEY_CONFIG 6 +#define QL_VND_SC_GET_FCINFO 7 +#define QL_VND_SC_GET_STATS 8 + +/* Application interface data structure for rtn data */ +#define EXT_DEF_EVENT_DATA_SIZE 64 +struct edif_app_dbell { + uint32_t event_code; + uint32_t event_data_size; + union { + port_id_t port_id; + uint8_t event_data[EXT_DEF_EVENT_DATA_SIZE]; + }; +} __packed; + +struct edif_sa_update_aen { + port_id_t port_id; + uint32_t key_type; /* Tx (1) or RX (2) */ + uint32_t status; /* 0 succes, 1 failed, 2 timeout , 3 error */ + uint8_t reserved[16]; +} __packed; + +#define QL_VND_SA_STAT_SUCCESS 0 +#define QL_VND_SA_STAT_FAILED 1 +#define QL_VND_SA_STAT_TIMEOUT 2 +#define QL_VND_SA_STAT_ERROR 3 + +#define QL_VND_RX_SA_KEY 1 +#define QL_VND_TX_SA_KEY 2 + +/* App defines for plogi auth'd ok and plogi auth bad requests */ +struct auth_complete_cmd { + struct app_id app_info; +#define PL_TYPE_WWPN 1 +#define PL_TYPE_DID 2 + uint32_t type; + union { + uint8_t wwpn[WWN_SIZE]; + port_id_t d_id; + } u; + uint32_t reserved[VND_CMD_APP_RESERVED_SIZE]; +} __packed; + +#define RX_DELAY_DELETE_TIMEOUT 20 + +#endif /* QLA_EDIF_BSG_H */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 2f867da822ae..edd0a3af1030 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -950,6 +950,10 @@ extern void qla_nvme_abort_process_comp_status /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); +void qla_edb_stop(scsi_qla_host_t *vha); +int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job); +void qla_enode_init(scsi_qla_host_t *vha); +void qla_enode_stop(scsi_qla_host_t *vha); void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea); #define QLA2XX_HW_ERROR BIT_0 -- cgit v1.2.3-70-g09d2 From 7878f22a2e03b69baf792f74488962981a1c9547 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:25:57 -0700 Subject: scsi: qla2xxx: edif: Add getfcinfo and statistic bsgs Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. Add two new BSG calls: - QL_VND_SC_GET_FCINFO: Application can from time to time request a list of all FC ports or a single device that supports secure connection. If driver sees a new or old device has logged into the switch, this call is used to check for the WWPN. - QL_VND_SC_GET_STATS: Application request for various statistics for each FC port. Link: https://lore.kernel.org/r/20210624052606.21613-3-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 3 +- drivers/scsi/qla2xxx/qla_edif.c | 188 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 0d28328722b2..ec28023b738f 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2576,10 +2576,11 @@ typedef struct fc_port { uint32_t app_sess_online:1; uint32_t tx_rekey_cnt; uint32_t rx_rekey_cnt; - /* delayed rx delete data structure list */ uint64_t tx_bytes; uint64_t rx_bytes; uint8_t non_secured_login; + uint8_t auth_state; + uint16_t rekey_cnt; } edif; } fc_port_t; diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index b0194ea1a32d..165c910c1b81 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -264,6 +264,188 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job) return rval; } +/** + * qla_edif_app_getfcinfo - app would like to read session info (wwpn, nportid, + * [initiator|target] mode. It can specific session with specific nport id or + * all sessions. + * @vha: host adapter pointer + * @bsg_job: user request pointer + */ +static int +qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + int32_t num_cnt = 1; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct app_pinfo_req app_req; + struct app_pinfo_reply *app_reply; + port_id_t tdid; + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app get fcinfo\n", __func__); + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &app_req, + sizeof(struct app_pinfo_req)); + + num_cnt = app_req.num_ports; /* num of ports alloc'd by app */ + + app_reply = kzalloc((sizeof(struct app_pinfo_reply) + + sizeof(struct app_pinfo) * num_cnt), GFP_KERNEL); + if (!app_reply) { + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + rval = -1; + } else { + struct fc_port *fcport = NULL, *tf; + uint32_t pcnt = 0; + + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { + if (!(fcport->flags & FCF_FCSP_DEVICE)) + continue; + + tdid = app_req.remote_pid; + + ql_dbg(ql_dbg_edif, vha, 0x2058, + "APP request entry - portid=%06x.\n", + tdid.b24); + + /* Ran out of space */ + if (pcnt > app_req.num_ports) + break; + + if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24) + continue; + + app_reply->ports[pcnt].remote_type = + VND_CMD_RTYPE_UNKNOWN; + if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET)) + app_reply->ports[pcnt].remote_type |= + VND_CMD_RTYPE_TARGET; + if (fcport->port_type & (FCT_NVME_INITIATOR | FCT_INITIATOR)) + app_reply->ports[pcnt].remote_type |= + VND_CMD_RTYPE_INITIATOR; + + app_reply->ports[pcnt].remote_pid = fcport->d_id; + + ql_dbg(ql_dbg_edif, vha, 0x2058, + "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%02x%02x%02x.\n", + fcport->node_name, fcport->port_name, pcnt, + fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa); + + switch (fcport->edif.auth_state) { + case VND_CMD_AUTH_STATE_ELS_RCVD: + if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) { + fcport->edif.auth_state = VND_CMD_AUTH_STATE_NEEDED; + app_reply->ports[pcnt].auth_state = + VND_CMD_AUTH_STATE_NEEDED; + } else { + app_reply->ports[pcnt].auth_state = + VND_CMD_AUTH_STATE_ELS_RCVD; + } + break; + default: + app_reply->ports[pcnt].auth_state = fcport->edif.auth_state; + break; + } + + memcpy(app_reply->ports[pcnt].remote_wwpn, + fcport->port_name, 8); + + app_reply->ports[pcnt].remote_state = + (atomic_read(&fcport->state) == + FCS_ONLINE ? 1 : 0); + + pcnt++; + + if (tdid.b24 != 0) + break; + } + app_reply->port_count = pcnt; + SET_DID_STATUS(bsg_reply->result, DID_OK); + } + + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, app_reply, + sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * num_cnt); + + kfree(app_reply); + + return rval; +} + +/** + * qla_edif_app_getstats - app would like to read various statistics info + * @vha: host adapter pointer + * @bsg_job: user request + */ +static int32_t +qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + uint32_t ret_size, size; + + struct app_sinfo_req app_req; + struct app_stats_reply *app_reply; + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &app_req, + sizeof(struct app_sinfo_req)); + if (app_req.num_ports == 0) { + ql_dbg(ql_dbg_async, vha, 0x911d, + "%s app did not indicate number of ports to return\n", + __func__); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + rval = -1; + } + + size = sizeof(struct app_stats_reply) + + (sizeof(struct app_sinfo) * app_req.num_ports); + + if (size > bsg_job->reply_payload.payload_len) + ret_size = bsg_job->reply_payload.payload_len; + else + ret_size = size; + + app_reply = kzalloc(size, GFP_KERNEL); + if (!app_reply) { + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + rval = -1; + } else { + struct fc_port *fcport = NULL, *tf; + uint32_t pcnt = 0; + + list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { + if (fcport->edif.enable) { + if (pcnt > app_req.num_ports) + break; + + app_reply->elem[pcnt].rekey_count = + fcport->edif.rekey_cnt; + app_reply->elem[pcnt].tx_bytes = + fcport->edif.tx_bytes; + app_reply->elem[pcnt].rx_bytes = + fcport->edif.rx_bytes; + + memcpy(app_reply->elem[pcnt].remote_wwpn, + fcport->port_name, 8); + + pcnt++; + } + } + app_reply->elem_count = pcnt; + SET_DID_STATUS(bsg_reply->result, DID_OK); + } + + bsg_reply->reply_payload_rcv_len = + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, app_reply, ret_size); + + kfree(app_reply); + + return rval; +} + int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job) { @@ -310,6 +492,12 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) case QL_VND_SC_APP_STOP: rval = qla_edif_app_stop(vha, bsg_job); break; + case QL_VND_SC_GET_FCINFO: + rval = qla_edif_app_getfcinfo(vha, bsg_job); + break; + case QL_VND_SC_GET_STATS: + rval = qla_edif_app_getstats(vha, bsg_job); + break; default: ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n", __func__, -- cgit v1.2.3-70-g09d2 From 84318a9f01ce13650ea23eb6362066bb95ccc9fe Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:25:58 -0700 Subject: scsi: qla2xxx: edif: Add send, receive, and accept for auth_els Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. Add the ability for authentication application to send and retrieve messages as part of the authentication process via existing FC_BSG_HST_ELS_NOLOGIN BSG interface. To send a message, application is expected to format the data in the AUTH ELS format. Refer to FC-SP2 for details. If a message was received, application is required to reply with either a LS_ACC or LS_RJT complete the exchange using the same interface. Otherwise, remote device will treat it as a timeout. Link: https://lore.kernel.org/r/20210624052606.21613-4-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 1 + drivers/scsi/qla2xxx/qla_bsg.c | 63 +++--- drivers/scsi/qla2xxx/qla_def.h | 48 +++++ drivers/scsi/qla2xxx/qla_edif.c | 396 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_edif.h | 34 ++++ drivers/scsi/qla2xxx/qla_gbl.h | 6 +- drivers/scsi/qla2xxx/qla_iocb.c | 41 ++++ drivers/scsi/qla2xxx/qla_isr.c | 95 +++++++-- drivers/scsi/qla2xxx/qla_os.c | 41 ++++ drivers/scsi/qla2xxx/qla_target.c | 7 +- 10 files changed, 692 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 3aa9869f6fae..d78db2949ef6 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -3107,6 +3107,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) qla2x00_wait_for_sess_deletion(vha); qla_nvme_delete(vha); + qla_enode_stop(vha); vha->flags.delete_progress = 1; qlt_remove_target(ha, vha); diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index e6cccbcc7a1b..2d43603e31ec 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -27,6 +27,10 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) sp->free(sp); + ql_dbg(ql_dbg_user, sp->vha, 0x7009, + "%s: sp hdl %x, result=%x bsg ptr %p\n", + __func__, sp->handle, res, bsg_job); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); @@ -53,11 +57,19 @@ void qla2x00_bsg_sp_free(srb_t *sp) bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); } else { - dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, - bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); - dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, - bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); + if (sp->remap.remapped) { + dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf, + sp->remap.rsp.dma); + dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf, + sp->remap.req.dma); + } else { + dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); + + dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); + } } if (sp->type == SRB_CT_CMD || @@ -266,6 +278,7 @@ qla2x00_process_els(struct bsg_job *bsg_job) int req_sg_cnt, rsp_sg_cnt; int rval = (DID_ERROR << 16); uint16_t nextlid = 0; + uint32_t els_cmd = 0; if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); @@ -279,6 +292,9 @@ qla2x00_process_els(struct bsg_job *bsg_job) vha = shost_priv(host); ha = vha->hw; type = "FC_BSG_HST_ELS_NOLOGIN"; + els_cmd = bsg_request->rqst_data.h_els.command_code; + if (els_cmd == ELS_AUTH_ELS) + return qla_edif_process_els(vha, bsg_job); } if (!vha->flags.online) { @@ -2948,27 +2964,26 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; - if (sp) { - if (((sp->type == SRB_CT_CMD) || - (sp->type == SRB_ELS_CMD_HST) || - (sp->type == SRB_FXIOCB_BCMD)) - && (sp->u.bsg_job == bsg_job)) { - req->outstanding_cmds[cnt] = NULL; - spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (ha->isp_ops->abort_command(sp)) { - ql_log(ql_log_warn, vha, 0x7089, - "mbx abort_command " - "failed.\n"); - bsg_reply->result = -EIO; - } else { - ql_dbg(ql_dbg_user, vha, 0x708a, - "mbx abort_command " - "success.\n"); - bsg_reply->result = 0; - } - spin_lock_irqsave(&ha->hardware_lock, flags); - goto done; + if (sp && + (sp->type == SRB_CT_CMD || + sp->type == SRB_ELS_CMD_HST || + sp->type == SRB_ELS_CMD_HST_NOLOGIN || + sp->type == SRB_FXIOCB_BCMD) && + sp->u.bsg_job == bsg_job) { + req->outstanding_cmds[cnt] = NULL; + spin_unlock_irqrestore(&ha->hardware_lock, flags); + if (ha->isp_ops->abort_command(sp)) { + ql_log(ql_log_warn, vha, 0x7089, + "mbx abort_command failed.\n"); + bsg_reply->result = -EIO; + } else { + ql_dbg(ql_dbg_user, vha, 0x708a, + "mbx abort_command success.\n"); + bsg_reply->result = 0; } + spin_lock_irqsave(&ha->hardware_lock, flags); + goto done; + } } } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ec28023b738f..fbf5ca75cf23 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -341,6 +341,13 @@ struct name_list_extended { u32 size; u8 sent; }; + +struct els_reject { + struct fc_els_ls_rjt *c; + dma_addr_t cdma; + u16 size; +}; + /* * Timeout timer counts in seconds */ @@ -618,6 +625,21 @@ struct srb_iocb { #define SRB_PRLI_CMD 21 #define SRB_CTRL_VP 22 #define SRB_PRLO_CMD 23 +#define SRB_SA_UPDATE 25 +#define SRB_ELS_CMD_HST_NOLOGIN 26 +#define SRB_SA_REPLACE 27 + +struct qla_els_pt_arg { + u8 els_opcode; + u8 vp_idx; + __le16 nport_handle; + u16 control_flags; + __le32 rx_xchg_address; + port_id_t did; + u32 tx_len, tx_byte_count, rx_len, rx_byte_count; + dma_addr_t tx_addr, rx_addr; + +}; enum { TYPE_SRB, @@ -631,6 +653,13 @@ struct iocb_resource { u16 iocb_cnt; }; +struct bsg_cmd { + struct bsg_job *bsg_job; + union { + struct qla_els_pt_arg els_arg; + } u; +}; + typedef struct srb { /* * Do not move cmd_type field, it needs to @@ -663,7 +692,21 @@ typedef struct srb { struct srb_iocb iocb_cmd; struct bsg_job *bsg_job; struct srb_cmd scmd; + struct bsg_cmd bsg_cmd; } u; + struct { + bool remapped; + struct { + dma_addr_t dma; + void *buf; + uint len; + } req; + struct { + dma_addr_t dma; + void *buf; + uint len; + } rsp; + } remap; /* * Report completion status @res and call sp_put(@sp). @res is * an NVMe status code, a SCSI result (e.g. DID_OK << 16) or a @@ -4640,8 +4683,12 @@ struct qla_hw_data { struct qla_hw_data_stat stat; pci_error_state_t pci_error_state; u64 prev_cmd_cnt; + struct dma_pool *purex_dma_pool; + struct els_reject elsrej; }; +#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES)) + struct active_regions { uint8_t global; struct { @@ -5113,6 +5160,7 @@ enum nexus_wait_type { WAIT_LUN, }; +#define QLA_SKIP_HANDLE QLA_TGT_SKIP_HANDLE /* Refer to SNIA SFF 8247 */ struct sff_8247_a0 { u8 txid; /* transceiver id */ diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 165c910c1b81..3d923914da69 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -11,6 +11,30 @@ #include #include +static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *); + +static struct els_sub_cmd { + uint16_t cmd; + const char *str; +} sc_str[] = { + {SEND_ELS, "send ELS"}, + {SEND_ELS_REPLY, "send ELS Reply"}, + {PULL_ELS, "retrieve ELS"}, +}; + +const char *sc_to_str(uint16_t cmd) +{ + int i; + struct els_sub_cmd *e; + + for (i = 0; i < ARRAY_SIZE(sc_str); i++) { + e = sc_str + i; + if (cmd == e->cmd) + return e->str; + } + return "unknown"; +} + static void qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port *fcport) { @@ -27,6 +51,72 @@ qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port *fcport) fcport->edif.rx_bytes = 0; } +static int qla_bsg_check(scsi_qla_host_t *vha, struct bsg_job *bsg_job, +fc_port_t *fcport) +{ + struct extra_auth_els *p; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct qla_bsg_auth_els_request *req = + (struct qla_bsg_auth_els_request *)bsg_job->request; + + if (!vha->hw->flags.edif_enabled) { + /* edif support not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x9105, + "%s edif not enabled\n", __func__); + goto done; + } + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s doorbell not enabled\n", __func__); + goto done; + } + + p = &req->e; + + /* Get response */ + if (p->sub_cmd == PULL_ELS) { + struct qla_bsg_auth_els_reply *rpl = + (struct qla_bsg_auth_els_reply *)bsg_job->reply; + + qla_pur_get_pending(vha, fcport, bsg_job); + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s %s %8phN sid=%x. xchg %x, nb=%xh bsg ptr %p\n", + __func__, sc_to_str(p->sub_cmd), fcport->port_name, + fcport->d_id.b24, rpl->rx_xchg_address, + rpl->r.reply_payload_rcv_len, bsg_job); + + goto done; + } + return 0; + +done: + + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); + return -EIO; +} + +fc_port_t * +qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id) +{ + fc_port_t *f, *tf; + + f = NULL; + list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) { + if ((f->flags & FCF_FCSP_DEVICE)) { + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058, + "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n", + f->node_name, f->port_name, + f->d_id.b24, id->b24); + if (f->d_id.b24 == id->b24) + return f; + } + } + return NULL; +} + /** * qla_edif_app_check(): check for valid application id. * @vha: host adapter pointer @@ -519,17 +609,168 @@ done: return rval; } +static void +qla_enode_free(scsi_qla_host_t *vha, struct enode *node) +{ + node->ntype = N_UNDEF; + kfree(node); +} + +/** + * qla_enode_init - initialize enode structs & lock + * @vha: host adapter pointer + * + * should only be called when driver attaching + */ +void +qla_enode_init(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + char name[32]; + + if (vha->pur_cinfo.enode_flags == ENODE_ACTIVE) { + /* list still active - error */ + ql_dbg(ql_dbg_edif, vha, 0x09102, "%s enode still active\n", + __func__); + return; + } + + /* initialize lock which protects pur_core & init list */ + spin_lock_init(&vha->pur_cinfo.pur_lock); + INIT_LIST_HEAD(&vha->pur_cinfo.head); + + snprintf(name, sizeof(name), "%s_%d_purex", QLA2XXX_DRIVER_NAME, + ha->pdev->device); +} + +/** + * qla_enode_stop - stop and clear and enode data + * @vha: host adapter pointer + * + * called when app notified it is exiting + */ void qla_enode_stop(scsi_qla_host_t *vha) { + unsigned long flags; + struct enode *node, *q; + if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) { /* doorbell list not enabled */ ql_dbg(ql_dbg_edif, vha, 0x09102, "%s enode not active\n", __func__); return; } + + /* grab lock so list doesn't move */ + spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags); + + vha->pur_cinfo.enode_flags &= ~ENODE_ACTIVE; /* mark it not active */ + + /* hopefully this is a null list at this point */ + list_for_each_entry_safe(node, q, &vha->pur_cinfo.head, list) { + ql_dbg(ql_dbg_edif, vha, 0x910f, + "%s freeing enode type=%x, cnt=%x\n", __func__, node->ntype, + node->dinfo.nodecnt); + list_del_init(&node->list); + qla_enode_free(vha, node); + } + spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); +} + +static struct enode * +qla_enode_find(scsi_qla_host_t *vha, uint32_t ntype, uint32_t p1, uint32_t p2) +{ + struct enode *node_rtn = NULL; + struct enode *list_node = NULL; + unsigned long flags; + struct list_head *pos, *q; + uint32_t sid; + uint32_t rw_flag; + struct purexevent *purex; + + /* secure the list from moving under us */ + spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags); + + list_for_each_safe(pos, q, &vha->pur_cinfo.head) { + list_node = list_entry(pos, struct enode, list); + + /* node type determines what p1 and p2 are */ + purex = &list_node->u.purexinfo; + sid = p1; + rw_flag = p2; + + if (purex->pur_info.pur_sid.b24 == sid) { + if (purex->pur_info.pur_pend == 1 && + rw_flag == PUR_GET) { + /* + * if the receive is in progress + * and its a read/get then can't + * transfer yet + */ + ql_dbg(ql_dbg_edif, vha, 0x9106, + "%s purex xfer in progress for sid=%x\n", + __func__, sid); + } else { + /* found it and its complete */ + node_rtn = list_node; + list_del(pos); + break; + } + } + } + + spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); + + return node_rtn; } +/** + * qla_pur_get_pending - read/return authentication message sent + * from remote port + * @vha: host adapter pointer + * @fcport: session pointer + * @bsg_job: user request where the message is copy to. + */ +static int +qla_pur_get_pending(scsi_qla_host_t *vha, fc_port_t *fcport, + struct bsg_job *bsg_job) +{ + struct enode *ptr; + struct purexevent *purex; + struct qla_bsg_auth_els_reply *rpl = + (struct qla_bsg_auth_els_reply *)bsg_job->reply; + + bsg_job->reply_len = sizeof(*rpl); + + ptr = qla_enode_find(vha, N_PUREX, fcport->d_id.b24, PUR_GET); + if (!ptr) { + ql_dbg(ql_dbg_edif, vha, 0x9111, + "%s no enode data found for %8phN sid=%06x\n", + __func__, fcport->port_name, fcport->d_id.b24); + SET_DID_STATUS(rpl->r.result, DID_IMM_RETRY); + return -EIO; + } + + /* + * enode is now off the linked list and is ours to deal with + */ + purex = &ptr->u.purexinfo; + + /* Copy info back to caller */ + rpl->rx_xchg_address = purex->pur_info.pur_rx_xchg_address; + + SET_DID_STATUS(rpl->r.result, DID_OK); + rpl->r.reply_payload_rcv_len = + sg_pcopy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, purex->msgp, + purex->pur_info.pur_bytes_rcvd, 0); + + /* data copy / passback completed - destroy enode */ + qla_enode_free(vha, ptr); + + return 0; +} /* function called when app is stopping */ void @@ -542,3 +783,158 @@ qla_edb_stop(scsi_qla_host_t *vha) return; } } + +static void qla_parse_auth_els_ctl(struct srb *sp) +{ + struct qla_els_pt_arg *a = &sp->u.bsg_cmd.u.els_arg; + struct bsg_job *bsg_job = sp->u.bsg_cmd.bsg_job; + struct fc_bsg_request *request = bsg_job->request; + struct qla_bsg_auth_els_request *p = + (struct qla_bsg_auth_els_request *)bsg_job->request; + + a->tx_len = a->tx_byte_count = sp->remap.req.len; + a->tx_addr = sp->remap.req.dma; + a->rx_len = a->rx_byte_count = sp->remap.rsp.len; + a->rx_addr = sp->remap.rsp.dma; + + if (p->e.sub_cmd == SEND_ELS_REPLY) { + a->control_flags = p->e.extra_control_flags << 13; + a->rx_xchg_address = cpu_to_le32(p->e.extra_rx_xchg_address); + if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_ACC) + a->els_opcode = ELS_LS_ACC; + else if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_RJT) + a->els_opcode = ELS_LS_RJT; + } + a->did = sp->fcport->d_id; + a->els_opcode = request->rqst_data.h_els.command_code; + a->nport_handle = cpu_to_le16(sp->fcport->loop_id); + a->vp_idx = sp->vha->vp_idx; +} + +int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + struct fc_bsg_request *bsg_request = bsg_job->request; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + fc_port_t *fcport = NULL; + struct qla_hw_data *ha = vha->hw; + srb_t *sp; + int rval = (DID_ERROR << 16); + port_id_t d_id; + struct qla_bsg_auth_els_request *p = + (struct qla_bsg_auth_els_request *)bsg_job->request; + + d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2]; + d_id.b.area = bsg_request->rqst_data.h_els.port_id[1]; + d_id.b.domain = bsg_request->rqst_data.h_els.port_id[0]; + + /* find matching d_id in fcport list */ + fcport = qla2x00_find_fcport_by_pid(vha, &d_id); + if (!fcport) { + ql_dbg(ql_dbg_edif, vha, 0x911a, + "%s fcport not find online portid=%06x.\n", + __func__, d_id.b24); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + return -EIO; + } + + if (qla_bsg_check(vha, bsg_job, fcport)) + return 0; + + if (fcport->loop_id == FC_NO_LOOP_ID) { + ql_dbg(ql_dbg_edif, vha, 0x910d, + "%s ELS code %x, no loop id.\n", __func__, + bsg_request->rqst_data.r_els.els_code); + SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET); + return -ENXIO; + } + + if (!vha->flags.online) { + ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n"); + SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET); + rval = -EIO; + goto done; + } + + /* pass through is supported only for ISP 4Gb or higher */ + if (!IS_FWI2_CAPABLE(ha)) { + ql_dbg(ql_dbg_user, vha, 0x7001, + "ELS passthru not supported for ISP23xx based adapters.\n"); + SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET); + rval = -EPERM; + goto done; + } + + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { + ql_dbg(ql_dbg_user, vha, 0x7004, + "Failed get sp pid=%06x\n", fcport->d_id.b24); + rval = -ENOMEM; + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + goto done; + } + + sp->remap.req.len = bsg_job->request_payload.payload_len; + sp->remap.req.buf = dma_pool_alloc(ha->purex_dma_pool, + GFP_KERNEL, &sp->remap.req.dma); + if (!sp->remap.req.buf) { + ql_dbg(ql_dbg_user, vha, 0x7005, + "Failed allocate request dma len=%x\n", + bsg_job->request_payload.payload_len); + rval = -ENOMEM; + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + goto done_free_sp; + } + + sp->remap.rsp.len = bsg_job->reply_payload.payload_len; + sp->remap.rsp.buf = dma_pool_alloc(ha->purex_dma_pool, + GFP_KERNEL, &sp->remap.rsp.dma); + if (!sp->remap.rsp.buf) { + ql_dbg(ql_dbg_user, vha, 0x7006, + "Failed allocate response dma len=%x\n", + bsg_job->reply_payload.payload_len); + rval = -ENOMEM; + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + goto done_free_remap_req; + } + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, sp->remap.req.buf, + sp->remap.req.len); + sp->remap.remapped = true; + + sp->type = SRB_ELS_CMD_HST_NOLOGIN; + sp->name = "SPCN_BSG_HST_NOLOGIN"; + sp->u.bsg_cmd.bsg_job = bsg_job; + qla_parse_auth_els_ctl(sp); + + sp->free = qla2x00_bsg_sp_free; + sp->done = qla2x00_bsg_job_done; + + rval = qla2x00_start_sp(sp); + + ql_dbg(ql_dbg_edif, vha, 0x700a, + "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n", + __func__, sc_to_str(p->e.sub_cmd), fcport->port_name, + p->e.extra_rx_xchg_address, p->e.extra_control_flags, + sp->handle, sp->remap.req.len, bsg_job); + + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x700e, + "qla2x00_start_sp failed = %d\n", rval); + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + rval = -EIO; + goto done_free_remap_rsp; + } + return rval; + +done_free_remap_rsp: + dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf, + sp->remap.rsp.dma); +done_free_remap_req: + dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf, + sp->remap.req.dma); +done_free_sp: + qla2x00_rel_sp(sp); + +done: + return rval; +} diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h index d7d1433295c7..93c423227d82 100644 --- a/drivers/scsi/qla2xxx/qla_edif.h +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -30,4 +30,38 @@ struct edif_dbell { struct completion dbell; }; +#define MAX_PAYLOAD 1024 +#define PUR_GET 1 + +struct dinfo { + int nodecnt; + int lstate; +}; + +struct pur_ninfo { + unsigned int pur_pend:1; + port_id_t pur_sid; + port_id_t pur_did; + uint8_t vp_idx; + short pur_bytes_rcvd; + unsigned short pur_nphdl; + unsigned int pur_rx_xchg_address; +}; + +struct purexevent { + struct pur_ninfo pur_info; + unsigned char *msgp; + u32 msgp_len; +}; + +#define N_UNDEF 0 +#define N_PUREX 1 +struct enode { + struct list_head list; + struct dinfo dinfo; + uint32_t ntype; + union { + struct purexevent purexinfo; + } u; +}; #endif /* __QLA_EDIF_H */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index edd0a3af1030..0479641a0648 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -130,6 +130,8 @@ void qla24xx_free_purex_item(struct purex_item *item); extern bool qla24xx_risc_firmware_invalid(uint32_t *); void qla_init_iocb_limit(scsi_qla_host_t *); +int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob); +const char *sc_to_str(uint16_t cmd); /* * Global Data in qla_os.c source file. @@ -280,7 +282,8 @@ extern int qla2x00_vp_abort_isp(scsi_qla_host_t *); /* * Global Function Prototypes in qla_iocb.c source file. */ - +void qla_els_pt_iocb(struct scsi_qla_host *vha, + struct els_entry_24xx *pkt, struct qla_els_pt_arg *a); extern uint16_t qla2x00_calc_iocbs_32(uint16_t); extern uint16_t qla2x00_calc_iocbs_64(uint16_t); extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); @@ -950,6 +953,7 @@ extern void qla_nvme_abort_process_comp_status /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); +fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id); void qla_edb_stop(scsi_qla_host_t *vha); int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job); void qla_enode_init(scsi_qla_host_t *vha); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 1376aafe1c5c..77bacf2c2340 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -3053,6 +3053,43 @@ done: return rval; } +/* it is assume qpair lock is held */ +void qla_els_pt_iocb(struct scsi_qla_host *vha, + struct els_entry_24xx *els_iocb, + struct qla_els_pt_arg *a) +{ + els_iocb->entry_type = ELS_IOCB_TYPE; + els_iocb->entry_count = 1; + els_iocb->sys_define = 0; + els_iocb->entry_status = 0; + els_iocb->handle = QLA_SKIP_HANDLE; + els_iocb->nport_handle = a->nport_handle; + els_iocb->rx_xchg_address = a->rx_xchg_address; + els_iocb->tx_dsd_count = cpu_to_le16(1); + els_iocb->vp_index = a->vp_idx; + els_iocb->sof_type = EST_SOFI3; + els_iocb->rx_dsd_count = cpu_to_le16(0); + els_iocb->opcode = a->els_opcode; + + els_iocb->d_id[0] = a->did.b.al_pa; + els_iocb->d_id[1] = a->did.b.area; + els_iocb->d_id[2] = a->did.b.domain; + /* For SID the byte order is different than DID */ + els_iocb->s_id[1] = vha->d_id.b.al_pa; + els_iocb->s_id[2] = vha->d_id.b.area; + els_iocb->s_id[0] = vha->d_id.b.domain; + + els_iocb->control_flags = cpu_to_le16(a->control_flags); + + els_iocb->tx_byte_count = cpu_to_le32(a->tx_byte_count); + els_iocb->tx_len = cpu_to_le32(a->tx_len); + put_unaligned_le64(a->tx_addr, &els_iocb->tx_address); + + els_iocb->rx_byte_count = cpu_to_le32(a->rx_byte_count); + els_iocb->rx_len = cpu_to_le32(a->rx_len); + put_unaligned_le64(a->rx_addr, &els_iocb->rx_address); +} + static void qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) { @@ -3751,6 +3788,10 @@ qla2x00_start_sp(srb_t *sp) case SRB_ELS_CMD_HST: qla24xx_els_iocb(sp, pkt); break; + case SRB_ELS_CMD_HST_NOLOGIN: + qla_els_pt_iocb(sp->vha, pkt, &sp->u.bsg_cmd.u.els_arg); + ((struct els_entry_24xx *)pkt)->handle = sp->handle; + break; case SRB_CT_CMD: IS_FWI2_CAPABLE(ha) ? qla24xx_ct_iocb(sp, pkt) : diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d9fb093a60a1..9a81b626ced8 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1971,7 +1971,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, } static void -qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, +qla24xx_els_ct_entry(scsi_qla_host_t *v, struct req_que *req, struct sts_entry_24xx *pkt, int iocb_type) { struct els_sts_entry_24xx *ese = (struct els_sts_entry_24xx *)pkt; @@ -1982,18 +1982,58 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, struct fc_bsg_reply *bsg_reply; uint16_t comp_status; uint32_t fw_status[3]; - int res; + int res, logit = 1; struct srb_iocb *els; + uint n; + scsi_qla_host_t *vha; + struct els_sts_entry_24xx *e = (struct els_sts_entry_24xx *)pkt; - sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); + sp = qla2x00_get_sp_from_handle(v, func, req, pkt); if (!sp) return; + bsg_job = sp->u.bsg_job; + vha = sp->vha; type = NULL; + + comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status); + fw_status[1] = le32_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_1); + fw_status[2] = le32_to_cpu(((struct els_sts_entry_24xx *)pkt)->error_subcode_2); + switch (sp->type) { case SRB_ELS_CMD_RPT: case SRB_ELS_CMD_HST: + type = "rpt hst"; + break; + case SRB_ELS_CMD_HST_NOLOGIN: type = "els"; + { + struct els_entry_24xx *els = (void *)pkt; + struct qla_bsg_auth_els_request *p = + (struct qla_bsg_auth_els_request *)bsg_job->request; + + ql_dbg(ql_dbg_user, vha, 0x700f, + "%s %s. portid=%02x%02x%02x status %x xchg %x bsg ptr %p\n", + __func__, sc_to_str(p->e.sub_cmd), + e->d_id[2], e->d_id[1], e->d_id[0], + comp_status, p->e.extra_rx_xchg_address, bsg_job); + + if (!(le16_to_cpu(els->control_flags) & ECF_PAYLOAD_DESCR_MASK)) { + if (sp->remap.remapped) { + n = sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, + sp->remap.rsp.buf, + sp->remap.rsp.len); + ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x700e, + "%s: SG copied %x of %x\n", + __func__, n, sp->remap.rsp.len); + } else { + ql_dbg(ql_dbg_user, vha, 0x700f, + "%s: NOT REMAPPED (error)...!!!\n", + __func__); + } + } + } break; case SRB_CT_CMD: type = "ct pass-through"; @@ -2023,10 +2063,6 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, return; } - comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status); - fw_status[1] = le32_to_cpu(ese->error_subcode_1); - fw_status[2] = le32_to_cpu(ese->error_subcode_2); - if (iocb_type == ELS_IOCB_TYPE) { els = &sp->u.iocb_cmd; els->u.els_plogi.fw_status[0] = cpu_to_le32(fw_status[0]); @@ -2040,15 +2076,52 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, res = DID_OK << 16; els->u.els_plogi.len = cpu_to_le16(le32_to_cpu( ese->total_byte_count)); + + if (sp->remap.remapped && + ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_ACC) { + ql_dbg(ql_dbg_user, vha, 0x503f, + "%s IOCB Done LS_ACC %02x%02x%02x -> %02x%02x%02x", + __func__, e->s_id[0], e->s_id[2], e->s_id[1], + e->d_id[2], e->d_id[1], e->d_id[0]); + logit = 0; + } + + } else if (comp_status == CS_PORT_LOGGED_OUT) { + els->u.els_plogi.len = 0; + res = DID_IMM_RETRY << 16; } else { els->u.els_plogi.len = 0; res = DID_ERROR << 16; } + + if (logit) { + if (sp->remap.remapped && + ((u8 *)sp->remap.rsp.buf)[0] == ELS_LS_RJT) { + ql_dbg(ql_dbg_user, vha, 0x503f, + "%s IOCB Done LS_RJT hdl=%x comp_status=0x%x\n", + type, sp->handle, comp_status); + + ql_dbg(ql_dbg_user, vha, 0x503f, + "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n", + fw_status[1], fw_status[2], + le32_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count), + e->s_id[0], e->s_id[2], e->s_id[1], + e->d_id[2], e->d_id[1], e->d_id[0]); + } else { + ql_log(ql_log_info, vha, 0x503f, + "%s IOCB Done hdl=%x comp_status=0x%x\n", + type, sp->handle, comp_status); + ql_log(ql_log_info, vha, 0x503f, + "subcode 1=0x%x subcode 2=0x%x bytes=0x%x %02x%02x%02x -> %02x%02x%02x\n", + fw_status[1], fw_status[2], + le32_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count), + e->s_id[0], e->s_id[2], e->s_id[1], + e->d_id[2], e->d_id[1], e->d_id[0]); + } + } } - ql_dbg(ql_dbg_disc, vha, 0x503f, - "ELS IOCB Done -%s hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", - type, sp->handle, comp_status, fw_status[1], fw_status[2], - le32_to_cpu(ese->total_byte_count)); goto els_ct_done; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index cedd558f65eb..8a698042db3e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3460,6 +3460,7 @@ skip_dpc: return 0; probe_failed: + qla_enode_stop(base_vha); if (base_vha->gnl.l) { dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size, base_vha->gnl.l, base_vha->gnl.ldma); @@ -3762,6 +3763,7 @@ qla2x00_remove_one(struct pci_dev *pdev) base_vha->gnl.size, base_vha->gnl.l, base_vha->gnl.ldma); base_vha->gnl.l = NULL; + qla_enode_stop(base_vha); vfree(base_vha->scan.l); @@ -4264,8 +4266,36 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, goto fail_flt_buffer; } + /* allocate the purex dma pool */ + ha->purex_dma_pool = dma_pool_create(name, &ha->pdev->dev, + MAX_PAYLOAD, 8, 0); + + if (!ha->purex_dma_pool) { + ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b, + "Unable to allocate purex_dma_pool.\n"); + goto fail_flt; + } + + ha->elsrej.size = sizeof(struct fc_els_ls_rjt) + 16; + ha->elsrej.c = dma_alloc_coherent(&ha->pdev->dev, + ha->elsrej.size, &ha->elsrej.cdma, GFP_KERNEL); + + if (!ha->elsrej.c) { + ql_dbg_pci(ql_dbg_init, ha->pdev, 0xffff, + "Alloc failed for els reject cmd.\n"); + goto fail_elsrej; + } + ha->elsrej.c->er_cmd = ELS_LS_RJT; + ha->elsrej.c->er_reason = ELS_RJT_BUSY; + ha->elsrej.c->er_explan = ELS_EXPL_UNAB_DATA; return 0; +fail_elsrej: + dma_pool_destroy(ha->purex_dma_pool); +fail_flt: + dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, + ha->flt, ha->flt_dma); + fail_flt_buffer: dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, ha->sfp_data, ha->sfp_data_dma); @@ -4776,6 +4806,16 @@ qla2x00_mem_free(struct qla_hw_data *ha) if (ha->init_cb) dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, ha->init_cb_dma); + + dma_pool_destroy(ha->purex_dma_pool); + ha->purex_dma_pool = NULL; + + if (ha->elsrej.c) { + dma_free_coherent(&ha->pdev->dev, ha->elsrej.size, + ha->elsrej.c, ha->elsrej.cdma); + ha->elsrej.c = NULL; + } + ha->init_cb = NULL; ha->init_cb_dma = 0; @@ -4837,6 +4877,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, spin_lock_init(&vha->cmd_list_lock); init_waitqueue_head(&vha->fcport_waitQ); init_waitqueue_head(&vha->vref_waitq); + qla_enode_init(vha); vha->gnl.size = sizeof(struct get_name_list_extended) * (ha->max_loop_id + 1); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index eb47140a899f..b930e25dc846 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -184,8 +184,7 @@ static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked) return QLA_SUCCESS; } -static inline -struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, +struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha, be_id_t d_id) { struct scsi_qla_host *host; @@ -299,7 +298,7 @@ static void qlt_try_to_dequeue_unknown_atios(struct scsi_qla_host *vha, goto abort; } - host = qlt_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id); + host = qla_find_host_by_d_id(vha, u->atio.u.isp24.fcp_hdr.d_id); if (host != NULL) { ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0x502f, "Requeuing unknown ATIO_TYPE7 %p\n", u); @@ -348,7 +347,7 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, switch (atio->u.raw.entry_type) { case ATIO_TYPE7: { - struct scsi_qla_host *host = qlt_find_host_by_d_id(vha, + struct scsi_qla_host *host = qla_find_host_by_d_id(vha, atio->u.isp24.fcp_hdr.d_id); if (unlikely(NULL == host)) { ql_dbg(ql_dbg_tgt, vha, 0xe03e, -- cgit v1.2.3-70-g09d2 From fac2807946c10b9a509b9c348afd442fa823c5f7 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:25:59 -0700 Subject: scsi: qla2xxx: edif: Add extraction of auth_els from the wire Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. Once authentication messages sent from a remote device have arrived, each message is extracted and placed in a buffer for application to retrieve. The FC frame header will be stripped, leaving behind the AUTH ELS payload. It is up to the application to strip the AUTH ELS header to get to the actual authentication message. Link: https://lore.kernel.org/r/20210624052606.21613-5-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_edif.c | 184 +++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 7 +- drivers/scsi/qla2xxx/qla_isr.c | 212 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_os.c | 11 +- drivers/scsi/qla2xxx/qla_target.c | 36 +++---- 6 files changed, 427 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index fbf5ca75cf23..485e427c1ff1 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3908,7 +3908,6 @@ struct qlt_hw_data { int num_act_qpairs; #define DEFAULT_NAQP 2 spinlock_t atio_lock ____cacheline_aligned; - struct btree_head32 host_map; }; #define MAX_QFULL_CMDS_ALLOC 8192 @@ -4684,6 +4683,7 @@ struct qla_hw_data { pci_error_state_t pci_error_state; u64 prev_cmd_cnt; struct dma_pool *purex_dma_pool; + struct btree_head32 host_map; struct els_reject elsrej; }; diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 3d923914da69..e50f8d7d9d94 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -678,6 +678,46 @@ qla_enode_stop(scsi_qla_host_t *vha) spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); } +/* + * allocate enode struct and populate buffer + * returns: enode pointer with buffers + * NULL on error + */ +static struct enode * +qla_enode_alloc(scsi_qla_host_t *vha, uint32_t ntype) +{ + struct enode *node; + struct purexevent *purex; + + node = kzalloc(RX_ELS_SIZE, GFP_ATOMIC); + if (!node) + return NULL; + + purex = &node->u.purexinfo; + purex->msgp = (u8 *)(node + 1); + purex->msgp_len = ELS_MAX_PAYLOAD; + + node->ntype = ntype; + INIT_LIST_HEAD(&node->list); + return node; +} + +static void +qla_enode_add(scsi_qla_host_t *vha, struct enode *ptr) +{ + unsigned long flags; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x9109, + "%s add enode for type=%x, cnt=%x\n", + __func__, ptr->ntype, ptr->dinfo.nodecnt); + + spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags); + list_add_tail(&ptr->list, &vha->pur_cinfo.head); + spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); + + return; +} + static struct enode * qla_enode_find(scsi_qla_host_t *vha, uint32_t ntype, uint32_t p1, uint32_t p2) { @@ -771,6 +811,32 @@ qla_pur_get_pending(scsi_qla_host_t *vha, fc_port_t *fcport, return 0; } + +/* it is assume qpair lock is held */ +static int +qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp, + struct qla_els_pt_arg *a) +{ + struct els_entry_24xx *els_iocb; + + els_iocb = __qla2x00_alloc_iocbs(qp, NULL); + if (!els_iocb) { + ql_log(ql_log_warn, vha, 0x700c, + "qla2x00_alloc_iocbs failed.\n"); + return QLA_FUNCTION_FAILED; + } + + qla_els_pt_iocb(vha, els_iocb, a); + + ql_dbg(ql_dbg_edif, vha, 0x0183, + "Sending ELS reject...\n"); + ql_dump_buffer(ql_dbg_edif + ql_dbg_verbose, vha, 0x0185, + vha->hw->elsrej.c, sizeof(*vha->hw->elsrej.c)); + /* flush iocb to mem before notifying hw doorbell */ + wmb(); + qla2x00_start_iocbs(vha, qp->req); + return 0; +} /* function called when app is stopping */ void @@ -784,6 +850,124 @@ qla_edb_stop(scsi_qla_host_t *vha) } } +void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) +{ + struct purex_entry_24xx *p = *pkt; + struct enode *ptr; + int sid; + u16 totlen; + struct purexevent *purex; + struct scsi_qla_host *host = NULL; + int rc; + struct fc_port *fcport; + struct qla_els_pt_arg a; + be_id_t beid; + + memset(&a, 0, sizeof(a)); + + a.els_opcode = ELS_AUTH_ELS; + a.nport_handle = p->nport_handle; + a.rx_xchg_address = p->rx_xchg_addr; + a.did.b.domain = p->s_id[2]; + a.did.b.area = p->s_id[1]; + a.did.b.al_pa = p->s_id[0]; + a.tx_byte_count = a.tx_len = sizeof(struct fc_els_ls_rjt); + a.tx_addr = vha->hw->elsrej.cdma; + a.vp_idx = vha->vp_idx; + a.control_flags = EPD_ELS_RJT; + + sid = p->s_id[0] | (p->s_id[1] << 8) | (p->s_id[2] << 16); + + totlen = (le16_to_cpu(p->frame_size) & 0x0fff) - PURX_ELS_HEADER_SIZE; + if (le16_to_cpu(p->status_flags) & 0x8000) { + totlen = le16_to_cpu(p->trunc_frame_size); + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + __qla_consume_iocb(vha, pkt, rsp); + return; + } + + if (totlen > MAX_PAYLOAD) { + ql_dbg(ql_dbg_edif, vha, 0x0910d, + "%s WARNING: verbose ELS frame received (totlen=%x)\n", + __func__, totlen); + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + __qla_consume_iocb(vha, pkt, rsp); + return; + } + + if (!vha->hw->flags.edif_enabled) { + /* edif support not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x910e, "%s edif not enabled\n", + __func__); + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + __qla_consume_iocb(vha, pkt, rsp); + return; + } + + ptr = qla_enode_alloc(vha, N_PUREX); + if (!ptr) { + ql_dbg(ql_dbg_edif, vha, 0x09109, + "WARNING: enode allloc failed for sid=%x\n", + sid); + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + __qla_consume_iocb(vha, pkt, rsp); + return; + } + + purex = &ptr->u.purexinfo; + purex->pur_info.pur_sid = a.did; + purex->pur_info.pur_pend = 0; + purex->pur_info.pur_bytes_rcvd = totlen; + purex->pur_info.pur_rx_xchg_address = le32_to_cpu(p->rx_xchg_addr); + purex->pur_info.pur_nphdl = le16_to_cpu(p->nport_handle); + purex->pur_info.pur_did.b.domain = p->d_id[2]; + purex->pur_info.pur_did.b.area = p->d_id[1]; + purex->pur_info.pur_did.b.al_pa = p->d_id[0]; + purex->pur_info.vp_idx = p->vp_idx; + + rc = __qla_copy_purex_to_buffer(vha, pkt, rsp, purex->msgp, + purex->msgp_len); + if (rc) { + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + qla_enode_free(vha, ptr); + return; + } + beid.al_pa = purex->pur_info.pur_did.b.al_pa; + beid.area = purex->pur_info.pur_did.b.area; + beid.domain = purex->pur_info.pur_did.b.domain; + host = qla_find_host_by_d_id(vha, beid); + if (!host) { + ql_log(ql_log_fatal, vha, 0x508b, + "%s Drop ELS due to unable to find host %06x\n", + __func__, purex->pur_info.pur_did.b24); + + qla_els_reject_iocb(vha, (*rsp)->qpair, &a); + qla_enode_free(vha, ptr); + return; + } + + fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid); + + if (host->e_dbell.db_flags != EDB_ACTIVE || + (fcport && fcport->loop_id == FC_NO_LOOP_ID)) { + ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n", + __func__, host->e_dbell.db_flags, + fcport ? fcport->d_id.b24 : 0); + + qla_els_reject_iocb(host, (*rsp)->qpair, &a); + qla_enode_free(host, ptr); + return; + } + + /* add the local enode to the list */ + qla_enode_add(host, ptr); + + ql_dbg(ql_dbg_edif, host, 0x0910c, + "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n", + __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24, + purex->pur_info.pur_did.b24, p->rx_xchg_addr); +} + static void qla_parse_auth_els_ctl(struct srb *sp) { struct qla_els_pt_arg *a = &sp->u.bsg_cmd.u.els_arg; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0479641a0648..d19f5ec24d8c 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -581,6 +581,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id); fc_port_t *qla2x00_find_fcport_by_loopid(scsi_qla_host_t *, uint16_t); fc_port_t *qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *, u8 *, u8); fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8); +void __qla_consume_iocb(struct scsi_qla_host *vha, void **pkt, struct rsp_que **rsp); /* * Global Function Prototypes in qla_sup.c source file. @@ -643,6 +644,8 @@ extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); extern void qla2xxx_flash_npiv_conf(scsi_qla_host_t *); extern int qla24xx_read_fcp_prio_cfg(scsi_qla_host_t *); +int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, void **pkt, + struct rsp_que **rsp, u8 *buf, u32 buf_len); /* * Global Function Prototypes in qla_dbg.c source file. @@ -926,6 +929,7 @@ extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *); extern void qlt_handle_abts_recv(struct scsi_qla_host *, struct rsp_que *, response_t *); +struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha, be_id_t d_id); int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *, struct imm_ntfy_from_isp *, int); void qla24xx_do_nack_work(struct scsi_qla_host *, struct qla_work_evt *); @@ -938,7 +942,7 @@ extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *, void qla24xx_delete_sess_fn(struct work_struct *); void qlt_unknown_atio_work_fn(struct work_struct *); void qlt_update_host_map(struct scsi_qla_host *, port_id_t); -void qlt_remove_target_resources(struct qla_hw_data *); +void qla_remove_hostmap(struct qla_hw_data *ha); void qlt_clr_qp_table(struct scsi_qla_host *vha); void qlt_set_mode(struct scsi_qla_host *); int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode); @@ -958,6 +962,7 @@ void qla_edb_stop(scsi_qla_host_t *vha); int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job); void qla_enode_init(scsi_qla_host_t *vha); void qla_enode_stop(scsi_qla_host_t *vha); +void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp); void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea); #define QLA2XX_HW_ERROR BIT_0 diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 9a81b626ced8..a64b990fd947 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -169,6 +169,149 @@ qla24xx_process_abts(struct scsi_qla_host *vha, struct purex_item *pkt) dma_free_coherent(&ha->pdev->dev, sizeof(*rsp_els), rsp_els, dma); } +/** + * __qla_consume_iocb - this routine is used to tell fw driver has processed + * or consumed the head IOCB along with the continuation IOCB's from the + * provided respond queue. + * @vha: host adapter pointer + * @pkt: pointer to current packet. On return, this pointer shall move + * to the next packet. + * @rsp: respond queue pointer. + * + * it is assumed pkt is the head iocb, not the continuation iocbk + */ +void __qla_consume_iocb(struct scsi_qla_host *vha, + void **pkt, struct rsp_que **rsp) +{ + struct rsp_que *rsp_q = *rsp; + response_t *new_pkt; + uint16_t entry_count_remaining; + struct purex_entry_24xx *purex = *pkt; + + entry_count_remaining = purex->entry_count; + while (entry_count_remaining > 0) { + new_pkt = rsp_q->ring_ptr; + *pkt = new_pkt; + + rsp_q->ring_index++; + if (rsp_q->ring_index == rsp_q->length) { + rsp_q->ring_index = 0; + rsp_q->ring_ptr = rsp_q->ring; + } else { + rsp_q->ring_ptr++; + } + + new_pkt->signature = RESPONSE_PROCESSED; + /* flush signature */ + wmb(); + --entry_count_remaining; + } +} + +/** + * __qla_copy_purex_to_buffer - extract ELS payload from Purex IOCB + * and save to provided buffer + * @vha: host adapter pointer + * @pkt: pointer Purex IOCB + * @rsp: respond queue + * @buf: extracted ELS payload copy here + * @buf_len: buffer length + */ +int __qla_copy_purex_to_buffer(struct scsi_qla_host *vha, + void **pkt, struct rsp_que **rsp, u8 *buf, u32 buf_len) +{ + struct purex_entry_24xx *purex = *pkt; + struct rsp_que *rsp_q = *rsp; + sts_cont_entry_t *new_pkt; + uint16_t no_bytes = 0, total_bytes = 0, pending_bytes = 0; + uint16_t buffer_copy_offset = 0; + uint16_t entry_count_remaining; + u16 tpad; + + entry_count_remaining = purex->entry_count; + total_bytes = (le16_to_cpu(purex->frame_size) & 0x0FFF) + - PURX_ELS_HEADER_SIZE; + + /* + * end of payload may not end in 4bytes boundary. Need to + * round up / pad for room to swap, before saving data + */ + tpad = roundup(total_bytes, 4); + + if (buf_len < tpad) { + ql_dbg(ql_dbg_async, vha, 0x5084, + "%s buffer is too small %d < %d\n", + __func__, buf_len, tpad); + __qla_consume_iocb(vha, pkt, rsp); + return -EIO; + } + + pending_bytes = total_bytes = tpad; + no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ? + sizeof(purex->els_frame_payload) : pending_bytes; + + memcpy(buf, &purex->els_frame_payload[0], no_bytes); + buffer_copy_offset += no_bytes; + pending_bytes -= no_bytes; + --entry_count_remaining; + + ((response_t *)purex)->signature = RESPONSE_PROCESSED; + /* flush signature */ + wmb(); + + do { + while ((total_bytes > 0) && (entry_count_remaining > 0)) { + new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr; + *pkt = new_pkt; + + if (new_pkt->entry_type != STATUS_CONT_TYPE) { + ql_log(ql_log_warn, vha, 0x507a, + "Unexpected IOCB type, partial data 0x%x\n", + buffer_copy_offset); + break; + } + + rsp_q->ring_index++; + if (rsp_q->ring_index == rsp_q->length) { + rsp_q->ring_index = 0; + rsp_q->ring_ptr = rsp_q->ring; + } else { + rsp_q->ring_ptr++; + } + no_bytes = (pending_bytes > sizeof(new_pkt->data)) ? + sizeof(new_pkt->data) : pending_bytes; + if ((buffer_copy_offset + no_bytes) <= total_bytes) { + memcpy((buf + buffer_copy_offset), new_pkt->data, + no_bytes); + buffer_copy_offset += no_bytes; + pending_bytes -= no_bytes; + --entry_count_remaining; + } else { + ql_log(ql_log_warn, vha, 0x5044, + "Attempt to copy more that we got, optimizing..%x\n", + buffer_copy_offset); + memcpy((buf + buffer_copy_offset), new_pkt->data, + total_bytes - buffer_copy_offset); + } + + ((response_t *)new_pkt)->signature = RESPONSE_PROCESSED; + /* flush signature */ + wmb(); + } + + if (pending_bytes != 0 || entry_count_remaining != 0) { + ql_log(ql_log_fatal, vha, 0x508b, + "Dropping partial Data, underrun bytes = 0x%x, entry cnts 0x%x\n", + total_bytes, entry_count_remaining); + return -EIO; + } + } while (entry_count_remaining > 0); + + be32_to_cpu_array((u32 *)buf, (__be32 *)buf, total_bytes >> 2); + + return 0; +} + /** * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. * @irq: interrupt number @@ -1727,6 +1870,9 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, srb_t *sp; uint16_t index; + if (pkt->handle == QLA_SKIP_HANDLE) + return NULL; + index = LSW(pkt->handle); if (index >= req->num_outstanding_cmds) { ql_log(ql_log_warn, vha, 0x5031, @@ -3525,6 +3671,63 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, sp->done(sp, comp_status); } +/** + * qla_chk_cont_iocb_avail - check for all continuation iocbs are available + * before iocb processing can start. + * @vha: host adapter pointer + * @rsp: respond queue + * @pkt: head iocb describing how many continuation iocb + * Return: 0 all iocbs has arrived, xx- all iocbs have not arrived. + */ +static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha, + struct rsp_que *rsp, response_t *pkt) +{ + int start_pkt_ring_index, end_pkt_ring_index, n_ring_index; + response_t *end_pkt; + int rc = 0; + u32 rsp_q_in; + + if (pkt->entry_count == 1) + return rc; + + /* ring_index was pre-increment. set it back to current pkt */ + if (rsp->ring_index == 0) + start_pkt_ring_index = rsp->length - 1; + else + start_pkt_ring_index = rsp->ring_index - 1; + + if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length) + end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - + rsp->length - 1; + else + end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1; + + end_pkt = rsp->ring + end_pkt_ring_index; + + /* next pkt = end_pkt + 1 */ + n_ring_index = end_pkt_ring_index + 1; + if (n_ring_index >= rsp->length) + n_ring_index = 0; + + rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr : + rd_reg_dword(rsp->rsp_q_in); + + /* rsp_q_in is either wrapped or pointing beyond endpkt */ + if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) || + rsp_q_in >= n_ring_index) + /* all IOCBs arrived. */ + rc = 0; + else + rc = -EIO; + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091, + "%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n", + __func__, rsp->ring, pkt, end_pkt, pkt->entry_count, + rsp_q_in, rc); + + return rc; +} + /** * qla24xx_process_response_queue() - Process response queue entries. * @vha: SCSI driver HA context @@ -3665,6 +3868,15 @@ process_err: qla27xx_process_purex_fpin); break; + case ELS_AUTH_ELS: + if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) { + ql_dbg(ql_dbg_init, vha, 0x5091, + "Defer processing ELS opcode %#x...\n", + purex_entry->els_frame_payload[3]); + return; + } + qla24xx_auth_els(vha, (void **)&pkt, &rsp); + break; default: ql_log(ql_log_warn, vha, 0x509c, "Discarding ELS Request opcode 0x%x\n", diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 8a698042db3e..b7e1d7437d81 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3797,7 +3797,6 @@ qla2x00_remove_one(struct pci_dev *pdev) qla2x00_free_sysfs_attr(base_vha, true); fc_remove_host(base_vha->host); - qlt_remove_target_resources(ha); scsi_remove_host(base_vha->host); @@ -3974,15 +3973,20 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, struct req_que **req, struct rsp_que **rsp) { char name[16]; + int rc; ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size, &ha->init_cb_dma, GFP_KERNEL); if (!ha->init_cb) goto fail; - if (qlt_mem_alloc(ha) < 0) + rc = btree_init32(&ha->host_map); + if (rc) goto fail_free_init_cb; + if (qlt_mem_alloc(ha) < 0) + goto fail_free_btree; + ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL); if (!ha->gid_list) @@ -4386,6 +4390,8 @@ fail_free_gid_list: ha->gid_list_dma = 0; fail_free_tgt_mem: qlt_mem_free(ha); +fail_free_btree: + btree_destroy32(&ha->host_map); fail_free_init_cb: dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, ha->init_cb_dma); @@ -4802,6 +4808,7 @@ qla2x00_mem_free(struct qla_hw_data *ha) ha->dif_bundl_pool = NULL; qlt_mem_free(ha); + qla_remove_hostmap(ha); if (ha->init_cb) dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index b930e25dc846..26b2bfddc462 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -197,7 +197,7 @@ struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha, key = be_to_port_id(d_id).b24; - host = btree_lookup32(&vha->hw->tgt.host_map, key); + host = btree_lookup32(&vha->hw->host_map, key); if (!host) ql_dbg(ql_dbg_tgt_mgt + ql_dbg_verbose, vha, 0xf005, "Unable to find host %06x\n", key); @@ -6443,15 +6443,15 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) return 0; } -void qlt_remove_target_resources(struct qla_hw_data *ha) +void qla_remove_hostmap(struct qla_hw_data *ha) { struct scsi_qla_host *node; u32 key = 0; - btree_for_each_safe32(&ha->tgt.host_map, key, node) - btree_remove32(&ha->tgt.host_map, key); + btree_for_each_safe32(&ha->host_map, key, node) + btree_remove32(&ha->host_map, key); - btree_destroy32(&ha->tgt.host_map); + btree_destroy32(&ha->host_map); } static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, @@ -7079,8 +7079,7 @@ qlt_modify_vp_config(struct scsi_qla_host *vha, void qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) { - int rc; - + mutex_init(&base_vha->vha_tgt.tgt_mutex); if (!QLA_TGT_MODE_ENABLED()) return; @@ -7093,7 +7092,6 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) ISP_ATIO_Q_OUT(base_vha) = &ha->iobase->isp24.atio_q_out; } - mutex_init(&base_vha->vha_tgt.tgt_mutex); mutex_init(&base_vha->vha_tgt.tgt_host_action_mutex); INIT_LIST_HEAD(&base_vha->unknown_atio_list); @@ -7102,11 +7100,6 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) qlt_clear_mode(base_vha); - rc = btree_init32(&ha->tgt.host_map); - if (rc) - ql_log(ql_log_info, base_vha, 0xd03d, - "Unable to initialize ha->host_map btree\n"); - qlt_update_vp_map(base_vha, SET_VP_IDX); } @@ -7227,21 +7220,20 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) u32 key; int rc; - if (!QLA_TGT_MODE_ENABLED()) - return; - key = vha->d_id.b24; switch (cmd) { case SET_VP_IDX: + if (!QLA_TGT_MODE_ENABLED()) + return; vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; break; case SET_AL_PA: - slot = btree_lookup32(&vha->hw->tgt.host_map, key); + slot = btree_lookup32(&vha->hw->host_map, key); if (!slot) { ql_dbg(ql_dbg_tgt_mgt, vha, 0xf018, "Save vha in host_map %p %06x\n", vha, key); - rc = btree_insert32(&vha->hw->tgt.host_map, + rc = btree_insert32(&vha->hw->host_map, key, vha, GFP_ATOMIC); if (rc) ql_log(ql_log_info, vha, 0xd03e, @@ -7251,17 +7243,19 @@ qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) } ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019, "replace existing vha in host_map %p %06x\n", vha, key); - btree_update32(&vha->hw->tgt.host_map, key, vha); + btree_update32(&vha->hw->host_map, key, vha); break; case RESET_VP_IDX: + if (!QLA_TGT_MODE_ENABLED()) + return; vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; break; case RESET_AL_PA: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a, "clear vha in host_map %p %06x\n", vha, key); - slot = btree_lookup32(&vha->hw->tgt.host_map, key); + slot = btree_lookup32(&vha->hw->host_map, key); if (slot) - btree_remove32(&vha->hw->tgt.host_map, key); + btree_remove32(&vha->hw->host_map, key); vha->d_id.b24 = 0; break; } -- cgit v1.2.3-70-g09d2 From dd30706e73b70d67e88fdaca688db7a3374fd5de Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:00 -0700 Subject: scsi: qla2xxx: edif: Add key update Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. As part of the authentication process, the authentication application will generate a SADB entry (Security Association/SA, key, SPI value, etc). This SADB is then passed to driver to be programmed into hardware. There will be a pair of SADB's (Tx and Rx) for each connection. After some period, the application can choose to change the key. At that time, a new set of SADB pair is given to driver. The old set of SADB will be deleted. Add a new bsg call (QL_VND_SC_SA_UPDATE) to allow application to allow adding or deleting SADB entries. Driver will not keep the key in memory. It will pass it to HW. It is assumed that application will assign a unique SPI value to this SADB (SA + key). Driver + hardware will assign a handle to track this unique SPI/SADB. Link: https://lore.kernel.org/r/20210624052606.21613-6-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 69 ++ drivers/scsi/qla2xxx/qla_edif.c | 1480 ++++++++++++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_edif.h | 61 ++ drivers/scsi/qla2xxx/qla_fw.h | 1 + drivers/scsi/qla2xxx/qla_gbl.h | 21 + drivers/scsi/qla2xxx/qla_init.c | 10 + drivers/scsi/qla2xxx/qla_iocb.c | 6 + drivers/scsi/qla2xxx/qla_isr.c | 8 + drivers/scsi/qla2xxx/qla_os.c | 17 + drivers/scsi/qla2xxx/qla_target.h | 2 +- 10 files changed, 1668 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 485e427c1ff1..3e4c4cfbf7d4 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -401,6 +401,7 @@ struct srb_cmd { #define SRB_CRC_CTX_DSD_VALID BIT_5 /* DIF: dsd_list valid */ #define SRB_WAKEUP_ON_COMP BIT_6 #define SRB_DIF_BUNDL_DMA_VALID BIT_7 /* DIF: DMA list valid */ +#define SRB_EDIF_CLEANUP_DELETE BIT_9 /* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */ #define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID) @@ -595,6 +596,10 @@ struct srb_iocb { u16 cmd; u16 vp_index; } ctrlvp; + struct { + struct edif_sa_ctl *sa_ctl; + struct qla_sa_update_frame sa_frame; + } sa_update; } u; struct timer_list timer; @@ -2616,7 +2621,12 @@ typedef struct fc_port { uint32_t app_stop:2; uint32_t app_started:1; uint32_t secured_login:1; + uint32_t aes_gmac:1; uint32_t app_sess_online:1; + uint32_t tx_sa_set:1; + uint32_t rx_sa_set:1; + uint32_t tx_sa_pending:1; + uint32_t rx_sa_pending:1; uint32_t tx_rekey_cnt; uint32_t rx_rekey_cnt; uint64_t tx_bytes; @@ -2624,6 +2634,12 @@ typedef struct fc_port { uint8_t non_secured_login; uint8_t auth_state; uint16_t rekey_cnt; + struct list_head edif_indx_list; + spinlock_t indx_list_lock; + + struct list_head tx_sa_list; + struct list_head rx_sa_list; + spinlock_t sa_list_lock; } edif; } fc_port_t; @@ -2679,6 +2695,7 @@ static const char * const port_dstate_str[] = { #define FCF_CONF_COMP_SUPPORTED BIT_4 #define FCF_ASYNC_ACTIVE BIT_5 #define FCF_FCSP_DEVICE BIT_6 +#define FCF_EDIF_DELETE BIT_7 /* No loop ID flag. */ #define FC_NO_LOOP_ID 0x1000 @@ -3449,6 +3466,7 @@ enum qla_work_type { QLA_EVT_SP_RETRY, QLA_EVT_IIDMA, QLA_EVT_ELS_PLOGI, + QLA_EVT_SA_REPLACE, }; @@ -3507,6 +3525,11 @@ struct qla_work_evt { u8 fc4_type; srb_t *sp; } gpnft; + struct { + struct edif_sa_ctl *sa_ctl; + fc_port_t *fcport; + uint16_t nport_handle; + } sa_update; } u; }; @@ -4684,6 +4707,16 @@ struct qla_hw_data { u64 prev_cmd_cnt; struct dma_pool *purex_dma_pool; struct btree_head32 host_map; + +#define EDIF_NUM_SA_INDEX 512 +#define EDIF_TX_SA_INDEX_BASE EDIF_NUM_SA_INDEX + void *edif_rx_sa_id_map; + void *edif_tx_sa_id_map; + spinlock_t sadb_fp_lock; + + struct list_head sadb_tx_index_list; + struct list_head sadb_rx_index_list; + spinlock_t sadb_lock; /* protects list */ struct els_reject elsrej; }; @@ -5160,7 +5193,43 @@ enum nexus_wait_type { WAIT_LUN, }; +#define INVALID_EDIF_SA_INDEX 0xffff +#define RX_DELETE_NO_EDIF_SA_INDEX 0xfffe + #define QLA_SKIP_HANDLE QLA_TGT_SKIP_HANDLE + +/* edif hash element */ +struct edif_list_entry { + uint16_t handle; /* nport_handle */ + uint32_t update_sa_index; + uint32_t delete_sa_index; + uint32_t count; /* counter for filtering sa_index */ +#define EDIF_ENTRY_FLAGS_CLEANUP 0x01 /* this index is being cleaned up */ + uint32_t flags; /* used by sadb cleanup code */ + fc_port_t *fcport; /* needed by rx delay timer function */ + struct timer_list timer; /* rx delay timer */ + struct list_head next; +}; + +#define EDIF_TX_INDX_BASE 512 +#define EDIF_RX_INDX_BASE 0 +#define EDIF_RX_DELETE_FILTER_COUNT 3 /* delay queuing rx delete until this many */ + +/* entry in the sa_index free pool */ + +struct sa_index_pair { + uint16_t sa_index; + uint32_t spi; +}; + +/* edif sa_index data structure */ +struct edif_sa_index_entry { + struct sa_index_pair sa_pair[2]; + fc_port_t *fcport; + uint16_t handle; + struct list_head next; +}; + /* Refer to SNIA SFF 8247 */ struct sff_8247_a0 { u8 txid; /* transceiver id */ diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index e50f8d7d9d94..15f9e10ac257 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -11,6 +11,12 @@ #include #include +static struct edif_sa_index_entry *qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle, + struct list_head *sa_list); +static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport, + struct qla_sa_update_frame *sa_frame); +static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle, + uint16_t sa_index); static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *); static struct els_sub_cmd { @@ -35,14 +41,151 @@ const char *sc_to_str(uint16_t cmd) return "unknown"; } +static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport, + uint16_t handle) +{ + struct edif_list_entry *entry; + struct edif_list_entry *tentry; + struct list_head *indx_list = &fcport->edif.edif_indx_list; + + list_for_each_entry_safe(entry, tentry, indx_list, next) { + if (entry->handle == handle) + return entry; + } + return NULL; +} + +/* timeout called when no traffic and delayed rx sa_index delete */ +static void qla2x00_sa_replace_iocb_timeout(struct timer_list *t) +{ + struct edif_list_entry *edif_entry = from_timer(edif_entry, t, timer); + fc_port_t *fcport = edif_entry->fcport; + struct scsi_qla_host *vha = fcport->vha; + struct edif_sa_ctl *sa_ctl; + uint16_t nport_handle; + unsigned long flags = 0; + + ql_dbg(ql_dbg_edif, vha, 0x3069, + "%s: nport_handle 0x%x, SA REPL Delay Timeout, %8phC portid=%06x\n", + __func__, edif_entry->handle, fcport->port_name, fcport->d_id.b24); + + /* + * if delete_sa_index is valid then no one has serviced this + * delayed delete + */ + spin_lock_irqsave(&fcport->edif.indx_list_lock, flags); + + /* + * delete_sa_index is invalidated when we find the new sa_index in + * the incoming data stream. If it is not invalidated then we are + * still looking for the new sa_index because there is no I/O and we + * need to just force the rx delete and move on. Otherwise + * we could get another rekey which will result in an error 66. + */ + if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) { + uint16_t delete_sa_index = edif_entry->delete_sa_index; + + edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX; + nport_handle = edif_entry->handle; + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + + sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, + delete_sa_index, 0); + + if (sa_ctl) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sa_ctl: %p, delete index %d, update index: %d, lid: 0x%x\n", + __func__, sa_ctl, delete_sa_index, edif_entry->update_sa_index, + nport_handle); + + sa_ctl->flags = EDIF_SA_CTL_FLG_DEL; + set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state); + qla_post_sa_replace_work(fcport->vha, fcport, + nport_handle, sa_ctl); + + } else { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sa_ctl not found for delete_sa_index: %d\n", + __func__, edif_entry->delete_sa_index); + } + } else { + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + } +} + +/* + * create a new list entry for this nport handle and + * add an sa_update index to the list - called for sa_update + */ +static int qla_edif_list_add_sa_update_index(fc_port_t *fcport, + uint16_t sa_index, uint16_t handle) +{ + struct edif_list_entry *entry; + unsigned long flags = 0; + + /* if the entry exists, then just update the sa_index */ + entry = qla_edif_list_find_sa_index(fcport, handle); + if (entry) { + entry->update_sa_index = sa_index; + entry->count = 0; + return 0; + } + + /* + * This is the normal path - there should be no existing entry + * when update is called. The exception is at startup + * when update is called for the first two sa_indexes + * followed by a delete of the first sa_index + */ + entry = kzalloc((sizeof(struct edif_list_entry)), GFP_ATOMIC); + if (!entry) + return -ENOMEM; + + INIT_LIST_HEAD(&entry->next); + entry->handle = handle; + entry->update_sa_index = sa_index; + entry->delete_sa_index = INVALID_EDIF_SA_INDEX; + entry->count = 0; + entry->flags = 0; + timer_setup(&entry->timer, qla2x00_sa_replace_iocb_timeout, 0); + spin_lock_irqsave(&fcport->edif.indx_list_lock, flags); + list_add_tail(&entry->next, &fcport->edif.edif_indx_list); + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + return 0; +} + +/* remove an entry from the list */ +static void qla_edif_list_delete_sa_index(fc_port_t *fcport, struct edif_list_entry *entry) +{ + unsigned long flags = 0; + + spin_lock_irqsave(&fcport->edif.indx_list_lock, flags); + list_del(&entry->next); + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); +} + +int qla_post_sa_replace_work(struct scsi_qla_host *vha, + fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl) +{ + struct qla_work_evt *e; + + e = qla2x00_alloc_work(vha, QLA_EVT_SA_REPLACE); + if (!e) + return QLA_FUNCTION_FAILED; + + e->u.sa_update.fcport = fcport; + e->u.sa_update.sa_ctl = sa_ctl; + e->u.sa_update.nport_handle = nport_handle; + fcport->flags |= FCF_ASYNC_ACTIVE; + return qla2x00_post_work(vha, e); +} + static void qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port *fcport) { ql_dbg(ql_dbg_edif, vha, 0x2058, - "Init SA_CTL List for fcport - nn %8phN pn %8phN portid=%02x%02x%02x.\n", - fcport->node_name, fcport->port_name, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "Init SA_CTL List for fcport - nn %8phN pn %8phN portid=%06x.\n", + fcport->node_name, fcport->port_name, fcport->d_id.b24); fcport->edif.tx_rekey_cnt = 0; fcport->edif.rx_rekey_cnt = 0; @@ -60,13 +203,11 @@ fc_port_t *fcport) (struct qla_bsg_auth_els_request *)bsg_job->request; if (!vha->hw->flags.edif_enabled) { - /* edif support not enabled */ ql_dbg(ql_dbg_edif, vha, 0x9105, "%s edif not enabled\n", __func__); goto done; } if (vha->e_dbell.db_flags != EDB_ACTIVE) { - /* doorbell list not enabled */ ql_dbg(ql_dbg_edif, vha, 0x09102, "%s doorbell not enabled\n", __func__); goto done; @@ -195,6 +336,167 @@ static void qla_edif_reset_auth_wait(struct fc_port *fcport, int state, } } +static void +qla_edif_free_sa_ctl(fc_port_t *fcport, struct edif_sa_ctl *sa_ctl, + int index) +{ + unsigned long flags = 0; + + spin_lock_irqsave(&fcport->edif.sa_list_lock, flags); + list_del(&sa_ctl->next); + spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags); + if (index >= 512) + fcport->edif.tx_rekey_cnt--; + else + fcport->edif.rx_rekey_cnt--; + kfree(sa_ctl); +} + +/* return an index to the freepool */ +static void qla_edif_add_sa_index_to_freepool(fc_port_t *fcport, int dir, + uint16_t sa_index) +{ + void *sa_id_map; + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + unsigned long flags = 0; + u16 lsa_index = sa_index; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063, + "%s: entry\n", __func__); + + if (dir) { + sa_id_map = ha->edif_tx_sa_id_map; + lsa_index -= EDIF_TX_SA_INDEX_BASE; + } else { + sa_id_map = ha->edif_rx_sa_id_map; + } + + spin_lock_irqsave(&ha->sadb_fp_lock, flags); + clear_bit(lsa_index, sa_id_map); + spin_unlock_irqrestore(&ha->sadb_fp_lock, flags); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: index %d added to free pool\n", __func__, sa_index); +} + +static void __qla2x00_release_all_sadb(struct scsi_qla_host *vha, + struct fc_port *fcport, struct edif_sa_index_entry *entry, + int pdir) +{ + struct edif_list_entry *edif_entry; + struct edif_sa_ctl *sa_ctl; + int i, dir; + int key_cnt = 0; + + for (i = 0; i < 2; i++) { + if (entry->sa_pair[i].sa_index == INVALID_EDIF_SA_INDEX) + continue; + + if (fcport->loop_id != entry->handle) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: ** WARNING %d** entry handle: 0x%x, lid: 0x%x, sa_index: %d\n", + __func__, i, entry->handle, fcport->loop_id, + entry->sa_pair[i].sa_index); + } + + /* release the sa_ctl */ + sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, + entry->sa_pair[i].sa_index, pdir); + if (sa_ctl && + qla_edif_find_sa_ctl_by_index(fcport, sa_ctl->index, pdir)) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_ctl for index %d\n", __func__, sa_ctl->index); + qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index); + } else { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sa_ctl NOT freed, sa_ctl: %p\n", __func__, sa_ctl); + } + + /* Release the index */ + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_index %d, nph: 0x%x\n", + __func__, entry->sa_pair[i].sa_index, entry->handle); + + dir = (entry->sa_pair[i].sa_index < + EDIF_TX_SA_INDEX_BASE) ? 0 : 1; + qla_edif_add_sa_index_to_freepool(fcport, dir, + entry->sa_pair[i].sa_index); + + /* Delete timer on RX */ + if (pdir != SAU_FLG_TX) { + edif_entry = + qla_edif_list_find_sa_index(fcport, entry->handle); + if (edif_entry) { + ql_dbg(ql_dbg_edif, vha, 0x5033, + "%s: remove edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n", + __func__, edif_entry, edif_entry->update_sa_index, + edif_entry->delete_sa_index); + qla_edif_list_delete_sa_index(fcport, edif_entry); + /* + * valid delete_sa_index indicates there is a rx + * delayed delete queued + */ + if (edif_entry->delete_sa_index != + INVALID_EDIF_SA_INDEX) { + del_timer(&edif_entry->timer); + + /* build and send the aen */ + fcport->edif.rx_sa_set = 1; + fcport->edif.rx_sa_pending = 0; + } + ql_dbg(ql_dbg_edif, vha, 0x5033, + "%s: release edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n", + __func__, edif_entry, edif_entry->update_sa_index, + edif_entry->delete_sa_index); + + kfree(edif_entry); + } + } + key_cnt++; + } + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: %d %s keys released\n", + __func__, key_cnt, pdir ? "tx" : "rx"); +} + +/* find an release all outstanding sadb sa_indicies */ +void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport) +{ + struct edif_sa_index_entry *entry, *tmp; + struct qla_hw_data *ha = vha->hw; + unsigned long flags; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063, + "%s: Starting...\n", __func__); + + spin_lock_irqsave(&ha->sadb_lock, flags); + + list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) { + if (entry->fcport == fcport) { + list_del(&entry->next); + spin_unlock_irqrestore(&ha->sadb_lock, flags); + __qla2x00_release_all_sadb(vha, fcport, entry, 0); + kfree(entry); + spin_lock_irqsave(&ha->sadb_lock, flags); + break; + } + } + + list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) { + if (entry->fcport == fcport) { + list_del(&entry->next); + spin_unlock_irqrestore(&ha->sadb_lock, flags); + + __qla2x00_release_all_sadb(vha, fcport, entry, SAU_FLG_TX); + + kfree(entry); + spin_lock_irqsave(&ha->sadb_lock, flags); + break; + } + } + spin_unlock_irqrestore(&ha->sadb_lock, flags); +} + /** * qla_edif_app_start: application has announce its present * @vha: host adapter pointer @@ -576,6 +878,10 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) } switch (vnd_sc) { + case QL_VND_SC_SA_UPDATE: + done = false; + rval = qla24xx_sadb_update(bsg_job); + break; case QL_VND_SC_APP_START: rval = qla_edif_app_start(vha, bsg_job); break; @@ -609,6 +915,438 @@ done: return rval; } +static struct edif_sa_ctl * +qla_edif_add_sa_ctl(fc_port_t *fcport, struct qla_sa_update_frame *sa_frame, + int dir) +{ + struct edif_sa_ctl *sa_ctl; + struct qla_sa_update_frame *sap; + int index = sa_frame->fast_sa_index; + unsigned long flags = 0; + + sa_ctl = kzalloc(sizeof(*sa_ctl), GFP_KERNEL); + if (!sa_ctl) { + /* couldn't get space */ + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "unable to allocate SA CTL\n"); + return NULL; + } + + /* + * need to allocate sa_index here and save it + * in both sa_ctl->index and sa_frame->fast_sa_index; + * If alloc fails then delete sa_ctl and return NULL + */ + INIT_LIST_HEAD(&sa_ctl->next); + sap = &sa_ctl->sa_frame; + *sap = *sa_frame; + sa_ctl->index = index; + sa_ctl->fcport = fcport; + sa_ctl->flags = 0; + sa_ctl->state = 0L; + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "%s: Added sa_ctl %p, index %d, state 0x%lx\n", + __func__, sa_ctl, sa_ctl->index, sa_ctl->state); + spin_lock_irqsave(&fcport->edif.sa_list_lock, flags); + if (dir == SAU_FLG_TX) + list_add_tail(&sa_ctl->next, &fcport->edif.tx_sa_list); + else + list_add_tail(&sa_ctl->next, &fcport->edif.rx_sa_list); + spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags); + + return sa_ctl; +} + +void +qla_edif_flush_sa_ctl_lists(fc_port_t *fcport) +{ + struct edif_sa_ctl *sa_ctl, *tsa_ctl; + unsigned long flags = 0; + + spin_lock_irqsave(&fcport->edif.sa_list_lock, flags); + + list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.tx_sa_list, + next) { + list_del(&sa_ctl->next); + kfree(sa_ctl); + } + + list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.rx_sa_list, + next) { + list_del(&sa_ctl->next); + kfree(sa_ctl); + } + + spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags); +} + +struct edif_sa_ctl * +qla_edif_find_sa_ctl_by_index(fc_port_t *fcport, int index, int dir) +{ + struct edif_sa_ctl *sa_ctl, *tsa_ctl; + struct list_head *sa_list; + + if (dir == SAU_FLG_TX) + sa_list = &fcport->edif.tx_sa_list; + else + sa_list = &fcport->edif.rx_sa_list; + + list_for_each_entry_safe(sa_ctl, tsa_ctl, sa_list, next) { + if (test_bit(EDIF_SA_CTL_USED, &sa_ctl->state) && + sa_ctl->index == index) + return sa_ctl; + } + return NULL; +} + +/* add the sa to the correct list */ +static int +qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport, + struct qla_sa_update_frame *sa_frame) +{ + struct edif_sa_ctl *sa_ctl = NULL; + int dir; + uint16_t sa_index; + + dir = (sa_frame->flags & SAU_FLG_TX); + + /* map the spi to an sa_index */ + sa_index = qla_edif_sadb_get_sa_index(fcport, sa_frame); + if (sa_index == RX_DELETE_NO_EDIF_SA_INDEX) { + /* process rx delete */ + ql_dbg(ql_dbg_edif, fcport->vha, 0x3063, + "%s: rx delete for lid 0x%x, spi 0x%x, no entry found\n", + __func__, fcport->loop_id, sa_frame->spi); + + /* build and send the aen */ + fcport->edif.rx_sa_set = 1; + fcport->edif.rx_sa_pending = 0; + + /* force a return of good bsg status; */ + return RX_DELETE_NO_EDIF_SA_INDEX; + } else if (sa_index == INVALID_EDIF_SA_INDEX) { + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "%s: Failed to get sa_index for spi 0x%x, dir: %d\n", + __func__, sa_frame->spi, dir); + return INVALID_EDIF_SA_INDEX; + } + + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "%s: index %d allocated to spi 0x%x, dir: %d, nport_handle: 0x%x\n", + __func__, sa_index, sa_frame->spi, dir, fcport->loop_id); + + /* This is a local copy of sa_frame. */ + sa_frame->fast_sa_index = sa_index; + /* create the sa_ctl */ + sa_ctl = qla_edif_add_sa_ctl(fcport, sa_frame, dir); + if (!sa_ctl) { + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "%s: Failed to add sa_ctl for spi 0x%x, dir: %d, sa_index: %d\n", + __func__, sa_frame->spi, dir, sa_index); + return -1; + } + + set_bit(EDIF_SA_CTL_USED, &sa_ctl->state); + + if (dir == SAU_FLG_TX) + fcport->edif.tx_rekey_cnt++; + else + fcport->edif.rx_rekey_cnt++; + + ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, + "%s: Found sa_ctl %p, index %d, state 0x%lx, tx_cnt %d, rx_cnt %d, nport_handle: 0x%x\n", + __func__, sa_ctl, sa_ctl->index, sa_ctl->state, + fcport->edif.tx_rekey_cnt, + fcport->edif.rx_rekey_cnt, fcport->loop_id); + + return 0; +} + +#define QLA_SA_UPDATE_FLAGS_RX_KEY 0x0 +#define QLA_SA_UPDATE_FLAGS_TX_KEY 0x2 + +int +qla24xx_sadb_update(struct bsg_job *bsg_job) +{ + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); + scsi_qla_host_t *vha = shost_priv(host); + fc_port_t *fcport = NULL; + srb_t *sp = NULL; + struct edif_list_entry *edif_entry = NULL; + int found = 0; + int rval = 0; + int result = 0; + struct qla_sa_update_frame sa_frame; + struct srb_iocb *iocb_cmd; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, + "%s entered, vha: 0x%p\n", __func__, vha); + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &sa_frame, + sizeof(struct qla_sa_update_frame)); + + /* Check if host is online */ + if (!vha->flags.online) { + ql_log(ql_log_warn, vha, 0x70a1, "Host is not online\n"); + rval = -EIO; + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + } + + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + ql_log(ql_log_warn, vha, 0x70a1, "App not started\n"); + rval = -EIO; + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + } + + fcport = qla2x00_find_fcport_by_pid(vha, &sa_frame.port_id); + if (fcport) { + found = 1; + if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_TX_KEY) + fcport->edif.tx_bytes = 0; + if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_RX_KEY) + fcport->edif.rx_bytes = 0; + } + + if (!found) { + ql_dbg(ql_dbg_edif, vha, 0x70a3, "Failed to find port= %06x\n", + sa_frame.port_id.b24); + rval = -EINVAL; + SET_DID_STATUS(bsg_reply->result, DID_TARGET_FAILURE); + goto done; + } + + /* make sure the nport_handle is valid */ + if (fcport->loop_id == FC_NO_LOOP_ID) { + ql_dbg(ql_dbg_edif, vha, 0x70e1, + "%s: %8phN lid=FC_NO_LOOP_ID, spi: 0x%x, DS %d, returning NO_CONNECT\n", + __func__, fcport->port_name, sa_frame.spi, + fcport->disc_state); + rval = -EINVAL; + SET_DID_STATUS(bsg_reply->result, DID_NO_CONNECT); + goto done; + } + + /* allocate and queue an sa_ctl */ + result = qla24xx_check_sadb_avail_slot(bsg_job, fcport, &sa_frame); + + /* failure of bsg */ + if (result == INVALID_EDIF_SA_INDEX) { + ql_dbg(ql_dbg_edif, vha, 0x70e1, + "%s: %8phN, skipping update.\n", + __func__, fcport->port_name); + rval = -EINVAL; + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + + /* rx delete failure */ + } else if (result == RX_DELETE_NO_EDIF_SA_INDEX) { + ql_dbg(ql_dbg_edif, vha, 0x70e1, + "%s: %8phN, skipping rx delete.\n", + __func__, fcport->port_name); + SET_DID_STATUS(bsg_reply->result, DID_OK); + goto done; + } + + ql_dbg(ql_dbg_edif, vha, 0x70e1, + "%s: %8phN, sa_index in sa_frame: %d flags %xh\n", + __func__, fcport->port_name, sa_frame.fast_sa_index, + sa_frame.flags); + + /* looking for rx index and delete */ + if (((sa_frame.flags & SAU_FLG_TX) == 0) && + (sa_frame.flags & SAU_FLG_INV)) { + uint16_t nport_handle = fcport->loop_id; + uint16_t sa_index = sa_frame.fast_sa_index; + + /* + * make sure we have an existing rx key, otherwise just process + * this as a straight delete just like TX + * This is NOT a normal case, it indicates an error recovery or key cleanup + * by the ipsec code above us. + */ + edif_entry = qla_edif_list_find_sa_index(fcport, fcport->loop_id); + if (!edif_entry) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: WARNING: no active sa_index for nport_handle 0x%x, forcing delete for sa_index 0x%x\n", + __func__, fcport->loop_id, sa_index); + goto force_rx_delete; + } + + /* + * if we have a forced delete for rx, remove the sa_index from the edif list + * and proceed with normal delete. The rx delay timer should not be running + */ + if ((sa_frame.flags & SAU_FLG_FORCE_DELETE) == SAU_FLG_FORCE_DELETE) { + qla_edif_list_delete_sa_index(fcport, edif_entry); + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: FORCE DELETE flag found for nport_handle 0x%x, sa_index 0x%x, forcing DELETE\n", + __func__, fcport->loop_id, sa_index); + kfree(edif_entry); + goto force_rx_delete; + } + + /* + * delayed rx delete + * + * if delete_sa_index is not invalid then there is already + * a delayed index in progress, return bsg bad status + */ + if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) { + struct edif_sa_ctl *sa_ctl; + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: delete for lid 0x%x, delete_sa_index %d is pending\n", + __func__, edif_entry->handle, edif_entry->delete_sa_index); + + /* free up the sa_ctl that was allocated with the sa_index */ + sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, sa_index, + (sa_frame.flags & SAU_FLG_TX)); + if (sa_ctl) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_ctl for index %d\n", + __func__, sa_ctl->index); + qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index); + } + + /* release the sa_index */ + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_index %d, nph: 0x%x\n", + __func__, sa_index, nport_handle); + qla_edif_sadb_delete_sa_index(fcport, nport_handle, sa_index); + + rval = -EINVAL; + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto done; + } + + fcport->edif.rekey_cnt++; + + /* configure and start the rx delay timer */ + edif_entry->fcport = fcport; + edif_entry->timer.expires = jiffies + RX_DELAY_DELETE_TIMEOUT * HZ; + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: adding timer, entry: %p, delete sa_index %d, lid 0x%x to edif_list\n", + __func__, edif_entry, sa_index, nport_handle); + + /* + * Start the timer when we queue the delayed rx delete. + * This is an activity timer that goes off if we have not + * received packets with the new sa_index + */ + add_timer(&edif_entry->timer); + + /* + * sa_delete for rx key with an active rx key including this one + * add the delete rx sa index to the hash so we can look for it + * in the rsp queue. Do this after making any changes to the + * edif_entry as part of the rx delete. + */ + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: delete sa_index %d, lid 0x%x to edif_list. bsg done ptr %p\n", + __func__, sa_index, nport_handle, bsg_job); + + edif_entry->delete_sa_index = sa_index; + + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + bsg_reply->result = DID_OK << 16; + + goto done; + + /* + * rx index and update + * add the index to the list and continue with normal update + */ + } else if (((sa_frame.flags & SAU_FLG_TX) == 0) && + ((sa_frame.flags & SAU_FLG_INV) == 0)) { + /* sa_update for rx key */ + uint32_t nport_handle = fcport->loop_id; + uint16_t sa_index = sa_frame.fast_sa_index; + int result; + + /* + * add the update rx sa index to the hash so we can look for it + * in the rsp queue and continue normally + */ + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: adding update sa_index %d, lid 0x%x to edif_list\n", + __func__, sa_index, nport_handle); + + result = qla_edif_list_add_sa_update_index(fcport, sa_index, + nport_handle); + if (result) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: SA_UPDATE failed to add new sa index %d to list for lid 0x%x\n", + __func__, sa_index, nport_handle); + } + } + if (sa_frame.flags & SAU_FLG_GMAC_MODE) + fcport->edif.aes_gmac = 1; + else + fcport->edif.aes_gmac = 0; + +force_rx_delete: + /* + * sa_update for both rx and tx keys, sa_delete for tx key + * immediately process the request + */ + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { + rval = -ENOMEM; + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + goto done; + } + + sp->type = SRB_SA_UPDATE; + sp->name = "bsg_sa_update"; + sp->u.bsg_job = bsg_job; + /* sp->free = qla2x00_bsg_sp_free; */ + sp->free = qla2x00_rel_sp; + sp->done = qla2x00_bsg_job_done; + iocb_cmd = &sp->u.iocb_cmd; + iocb_cmd->u.sa_update.sa_frame = sa_frame; + + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { + ql_log(ql_dbg_edif, vha, 0x70e3, + "qla2x00_start_sp failed=%d.\n", rval); + + qla2x00_rel_sp(sp); + rval = -EIO; + SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY); + goto done; + } + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: %s sent, hdl=%x, portid=%06x.\n", + __func__, sp->name, sp->handle, fcport->d_id.b24); + + fcport->edif.rekey_cnt++; + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + SET_DID_STATUS(bsg_reply->result, DID_OK); + + return 0; + +/* + * send back error status + */ +done: + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s:status: FAIL, result: 0x%x, bsg ptr done %p\n", + __func__, bsg_reply->result, bsg_job); + bsg_job_done(bsg_job, bsg_reply->result, + bsg_reply->reply_payload_rcv_len); + + return 0; +} + static void qla_enode_free(scsi_qla_host_t *vha, struct enode *node) { @@ -850,6 +1588,198 @@ qla_edb_stop(scsi_qla_host_t *vha) } } +static void qla_noop_sp_done(srb_t *sp, int res) +{ + sp->free(sp); +} + +/* + * Called from work queue + * build and send the sa_update iocb to delete an rx sa_index + */ +int +qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e) +{ + srb_t *sp; + fc_port_t *fcport = NULL; + struct srb_iocb *iocb_cmd = NULL; + int rval = QLA_SUCCESS; + struct edif_sa_ctl *sa_ctl = e->u.sa_update.sa_ctl; + uint16_t nport_handle = e->u.sa_update.nport_handle; + + ql_dbg(ql_dbg_edif, vha, 0x70e6, + "%s: starting, sa_ctl: %p\n", __func__, sa_ctl); + + if (!sa_ctl) { + ql_dbg(ql_dbg_edif, vha, 0x70e6, + "sa_ctl allocation failed\n"); + return -ENOMEM; + } + + fcport = sa_ctl->fcport; + + /* Alloc SRB structure */ + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { + ql_dbg(ql_dbg_edif, vha, 0x70e6, + "SRB allocation failed\n"); + return -ENOMEM; + } + + fcport->flags |= FCF_ASYNC_SENT; + iocb_cmd = &sp->u.iocb_cmd; + iocb_cmd->u.sa_update.sa_ctl = sa_ctl; + + ql_dbg(ql_dbg_edif, vha, 0x3073, + "Enter: SA REPL portid=%06x, sa_ctl %p, index %x, nport_handle: 0x%x\n", + fcport->d_id.b24, sa_ctl, sa_ctl->index, nport_handle); + /* + * if this is a sadb cleanup delete, mark it so the isr can + * take the correct action + */ + if (sa_ctl->flags & EDIF_SA_CTL_FLG_CLEANUP_DEL) { + /* mark this srb as a cleanup delete */ + sp->flags |= SRB_EDIF_CLEANUP_DELETE; + ql_dbg(ql_dbg_edif, vha, 0x70e6, + "%s: sp 0x%p flagged as cleanup delete\n", __func__, sp); + } + + sp->type = SRB_SA_REPLACE; + sp->name = "SA_REPLACE"; + sp->fcport = fcport; + sp->free = qla2x00_rel_sp; + sp->done = qla_noop_sp_done; + + rval = qla2x00_start_sp(sp); + + if (rval != QLA_SUCCESS) + rval = QLA_FUNCTION_FAILED; + + return rval; +} + +void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb) +{ + int itr = 0; + struct scsi_qla_host *vha = sp->vha; + struct qla_sa_update_frame *sa_frame = + &sp->u.iocb_cmd.u.sa_update.sa_frame; + u8 flags = 0; + + switch (sa_frame->flags & (SAU_FLG_INV | SAU_FLG_TX)) { + case 0: + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: EDIF SA UPDATE RX IOCB vha: 0x%p index: %d\n", + __func__, vha, sa_frame->fast_sa_index); + break; + case 1: + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: EDIF SA DELETE RX IOCB vha: 0x%p index: %d\n", + __func__, vha, sa_frame->fast_sa_index); + flags |= SA_FLAG_INVALIDATE; + break; + case 2: + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: EDIF SA UPDATE TX IOCB vha: 0x%p index: %d\n", + __func__, vha, sa_frame->fast_sa_index); + flags |= SA_FLAG_TX; + break; + case 3: + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s: EDIF SA DELETE TX IOCB vha: 0x%p index: %d\n", + __func__, vha, sa_frame->fast_sa_index); + flags |= SA_FLAG_TX | SA_FLAG_INVALIDATE; + break; + } + + sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE; + sa_update_iocb->entry_count = 1; + sa_update_iocb->sys_define = 0; + sa_update_iocb->entry_status = 0; + sa_update_iocb->handle = sp->handle; + sa_update_iocb->u.nport_handle = cpu_to_le16(sp->fcport->loop_id); + sa_update_iocb->vp_index = sp->fcport->vha->vp_idx; + sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; + sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area; + sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain; + + sa_update_iocb->flags = flags; + sa_update_iocb->salt = cpu_to_le32(sa_frame->salt); + sa_update_iocb->spi = cpu_to_le32(sa_frame->spi); + sa_update_iocb->sa_index = cpu_to_le16(sa_frame->fast_sa_index); + + sa_update_iocb->sa_control |= SA_CNTL_ENC_FCSP; + if (sp->fcport->edif.aes_gmac) + sa_update_iocb->sa_control |= SA_CNTL_AES_GMAC; + + if (sa_frame->flags & SAU_FLG_KEY256) { + sa_update_iocb->sa_control |= SA_CNTL_KEY256; + for (itr = 0; itr < 32; itr++) + sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr]; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x921f, "%s 256 sa key=%32phN\n", + __func__, sa_update_iocb->sa_key); + } else { + sa_update_iocb->sa_control |= SA_CNTL_KEY128; + for (itr = 0; itr < 16; itr++) + sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr]; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x921f, "%s 128 sa key=%16phN\n", + __func__, sa_update_iocb->sa_key); + } + + ql_dbg(ql_dbg_edif, vha, 0x921d, + "%s SAU Port ID = %02x%02x%02x, flags=%xh, index=%u, ctl=%xh, SPI 0x%x flags 0x%x hdl=%x gmac %d\n", + __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1], + sa_update_iocb->port_id[0], sa_update_iocb->flags, sa_update_iocb->sa_index, + sa_update_iocb->sa_control, sa_update_iocb->spi, sa_frame->flags, sp->handle, + sp->fcport->edif.aes_gmac); + + if (sa_frame->flags & SAU_FLG_TX) + sp->fcport->edif.tx_sa_pending = 1; + else + sp->fcport->edif.rx_sa_pending = 1; + + sp->fcport->vha->qla_stats.control_requests++; +} + +void +qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb) +{ + struct scsi_qla_host *vha = sp->vha; + struct srb_iocb *srb_iocb = &sp->u.iocb_cmd; + struct edif_sa_ctl *sa_ctl = srb_iocb->u.sa_update.sa_ctl; + uint16_t nport_handle = sp->fcport->loop_id; + + sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE; + sa_update_iocb->entry_count = 1; + sa_update_iocb->sys_define = 0; + sa_update_iocb->entry_status = 0; + sa_update_iocb->handle = sp->handle; + + sa_update_iocb->u.nport_handle = cpu_to_le16(nport_handle); + + sa_update_iocb->vp_index = sp->fcport->vha->vp_idx; + sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; + sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area; + sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain; + + /* Invalidate the index. salt, spi, control & key are ignore */ + sa_update_iocb->flags = SA_FLAG_INVALIDATE; + sa_update_iocb->salt = 0; + sa_update_iocb->spi = 0; + sa_update_iocb->sa_index = cpu_to_le16(sa_ctl->index); + sa_update_iocb->sa_control = 0; + + ql_dbg(ql_dbg_edif, vha, 0x921d, + "%s SAU DELETE RX Port ID = %02x:%02x:%02x, lid %d flags=%xh, index=%u, hdl=%x\n", + __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1], + sa_update_iocb->port_id[0], nport_handle, sa_update_iocb->flags, + sa_update_iocb->sa_index, sp->handle); + + sp->fcport->vha->qla_stats.control_requests++; +} + void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) { struct purex_entry_24xx *p = *pkt; @@ -968,6 +1898,544 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) purex->pur_info.pur_did.b24, p->rx_xchg_addr); } +static uint16_t qla_edif_get_sa_index_from_freepool(fc_port_t *fcport, int dir) +{ + struct scsi_qla_host *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + void *sa_id_map; + unsigned long flags = 0; + u16 sa_index; + + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063, + "%s: entry\n", __func__); + + if (dir) + sa_id_map = ha->edif_tx_sa_id_map; + else + sa_id_map = ha->edif_rx_sa_id_map; + + spin_lock_irqsave(&ha->sadb_fp_lock, flags); + sa_index = find_first_zero_bit(sa_id_map, EDIF_NUM_SA_INDEX); + if (sa_index >= EDIF_NUM_SA_INDEX) { + spin_unlock_irqrestore(&ha->sadb_fp_lock, flags); + return INVALID_EDIF_SA_INDEX; + } + set_bit(sa_index, sa_id_map); + spin_unlock_irqrestore(&ha->sadb_fp_lock, flags); + + if (dir) + sa_index += EDIF_TX_SA_INDEX_BASE; + + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: index retrieved from free pool %d\n", __func__, sa_index); + + return sa_index; +} + +/* find an sadb entry for an nport_handle */ +static struct edif_sa_index_entry * +qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle, + struct list_head *sa_list) +{ + struct edif_sa_index_entry *entry; + struct edif_sa_index_entry *tentry; + struct list_head *indx_list = sa_list; + + list_for_each_entry_safe(entry, tentry, indx_list, next) { + if (entry->handle == nport_handle) + return entry; + } + return NULL; +} + +/* remove an sa_index from the nport_handle and return it to the free pool */ +static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle, + uint16_t sa_index) +{ + struct edif_sa_index_entry *entry; + struct list_head *sa_list; + int dir = (sa_index < EDIF_TX_SA_INDEX_BASE) ? 0 : 1; + int slot = 0; + int free_slot_count = 0; + scsi_qla_host_t *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + unsigned long flags = 0; + + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: entry\n", __func__); + + if (dir) + sa_list = &ha->sadb_tx_index_list; + else + sa_list = &ha->sadb_rx_index_list; + + entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list); + if (!entry) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: no entry found for nport_handle 0x%x\n", + __func__, nport_handle); + return -1; + } + + spin_lock_irqsave(&ha->sadb_lock, flags); + /* + * each tx/rx direction has up to 2 sa indexes/slots. 1 slot for in flight traffic + * the other is use at re-key time. + */ + for (slot = 0; slot < 2; slot++) { + if (entry->sa_pair[slot].sa_index == sa_index) { + entry->sa_pair[slot].sa_index = INVALID_EDIF_SA_INDEX; + entry->sa_pair[slot].spi = 0; + free_slot_count++; + qla_edif_add_sa_index_to_freepool(fcport, dir, sa_index); + } else if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) { + free_slot_count++; + } + } + + if (free_slot_count == 2) { + list_del(&entry->next); + kfree(entry); + } + spin_unlock_irqrestore(&ha->sadb_lock, flags); + + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sa_index %d removed, free_slot_count: %d\n", + __func__, sa_index, free_slot_count); + + return 0; +} + +void +qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req, + struct sa_update_28xx *pkt) +{ + const char *func = "SA_UPDATE_RESPONSE_IOCB"; + srb_t *sp; + struct edif_sa_ctl *sa_ctl; + int old_sa_deleted = 1; + uint16_t nport_handle; + struct scsi_qla_host *vha; + + sp = qla2x00_get_sp_from_handle(v, func, req, pkt); + + if (!sp) { + ql_dbg(ql_dbg_edif, v, 0x3063, + "%s: no sp found for pkt\n", __func__); + return; + } + /* use sp->vha due to npiv */ + vha = sp->vha; + + switch (pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) { + case 0: + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: EDIF SA UPDATE RX IOCB vha: 0x%p index: %d\n", + __func__, vha, pkt->sa_index); + break; + case 1: + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: EDIF SA DELETE RX IOCB vha: 0x%p index: %d\n", + __func__, vha, pkt->sa_index); + break; + case 2: + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: EDIF SA UPDATE TX IOCB vha: 0x%p index: %d\n", + __func__, vha, pkt->sa_index); + break; + case 3: + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: EDIF SA DELETE TX IOCB vha: 0x%p index: %d\n", + __func__, vha, pkt->sa_index); + break; + } + + /* + * dig the nport handle out of the iocb, fcport->loop_id can not be trusted + * to be correct during cleanup sa_update iocbs. + */ + nport_handle = sp->fcport->loop_id; + + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: %8phN comp status=%x old_sa_info=%x new_sa_info=%x lid %d, index=0x%x pkt_flags %xh hdl=%x\n", + __func__, sp->fcport->port_name, pkt->u.comp_sts, pkt->old_sa_info, pkt->new_sa_info, + nport_handle, pkt->sa_index, pkt->flags, sp->handle); + + /* if rx delete, remove the timer */ + if ((pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) == SA_FLAG_INVALIDATE) { + struct edif_list_entry *edif_entry; + + sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + + edif_entry = qla_edif_list_find_sa_index(sp->fcport, nport_handle); + if (edif_entry) { + ql_dbg(ql_dbg_edif, vha, 0x5033, + "%s: removing edif_entry %p, new sa_index: 0x%x\n", + __func__, edif_entry, pkt->sa_index); + qla_edif_list_delete_sa_index(sp->fcport, edif_entry); + del_timer(&edif_entry->timer); + + ql_dbg(ql_dbg_edif, vha, 0x5033, + "%s: releasing edif_entry %p, new sa_index: 0x%x\n", + __func__, edif_entry, pkt->sa_index); + + kfree(edif_entry); + } + } + + /* + * if this is a delete for either tx or rx, make sure it succeeded. + * The new_sa_info field should be 0xffff on success + */ + if (pkt->flags & SA_FLAG_INVALIDATE) + old_sa_deleted = (le16_to_cpu(pkt->new_sa_info) == 0xffff) ? 1 : 0; + + /* Process update and delete the same way */ + + /* If this is an sadb cleanup delete, bypass sending events to IPSEC */ + if (sp->flags & SRB_EDIF_CLEANUP_DELETE) { + sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: nph 0x%x, sa_index %d removed from fw\n", + __func__, sp->fcport->loop_id, pkt->sa_index); + + } else if ((pkt->entry_status == 0) && (pkt->u.comp_sts == 0) && + old_sa_deleted) { + /* + * Note: Wa are only keeping track of latest SA, + * so we know when we can start enableing encryption per I/O. + * If all SA's get deleted, let FW reject the IOCB. + + * TODO: edif: don't set enabled here I think + * TODO: edif: prli complete is where it should be set + */ + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063, + "SA(%x)updated for s_id %02x%02x%02x\n", + pkt->new_sa_info, + pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]); + sp->fcport->edif.enable = 1; + if (pkt->flags & SA_FLAG_TX) { + sp->fcport->edif.tx_sa_set = 1; + sp->fcport->edif.tx_sa_pending = 0; + } else { + sp->fcport->edif.rx_sa_set = 1; + sp->fcport->edif.rx_sa_pending = 0; + } + } else { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: %8phN SA update FAILED: sa_index: %d, new_sa_info %d, %02x%02x%02x\n", + __func__, sp->fcport->port_name, pkt->sa_index, pkt->new_sa_info, + pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]); + } + + /* for delete, release sa_ctl, sa_index */ + if (pkt->flags & SA_FLAG_INVALIDATE) { + /* release the sa_ctl */ + sa_ctl = qla_edif_find_sa_ctl_by_index(sp->fcport, + le16_to_cpu(pkt->sa_index), (pkt->flags & SA_FLAG_TX)); + if (sa_ctl && + qla_edif_find_sa_ctl_by_index(sp->fcport, sa_ctl->index, + (pkt->flags & SA_FLAG_TX)) != NULL) { + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063, + "%s: freeing sa_ctl for index %d\n", + __func__, sa_ctl->index); + qla_edif_free_sa_ctl(sp->fcport, sa_ctl, sa_ctl->index); + } else { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sa_ctl NOT freed, sa_ctl: %p\n", + __func__, sa_ctl); + } + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_index %d, nph: 0x%x\n", + __func__, le16_to_cpu(pkt->sa_index), nport_handle); + qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle, + le16_to_cpu(pkt->sa_index)); + /* + * check for a failed sa_update and remove + * the sadb entry. + */ + } else if (pkt->u.comp_sts) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: freeing sa_index %d, nph: 0x%x\n", + __func__, pkt->sa_index, nport_handle); + qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle, + le16_to_cpu(pkt->sa_index)); + } + + sp->done(sp, 0); +} + +/****************** + * SADB functions * + ******************/ + +/* allocate/retrieve an sa_index for a given spi */ +static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport, + struct qla_sa_update_frame *sa_frame) +{ + struct edif_sa_index_entry *entry; + struct list_head *sa_list; + uint16_t sa_index; + int dir = sa_frame->flags & SAU_FLG_TX; + int slot = 0; + int free_slot = -1; + scsi_qla_host_t *vha = fcport->vha; + struct qla_hw_data *ha = vha->hw; + unsigned long flags = 0; + uint16_t nport_handle = fcport->loop_id; + + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: entry fc_port: %p, nport_handle: 0x%x\n", + __func__, fcport, nport_handle); + + if (dir) + sa_list = &ha->sadb_tx_index_list; + else + sa_list = &ha->sadb_rx_index_list; + + entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list); + if (!entry) { + if ((sa_frame->flags & (SAU_FLG_TX | SAU_FLG_INV)) == SAU_FLG_INV) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: rx delete request with no entry\n", __func__); + return RX_DELETE_NO_EDIF_SA_INDEX; + } + + /* if there is no entry for this nport, add one */ + entry = kzalloc((sizeof(struct edif_sa_index_entry)), GFP_ATOMIC); + if (!entry) + return INVALID_EDIF_SA_INDEX; + + sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir); + if (sa_index == INVALID_EDIF_SA_INDEX) { + kfree(entry); + return INVALID_EDIF_SA_INDEX; + } + + INIT_LIST_HEAD(&entry->next); + entry->handle = nport_handle; + entry->fcport = fcport; + entry->sa_pair[0].spi = sa_frame->spi; + entry->sa_pair[0].sa_index = sa_index; + entry->sa_pair[1].spi = 0; + entry->sa_pair[1].sa_index = INVALID_EDIF_SA_INDEX; + spin_lock_irqsave(&ha->sadb_lock, flags); + list_add_tail(&entry->next, sa_list); + spin_unlock_irqrestore(&ha->sadb_lock, flags); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: Created new sadb entry for nport_handle 0x%x, spi 0x%x, returning sa_index %d\n", + __func__, nport_handle, sa_frame->spi, sa_index); + + return sa_index; + } + + spin_lock_irqsave(&ha->sadb_lock, flags); + + /* see if we already have an entry for this spi */ + for (slot = 0; slot < 2; slot++) { + if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) { + free_slot = slot; + } else { + if (entry->sa_pair[slot].spi == sa_frame->spi) { + spin_unlock_irqrestore(&ha->sadb_lock, flags); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: sadb slot %d entry for lid 0x%x, spi 0x%x found, sa_index %d\n", + __func__, slot, entry->handle, sa_frame->spi, + entry->sa_pair[slot].sa_index); + return entry->sa_pair[slot].sa_index; + } + } + } + spin_unlock_irqrestore(&ha->sadb_lock, flags); + + /* both slots are used */ + if (free_slot == -1) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: WARNING: No free slots in sadb for nport_handle 0x%x, spi: 0x%x\n", + __func__, entry->handle, sa_frame->spi); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: Slot 0 spi: 0x%x sa_index: %d, Slot 1 spi: 0x%x sa_index: %d\n", + __func__, entry->sa_pair[0].spi, entry->sa_pair[0].sa_index, + entry->sa_pair[1].spi, entry->sa_pair[1].sa_index); + + return INVALID_EDIF_SA_INDEX; + } + + /* there is at least one free slot, use it */ + sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir); + if (sa_index == INVALID_EDIF_SA_INDEX) { + ql_dbg(ql_dbg_edif, fcport->vha, 0x3063, + "%s: empty freepool!!\n", __func__); + return INVALID_EDIF_SA_INDEX; + } + + spin_lock_irqsave(&ha->sadb_lock, flags); + entry->sa_pair[free_slot].spi = sa_frame->spi; + entry->sa_pair[free_slot].sa_index = sa_index; + spin_unlock_irqrestore(&ha->sadb_lock, flags); + ql_dbg(ql_dbg_edif, fcport->vha, 0x3063, + "%s: sadb slot %d entry for nport_handle 0x%x, spi 0x%x added, returning sa_index %d\n", + __func__, free_slot, entry->handle, sa_frame->spi, sa_index); + + return sa_index; +} + +/* release any sadb entries -- only done at teardown */ +void qla_edif_sadb_release(struct qla_hw_data *ha) +{ + struct list_head *pos; + struct list_head *tmp; + struct edif_sa_index_entry *entry; + + list_for_each_safe(pos, tmp, &ha->sadb_rx_index_list) { + entry = list_entry(pos, struct edif_sa_index_entry, next); + list_del(&entry->next); + kfree(entry); + } + + list_for_each_safe(pos, tmp, &ha->sadb_tx_index_list) { + entry = list_entry(pos, struct edif_sa_index_entry, next); + list_del(&entry->next); + kfree(entry); + } +} + +/************************** + * sadb freepool functions + **************************/ + +/* build the rx and tx sa_index free pools -- only done at fcport init */ +int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha) +{ + ha->edif_tx_sa_id_map = + kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL); + + if (!ha->edif_tx_sa_id_map) { + ql_log_pci(ql_log_fatal, ha->pdev, 0x0009, + "Unable to allocate memory for sadb tx.\n"); + return -ENOMEM; + } + + ha->edif_rx_sa_id_map = + kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL); + if (!ha->edif_rx_sa_id_map) { + kfree(ha->edif_tx_sa_id_map); + ha->edif_tx_sa_id_map = NULL; + ql_log_pci(ql_log_fatal, ha->pdev, 0x0009, + "Unable to allocate memory for sadb rx.\n"); + return -ENOMEM; + } + return 0; +} + +/* release the free pool - only done during fcport teardown */ +void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha) +{ + kfree(ha->edif_tx_sa_id_map); + ha->edif_tx_sa_id_map = NULL; + kfree(ha->edif_rx_sa_id_map); + ha->edif_rx_sa_id_map = NULL; +} + +static void __chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, + fc_port_t *fcport, uint32_t handle, uint16_t sa_index) +{ + struct edif_list_entry *edif_entry; + struct edif_sa_ctl *sa_ctl; + uint16_t delete_sa_index = INVALID_EDIF_SA_INDEX; + unsigned long flags = 0; + uint16_t nport_handle = fcport->loop_id; + uint16_t cached_nport_handle; + + spin_lock_irqsave(&fcport->edif.indx_list_lock, flags); + edif_entry = qla_edif_list_find_sa_index(fcport, nport_handle); + if (!edif_entry) { + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + return; /* no pending delete for this handle */ + } + + /* + * check for no pending delete for this index or iocb does not + * match rx sa_index + */ + if (edif_entry->delete_sa_index == INVALID_EDIF_SA_INDEX || + edif_entry->update_sa_index != sa_index) { + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + return; + } + + /* + * wait until we have seen at least EDIF_DELAY_COUNT transfers before + * queueing RX delete + */ + if (edif_entry->count++ < EDIF_RX_DELETE_FILTER_COUNT) { + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + return; + } + + ql_dbg(ql_dbg_edif, vha, 0x5033, + "%s: invalidating delete_sa_index, update_sa_index: 0x%x sa_index: 0x%x, delete_sa_index: 0x%x\n", + __func__, edif_entry->update_sa_index, sa_index, edif_entry->delete_sa_index); + + delete_sa_index = edif_entry->delete_sa_index; + edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX; + cached_nport_handle = edif_entry->handle; + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); + + /* sanity check on the nport handle */ + if (nport_handle != cached_nport_handle) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: POST SA DELETE nport_handle mismatch: lid: 0x%x, edif_entry nph: 0x%x\n", + __func__, nport_handle, cached_nport_handle); + } + + /* find the sa_ctl for the delete and schedule the delete */ + sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, delete_sa_index, 0); + if (sa_ctl) { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: POST SA DELETE sa_ctl: %p, index recvd %d\n", + __func__, sa_ctl, sa_index); + ql_dbg(ql_dbg_edif, vha, 0x3063, + "delete index %d, update index: %d, nport handle: 0x%x, handle: 0x%x\n", + delete_sa_index, + edif_entry->update_sa_index, nport_handle, handle); + + sa_ctl->flags = EDIF_SA_CTL_FLG_DEL; + set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state); + qla_post_sa_replace_work(fcport->vha, fcport, + nport_handle, sa_ctl); + } else { + ql_dbg(ql_dbg_edif, vha, 0x3063, + "%s: POST SA DELETE sa_ctl not found for delete_sa_index: %d\n", + __func__, delete_sa_index); + } +} + +void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, + srb_t *sp, struct sts_entry_24xx *sts24) +{ + fc_port_t *fcport = sp->fcport; + /* sa_index used by this iocb */ + struct scsi_cmnd *cmd = GET_CMD_SP(sp); + uint32_t handle; + + handle = (uint32_t)LSW(sts24->handle); + + /* find out if this status iosb is for a scsi read */ + if (cmd->sc_data_direction != DMA_FROM_DEVICE) + return; + + return __chk_edif_rx_sa_delete_pending(vha, fcport, handle, + le16_to_cpu(sts24->edif_sa_index)); +} + +void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport, + struct ctio7_from_24xx *pkt) +{ + __chk_edif_rx_sa_delete_pending(vha, fcport, + pkt->handle, le16_to_cpu(pkt->edif_sa_index)); +} + static void qla_parse_auth_els_ctl(struct srb *sp) { struct qla_els_pt_arg *a = &sp->u.bsg_cmd.u.els_arg; diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h index 93c423227d82..1cff02e5bd43 100644 --- a/drivers/scsi/qla2xxx/qla_edif.h +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -9,6 +9,27 @@ struct qla_scsi_host; #define EDIF_APP_ID 0x73730001 +#define EDIF_MAX_INDEX 2048 +struct edif_sa_ctl { + struct list_head next; + uint16_t del_index; + uint16_t index; + uint16_t slot; + uint16_t flags; +#define EDIF_SA_CTL_FLG_REPL BIT_0 +#define EDIF_SA_CTL_FLG_DEL BIT_1 +#define EDIF_SA_CTL_FLG_CLEANUP_DEL BIT_4 + // Invalidate Index bit and mirrors QLA_SA_UPDATE_FLAGS_DELETE + unsigned long state; +#define EDIF_SA_CTL_USED 1 /* Active Sa update */ +#define EDIF_SA_CTL_PEND 2 /* Waiting for slot */ +#define EDIF_SA_CTL_REPL 3 /* Active Replace and Delete */ +#define EDIF_SA_CTL_DEL 4 /* Delete Pending */ + struct fc_port *fcport; + struct bsg_job *bsg_job; + struct qla_sa_update_frame sa_frame; +}; + enum enode_flags_t { ENODE_ACTIVE = 0x1, }; @@ -30,6 +51,46 @@ struct edif_dbell { struct completion dbell; }; +#define SA_UPDATE_IOCB_TYPE 0x71 /* Security Association Update IOCB entry */ +struct sa_update_28xx { + uint8_t entry_type; /* Entry type. */ + uint8_t entry_count; /* Entry count. */ + uint8_t sys_define; /* System Defined. */ + uint8_t entry_status; /* Entry Status. */ + + uint32_t handle; /* IOCB System handle. */ + + union { + __le16 nport_handle; /* in: N_PORT handle. */ + __le16 comp_sts; /* out: completion status */ +#define CS_PORT_EDIF_SUPP_NOT_RDY 0x64 +#define CS_PORT_EDIF_INV_REQ 0x66 + } u; + uint8_t vp_index; + uint8_t reserved_1; + uint8_t port_id[3]; + uint8_t flags; +#define SA_FLAG_INVALIDATE BIT_0 +#define SA_FLAG_TX BIT_1 // 1=tx, 0=rx + + uint8_t sa_key[32]; /* 256 bit key */ + __le32 salt; + __le32 spi; + uint8_t sa_control; +#define SA_CNTL_ENC_FCSP (1 << 3) +#define SA_CNTL_ENC_OPD (2 << 3) +#define SA_CNTL_ENC_MSK (3 << 3) // mask bits 4,3 +#define SA_CNTL_AES_GMAC (1 << 2) +#define SA_CNTL_KEY256 (2 << 0) +#define SA_CNTL_KEY128 0 + + uint8_t reserved_2; + __le16 sa_index; // reserve: bit 11-15 + __le16 old_sa_info; + __le16 new_sa_info; +}; + +#define NUM_ENTRIES 256 #define MAX_PAYLOAD 1024 #define PUR_GET 1 diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 49df418030e4..c067cd202dc4 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -611,6 +611,7 @@ struct sts_entry_24xx { union { __le16 reserved_1; __le16 nvme_rsp_pyld_len; + __le16 edif_sa_index; /* edif sa_index used for initiator read data */ }; __le16 state_flags; /* State flags. */ diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index d19f5ec24d8c..e7c5143c66ef 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -130,6 +130,13 @@ void qla24xx_free_purex_item(struct purex_item *item); extern bool qla24xx_risc_firmware_invalid(uint32_t *); void qla_init_iocb_limit(scsi_qla_host_t *); +void qla_edif_sadb_release(struct qla_hw_data *ha); +int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha); +void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha); +void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, + srb_t *sp, struct sts_entry_24xx *sts24); +void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport, + struct ctio7_from_24xx *ctio); int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob); const char *sc_to_str(uint16_t cmd); @@ -238,6 +245,8 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, struct purex_item *pkt); void qla_pci_set_eeh_busy(struct scsi_qla_host *); void qla_schedule_eeh_work(struct scsi_qla_host *); +struct edif_sa_ctl *qla_edif_find_sa_ctl_by_index(fc_port_t *fcport, + int index, int dir); /* * Global Functions in qla_mid.c source file. @@ -313,6 +322,8 @@ extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, struct dsd64 *, uint16_t, struct qla_tgt_cmd *); extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); +extern int qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, + struct qla_work_evt *e); /* * Global Function Prototypes in qla_mbx.c source file. @@ -885,6 +896,9 @@ extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, uint32_t); extern int qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *); +extern int qla24xx_sadb_update(struct bsg_job *bsg_job); +extern int qla_post_sa_replace_work(struct scsi_qla_host *vha, + fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl); /* 83xx related functions */ void qla83xx_fw_dump(scsi_qla_host_t *vha); @@ -957,12 +971,19 @@ extern void qla_nvme_abort_process_comp_status /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); + +/* qla_edif.c */ fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id); void qla_edb_stop(scsi_qla_host_t *vha); int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job); void qla_enode_init(scsi_qla_host_t *vha); void qla_enode_stop(scsi_qla_host_t *vha); +void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport); +void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); +void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp); +void qla28xx_sa_update_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, + struct sa_update_28xx *pkt); void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea); #define QLA2XX_HW_ERROR BIT_0 diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f8f471157109..663182f16471 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5071,6 +5071,16 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) INIT_LIST_HEAD(&fcport->sess_cmd_list); spin_lock_init(&fcport->sess_cmd_lock); + spin_lock_init(&fcport->edif.sa_list_lock); + INIT_LIST_HEAD(&fcport->edif.tx_sa_list); + INIT_LIST_HEAD(&fcport->edif.rx_sa_list); + + if (vha->e_dbell.db_flags == EDB_ACTIVE) + fcport->edif.app_started = 1; + + spin_lock_init(&fcport->edif.indx_list_lock); + INIT_LIST_HEAD(&fcport->edif.edif_indx_list); + return fcport; } diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 77bacf2c2340..fd22bedc8a00 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -3839,6 +3839,12 @@ qla2x00_start_sp(srb_t *sp) case SRB_PRLO_CMD: qla24xx_prlo_iocb(sp, pkt); break; + case SRB_SA_UPDATE: + qla24xx_sa_update_iocb(sp, pkt); + break; + case SRB_SA_REPLACE: + qla24xx_sa_replace_iocb(sp, pkt); + break; default: break; } diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index a64b990fd947..657fe0d9ee21 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3191,6 +3191,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) sp->qpair->cmd_completion_cnt++; /* Fast path completion. */ + qla_chk_edif_rx_sa_delete_pending(vha, sp, sts24); + if (comp_status == CS_COMPLETE && scsi_status == 0) { qla2x00_process_completed_request(vha, req, handle); @@ -3585,6 +3587,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) } break; + case SA_UPDATE_IOCB_TYPE: case ABTS_RESP_24XX: case CTIO_TYPE7: case CTIO_CRC2: @@ -3883,6 +3886,11 @@ process_err: purex_entry->els_frame_payload[3]); } break; + case SA_UPDATE_IOCB_TYPE: + qla28xx_sa_update_iocb_entry(vha, rsp->req, + (struct sa_update_28xx *)pkt); + break; + default: /* Type Not Supported. */ ql_dbg(ql_dbg_async, vha, 0x5042, diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b7e1d7437d81..0ae4d0fd622f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2835,6 +2835,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(&ha->tgt.sess_lock); spin_lock_init(&ha->tgt.atio_lock); + spin_lock_init(&ha->sadb_lock); + INIT_LIST_HEAD(&ha->sadb_tx_index_list); + INIT_LIST_HEAD(&ha->sadb_rx_index_list); + + spin_lock_init(&ha->sadb_fp_lock); + + if (qla_edif_sadb_build_free_pool(ha)) { + kfree(ha); + goto disable_device; + } + atomic_set(&ha->nvme_active_aen_cnt, 0); /* Clear our data area */ @@ -3868,6 +3879,9 @@ qla2x00_free_device(scsi_qla_host_t *vha) qla82xx_md_free(vha); + qla_edif_sadb_release_free_pool(ha); + qla_edif_sadb_release(ha); + qla2x00_free_queues(ha); } @@ -5375,6 +5389,9 @@ qla2x00_do_work(struct scsi_qla_host *vha) qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI, e->u.fcport.fcport, false); break; + case QLA_EVT_SA_REPLACE: + qla24xx_issue_sa_replace_iocb(vha, e); + break; } if (rc == EAGAIN) { diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 01620f3eab39..8a319b78cdf6 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -446,7 +446,7 @@ struct ctio7_from_24xx { uint8_t vp_index; uint8_t reserved1[5]; __le32 exchange_address; - __le16 reserved2; + __le16 edif_sa_index; __le16 flags; __le32 residual; __le16 ox_id; -- cgit v1.2.3-70-g09d2 From 8a4bb2c1dd623b5a71609de5b04ef3b5086b0a3e Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:01 -0700 Subject: scsi: qla2xxx: edif: Add authentication pass + fail bsgs Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. On completion of the authentication process, the authentication application will notify driver on whether it is successful or not. In case of success, application will use the QL_VND_SC_AUTH_OK BSG call to tell driver to proceed to the PRLI phase. In case of failure, application will use the QL_VND_SC_AUTH_FAIL bsg call to tell driver to tear down the connection and retry. In the case where an existing session is active, the re-key process can fail. The session tear down ensures data is not further compromised. Link: https://lore.kernel.org/r/20210624052606.21613-7-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_edif.c | 213 ++++++++++++++++++++++++++++++++++++++-- drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_init.c | 3 +- 3 files changed, 209 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 15f9e10ac257..8f486bd1201f 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -656,6 +656,204 @@ qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job) return rval; } +static int +qla_edif_app_chk_sa_update(scsi_qla_host_t *vha, fc_port_t *fcport, + struct app_plogi_reply *appplogireply) +{ + int ret = 0; + + if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n", + __func__, fcport->port_name, fcport->edif.tx_sa_set, + fcport->edif.rx_sa_set); + appplogireply->prli_status = 0; + ret = 1; + } else { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC Both SA(s) updated.\n", __func__, + fcport->port_name); + fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0; + fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0; + appplogireply->prli_status = 1; + } + return ret; +} + +/** + * qla_edif_app_authok - authentication by app succeeded. Driver can proceed + * with prli + * @vha: host adapter pointer + * @bsg_job: user request + */ +static int +qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + struct auth_complete_cmd appplogiok; + struct app_plogi_reply appplogireply = {0}; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + fc_port_t *fcport = NULL; + port_id_t portid = {0}; + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &appplogiok, + sizeof(struct auth_complete_cmd)); + + switch (appplogiok.type) { + case PL_TYPE_WWPN: + fcport = qla2x00_find_fcport_by_wwpn(vha, + appplogiok.u.wwpn, 0); + if (!fcport) + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s wwpn lookup failed: %8phC\n", + __func__, appplogiok.u.wwpn); + break; + case PL_TYPE_DID: + fcport = qla2x00_find_fcport_by_pid(vha, &appplogiok.u.d_id); + if (!fcport) + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s d_id lookup failed: %x\n", __func__, + portid.b24); + break; + default: + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s undefined type: %x\n", __func__, + appplogiok.type); + break; + } + + if (!fcport) { + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + goto errstate_exit; + } + + /* + * if port is online then this is a REKEY operation + * Only do sa update checking + */ + if (atomic_read(&fcport->state) == FCS_ONLINE) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s Skipping PRLI complete based on rekey\n", __func__); + appplogireply.prli_status = 1; + SET_DID_STATUS(bsg_reply->result, DID_OK); + qla_edif_app_chk_sa_update(vha, fcport, &appplogireply); + goto errstate_exit; + } + + /* make sure in AUTH_PENDING or else reject */ + if (fcport->disc_state != DSC_LOGIN_AUTH_PEND) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC is not in auth pending state (%x)\n", + __func__, fcport->port_name, fcport->disc_state); + SET_DID_STATUS(bsg_reply->result, DID_OK); + appplogireply.prli_status = 0; + goto errstate_exit; + } + + SET_DID_STATUS(bsg_reply->result, DID_OK); + appplogireply.prli_status = 1; + if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n", + __func__, fcport->port_name, fcport->edif.tx_sa_set, + fcport->edif.rx_sa_set); + SET_DID_STATUS(bsg_reply->result, DID_OK); + appplogireply.prli_status = 0; + goto errstate_exit; + + } else { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC Both SA(s) updated.\n", __func__, + fcport->port_name); + fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0; + fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0; + } + + if (qla_ini_mode_enabled(vha)) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s AUTH complete - RESUME with prli for wwpn %8phC\n", + __func__, fcport->port_name); + qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 1); + qla24xx_post_prli_work(vha, fcport); + } + +errstate_exit: + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, &appplogireply, + sizeof(struct app_plogi_reply)); + + return rval; +} + +/** + * qla_edif_app_authfail - authentication by app has failed. Driver is given + * notice to tear down current session. + * @vha: host adapter pointer + * @bsg_job: user request + */ +static int +qla_edif_app_authfail(scsi_qla_host_t *vha, struct bsg_job *bsg_job) +{ + int32_t rval = 0; + struct auth_complete_cmd appplogifail; + struct fc_bsg_reply *bsg_reply = bsg_job->reply; + fc_port_t *fcport = NULL; + port_id_t portid = {0}; + + ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app auth fail\n", __func__); + + sg_copy_to_buffer(bsg_job->request_payload.sg_list, + bsg_job->request_payload.sg_cnt, &appplogifail, + sizeof(struct auth_complete_cmd)); + + /* + * TODO: edif: app has failed this plogi. Inform driver to + * take any action (if any). + */ + switch (appplogifail.type) { + case PL_TYPE_WWPN: + fcport = qla2x00_find_fcport_by_wwpn(vha, + appplogifail.u.wwpn, 0); + SET_DID_STATUS(bsg_reply->result, DID_OK); + break; + case PL_TYPE_DID: + fcport = qla2x00_find_fcport_by_pid(vha, &appplogifail.u.d_id); + if (!fcport) + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s d_id lookup failed: %x\n", __func__, + portid.b24); + SET_DID_STATUS(bsg_reply->result, DID_OK); + break; + default: + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s undefined type: %x\n", __func__, + appplogifail.type); + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + rval = -1; + break; + } + + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s fcport is 0x%p\n", __func__, fcport); + + if (fcport) { + /* set/reset edif values and flags */ + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s reset the auth process - %8phC, loopid=%x portid=%06x.\n", + __func__, fcport->port_name, fcport->loop_id, fcport->d_id.b24); + + if (qla_ini_mode_enabled(fcport->vha)) { + fcport->send_els_logo = 1; + qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); + } + } + + return rval; +} + /** * qla_edif_app_getfcinfo - app would like to read session info (wwpn, nportid, * [initiator|target] mode. It can specific session with specific nport id or @@ -697,8 +895,7 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) tdid = app_req.remote_pid; ql_dbg(ql_dbg_edif, vha, 0x2058, - "APP request entry - portid=%06x.\n", - tdid.b24); + "APP request entry - portid=%06x.\n", tdid.b24); /* Ran out of space */ if (pcnt > app_req.num_ports) @@ -719,10 +916,8 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) app_reply->ports[pcnt].remote_pid = fcport->d_id; ql_dbg(ql_dbg_edif, vha, 0x2058, - "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%02x%02x%02x.\n", - fcport->node_name, fcport->port_name, pcnt, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa); + "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%06x\n", + fcport->node_name, fcport->port_name, pcnt, fcport->d_id.b24); switch (fcport->edif.auth_state) { case VND_CMD_AUTH_STATE_ELS_RCVD: @@ -888,6 +1083,12 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) case QL_VND_SC_APP_STOP: rval = qla_edif_app_stop(vha, bsg_job); break; + case QL_VND_SC_AUTH_OK: + rval = qla_edif_app_authok(vha, bsg_job); + break; + case QL_VND_SC_AUTH_FAIL: + rval = qla_edif_app_authfail(vha, bsg_job); + break; case QL_VND_SC_GET_FCINFO: rval = qla_edif_app_getfcinfo(vha, bsg_job); break; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e7c5143c66ef..d9d554101788 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -12,6 +12,7 @@ * Global Function Prototypes in qla_init.c source file. */ extern int qla2x00_initialize_adapter(scsi_qla_host_t *); +extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport); extern int qla2100_pci_config(struct scsi_qla_host *); extern int qla2300_pci_config(struct scsi_qla_host *); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 663182f16471..71f6c76be401 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -34,7 +34,6 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); static int qla84xx_init_chip(scsi_qla_host_t *); static int qla25xx_init_queues(struct qla_hw_data *); -static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *); static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea); static void qla24xx_handle_prli_done_event(struct scsi_qla_host *, @@ -1191,7 +1190,7 @@ done: sp->free(sp); } -static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) +int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) { struct qla_work_evt *e; -- cgit v1.2.3-70-g09d2 From 9efea843a906c6674ac6728f3f5db2cbfa3e1830 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:02 -0700 Subject: scsi: qla2xxx: edif: Add detection of secure device Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. There is no FC switch scan service that can indicate whether a device is secure or non-secure. In order to detect whether the remote port supports encrypted operation, driver must first do a PLOGI with the remote device. On completion of the PLOGI, driver will query firmware to see if the device supports secure login. To do that, driver + firmware must advertise the security bit via PLOGI's service parameter. The remote device shall respond using the same service parameter whether it supports it or not. Link: https://lore.kernel.org/r/20210624052606.21613-8-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 5 +- drivers/scsi/qla2xxx/qla_edif.c | 31 +++++++++ drivers/scsi/qla2xxx/qla_fw.h | 8 ++- drivers/scsi/qla2xxx/qla_gbl.h | 3 + drivers/scsi/qla2xxx/qla_gs.c | 4 ++ drivers/scsi/qla2xxx/qla_init.c | 141 ++++++++++++++++++++++++++++++++------ drivers/scsi/qla2xxx/qla_iocb.c | 17 ++++- drivers/scsi/qla2xxx/qla_isr.c | 4 ++ drivers/scsi/qla2xxx/qla_mbx.c | 6 ++ drivers/scsi/qla2xxx/qla_mid.c | 7 +- drivers/scsi/qla2xxx/qla_os.c | 19 +++++ drivers/scsi/qla2xxx/qla_target.c | 61 ++++++++++++++++- drivers/scsi/qla2xxx/qla_target.h | 1 + 13 files changed, 279 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3e4c4cfbf7d4..af0e8be0eb9b 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -492,6 +492,7 @@ struct srb_iocb { #define SRB_LOGIN_SKIP_PRLI BIT_2 #define SRB_LOGIN_NVME_PRLI BIT_3 #define SRB_LOGIN_PRLI_ONLY BIT_4 +#define SRB_LOGIN_FCSP BIT_5 uint16_t data[2]; u32 iop[2]; } logio; @@ -2343,6 +2344,7 @@ struct imm_ntfy_from_isp { __le16 nport_handle; uint16_t reserved_2; __le16 flags; +#define NOTIFY24XX_FLAGS_FCSP BIT_5 #define NOTIFY24XX_FLAGS_GLOBAL_TPRLO BIT_1 #define NOTIFY24XX_FLAGS_PUREX_IOCB BIT_0 __le16 srr_rx_id; @@ -2682,7 +2684,8 @@ static const char * const port_dstate_str[] = { "UPD_FCPORT", "LOGIN_COMPLETE", "ADISC", - "DELETE_PEND" + "DELETE_PEND", + "LOGIN_AUTH_PEND", }; /* diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 8f486bd1201f..51f96f5882af 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2366,6 +2366,26 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req, sp->done(sp, 0); } +/********************************************** + * edif update/delete sa_index list functions * + **********************************************/ + +/* clear the edif_indx_list for this port */ +void qla_edif_list_del(fc_port_t *fcport) +{ + struct edif_list_entry *indx_lst; + struct edif_list_entry *tindx_lst; + struct list_head *indx_list = &fcport->edif.edif_indx_list; + unsigned long flags = 0; + + spin_lock_irqsave(&fcport->edif.indx_list_lock, flags); + list_for_each_entry_safe(indx_lst, tindx_lst, indx_list, next) { + list_del(&indx_lst->next); + kfree(indx_lst); + } + spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags); +} + /****************** * SADB functions * ******************/ @@ -2791,3 +2811,14 @@ done_free_sp: done: return rval; } + +void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess) +{ + if (sess->edif.app_sess_online && vha->e_dbell.db_flags & EDB_ACTIVE) { + ql_dbg(ql_dbg_disc, vha, 0xf09c, + "%s: sess %8phN send port_offline event\n", + __func__, sess->port_name); + sess->edif.app_sess_online = 0; + qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24); + } +} diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index c067cd202dc4..4934b08a8990 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -82,10 +82,11 @@ struct port_database_24xx { uint8_t port_name[WWN_SIZE]; uint8_t node_name[WWN_SIZE]; - uint8_t reserved_3[4]; + uint8_t reserved_3[2]; + uint16_t nvme_first_burst_size; uint16_t prli_nvme_svc_param_word_0; /* Bits 15-0 of word 0 */ uint16_t prli_nvme_svc_param_word_3; /* Bits 15-0 of word 3 */ - uint16_t nvme_first_burst_size; + uint8_t secure_login; uint8_t reserved_4[14]; }; @@ -897,6 +898,7 @@ struct logio_entry_24xx { #define LCF_FCP2_OVERRIDE BIT_9 /* Set/Reset word 3 of PRLI. */ #define LCF_CLASS_2 BIT_8 /* Enable class 2 during PLOGI. */ #define LCF_FREE_NPORT BIT_7 /* Release NPORT handle after LOGO. */ +#define LCF_COMMON_FEAT BIT_7 /* PLOGI - Set Common Features Field */ #define LCF_EXPL_LOGO BIT_6 /* Perform an explicit LOGO. */ #define LCF_NVME_PRLI BIT_6 /* Perform NVME FC4 PRLI */ #define LCF_SKIP_PRLI BIT_5 /* Skip PRLI after PLOGI. */ @@ -921,6 +923,8 @@ struct logio_entry_24xx { uint8_t rsp_size; /* Response size in 32bit words. */ __le32 io_parameter[11]; /* General I/O parameters. */ +#define LIO_COMM_FEAT_FCSP BIT_21 +#define LIO_COMM_FEAT_CIO BIT_31 #define LSC_SCODE_NOLINK 0x01 #define LSC_SCODE_NOIOCB 0x02 #define LSC_SCODE_NOXCB 0x03 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index d9d554101788..61b0164ac283 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -131,6 +131,7 @@ void qla24xx_free_purex_item(struct purex_item *item); extern bool qla24xx_risc_firmware_invalid(uint32_t *); void qla_init_iocb_limit(scsi_qla_host_t *); +void qla_edif_list_del(fc_port_t *fcport); void qla_edif_sadb_release(struct qla_hw_data *ha); int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha); void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha); @@ -138,7 +139,9 @@ void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, srb_t *sp, struct sts_entry_24xx *sts24); void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport, struct ctio7_from_24xx *ctio); +void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport); int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob); +void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess); const char *sc_to_str(uint16_t cmd); /* diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 5b6e04a91a18..99fb330053ae 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -2826,6 +2826,10 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea) if (fcport->disc_state == DSC_DELETE_PEND) return; + /* We will figure-out what happen after AUTH completes */ + if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) + return; + if (ea->sp->gen2 != fcport->login_gen) { /* target side must have changed it. */ ql_dbg(ql_dbg_disc, vha, 0x20d3, diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 71f6c76be401..22474baf57aa 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -342,10 +342,22 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); sp->done = qla2x00_async_login_sp_done; - if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport)) + if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport)) { lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY; - else - lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; + } else { + if (vha->hw->flags.edif_enabled) { + if (fcport->edif.non_secured_login == 0) { + lio->u.logio.flags |= + (SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI); + ql_dbg(ql_dbg_disc, vha, 0x2072, + "Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n", + fcport->port_name, sp->handle, fcport->loop_id, + fcport->d_id.b24); + } + } else { + lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; + } + } if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; @@ -377,7 +389,7 @@ static void qla2x00_async_logout_sp_done(srb_t *sp, int res) { sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); sp->fcport->login_gen++; - qlt_logo_completion_handler(sp->fcport, res); + qlt_logo_completion_handler(sp->fcport, sp->u.iocb_cmd.u.logio.data[0]); sp->free(sp); } @@ -403,10 +415,10 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) sp->done = qla2x00_async_logout_sp_done; ql_dbg(ql_dbg_disc, vha, 0x2070, - "Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x %8phC.\n", + "Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x %8phC explicit %d.\n", sp->handle, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, - fcport->port_name); + fcport->port_name, fcport->explicit_logout); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) @@ -691,11 +703,11 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, fcport = ea->fcport; ql_dbg(ql_dbg_disc, vha, 0xffff, - "%s %8phC DS %d LS rc %d %d login %d|%d rscn %d|%d lid %d\n", + "%s %8phC DS %d LS rc %d %d login %d|%d rscn %d|%d lid %d edif %d\n", __func__, fcport->port_name, fcport->disc_state, fcport->fw_login_state, ea->rc, fcport->login_gen, fcport->last_login_gen, - fcport->rscn_gen, fcport->last_rscn_gen, vha->loop_id); + fcport->rscn_gen, fcport->last_rscn_gen, vha->loop_id, fcport->edif.enable); if (fcport->disc_state == DSC_DELETE_PEND) return; @@ -821,6 +833,13 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, qla2x00_post_async_adisc_work(vha, fcport, data); break; + case DSC_LS_PLOGI_COMP: + if (vha->hw->flags.edif_enabled) { + /* check to see if App support Secure */ + qla24xx_post_gpdb_work(vha, fcport, 0); + break; + } + fallthrough; case DSC_LS_PORT_UNAVAIL: default: if (fcport->loop_id == FC_NO_LOOP_ID) { @@ -1417,6 +1436,57 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); } +static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport, + struct port_database_24xx *pd) +{ + int rc = 0; + + if (pd->secure_login) { + ql_dbg(ql_dbg_disc, vha, 0x104d, + "Secure Login established on %8phC\n", + fcport->port_name); + fcport->edif.secured_login = 1; + fcport->edif.non_secured_login = 0; + fcport->flags |= FCF_FCSP_DEVICE; + } else { + ql_dbg(ql_dbg_disc, vha, 0x104d, + "non-Secure Login %8phC", + fcport->port_name); + fcport->edif.secured_login = 0; + fcport->edif.non_secured_login = 1; + } + if (vha->hw->flags.edif_enabled) { + if (fcport->flags & FCF_FCSP_DEVICE) { + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_AUTH_PEND); + /* Start edif prli timer & ring doorbell for app */ + fcport->edif.rx_sa_set = 0; + fcport->edif.tx_sa_set = 0; + fcport->edif.rx_sa_pending = 0; + fcport->edif.tx_sa_pending = 0; + + qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, + fcport->d_id.b24); + + if (vha->e_dbell.db_flags == EDB_ACTIVE) { + ql_dbg(ql_dbg_disc, vha, 0x20ef, + "%s %d %8phC EDIF: post DB_AUTH: AUTH needed\n", + __func__, __LINE__, fcport->port_name); + fcport->edif.app_started = 1; + fcport->edif.app_sess_online = 1; + } + + rc = 1; + } else { + ql_dbg(ql_dbg_disc, vha, 0x2117, + "%s %d %8phC post prli\n", + __func__, __LINE__, fcport->port_name); + qla24xx_post_prli_work(vha, fcport); + rc = 1; + } + } + return rc; +} + static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) { @@ -1459,8 +1529,11 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) case PDS_PRLI_COMPLETE: __qla24xx_parse_gpdb(vha, fcport, pd); break; - case PDS_PLOGI_PENDING: case PDS_PLOGI_COMPLETE: + if (qla_chk_secure_login(vha, fcport, pd)) + return; + fallthrough; + case PDS_PLOGI_PENDING: case PDS_PRLI_PENDING: case PDS_PRLI2_PENDING: /* Set discovery state back to GNL to Relogin attempt */ @@ -2052,26 +2125,38 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) * force a relogin attempt via implicit LOGO, PLOGI, and PRLI * requests. */ - if (NVME_TARGET(vha->hw, ea->fcport)) { - ql_dbg(ql_dbg_disc, vha, 0x2117, - "%s %d %8phC post prli\n", - __func__, __LINE__, ea->fcport->port_name); - qla24xx_post_prli_work(vha, ea->fcport); - } else { - ql_dbg(ql_dbg_disc, vha, 0x20ea, - "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n", - __func__, __LINE__, ea->fcport->port_name, - ea->fcport->loop_id, ea->fcport->d_id.b24); - + if (vha->hw->flags.edif_enabled) { set_bit(ea->fcport->loop_id, vha->hw->loop_id_map); spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset; ea->fcport->logout_on_delete = 1; ea->fcport->send_els_logo = 0; - ea->fcport->fw_login_state = DSC_LS_PRLI_COMP; + ea->fcport->fw_login_state = DSC_LS_PLOGI_COMP; spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); qla24xx_post_gpdb_work(vha, ea->fcport, 0); + } else { + if (NVME_TARGET(vha->hw, fcport)) { + ql_dbg(ql_dbg_disc, vha, 0x2117, + "%s %d %8phC post prli\n", + __func__, __LINE__, fcport->port_name); + qla24xx_post_prli_work(vha, fcport); + } else { + ql_dbg(ql_dbg_disc, vha, 0x20ea, + "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n", + __func__, __LINE__, fcport->port_name, + fcport->loop_id, fcport->d_id.b24); + + set_bit(fcport->loop_id, vha->hw->loop_id_map); + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); + fcport->chip_reset = vha->hw->base_qpair->chip_reset; + fcport->logout_on_delete = 1; + fcport->send_els_logo = 0; + fcport->fw_login_state = DSC_LS_PRLI_COMP; + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + + qla24xx_post_gpdb_work(vha, fcport, 0); + } } break; case MBS_COMMAND_ERROR: @@ -5093,8 +5178,13 @@ qla2x00_free_fcport(fc_port_t *fcport) fcport->ct_desc.ct_sns = NULL; } + + qla_edif_flush_sa_ctl_lists(fcport); list_del(&fcport->list); qla2x00_clear_loop_id(fcport); + + qla_edif_list_del(fcport); + kfree(fcport); } @@ -5213,6 +5303,12 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) "LOOP READY.\n"); ha->flags.fw_init_done = 1; + if (vha->hw->flags.edif_enabled && + vha->e_dbell.db_flags != EDB_ACTIVE) { + /* wake up authentication app to get ready */ + qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, 0); + } + /* * Process any ATIO queue entries that came in * while we weren't online. @@ -5232,7 +5328,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) "%s *** FAILED ***.\n", __func__); } else { ql_dbg(ql_dbg_disc, vha, 0x206b, - "%s: exiting normally.\n", __func__); + "%s: exiting normally. local port wwpn %8phN id %06x)\n", + __func__, vha->port_name, vha->d_id.b24); } /* Restore state if a resync event occurred during processing */ diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index fd22bedc8a00..4855680a8833 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2413,6 +2413,12 @@ qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio) logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI); if (lio->u.logio.flags & SRB_LOGIN_SKIP_PRLI) logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI); + if (lio->u.logio.flags & SRB_LOGIN_FCSP) { + logio->control_flags |= + cpu_to_le16(LCF_COMMON_FEAT | LCF_SKIP_PRLI); + logio->io_parameter[0] = + cpu_to_le32(LIO_COMM_FEAT_FCSP | LIO_COMM_FEAT_CIO); + } } logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->port_id[0] = sp->fcport->d_id.b.al_pa; @@ -2753,7 +2759,6 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) (uint8_t *)els_iocb, sizeof(*els_iocb)); } else { - els_iocb->control_flags = cpu_to_le16(1 << 13); els_iocb->tx_byte_count = cpu_to_le32(sizeof(struct els_logo_payload)); put_unaligned_le64(elsio->u.els_logo.els_logo_pyld_dma, @@ -3684,6 +3689,16 @@ static void qla2x00_send_notify_ack_iocb(srb_t *sp, nack->u.isp24.srr_reject_code = 0; nack->u.isp24.srr_reject_code_expl = 0; nack->u.isp24.vp_index = ntfy->u.isp24.vp_index; + + if (ntfy->u.isp24.status_subcode == ELS_PLOGI && + (le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP) && + sp->vha->hw->flags.edif_enabled) { + ql_dbg(ql_dbg_disc, sp->vha, 0x3074, + "%s PLOGI NACK sent with FC SECURITY bit, hdl=%x, loopid=%x, to pid %06x\n", + sp->name, sp->handle, sp->fcport->loop_id, + sp->fcport->d_id.b24); + nack->u.isp24.flags |= cpu_to_le16(NOTIFY_ACK_FLAGS_FCSP); + } } /* diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 657fe0d9ee21..ce4f93fb4d25 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2372,6 +2372,10 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, if (sp->type != SRB_LOGIN_CMD) goto logio_done; + lio->u.logio.iop[1] = le32_to_cpu(logio->io_parameter[5]); + if (le32_to_cpu(logio->io_parameter[5]) & LIO_COMM_FEAT_FCSP) + fcport->flags |= FCF_FCSP_DEVICE; + iop[0] = le32_to_cpu(logio->io_parameter[0]); if (iop[0] & BIT_4) { fcport->port_type = FCT_TARGET; diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 9f3ad8aa649c..19fa50884293 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -6588,6 +6588,12 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->d_id.b.al_pa = pd->port_id[2]; fcport->d_id.b.rsvd_1 = 0; + ql_dbg(ql_dbg_disc, vha, 0x2062, + "%8phC SVC Param w3 %02x%02x", + fcport->port_name, + pd->prli_svc_param_word_3[1], + pd->prli_svc_param_word_3[0]); + if (NVME_TARGET(vha->hw, fcport)) { fcport->port_type = FCT_NVME; if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index c7caf322f445..078d596dbd49 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -158,6 +158,10 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) int ret = QLA_SUCCESS; fc_port_t *fcport; + if (vha->hw->flags.edif_enabled) + /* delete sessions and flush sa_indexes */ + qla2x00_wait_for_sess_deletion(vha); + if (vha->hw->flags.fw_started) ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); @@ -166,7 +170,8 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) list_for_each_entry(fcport, &vha->vp_fcports, list) fcport->logout_on_delete = 0; - qla2x00_mark_all_devices_lost(vha); + if (!vha->hw->flags.edif_enabled) + qla2x00_wait_for_sess_deletion(vha); /* Remove port id from vp target map */ spin_lock_irqsave(&vha->hw->hardware_lock, flags); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0ae4d0fd622f..216f132dc5b2 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1120,12 +1120,28 @@ static inline int test_fcport_count(scsi_qla_host_t *vha) struct qla_hw_data *ha = vha->hw; unsigned long flags; int res; + /* Return 0 = sleep, x=wake */ spin_lock_irqsave(&ha->tgt.sess_lock, flags); ql_dbg(ql_dbg_init, vha, 0x00ec, "tgt %p, fcport_count=%d\n", vha, vha->fcport_count); res = (vha->fcport_count == 0); + if (res) { + struct fc_port *fcport; + + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->deleted != QLA_SESS_DELETED) { + /* session(s) may not be fully logged in + * (ie fcport_count=0), but session + * deletion thread(s) may be inflight. + */ + + res = 0; + break; + } + } + } spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); return res; @@ -3934,6 +3950,8 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); qla2x00_schedule_rport_del(vha, fcport); } + + qla_edif_sess_down(vha, fcport); /* * We may need to retry the login, so don't change the state of the * port but do the retries. @@ -5441,6 +5459,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) if (atomic_read(&fcport->state) != FCS_ONLINE && fcport->login_retry) { if (fcport->scan_state != QLA_FCPORT_FOUND || + fcport->disc_state == DSC_LOGIN_AUTH_PEND || fcport->disc_state == DSC_LOGIN_COMPLETE) continue; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 26b2bfddc462..c7e12715186e 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -576,6 +576,16 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res) sp->fcport->logout_on_delete = 1; sp->fcport->plogi_nack_done_deadline = jiffies + HZ; sp->fcport->send_els_logo = 0; + + if (sp->fcport->flags & FCF_FCSP_DEVICE) { + ql_dbg(ql_dbg_edif, vha, 0x20ef, + "%s %8phC edif: PLOGI- AUTH WAIT\n", __func__, + sp->fcport->port_name); + qla2x00_set_fcport_disc_state(sp->fcport, + DSC_LOGIN_AUTH_PEND); + qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, + sp->fcport->d_id.b24); + } break; case SRB_NACK_PRLI: @@ -623,6 +633,10 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport, case SRB_NACK_PLOGI: fcport->fw_login_state = DSC_LS_PLOGI_PEND; c = "PLOGI"; + if (vha->hw->flags.edif_enabled && + (le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) { + fcport->flags |= FCF_FCSP_DEVICE; + } break; case SRB_NACK_PRLI: fcport->fw_login_state = DSC_LS_PRLI_PEND; @@ -692,7 +706,12 @@ void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e) void qla24xx_delete_sess_fn(struct work_struct *work) { fc_port_t *fcport = container_of(work, struct fc_port, del_work); - struct qla_hw_data *ha = fcport->vha->hw; + struct qla_hw_data *ha = NULL; + + if (!fcport || !fcport->vha || !fcport->vha->hw) + return; + + ha = fcport->vha->hw; if (fcport->se_sess) { ha->tgt.tgt_ops->shutdown_sess(fcport); @@ -964,6 +983,19 @@ void qlt_free_session_done(struct work_struct *work) sess->send_els_logo); if (!IS_SW_RESV_ADDR(sess->d_id)) { + if (ha->flags.edif_enabled && + (!own || own->iocb.u.isp24.status_subcode == ELS_PLOGI)) { + if (!ha->flags.host_shutting_down) { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla2x00_release_all_sadb\n", + __func__, sess->port_name); + qla2x00_release_all_sadb(vha, sess); + } else { + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s bypassing release_all_sadb\n", + __func__); + } + } qla2x00_mark_device_lost(vha, sess, 0); if (sess->send_els_logo) { @@ -971,6 +1003,7 @@ void qlt_free_session_done(struct work_struct *work) logo.id = sess->d_id; logo.cmd_count = 0; + INIT_LIST_HEAD(&logo.list); if (!own) qlt_send_first_logo(vha, &logo); sess->send_els_logo = 0; @@ -981,6 +1014,7 @@ void qlt_free_session_done(struct work_struct *work) if (!own || (own->iocb.u.isp24.status_subcode == ELS_PLOGI)) { + sess->logout_completed = 0; rc = qla2x00_post_async_logout_work(vha, sess, NULL); if (rc != QLA_SUCCESS) @@ -1719,6 +1753,12 @@ static void qlt_send_notify_ack(struct qla_qpair *qpair, nack->u.isp24.srr_reject_code_expl = srr_explan; nack->u.isp24.vp_index = ntfy->u.isp24.vp_index; + /* TODO qualify this with EDIF enable */ + if (ntfy->u.isp24.status_subcode == ELS_PLOGI && + (le16_to_cpu(ntfy->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) { + nack->u.isp24.flags |= cpu_to_le16(NOTIFY_ACK_FLAGS_FCSP); + } + ql_dbg(ql_dbg_tgt, vha, 0xe005, "qla_target(%d): Sending 24xx Notify Ack %d\n", vha->vp_idx, nack->u.isp24.status); @@ -4726,6 +4766,15 @@ static int qlt_handle_login(struct scsi_qla_host *vha, goto out; } + if (vha->hw->flags.edif_enabled && + vha->e_dbell.db_flags != EDB_ACTIVE) { + ql_dbg(ql_dbg_disc, vha, 0xffff, + "%s %d Term INOT due to app not available lid=%d, NportID %06X ", + __func__, __LINE__, loop_id, port_id.b24); + qlt_send_term_imm_notif(vha, iocb, 1); + goto out; + } + pla = qlt_plogi_ack_find_add(vha, &port_id, iocb); if (!pla) { ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, @@ -4791,6 +4840,16 @@ static int qlt_handle_login(struct scsi_qla_host *vha, qlt_plogi_ack_link(vha, pla, sess, QLT_PLOGI_LINK_SAME_WWN); sess->d_id = port_id; sess->login_gen++; + sess->loop_id = loop_id; + + if (iocb->u.isp24.status_subcode == ELS_PLOGI) { + ql_dbg(ql_dbg_disc, vha, 0xffff, + "%s %8phC - send port online\n", + __func__, sess->port_name); + + qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, + sess->d_id.b24); + } if (iocb->u.isp24.status_subcode == ELS_PRLI) { sess->fw_login_state = DSC_LS_PRLI_PEND; diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 8a319b78cdf6..b910f8f09353 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -176,6 +176,7 @@ struct nack_to_isp { uint8_t reserved[2]; __le16 ox_id; } __packed; +#define NOTIFY_ACK_FLAGS_FCSP BIT_5 #define NOTIFY_ACK_FLAGS_TERMINATE BIT_3 #define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0 #define NOTIFY_ACK_SRR_FLAGS_REJECT 1 -- cgit v1.2.3-70-g09d2 From 7a09e8d92c6d56121910ccb2e8bc0d1affff66ee Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:03 -0700 Subject: scsi: qla2xxx: edif: Add doorbell notification for app Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. During runtime, driver and authentication application need to stay in sync in terms of: Session being down|up, arrival of new authentication message (AUTH ELS) and SADB update completion. These events are queued up as doorbell to the authentication application. Application would read this doorbell on regular basis to stay up to date. Each SCSI host would have a separate doorbell queue. The doorbell interface can daisy chain a list of events for each read. Each event contains an event code + hint to help application steer the next course of action. Link: https://lore.kernel.org/r/20210624052606.21613-9-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 4 + drivers/scsi/qla2xxx/qla_bsg.c | 24 ++- drivers/scsi/qla2xxx/qla_edif.c | 329 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/qla2xxx/qla_gbl.h | 4 + drivers/scsi/qla2xxx/qla_init.c | 3 + drivers/scsi/qla2xxx/qla_os.c | 4 + drivers/scsi/qla2xxx/qla_target.c | 2 + 7 files changed, 366 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index d78db2949ef6..22191e9a04a0 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2435,6 +2435,7 @@ static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show, qla2x00_port_speed_store); static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL); static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL); +static DEVICE_ATTR_RO(edif_doorbell); struct device_attribute *qla2x00_host_attrs[] = { @@ -2480,6 +2481,7 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_port_no, &dev_attr_fw_attr, &dev_attr_dport_diagnostics, + &dev_attr_edif_doorbell, NULL, /* reserve for qlini_mode */ NULL, /* reserve for ql2xiniexchg */ NULL, /* reserve for ql2xexchoffld */ @@ -3108,6 +3110,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) qla_nvme_delete(vha); qla_enode_stop(vha); + qla_edb_stop(vha); + vha->flags.delete_progress = 1; qlt_remove_target(ha, vha); diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 2d43603e31ec..0739f8ad525a 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2784,10 +2784,13 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job) } static int -qla2x00_process_vendor_specific(struct bsg_job *bsg_job) +qla2x00_process_vendor_specific(struct scsi_qla_host *vha, struct bsg_job *bsg_job) { struct fc_bsg_request *bsg_request = bsg_job->request; + ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n", + __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]); + switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) { case QL_VND_LOOPBACK: return qla2x00_process_loopback(bsg_job); @@ -2916,12 +2919,19 @@ qla24xx_bsg_request(struct bsg_job *bsg_job) ql_dbg(ql_dbg_user, vha, 0x709f, "BSG: ISP abort active/needed -- cmd=%d.\n", bsg_request->msgcode); + SET_DID_STATUS(bsg_reply->result, DID_ERROR); return -EBUSY; } + if (test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags)) { + SET_DID_STATUS(bsg_reply->result, DID_ERROR); + return -EIO; + } + skip_chip_chk: - ql_dbg(ql_dbg_user, vha, 0x7000, - "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode); + ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000, + "Entered %s msgcode=0x%x. bsg ptr %px\n", + __func__, bsg_request->msgcode, bsg_job); switch (bsg_request->msgcode) { case FC_BSG_RPT_ELS: @@ -2932,7 +2942,7 @@ skip_chip_chk: ret = qla2x00_process_ct(bsg_job); break; case FC_BSG_HST_VENDOR: - ret = qla2x00_process_vendor_specific(bsg_job); + ret = qla2x00_process_vendor_specific(vha, bsg_job); break; case FC_BSG_HST_ADD_RPORT: case FC_BSG_HST_DEL_RPORT: @@ -2941,6 +2951,10 @@ skip_chip_chk: ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n"); break; } + + ql_dbg(ql_dbg_user + ql_dbg_verbose, vha, 0x7000, + "%s done with return %x\n", __func__, ret); + return ret; } @@ -2955,6 +2969,8 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_job) unsigned long flags; struct req_que *req; + ql_log(ql_log_info, vha, 0x708b, "%s CMD timeout. bsg ptr %p.\n", + __func__, bsg_job); /* find the bsg job from the active list of commands */ spin_lock_irqsave(&ha->hardware_lock, flags); for (que = 0; que < ha->max_req_queues; que++) { diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 51f96f5882af..818d740fdfd1 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -19,6 +19,17 @@ static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handl uint16_t sa_index); static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *); +struct edb_node { + struct list_head list; + uint32_t ntype; + union { + port_id_t plogi_did; + uint32_t async; + port_id_t els_sid; + struct edif_sa_update_aen sa_aen; + } u; +}; + static struct els_sub_cmd { uint16_t cmd; const char *str; @@ -443,6 +454,10 @@ static void __qla2x00_release_all_sadb(struct scsi_qla_host *vha, /* build and send the aen */ fcport->edif.rx_sa_set = 1; fcport->edif.rx_sa_pending = 0; + qla_edb_eventcreate(vha, + VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + QL_VND_SA_STAT_SUCCESS, + QL_VND_RX_SA_KEY, fcport); } ql_dbg(ql_dbg_edif, vha, 0x5033, "%s: release edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n", @@ -539,6 +554,12 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) fcport->loop_id, fcport->d_id.b24, fcport->logout_on_delete); + ql_dbg(ql_dbg_edif, vha, 0xf084, + "keep %d els_logo %d disc state %d auth state %d stop state %d\n", + fcport->keep_nport_handle, + fcport->send_els_logo, fcport->disc_state, + fcport->edif.auth_state, fcport->edif.app_stop); + if (atomic_read(&vha->loop_state) == LOOP_DOWN) break; @@ -1222,6 +1243,10 @@ qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport, /* build and send the aen */ fcport->edif.rx_sa_set = 1; fcport->edif.rx_sa_pending = 0; + qla_edb_eventcreate(fcport->vha, + VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + QL_VND_SA_STAT_SUCCESS, + QL_VND_RX_SA_KEY, fcport); /* force a return of good bsg status; */ return RX_DELETE_NO_EDIF_SA_INDEX; @@ -1776,17 +1801,302 @@ qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp, qla2x00_start_iocbs(vha, qp->req); return 0; } + +void +qla_edb_init(scsi_qla_host_t *vha) +{ + if (vha->e_dbell.db_flags == EDB_ACTIVE) { + /* list already init'd - error */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "edif db already initialized, cannot reinit\n"); + return; + } + + /* initialize lock which protects doorbell & init list */ + spin_lock_init(&vha->e_dbell.db_lock); + INIT_LIST_HEAD(&vha->e_dbell.head); + + /* create and initialize doorbell */ + init_completion(&vha->e_dbell.dbell); +} + +static void +qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node) +{ + /* + * releases the space held by this edb node entry + * this function does _not_ free the edb node itself + * NB: the edb node entry passed should not be on any list + * + * currently for doorbell there's no additional cleanup + * needed, but here as a placeholder for furture use. + */ + + if (!node) { + ql_dbg(ql_dbg_edif, vha, 0x09122, + "%s error - no valid node passed\n", __func__); + return; + } + + node->ntype = N_UNDEF; +} + /* function called when app is stopping */ void qla_edb_stop(scsi_qla_host_t *vha) { + unsigned long flags; + struct edb_node *node, *q; + + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s doorbell not enabled\n", __func__); + return; + } + + /* grab lock so list doesn't move */ + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + + vha->e_dbell.db_flags &= ~EDB_ACTIVE; /* mark it not active */ + /* hopefully this is a null list at this point */ + list_for_each_entry_safe(node, q, &vha->e_dbell.head, list) { + ql_dbg(ql_dbg_edif, vha, 0x910f, + "%s freeing edb_node type=%x\n", + __func__, node->ntype); + qla_edb_node_free(vha, node); + list_del(&node->list); + + kfree(node); + } + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + /* wake up doorbell waiters - they'll be dismissed with error code */ + complete_all(&vha->e_dbell.dbell); +} + +static struct edb_node * +qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype) +{ + struct edb_node *node; + + node = kzalloc(sizeof(*node), GFP_ATOMIC); + if (!node) { + /* couldn't get space */ + ql_dbg(ql_dbg_edif, vha, 0x9100, + "edb node unable to be allocated\n"); + return NULL; + } + + node->ntype = ntype; + INIT_LIST_HEAD(&node->list); + return node; +} + +/* adds a already alllocated enode to the linked list */ +static bool +qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr) +{ + unsigned long flags; + if (vha->e_dbell.db_flags != EDB_ACTIVE) { /* doorbell list not enabled */ ql_dbg(ql_dbg_edif, vha, 0x09102, "%s doorbell not enabled\n", __func__); + return false; + } + + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + list_add_tail(&ptr->list, &vha->e_dbell.head); + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + /* ring doorbell for waiters */ + complete(&vha->e_dbell.dbell); + + return true; +} + +/* adds event to doorbell list */ +void +qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, + uint32_t data, uint32_t data2, fc_port_t *sfcport) +{ + struct edb_node *edbnode; + fc_port_t *fcport = sfcport; + port_id_t id; + + if (!vha->hw->flags.edif_enabled) { + /* edif not enabled */ return; } + + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + if (fcport) + fcport->edif.auth_state = dbtype; + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s doorbell not enabled (type=%d\n", __func__, dbtype); + return; + } + + edbnode = qla_edb_node_alloc(vha, dbtype); + if (!edbnode) { + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s unable to alloc db node\n", __func__); + return; + } + + if (!fcport) { + id.b.domain = (data >> 16) & 0xff; + id.b.area = (data >> 8) & 0xff; + id.b.al_pa = data & 0xff; + ql_dbg(ql_dbg_edif, vha, 0x09222, + "%s: Arrived s_id: %06x\n", __func__, + id.b24); + fcport = qla2x00_find_fcport_by_pid(vha, &id); + if (!fcport) { + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s can't find fcport for sid= 0x%x - ignoring\n", + __func__, id.b24); + kfree(edbnode); + return; + } + } + + /* populate the edb node */ + switch (dbtype) { + case VND_CMD_AUTH_STATE_NEEDED: + case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN: + edbnode->u.plogi_did.b24 = fcport->d_id.b24; + break; + case VND_CMD_AUTH_STATE_ELS_RCVD: + edbnode->u.els_sid.b24 = fcport->d_id.b24; + break; + case VND_CMD_AUTH_STATE_SAUPDATE_COMPL: + edbnode->u.sa_aen.port_id = fcport->d_id; + edbnode->u.sa_aen.status = data; + edbnode->u.sa_aen.key_type = data2; + break; + default: + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s unknown type: %x\n", __func__, dbtype); + qla_edb_node_free(vha, edbnode); + kfree(edbnode); + edbnode = NULL; + break; + } + + if (edbnode && (!qla_edb_node_add(vha, edbnode))) { + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s unable to add dbnode\n", __func__); + qla_edb_node_free(vha, edbnode); + kfree(edbnode); + return; + } + if (edbnode && fcport) + fcport->edif.auth_state = dbtype; + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode); +} + +static struct edb_node * +qla_edb_getnext(scsi_qla_host_t *vha) +{ + unsigned long flags; + struct edb_node *edbnode = NULL; + + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + + /* db nodes are fifo - no qualifications done */ + if (!list_empty(&vha->e_dbell.head)) { + edbnode = list_first_entry(&vha->e_dbell.head, + struct edb_node, list); + list_del(&edbnode->list); + } + + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + return edbnode; +} + +/* + * app uses separate thread to read this. It'll wait until the doorbell + * is rung by the driver or the max wait time has expired + */ +ssize_t +edif_doorbell_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + struct edb_node *dbnode = NULL; + struct edif_app_dbell *ap = (struct edif_app_dbell *)buf; + uint32_t dat_siz, buf_size, sz; + + /* TODO: app currently hardcoded to 256. Will transition to bsg */ + sz = 256; + + /* stop new threads from waiting if we're not init'd */ + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122, + "%s error - edif db not enabled\n", __func__); + return 0; + } + + if (!vha->hw->flags.edif_enabled) { + /* edif not enabled */ + ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122, + "%s error - edif not enabled\n", __func__); + return -1; + } + + buf_size = 0; + while ((sz - buf_size) >= sizeof(struct edb_node)) { + /* remove the next item from the doorbell list */ + dat_siz = 0; + dbnode = qla_edb_getnext(vha); + if (dbnode) { + ap->event_code = dbnode->ntype; + switch (dbnode->ntype) { + case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN: + case VND_CMD_AUTH_STATE_NEEDED: + ap->port_id = dbnode->u.plogi_did; + dat_siz += sizeof(ap->port_id); + break; + case VND_CMD_AUTH_STATE_ELS_RCVD: + ap->port_id = dbnode->u.els_sid; + dat_siz += sizeof(ap->port_id); + break; + case VND_CMD_AUTH_STATE_SAUPDATE_COMPL: + ap->port_id = dbnode->u.sa_aen.port_id; + memcpy(ap->event_data, &dbnode->u, + sizeof(struct edif_sa_update_aen)); + dat_siz += sizeof(struct edif_sa_update_aen); + break; + default: + /* unknown node type, rtn unknown ntype */ + ap->event_code = VND_CMD_AUTH_STATE_UNDEF; + memcpy(ap->event_data, &dbnode->ntype, 4); + dat_siz += 4; + break; + } + + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s Doorbell consumed : type=%d %p\n", + __func__, dbnode->ntype, dbnode); + /* we're done with the db node, so free it up */ + qla_edb_node_free(vha, dbnode); + kfree(dbnode); + } else { + break; + } + + ap->event_data_size = dat_siz; + /* 8bytes = ap->event_code + ap->event_data_size */ + buf_size += dat_siz + 8; + ap = (struct edif_app_dbell *)(buf + buf_size); + } + return buf_size; } static void qla_noop_sp_done(srb_t *sp, int res) @@ -2097,6 +2407,8 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n", __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24, purex->pur_info.pur_did.b24, p->rx_xchg_addr); + + qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL); } static uint16_t qla_edif_get_sa_index_from_freepool(fc_port_t *fcport, int dir) @@ -2318,15 +2630,30 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req, if (pkt->flags & SA_FLAG_TX) { sp->fcport->edif.tx_sa_set = 1; sp->fcport->edif.tx_sa_pending = 0; + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + QL_VND_SA_STAT_SUCCESS, + QL_VND_TX_SA_KEY, sp->fcport); } else { sp->fcport->edif.rx_sa_set = 1; sp->fcport->edif.rx_sa_pending = 0; + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + QL_VND_SA_STAT_SUCCESS, + QL_VND_RX_SA_KEY, sp->fcport); } } else { ql_dbg(ql_dbg_edif, vha, 0x3063, "%s: %8phN SA update FAILED: sa_index: %d, new_sa_info %d, %02x%02x%02x\n", __func__, sp->fcport->port_name, pkt->sa_index, pkt->new_sa_info, pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]); + + if (pkt->flags & SA_FLAG_TX) + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + (le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED, + QL_VND_TX_SA_KEY, sp->fcport); + else + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL, + (le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED, + QL_VND_RX_SA_KEY, sp->fcport); } /* for delete, release sa_ctl, sa_index */ @@ -2819,6 +3146,8 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess) "%s: sess %8phN send port_offline event\n", __func__, sess->port_name); sess->edif.app_sess_online = 0; + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN, + sess->d_id.b24, 0, sess); qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24); } } diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 61b0164ac283..4fc20491898d 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -978,11 +978,15 @@ void qla_nvme_unregister_remote_port(struct fc_port *fcport); /* qla_edif.c */ fc_port_t *qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id); +void qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype, uint32_t data, uint32_t data2, + fc_port_t *fcport); void qla_edb_stop(scsi_qla_host_t *vha); +ssize_t edif_doorbell_show(struct device *dev, struct device_attribute *attr, char *buf); int32_t qla_edif_app_mgmt(struct bsg_job *bsg_job); void qla_enode_init(scsi_qla_host_t *vha); void qla_enode_stop(scsi_qla_host_t *vha); void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport); +void qla_edb_init(scsi_qla_host_t *vha); void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 22474baf57aa..46dddc1dba9b 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1473,6 +1473,9 @@ static int qla_chk_secure_login(scsi_qla_host_t *vha, fc_port_t *fcport, __func__, __LINE__, fcport->port_name); fcport->edif.app_started = 1; fcport->edif.app_sess_online = 1; + + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, + fcport->d_id.b24, 0, fcport); } rc = 1; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 216f132dc5b2..0234cd90bb01 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3488,6 +3488,7 @@ skip_dpc: probe_failed: qla_enode_stop(base_vha); + qla_edb_stop(base_vha); if (base_vha->gnl.l) { dma_free_coherent(&ha->pdev->dev, base_vha->gnl.size, base_vha->gnl.l, base_vha->gnl.ldma); @@ -3791,6 +3792,7 @@ qla2x00_remove_one(struct pci_dev *pdev) base_vha->gnl.l = NULL; qla_enode_stop(base_vha); + qla_edb_stop(base_vha); vfree(base_vha->scan.l); @@ -4917,6 +4919,8 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, init_waitqueue_head(&vha->fcport_waitQ); init_waitqueue_head(&vha->vref_waitq); qla_enode_init(vha); + qla_edb_init(vha); + vha->gnl.size = sizeof(struct get_name_list_extended) * (ha->max_loop_id + 1); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index c7e12715186e..77b54e9ac0a1 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -585,6 +585,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res) DSC_LOGIN_AUTH_PEND); qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, sp->fcport->d_id.b24); + qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_NEEDED, sp->fcport->d_id.b24, + 0, sp->fcport); } break; -- cgit v1.2.3-70-g09d2 From 44d018577f179383ea2c409f3a392e9dbd1a155e Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:04 -0700 Subject: scsi: qla2xxx: edif: Add encryption to I/O path Some FC adapters from Marvell offer the ability to encrypt data in flight (EDIF). This feature requires an application to act as an authenticator. After the completion of PLOGI, both sides have authenticated and PRLI completed, encrypted I/Os are allowed to proceed. - Use new firmware API to encrypt traffic on the wire - Add driver parameter to enable|disable EDIF feature # modprobe qla2xxx ql2xsecenable=1 Link: https://lore.kernel.org/r/20210624052606.21613-10-njavali@marvell.com Reviewed-by: Hannes Reinecke Reviewed-by: Himanshu Madhani Co-developed-by: Larry Wisneski Signed-off-by: Larry Wisneski Co-developed-by: Duane Grigsby Signed-off-by: Duane Grigsby Co-developed-by: Rick Hicksted Jr Signed-off-by: Rick Hicksted Jr Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_edif.c | 337 +++++++++++++++++++++++++++++++++----- drivers/scsi/qla2xxx/qla_fw.h | 3 + drivers/scsi/qla2xxx/qla_gbl.h | 4 + drivers/scsi/qla2xxx/qla_gs.c | 2 +- drivers/scsi/qla2xxx/qla_init.c | 29 ++-- drivers/scsi/qla2xxx/qla_iocb.c | 5 +- drivers/scsi/qla2xxx/qla_mbx.c | 27 ++- drivers/scsi/qla2xxx/qla_nvme.c | 4 + drivers/scsi/qla2xxx/qla_os.c | 9 +- drivers/scsi/qla2xxx/qla_target.c | 41 ++++- drivers/scsi/qla2xxx/qla_target.h | 16 +- 11 files changed, 406 insertions(+), 71 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 818d740fdfd1..8e730cc882e6 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -547,41 +547,30 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) } list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { - if ((fcport->flags & FCF_FCSP_DEVICE)) { - ql_dbg(ql_dbg_edif, vha, 0xf084, - "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n", - __func__, fcport, fcport->port_name, - fcport->loop_id, fcport->d_id.b24, - fcport->logout_on_delete); - - ql_dbg(ql_dbg_edif, vha, 0xf084, - "keep %d els_logo %d disc state %d auth state %d stop state %d\n", - fcport->keep_nport_handle, - fcport->send_els_logo, fcport->disc_state, - fcport->edif.auth_state, fcport->edif.app_stop); - - if (atomic_read(&vha->loop_state) == LOOP_DOWN) - break; + ql_dbg(ql_dbg_edif, vha, 0xf084, + "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n", + __func__, fcport, fcport->port_name, + fcport->loop_id, fcport->d_id.b24, + fcport->logout_on_delete); + + ql_dbg(ql_dbg_edif, vha, 0xf084, + "keep %d els_logo %d disc state %d auth state %d stop state %d\n", + fcport->keep_nport_handle, + fcport->send_els_logo, fcport->disc_state, + fcport->edif.auth_state, fcport->edif.app_stop); + + if (atomic_read(&vha->loop_state) == LOOP_DOWN) + break; - if (!fcport->edif.secured_login) - continue; + fcport->edif.app_started = 1; + fcport->edif.app_stop = 0; - fcport->edif.app_started = 1; - if (fcport->edif.app_stop || - (fcport->disc_state != DSC_LOGIN_COMPLETE && - fcport->disc_state != DSC_LOGIN_PEND && - fcport->disc_state != DSC_DELETED)) { - /* no activity */ - fcport->edif.app_stop = 0; - - ql_dbg(ql_dbg_edif, vha, 0x911e, - "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", - __func__, fcport->port_name); - fcport->edif.app_sess_online = 1; - qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); - } - qla_edif_sa_ctl_init(vha, fcport); - } + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", + __func__, fcport->port_name); + fcport->edif.app_sess_online = 1; + qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); + qla_edif_sa_ctl_init(vha, fcport); } if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) { @@ -925,6 +914,9 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24) continue; + app_reply->ports[pcnt].rekey_count = + fcport->edif.rekey_cnt; + app_reply->ports[pcnt].remote_type = VND_CMD_RTYPE_UNKNOWN; if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET)) @@ -1076,8 +1068,8 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) if (!vha->hw->flags.edif_enabled || test_bit(VPORT_DELETE, &vha->dpc_flags)) { ql_dbg(ql_dbg_edif, vha, 0x911d, - "%s edif not enabled or vp delete. bsg ptr done %p\n", - __func__, bsg_job); + "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n", + __func__, bsg_job, vha->dpc_flags); SET_DID_STATUS(bsg_reply->result, DID_ERROR); goto done; @@ -2227,16 +2219,10 @@ void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb) sa_update_iocb->sa_control |= SA_CNTL_KEY256; for (itr = 0; itr < 32; itr++) sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr]; - - ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x921f, "%s 256 sa key=%32phN\n", - __func__, sa_update_iocb->sa_key); } else { sa_update_iocb->sa_control |= SA_CNTL_KEY128; for (itr = 0; itr < 16; itr++) sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr]; - - ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x921f, "%s 128 sa key=%16phN\n", - __func__, sa_update_iocb->sa_key); } ql_dbg(ql_dbg_edif, vha, 0x921d, @@ -2693,6 +2679,275 @@ qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req, sp->done(sp, 0); } +/** + * qla28xx_start_scsi_edif() - Send a SCSI type 6 command to the ISP + * @sp: command to send to the ISP + * + * Return: non-zero if a failure occurred, else zero. + */ +int +qla28xx_start_scsi_edif(srb_t *sp) +{ + int nseg; + unsigned long flags; + struct scsi_cmnd *cmd; + uint32_t *clr_ptr; + uint32_t index, i; + uint32_t handle; + uint16_t cnt; + int16_t req_cnt; + uint16_t tot_dsds; + __be32 *fcp_dl; + uint8_t additional_cdb_len; + struct ct6_dsd *ctx; + struct scsi_qla_host *vha = sp->vha; + struct qla_hw_data *ha = vha->hw; + struct cmd_type_6 *cmd_pkt; + struct dsd64 *cur_dsd; + uint8_t avail_dsds = 0; + struct scatterlist *sg; + struct req_que *req = sp->qpair->req; + spinlock_t *lock = sp->qpair->qp_lock_ptr; + + /* Setup device pointers. */ + cmd = GET_CMD_SP(sp); + + /* So we know we haven't pci_map'ed anything yet */ + tot_dsds = 0; + + /* Send marker if required */ + if (vha->marker_needed != 0) { + if (qla2x00_marker(vha, sp->qpair, 0, 0, MK_SYNC_ALL) != + QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x300c, + "qla2x00_marker failed for cmd=%p.\n", cmd); + return QLA_FUNCTION_FAILED; + } + vha->marker_needed = 0; + } + + /* Acquire ring specific lock */ + spin_lock_irqsave(lock, flags); + + /* Check for room in outstanding command list. */ + handle = req->current_outstanding_cmd; + for (index = 1; index < req->num_outstanding_cmds; index++) { + handle++; + if (handle == req->num_outstanding_cmds) + handle = 1; + if (!req->outstanding_cmds[handle]) + break; + } + if (index == req->num_outstanding_cmds) + goto queuing_error; + + /* Map the sg table so we have an accurate count of sg entries needed */ + if (scsi_sg_count(cmd)) { + nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd), + scsi_sg_count(cmd), cmd->sc_data_direction); + if (unlikely(!nseg)) + goto queuing_error; + } else { + nseg = 0; + } + + tot_dsds = nseg; + req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + if (req->cnt < (req_cnt + 2)) { + cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : + rd_reg_dword(req->req_q_out); + if (req->ring_index < cnt) + req->cnt = cnt - req->ring_index; + else + req->cnt = req->length - + (req->ring_index - cnt); + if (req->cnt < (req_cnt + 2)) + goto queuing_error; + } + + ctx = sp->u.scmd.ct6_ctx = + mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); + if (!ctx) { + ql_log(ql_log_fatal, vha, 0x3010, + "Failed to allocate ctx for cmd=%p.\n", cmd); + goto queuing_error; + } + + memset(ctx, 0, sizeof(struct ct6_dsd)); + ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool, + GFP_ATOMIC, &ctx->fcp_cmnd_dma); + if (!ctx->fcp_cmnd) { + ql_log(ql_log_fatal, vha, 0x3011, + "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd); + goto queuing_error; + } + + /* Initialize the DSD list and dma handle */ + INIT_LIST_HEAD(&ctx->dsd_list); + ctx->dsd_use_cnt = 0; + + if (cmd->cmd_len > 16) { + additional_cdb_len = cmd->cmd_len - 16; + if ((cmd->cmd_len % 4) != 0) { + /* + * SCSI command bigger than 16 bytes must be + * multiple of 4 + */ + ql_log(ql_log_warn, vha, 0x3012, + "scsi cmd len %d not multiple of 4 for cmd=%p.\n", + cmd->cmd_len, cmd); + goto queuing_error_fcp_cmnd; + } + ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4; + } else { + additional_cdb_len = 0; + ctx->fcp_cmnd_len = 12 + 16 + 4; + } + + cmd_pkt = (struct cmd_type_6 *)req->ring_ptr; + cmd_pkt->handle = make_handle(req->id, handle); + + /* + * Zero out remaining portion of packet. + * tagged queuing modifier -- default is TSK_SIMPLE (0). + */ + clr_ptr = (uint32_t *)cmd_pkt + 2; + memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8); + cmd_pkt->dseg_count = cpu_to_le16(tot_dsds); + + /* No data transfer */ + if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { + cmd_pkt->byte_count = cpu_to_le32(0); + goto no_dsds; + } + + /* Set transfer direction */ + if (cmd->sc_data_direction == DMA_TO_DEVICE) { + cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA); + vha->qla_stats.output_bytes += scsi_bufflen(cmd); + vha->qla_stats.output_requests++; + sp->fcport->edif.tx_bytes += scsi_bufflen(cmd); + } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { + cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA); + vha->qla_stats.input_bytes += scsi_bufflen(cmd); + vha->qla_stats.input_requests++; + sp->fcport->edif.rx_bytes += scsi_bufflen(cmd); + } + + cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF); + cmd_pkt->control_flags &= ~(cpu_to_le16(CF_NEW_SA)); + + /* One DSD is available in the Command Type 6 IOCB */ + avail_dsds = 1; + cur_dsd = &cmd_pkt->fcp_dsd; + + /* Load data segments */ + scsi_for_each_sg(cmd, sg, tot_dsds, i) { + dma_addr_t sle_dma; + cont_a64_entry_t *cont_pkt; + + /* Allocate additional continuation packets? */ + if (avail_dsds == 0) { + /* + * Five DSDs are available in the Continuation + * Type 1 IOCB. + */ + cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req); + cur_dsd = cont_pkt->dsd; + avail_dsds = 5; + } + + sle_dma = sg_dma_address(sg); + put_unaligned_le64(sle_dma, &cur_dsd->address); + cur_dsd->length = cpu_to_le32(sg_dma_len(sg)); + cur_dsd++; + avail_dsds--; + } + +no_dsds: + /* Set NPORT-ID and LUN number*/ + cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); + cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; + cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; + cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; + cmd_pkt->vp_index = sp->vha->vp_idx; + + cmd_pkt->entry_type = COMMAND_TYPE_6; + + /* Set total data segment count. */ + cmd_pkt->entry_count = (uint8_t)req_cnt; + + int_to_scsilun(cmd->device->lun, &cmd_pkt->lun); + host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); + + /* build FCP_CMND IU */ + int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun); + ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; + + if (cmd->sc_data_direction == DMA_TO_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 1; + else if (cmd->sc_data_direction == DMA_FROM_DEVICE) + ctx->fcp_cmnd->additional_cdb_len |= 2; + + /* Populate the FCP_PRIO. */ + if (ha->flags.fcp_prio_enabled) + ctx->fcp_cmnd->task_attribute |= + sp->fcport->fcp_prio << 3; + + memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); + + fcp_dl = (__be32 *)(ctx->fcp_cmnd->cdb + 16 + + additional_cdb_len); + *fcp_dl = htonl((uint32_t)scsi_bufflen(cmd)); + + cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len); + put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address); + + sp->flags |= SRB_FCP_CMND_DMA_VALID; + cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd)); + /* Set total data segment count. */ + cmd_pkt->entry_count = (uint8_t)req_cnt; + cmd_pkt->entry_status = 0; + + /* Build command packet. */ + req->current_outstanding_cmd = handle; + req->outstanding_cmds[handle] = sp; + sp->handle = handle; + cmd->host_scribble = (unsigned char *)(unsigned long)handle; + req->cnt -= req_cnt; + + /* Adjust ring index. */ + wmb(); + req->ring_index++; + if (req->ring_index == req->length) { + req->ring_index = 0; + req->ring_ptr = req->ring; + } else { + req->ring_ptr++; + } + + /* Set chip new ring index. */ + wrt_reg_dword(req->req_q_in, req->ring_index); + + spin_unlock_irqrestore(lock, flags); + + return QLA_SUCCESS; + +queuing_error_fcp_cmnd: + dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma); +queuing_error: + if (tot_dsds) + scsi_dma_unmap(cmd); + + if (sp->u.scmd.ct6_ctx) { + mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool); + sp->u.scmd.ct6_ctx = NULL; + } + spin_unlock_irqrestore(lock, flags); + + return QLA_FUNCTION_FAILED; +} + /********************************************** * edif update/delete sa_index list functions * **********************************************/ diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 4934b08a8990..c257af8d87fd 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -490,6 +490,9 @@ struct cmd_type_6 { struct scsi_lun lun; /* FCP LUN (BE). */ __le16 control_flags; /* Control flags. */ +#define CF_NEW_SA BIT_12 +#define CF_EN_EDIF BIT_9 +#define CF_ADDITIONAL_PARAM_BLK BIT_8 #define CF_DIF_SEG_DESCR_ENABLE BIT_3 #define CF_DATA_SEG_DESCR_ENABLE BIT_2 #define CF_READ_DATA BIT_1 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 4fc20491898d..2b8bdb146a8f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -188,6 +188,7 @@ extern int ql2xenablemsix; extern int qla2xuseresexchforels; extern int ql2xdifbundlinginternalbuffers; extern int ql2xfulldump_on_mpifail; +extern int ql2xsecenable; extern int ql2xenforce_iocb_limit; extern int ql2xabts_wait_nvme; @@ -297,6 +298,8 @@ extern int qla2x00_vp_abort_isp(scsi_qla_host_t *); */ void qla_els_pt_iocb(struct scsi_qla_host *vha, struct els_entry_24xx *pkt, struct qla_els_pt_arg *a); +cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, + struct req_que *que); extern uint16_t qla2x00_calc_iocbs_32(uint16_t); extern uint16_t qla2x00_calc_iocbs_64(uint16_t); extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); @@ -987,6 +990,7 @@ void qla_enode_init(scsi_qla_host_t *vha); void qla_enode_stop(scsi_qla_host_t *vha); void qla_edif_flush_sa_ctl_lists(fc_port_t *fcport); void qla_edb_init(scsi_qla_host_t *vha); +int qla28xx_start_scsi_edif(srb_t *sp); void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); void qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb); void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 99fb330053ae..b16b7d16be12 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -632,7 +632,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id) ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id); ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ - if (vha->flags.nvme_enabled) + if (vha->flags.nvme_enabled && qla_ini_mode_enabled(vha)) ct_req->req.rft_id.fc4_types[6] = 1; /* NVMe type 28h */ sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 46dddc1dba9b..ad0d3f536a31 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -345,15 +345,13 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport)) { lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY; } else { - if (vha->hw->flags.edif_enabled) { - if (fcport->edif.non_secured_login == 0) { - lio->u.logio.flags |= - (SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI); - ql_dbg(ql_dbg_disc, vha, 0x2072, - "Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n", - fcport->port_name, sp->handle, fcport->loop_id, - fcport->d_id.b24); - } + if (vha->hw->flags.edif_enabled && + vha->e_dbell.db_flags & EDB_ACTIVE) { + lio->u.logio.flags |= + (SRB_LOGIN_FCSP | SRB_LOGIN_SKIP_PRLI); + ql_dbg(ql_dbg_disc, vha, 0x2072, + "Async-login: w/ FCSP %8phC hdl=%x, loopid=%x portid=%06x\n", + fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24); } else { lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; } @@ -363,10 +361,9 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; ql_log(ql_log_warn, vha, 0x2072, - "Async-login - %8phC hdl=%x, loopid=%x portid=%02x%02x%02x retries=%d.\n", + "Async-login - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n", fcport->port_name, sp->handle, fcport->loop_id, - fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, - fcport->login_retry); + fcport->d_id.b24, fcport->login_retry); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -3964,7 +3961,8 @@ enable_82xx_npiv: } /* Enable PUREX PASSTHRU */ - if (ql2xrdpenable || ha->flags.scm_supported_f) + if (ql2xrdpenable || ha->flags.scm_supported_f || + ha->flags.edif_enabled) qla25xx_set_els_cmds_supported(vha); } else goto failed; @@ -4149,7 +4147,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) } /* Move PUREX, ABTS RX & RIDA to ATIOQ */ - if (ql2xmvasynctoatio && + if (ql2xmvasynctoatio && !ha->flags.edif_enabled && (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) { if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) @@ -4177,7 +4175,8 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha) ha->fw_options[2] &= ~BIT_8; } - if (ql2xrdpenable || ha->flags.scm_supported_f) + if (ql2xrdpenable || ha->flags.scm_supported_f || + ha->flags.edif_enabled) ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB; /* Enable Async 8130/8131 events -- transceiver insertion/removal */ diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 4855680a8833..625d6b237fb2 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -118,7 +118,7 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha) * * Returns a pointer to the continuation type 1 IOCB packet. */ -static inline cont_a64_entry_t * +cont_a64_entry_t * qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req) { cont_a64_entry_t *cont_pkt; @@ -1910,6 +1910,9 @@ qla2xxx_start_scsi_mq(srb_t *sp) struct qla_hw_data *ha = vha->hw; struct qla_qpair *qpair = sp->qpair; + if (sp->fcport->edif.enable) + return qla28xx_start_scsi_edif(sp); + /* Acquire qpair specific lock */ spin_lock_irqsave(&qpair->qp_lock, flags); diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 19fa50884293..4dd008e06617 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -739,7 +739,7 @@ again: mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE; mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11; - mcp->in_mb |= MBX_3 | MBX_2 | MBX_1; + mcp->in_mb |= MBX_5 | MBX_3 | MBX_2 | MBX_1; } else { mcp->mb[1] = LSW(risc_addr); mcp->out_mb |= MBX_1; @@ -795,6 +795,12 @@ again: } } + if (IS_QLA28XX(ha) && (mcp->mb[5] & BIT_10) && ql2xsecenable) { + ha->flags.edif_enabled = 1; + ql_log(ql_log_info, vha, 0xffff, + "%s: edif is enabled\n", __func__); + } + done: ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, "Done %s.\n", __func__); @@ -4946,7 +4952,7 @@ qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, return rval; } -#define PUREX_CMD_COUNT 2 +#define PUREX_CMD_COUNT 4 int qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) { @@ -4954,6 +4960,7 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; uint8_t *els_cmd_map; + uint8_t active_cnt = 0; dma_addr_t els_cmd_map_dma; uint8_t cmd_opcode[PUREX_CMD_COUNT]; uint8_t i, index, purex_bit; @@ -4975,10 +4982,20 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) } /* List of Purex ELS */ - cmd_opcode[0] = ELS_FPIN; - cmd_opcode[1] = ELS_RDP; + if (ql2xrdpenable) { + cmd_opcode[active_cnt] = ELS_RDP; + active_cnt++; + } + if (ha->flags.scm_supported_f) { + cmd_opcode[active_cnt] = ELS_FPIN; + active_cnt++; + } + if (ha->flags.edif_enabled) { + cmd_opcode[active_cnt] = ELS_AUTH_ELS; + active_cnt++; + } - for (i = 0; i < PUREX_CMD_COUNT; i++) { + for (i = 0; i < active_cnt; i++) { index = cmd_opcode[i] / 8; purex_bit = cmd_opcode[i] % 8; els_cmd_map[index] |= 1 << purex_bit; diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 3e5c70a1d969..fdac3f7fa080 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -463,6 +463,10 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) } else if (fd->io_dir == 0) { cmd_pkt->control_flags = 0; } + + if (sp->fcport->edif.enable && fd->io_dir != 0) + cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF); + /* Set BIT_13 of control flags for Async event */ if (vha->flags.nvme2_enabled && cmd->sqe.common.opcode == nvme_admin_async_event) { diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0234cd90bb01..868037c7d608 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -53,6 +53,11 @@ static struct kmem_cache *ctx_cachep; */ uint ql_errlev = 0x8001; +int ql2xsecenable; +module_param(ql2xsecenable, int, S_IRUGO); +MODULE_PARM_DESC(ql2xsecenable, + "Enable/disable security. 0(Default) - Security disabled. 1 - Security enabled."); + static int ql2xenableclass2; module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xenableclass2, @@ -4030,7 +4035,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, if (!ha->srb_mempool) goto fail_free_gid_list; - if (IS_P3P_TYPE(ha)) { + if (IS_P3P_TYPE(ha) || IS_QLA27XX(ha) || (ql2xsecenable && IS_QLA28XX(ha))) { /* Allocate cache for CT6 Ctx. */ if (!ctx_cachep) { ctx_cachep = kmem_cache_create("qla2xxx_ctx", @@ -4064,7 +4069,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n", ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool); - if (IS_P3P_TYPE(ha) || ql2xenabledif) { + if (IS_P3P_TYPE(ha) || ql2xenabledif || (IS_QLA28XX(ha) && ql2xsecenable)) { ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev, DSD_LIST_DMA_POOL_SIZE, 8, 0); if (!ha->dl_dma_pool) { diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 77b54e9ac0a1..c3a589659658 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1313,8 +1313,8 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) qla24xx_chk_fcp_state(sess); ql_dbg(ql_log_warn, sess->vha, 0xe001, - "Scheduling sess %p for deletion %8phC\n", - sess, sess->port_name); + "Scheduling sess %p for deletion %8phC fc4_type %x\n", + sess, sess->port_name, sess->fc4_type); WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work)); } @@ -2612,6 +2612,7 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair, struct ctio7_to_24xx *pkt; struct atio_from_isp *atio = &prm->cmd->atio; uint16_t temp; + struct qla_tgt_cmd *cmd = prm->cmd; pkt = (struct ctio7_to_24xx *)qpair->req->ring_ptr; prm->pkt = pkt; @@ -2644,6 +2645,15 @@ static int qlt_24xx_build_ctio_pkt(struct qla_qpair *qpair, pkt->u.status0.ox_id = cpu_to_le16(temp); pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); + if (cmd->edif) { + if (cmd->dma_data_direction == DMA_TO_DEVICE) + prm->cmd->sess->edif.rx_bytes += cmd->bufflen; + if (cmd->dma_data_direction == DMA_FROM_DEVICE) + prm->cmd->sess->edif.tx_bytes += cmd->bufflen; + + pkt->u.status0.edif_flags |= EF_EN_EDIF; + } + return 0; } @@ -3334,8 +3344,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, if (xmit_type & QLA_TGT_XMIT_STATUS) { pkt->u.status0.scsi_status = cpu_to_le16(prm.rq_result); - pkt->u.status0.residual = - cpu_to_le32(prm.residual); + if (!cmd->edif) + pkt->u.status0.residual = + cpu_to_le32(prm.residual); + pkt->u.status0.flags |= cpu_to_le16( CTIO7_FLAGS_SEND_STATUS); if (qlt_need_explicit_conf(cmd, 0)) { @@ -3982,6 +3994,12 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, if (cmd == NULL) return; + if ((le16_to_cpu(((struct ctio7_from_24xx *)ctio)->flags) & CTIO7_FLAGS_DATA_OUT) && + cmd->sess) { + qlt_chk_edif_rx_sa_delete_pending(vha, cmd->sess, + (struct ctio7_from_24xx *)ctio); + } + se_cmd = &cmd->se_cmd; cmd->cmd_sent_to_fw = 0; @@ -4052,6 +4070,16 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, qlt_handle_dif_error(qpair, cmd, ctio); return; } + + case CTIO_FAST_AUTH_ERR: + case CTIO_FAST_INCOMP_PAD_LEN: + case CTIO_FAST_INVALID_REQ: + case CTIO_FAST_SPI_ERR: + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, + "qla_target(%d): CTIO with EDIF error status 0x%x received (state %x, se_cmd %p\n", + vha->vp_idx, status, cmd->state, se_cmd); + break; + default: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, "qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n", @@ -4353,6 +4381,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, qlt_assign_qpair(vha, cmd); cmd->reset_count = vha->hw->base_qpair->chip_reset; cmd->vp_idx = vha->vp_idx; + cmd->edif = sess->edif.enable; return cmd; } @@ -4769,7 +4798,9 @@ static int qlt_handle_login(struct scsi_qla_host *vha, } if (vha->hw->flags.edif_enabled && - vha->e_dbell.db_flags != EDB_ACTIVE) { + !(vha->e_dbell.db_flags & EDB_ACTIVE) && + iocb->u.isp24.status_subcode == ELS_PLOGI && + !(le16_to_cpu(iocb->u.isp24.flags) & NOTIFY24XX_FLAGS_FCSP)) { ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d Term INOT due to app not available lid=%d, NportID %06X ", __func__, __LINE__, loop_id, port_id.b24); diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index b910f8f09353..156b950ca7e7 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -239,6 +239,10 @@ struct ctio_to_2xxx { #define CTIO_PORT_LOGGED_OUT 0x29 #define CTIO_PORT_CONF_CHANGED 0x2A #define CTIO_SRR_RECEIVED 0x45 +#define CTIO_FAST_AUTH_ERR 0x63 +#define CTIO_FAST_INCOMP_PAD_LEN 0x65 +#define CTIO_FAST_INVALID_REQ 0x66 +#define CTIO_FAST_SPI_ERR 0x67 #endif #ifndef CTIO_RET_TYPE @@ -409,7 +413,16 @@ struct ctio7_to_24xx { struct { __le16 reserved1; __le16 flags; - __le32 residual; + union { + __le32 residual; + struct { + uint8_t rsvd1; + uint8_t edif_flags; +#define EF_EN_EDIF BIT_0 +#define EF_NEW_SA BIT_1 + uint16_t rsvd2; + }; + }; __le16 ox_id; __le16 scsi_status; __le32 relative_offset; @@ -876,6 +889,7 @@ struct qla_tgt_cmd { unsigned int term_exchg:1; unsigned int cmd_sent_to_fw:1; unsigned int cmd_in_wq:1; + unsigned int edif:1; /* * This variable may be set from outside the LIO and I/O completion -- cgit v1.2.3-70-g09d2 From 71bef5020cd13e1aaa878d10481aafc1ecd4a8f6 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Wed, 23 Jun 2021 22:26:05 -0700 Subject: scsi: qla2xxx: edif: Increment command and completion counts Increment the command and the completion counts. Link: https://lore.kernel.org/r/20210624052606.21613-11-njavali@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_edif.c | 1 + drivers/scsi/qla2xxx/qla_isr.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 8e730cc882e6..ccbe0e1bfcbc 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2926,6 +2926,7 @@ no_dsds: req->ring_ptr++; } + sp->qpair->cmd_cnt++; /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ce4f93fb4d25..e8928fd83049 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3192,10 +3192,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) return; } - sp->qpair->cmd_completion_cnt++; - /* Fast path completion. */ qla_chk_edif_rx_sa_delete_pending(vha, sp, sts24); + sp->qpair->cmd_completion_cnt++; if (comp_status == CS_COMPLETE && scsi_status == 0) { qla2x00_process_completed_request(vha, req, handle); -- cgit v1.2.3-70-g09d2 From 9798c653547d35cebef59d35edbbc269d85fb1b3 Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Wed, 23 Jun 2021 22:26:06 -0700 Subject: scsi: qla2xxx: Update version to 10.02.00.107-k Link: https://lore.kernel.org/r/20210624052606.21613-12-njavali@marvell.com Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index da11829fa12d..2e05dd74b5cb 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.00.106-k" +#define QLA2XXX_VERSION "10.02.00.107-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 106 +#define QLA_DRIVER_BETA_VER 107 -- cgit v1.2.3-70-g09d2 From 91d1be9fb7d667ae136f05cc645276eb2c9fa40e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 19 Jul 2021 17:17:00 +0200 Subject: pinctrl: renesas: Fix pin control matching on R-Car H3e-2G As R-Car H3 ES1.x (R8A77950) and R-Car ES2.0+ (R8A77951) use the same compatible value, the pin control driver relies on soc_device_match() with soc_id = "r8a7795" and the (non)matching of revision = "ES1.*" to match with and distinguish between the two SoC variants. The corresponding entries in the normal of_match_table are present only to make the optional sanity checks work. The R-Car H3e-2G (R8A779M1) SoC is a different grading of the R-Car H3 ES3.0 (R8A77951) SoC. It uses the same compatible values for individual devices, but has an additional compatible value for the root node. When running on an R-Car H3e-2G SoC, soc_device_match() with soc_id = "r8a7795" does not return a match. Hence the pin control driver falls back to the normal of_match_table, and, as the R8A77950 entry is listed first, incorrectly uses the sub-driver for R-Car H3 ES1.x. Fix this by moving the entry for R8A77951 before the entry for R8A77950. Simplify sh_pfc_quirk_match() to only handle R-Car H3 ES1,x, as R-Car H3 ES2.0+ can now be matched using the normal of_match_table as well. Signed-off-by: Geert Uytterhoeven Reviewed-by: Laurent Pinchart Reviewed-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/6cdc5bfa424461105779b56f455387e03560cf66.1626707688.git.geert+renesas@glider.be --- drivers/pinctrl/renesas/core.c | 29 ++++++++++++----------------- drivers/pinctrl/renesas/sh_pfc.h | 4 ++-- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 5ccc49b387f1..f2ab02225837 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -571,17 +571,21 @@ static const struct of_device_id sh_pfc_of_table[] = { .data = &r8a7794_pinmux_info, }, #endif -/* Both r8a7795 entries must be present to make sanity checks work */ -#ifdef CONFIG_PINCTRL_PFC_R8A77950 +/* + * Both r8a7795 entries must be present to make sanity checks work, but only + * the first entry is actually used. + * R-Car H3 ES1.x is matched using soc_device_match() instead. + */ +#ifdef CONFIG_PINCTRL_PFC_R8A77951 { .compatible = "renesas,pfc-r8a7795", - .data = &r8a77950_pinmux_info, + .data = &r8a77951_pinmux_info, }, #endif -#ifdef CONFIG_PINCTRL_PFC_R8A77951 +#ifdef CONFIG_PINCTRL_PFC_R8A77950 { .compatible = "renesas,pfc-r8a7795", - .data = &r8a77951_pinmux_info, + .data = &r8a77950_pinmux_info, }, #endif #ifdef CONFIG_PINCTRL_PFC_R8A77960 @@ -1085,26 +1089,20 @@ static inline void sh_pfc_check_driver(struct platform_driver *pdrv) {} #ifdef CONFIG_OF static const void *sh_pfc_quirk_match(void) { -#if defined(CONFIG_PINCTRL_PFC_R8A77950) || \ - defined(CONFIG_PINCTRL_PFC_R8A77951) +#ifdef CONFIG_PINCTRL_PFC_R8A77950 const struct soc_device_attribute *match; static const struct soc_device_attribute quirks[] = { { .soc_id = "r8a7795", .revision = "ES1.*", .data = &r8a77950_pinmux_info, }, - { - .soc_id = "r8a7795", - .data = &r8a77951_pinmux_info, - }, - { /* sentinel */ } }; match = soc_device_match(quirks); if (match) - return match->data ?: ERR_PTR(-ENODEV); -#endif /* CONFIG_PINCTRL_PFC_R8A77950 || CONFIG_PINCTRL_PFC_R8A77951 */ + return match->data; +#endif /* CONFIG_PINCTRL_PFC_R8A77950 */ return NULL; } @@ -1119,9 +1117,6 @@ static int sh_pfc_probe(struct platform_device *pdev) #ifdef CONFIG_OF if (pdev->dev.of_node) { info = sh_pfc_quirk_match(); - if (IS_ERR(info)) - return PTR_ERR(info); - if (!info) info = of_device_get_match_data(&pdev->dev); } else diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h index bf9822ef7e8c..2479b4fb9cf9 100644 --- a/drivers/pinctrl/renesas/sh_pfc.h +++ b/drivers/pinctrl/renesas/sh_pfc.h @@ -332,8 +332,8 @@ extern const struct sh_pfc_soc_info r8a7791_pinmux_info; extern const struct sh_pfc_soc_info r8a7792_pinmux_info; extern const struct sh_pfc_soc_info r8a7793_pinmux_info; extern const struct sh_pfc_soc_info r8a7794_pinmux_info; -extern const struct sh_pfc_soc_info r8a77950_pinmux_info __weak; -extern const struct sh_pfc_soc_info r8a77951_pinmux_info __weak; +extern const struct sh_pfc_soc_info r8a77950_pinmux_info; +extern const struct sh_pfc_soc_info r8a77951_pinmux_info; extern const struct sh_pfc_soc_info r8a77960_pinmux_info; extern const struct sh_pfc_soc_info r8a77961_pinmux_info; extern const struct sh_pfc_soc_info r8a77965_pinmux_info; -- cgit v1.2.3-70-g09d2 From 95f7f15461fa482a05237669507b4c9b06865b73 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Wed, 14 Jul 2021 11:26:20 +0530 Subject: kdb: Get rid of custom debug heap allocator Currently the only user for debug heap is kdbnearsym() which can be modified to rather use statically allocated buffer for symbol name as per it's current usage. So do that and hence remove custom debug heap allocator. Note that this change puts a restriction on kdbnearsym() callers to carefully use shared namebuf such that a caller should consume the symbol returned immediately prior to another call to fetch a different symbol. Also, this change uses standard KSYM_NAME_LEN macro for namebuf allocation instead of local variable: knt1_size which should avoid any conflicts caused by changes to KSYM_NAME_LEN macro value. This change has been tested using kgdbtest on arm64 which doesn't show any regressions. Suggested-by: Daniel Thompson Signed-off-by: Sumit Garg Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20210714055620.369915-1-sumit.garg@linaro.org Signed-off-by: Daniel Thompson --- kernel/debug/kdb/kdb_debugger.c | 1 - kernel/debug/kdb/kdb_private.h | 5 - kernel/debug/kdb/kdb_support.c | 329 ++++------------------------------------ 3 files changed, 28 insertions(+), 307 deletions(-) diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index 0220afda3200..e91fc3e4edd5 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c @@ -140,7 +140,6 @@ int kdb_stub(struct kgdb_state *ks) */ kdb_common_deinit_state(); KDB_STATE_CLEAR(PAGER); - kdbnearsym_cleanup(); if (error == KDB_CMD_KGDB) { if (KDB_STATE(DOING_KGDB)) KDB_STATE_CLEAR(DOING_KGDB); diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 170c69aedebb..8dbc840113c9 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -109,7 +109,6 @@ extern int kdbgetaddrarg(int, const char **, int*, unsigned long *, long *, char **); extern int kdbgetsymval(const char *, kdb_symtab_t *); extern int kdbnearsym(unsigned long, kdb_symtab_t *); -extern void kdbnearsym_cleanup(void); extern char *kdb_strdup(const char *str, gfp_t type); extern void kdb_symbol_print(unsigned long, const kdb_symtab_t *, unsigned int); @@ -233,10 +232,6 @@ extern struct task_struct *kdb_curr_task(int); #define GFP_KDB (in_dbg_master() ? GFP_ATOMIC : GFP_KERNEL) -extern void *debug_kmalloc(size_t size, gfp_t flags); -extern void debug_kfree(void *); -extern void debug_kusage(void); - extern struct task_struct *kdb_current_task; extern struct pt_regs *kdb_current_regs; diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 9f50d22d68e6..c605b17b2a0d 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -52,48 +52,48 @@ int kdbgetsymval(const char *symname, kdb_symtab_t *symtab) } EXPORT_SYMBOL(kdbgetsymval); -static char *kdb_name_table[100]; /* arbitrary size */ - -/* - * kdbnearsym - Return the name of the symbol with the nearest address - * less than 'addr'. +/** + * kdbnearsym() - Return the name of the symbol with the nearest address + * less than @addr. + * @addr: Address to check for near symbol + * @symtab: Structure to receive results * - * Parameters: - * addr Address to check for symbol near - * symtab Structure to receive results - * Returns: - * 0 No sections contain this address, symtab zero filled - * 1 Address mapped to module/symbol/section, data in symtab - * Remarks: - * 2.6 kallsyms has a "feature" where it unpacks the name into a - * string. If that string is reused before the caller expects it - * then the caller sees its string change without warning. To - * avoid cluttering up the main kdb code with lots of kdb_strdup, - * tests and kfree calls, kdbnearsym maintains an LRU list of the - * last few unique strings. The list is sized large enough to - * hold active strings, no kdb caller of kdbnearsym makes more - * than ~20 later calls before using a saved value. + * WARNING: This function may return a pointer to a single statically + * allocated buffer (namebuf). kdb's unusual calling context (single + * threaded, all other CPUs halted) provides us sufficient locking for + * this to be safe. The only constraint imposed by the static buffer is + * that the caller must consume any previous reply prior to another call + * to lookup a new symbol. + * + * Note that, strictly speaking, some architectures may re-enter the kdb + * trap if the system turns out to be very badly damaged and this breaks + * the single-threaded assumption above. In these circumstances successful + * continuation and exit from the inner trap is unlikely to work and any + * user attempting this receives a prominent warning before being allowed + * to progress. In these circumstances we remain memory safe because + * namebuf[KSYM_NAME_LEN-1] will never change from '\0' although we do + * tolerate the possibility of garbled symbol display from the outer kdb + * trap. + * + * Return: + * * 0 - No sections contain this address, symtab zero filled + * * 1 - Address mapped to module/symbol/section, data in symtab */ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) { int ret = 0; unsigned long symbolsize = 0; unsigned long offset = 0; -#define knt1_size 128 /* must be >= kallsyms table size */ - char *knt1 = NULL; + static char namebuf[KSYM_NAME_LEN]; kdb_dbg_printf(AR, "addr=0x%lx, symtab=%px\n", addr, symtab); memset(symtab, 0, sizeof(*symtab)); if (addr < 4096) goto out; - knt1 = debug_kmalloc(knt1_size, GFP_ATOMIC); - if (!knt1) { - kdb_func_printf("addr=0x%lx cannot kmalloc knt1\n", addr); - goto out; - } + symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset, - (char **)(&symtab->mod_name), knt1); + (char **)(&symtab->mod_name), namebuf); if (offset > 8*1024*1024) { symtab->sym_name = NULL; addr = offset = symbolsize = 0; @@ -102,63 +102,14 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) symtab->sym_end = symtab->sym_start + symbolsize; ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0'; - if (ret) { - int i; - /* Another 2.6 kallsyms "feature". Sometimes the sym_name is - * set but the buffer passed into kallsyms_lookup is not used, - * so it contains garbage. The caller has to work out which - * buffer needs to be saved. - * - * What was Rusty smoking when he wrote that code? - */ - if (symtab->sym_name != knt1) { - strncpy(knt1, symtab->sym_name, knt1_size); - knt1[knt1_size-1] = '\0'; - } - for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) { - if (kdb_name_table[i] && - strcmp(kdb_name_table[i], knt1) == 0) - break; - } - if (i >= ARRAY_SIZE(kdb_name_table)) { - debug_kfree(kdb_name_table[0]); - memmove(kdb_name_table, kdb_name_table+1, - sizeof(kdb_name_table[0]) * - (ARRAY_SIZE(kdb_name_table)-1)); - } else { - debug_kfree(knt1); - knt1 = kdb_name_table[i]; - memmove(kdb_name_table+i, kdb_name_table+i+1, - sizeof(kdb_name_table[0]) * - (ARRAY_SIZE(kdb_name_table)-i-1)); - } - i = ARRAY_SIZE(kdb_name_table) - 1; - kdb_name_table[i] = knt1; - symtab->sym_name = kdb_name_table[i]; - knt1 = NULL; - } - if (symtab->mod_name == NULL) symtab->mod_name = "kernel"; kdb_dbg_printf(AR, "returns %d symtab->sym_start=0x%lx, symtab->mod_name=%px, symtab->sym_name=%px (%s)\n", ret, symtab->sym_start, symtab->mod_name, symtab->sym_name, symtab->sym_name); - out: - debug_kfree(knt1); return ret; } -void kdbnearsym_cleanup(void) -{ - int i; - for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) { - if (kdb_name_table[i]) { - debug_kfree(kdb_name_table[i]); - kdb_name_table[i] = NULL; - } - } -} - static char ks_namebuf[KSYM_NAME_LEN+1], ks_namebuf_prev[KSYM_NAME_LEN+1]; /* @@ -656,230 +607,6 @@ unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask) return (mask & kdb_task_state_string(state)) != 0; } -/* Last ditch allocator for debugging, so we can still debug even when - * the GFP_ATOMIC pool has been exhausted. The algorithms are tuned - * for space usage, not for speed. One smallish memory pool, the free - * chain is always in ascending address order to allow coalescing, - * allocations are done in brute force best fit. - */ - -struct debug_alloc_header { - u32 next; /* offset of next header from start of pool */ - u32 size; - void *caller; -}; - -/* The memory returned by this allocator must be aligned, which means - * so must the header size. Do not assume that sizeof(struct - * debug_alloc_header) is a multiple of the alignment, explicitly - * calculate the overhead of this header, including the alignment. - * The rest of this code must not use sizeof() on any header or - * pointer to a header. - */ -#define dah_align 8 -#define dah_overhead ALIGN(sizeof(struct debug_alloc_header), dah_align) - -static u64 debug_alloc_pool_aligned[256*1024/dah_align]; /* 256K pool */ -static char *debug_alloc_pool = (char *)debug_alloc_pool_aligned; -static u32 dah_first, dah_first_call = 1, dah_used, dah_used_max; - -/* Locking is awkward. The debug code is called from all contexts, - * including non maskable interrupts. A normal spinlock is not safe - * in NMI context. Try to get the debug allocator lock, if it cannot - * be obtained after a second then give up. If the lock could not be - * previously obtained on this cpu then only try once. - * - * sparse has no annotation for "this function _sometimes_ acquires a - * lock", so fudge the acquire/release notation. - */ -static DEFINE_SPINLOCK(dap_lock); -static int get_dap_lock(void) - __acquires(dap_lock) -{ - static int dap_locked = -1; - int count; - if (dap_locked == smp_processor_id()) - count = 1; - else - count = 1000; - while (1) { - if (spin_trylock(&dap_lock)) { - dap_locked = -1; - return 1; - } - if (!count--) - break; - udelay(1000); - } - dap_locked = smp_processor_id(); - __acquire(dap_lock); - return 0; -} - -void *debug_kmalloc(size_t size, gfp_t flags) -{ - unsigned int rem, h_offset; - struct debug_alloc_header *best, *bestprev, *prev, *h; - void *p = NULL; - if (!get_dap_lock()) { - __release(dap_lock); /* we never actually got it */ - return NULL; - } - h = (struct debug_alloc_header *)(debug_alloc_pool + dah_first); - if (dah_first_call) { - h->size = sizeof(debug_alloc_pool_aligned) - dah_overhead; - dah_first_call = 0; - } - size = ALIGN(size, dah_align); - prev = best = bestprev = NULL; - while (1) { - if (h->size >= size && (!best || h->size < best->size)) { - best = h; - bestprev = prev; - if (h->size == size) - break; - } - if (!h->next) - break; - prev = h; - h = (struct debug_alloc_header *)(debug_alloc_pool + h->next); - } - if (!best) - goto out; - rem = best->size - size; - /* The pool must always contain at least one header */ - if (best->next == 0 && bestprev == NULL && rem < dah_overhead) - goto out; - if (rem >= dah_overhead) { - best->size = size; - h_offset = ((char *)best - debug_alloc_pool) + - dah_overhead + best->size; - h = (struct debug_alloc_header *)(debug_alloc_pool + h_offset); - h->size = rem - dah_overhead; - h->next = best->next; - } else - h_offset = best->next; - best->caller = __builtin_return_address(0); - dah_used += best->size; - dah_used_max = max(dah_used, dah_used_max); - if (bestprev) - bestprev->next = h_offset; - else - dah_first = h_offset; - p = (char *)best + dah_overhead; - memset(p, POISON_INUSE, best->size - 1); - *((char *)p + best->size - 1) = POISON_END; -out: - spin_unlock(&dap_lock); - return p; -} - -void debug_kfree(void *p) -{ - struct debug_alloc_header *h; - unsigned int h_offset; - if (!p) - return; - if ((char *)p < debug_alloc_pool || - (char *)p >= debug_alloc_pool + sizeof(debug_alloc_pool_aligned)) { - kfree(p); - return; - } - if (!get_dap_lock()) { - __release(dap_lock); /* we never actually got it */ - return; /* memory leak, cannot be helped */ - } - h = (struct debug_alloc_header *)((char *)p - dah_overhead); - memset(p, POISON_FREE, h->size - 1); - *((char *)p + h->size - 1) = POISON_END; - h->caller = NULL; - dah_used -= h->size; - h_offset = (char *)h - debug_alloc_pool; - if (h_offset < dah_first) { - h->next = dah_first; - dah_first = h_offset; - } else { - struct debug_alloc_header *prev; - unsigned int prev_offset; - prev = (struct debug_alloc_header *)(debug_alloc_pool + - dah_first); - while (1) { - if (!prev->next || prev->next > h_offset) - break; - prev = (struct debug_alloc_header *) - (debug_alloc_pool + prev->next); - } - prev_offset = (char *)prev - debug_alloc_pool; - if (prev_offset + dah_overhead + prev->size == h_offset) { - prev->size += dah_overhead + h->size; - memset(h, POISON_FREE, dah_overhead - 1); - *((char *)h + dah_overhead - 1) = POISON_END; - h = prev; - h_offset = prev_offset; - } else { - h->next = prev->next; - prev->next = h_offset; - } - } - if (h_offset + dah_overhead + h->size == h->next) { - struct debug_alloc_header *next; - next = (struct debug_alloc_header *) - (debug_alloc_pool + h->next); - h->size += dah_overhead + next->size; - h->next = next->next; - memset(next, POISON_FREE, dah_overhead - 1); - *((char *)next + dah_overhead - 1) = POISON_END; - } - spin_unlock(&dap_lock); -} - -void debug_kusage(void) -{ - struct debug_alloc_header *h_free, *h_used; -#ifdef CONFIG_IA64 - /* FIXME: using dah for ia64 unwind always results in a memory leak. - * Fix that memory leak first, then set debug_kusage_one_time = 1 for - * all architectures. - */ - static int debug_kusage_one_time; -#else - static int debug_kusage_one_time = 1; -#endif - if (!get_dap_lock()) { - __release(dap_lock); /* we never actually got it */ - return; - } - h_free = (struct debug_alloc_header *)(debug_alloc_pool + dah_first); - if (dah_first == 0 && - (h_free->size == sizeof(debug_alloc_pool_aligned) - dah_overhead || - dah_first_call)) - goto out; - if (!debug_kusage_one_time) - goto out; - debug_kusage_one_time = 0; - kdb_func_printf("debug_kmalloc memory leak dah_first %d\n", dah_first); - if (dah_first) { - h_used = (struct debug_alloc_header *)debug_alloc_pool; - kdb_func_printf("h_used %px size %d\n", h_used, h_used->size); - } - do { - h_used = (struct debug_alloc_header *) - ((char *)h_free + dah_overhead + h_free->size); - kdb_func_printf("h_used %px size %d caller %px\n", - h_used, h_used->size, h_used->caller); - h_free = (struct debug_alloc_header *) - (debug_alloc_pool + h_free->next); - } while (h_free->next); - h_used = (struct debug_alloc_header *) - ((char *)h_free + dah_overhead + h_free->size); - if ((char *)h_used - debug_alloc_pool != - sizeof(debug_alloc_pool_aligned)) - kdb_func_printf("h_used %px size %d caller %px\n", - h_used, h_used->size, h_used->caller); -out: - spin_unlock(&dap_lock); -} - /* Maintain a small stack of kdb_flags to allow recursion without disturbing * the global kdb state. */ -- cgit v1.2.3-70-g09d2 From f997ea3b7afc108eb9761f321b57de2d089c7c48 Mon Sep 17 00:00:00 2001 From: Xie Yongji Date: Mon, 17 May 2021 16:35:57 +0800 Subject: 9p/trans_virtio: Remove sysfs file on probe failure This ensures we don't leak the sysfs file if we failed to allocate chan->vc_wq during probe. Link: http://lkml.kernel.org/r/20210517083557.172-1-xieyongji@bytedance.com Fixes: 86c8437383ac ("net/9p: Add sysfs mount_tag file for virtio 9P device") Signed-off-by: Xie Yongji Signed-off-by: Dominique Martinet --- net/9p/trans_virtio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 2bbd7dce0f1d..490a4c900339 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -610,7 +610,7 @@ static int p9_virtio_probe(struct virtio_device *vdev) chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL); if (!chan->vc_wq) { err = -ENOMEM; - goto out_free_tag; + goto out_remove_file; } init_waitqueue_head(chan->vc_wq); chan->ring_bufs_avail = 1; @@ -628,6 +628,8 @@ static int p9_virtio_probe(struct virtio_device *vdev) return 0; +out_remove_file: + sysfs_remove_file(&vdev->dev.kobj, &dev_attr_mount_tag.attr); out_free_tag: kfree(tag); out_free_vq: -- cgit v1.2.3-70-g09d2 From 732b33d0dbf17e9483f0b50385bf606f724f50a2 Mon Sep 17 00:00:00 2001 From: Harshvardhan Jha Date: Tue, 27 Jul 2021 05:37:10 +0530 Subject: 9p/xen: Fix end of loop tests for list_for_each_entry This patch addresses the following problems: - priv can never be NULL, so this part of the check is useless - if the loop ran through the whole list, priv->client is invalid and it is more appropriate and sufficient to check for the end of list_for_each_entry loop condition. Link: http://lkml.kernel.org/r/20210727000709.225032-1-harshvardhan.jha@oracle.com Signed-off-by: Harshvardhan Jha Reviewed-by: Stefano Stabellini Tested-by: Stefano Stabellini Cc: Signed-off-by: Dominique Martinet --- net/9p/trans_xen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index f4fea28e05da..3ec1a51a6944 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -138,7 +138,7 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size) static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) { - struct xen_9pfs_front_priv *priv = NULL; + struct xen_9pfs_front_priv *priv; RING_IDX cons, prod, masked_cons, masked_prod; unsigned long flags; u32 size = p9_req->tc.size; @@ -151,7 +151,7 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) break; } read_unlock(&xen_9pfs_lock); - if (!priv || priv->client != client) + if (list_entry_is_head(priv, &xen_9pfs_devs, list)) return -EINVAL; num = p9_req->tc.tag % priv->num_rings; -- cgit v1.2.3-70-g09d2 From b39cded834154cf54442489b56b33d047edd6d8f Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Mon, 12 Jul 2021 19:16:17 +0530 Subject: kdb: Rename struct defcmd_set to struct kdb_macro Rename struct defcmd_set to struct kdb_macro as that sounds more appropriate given its purpose. Suggested-by: Daniel Thompson Signed-off-by: Sumit Garg Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20210712134620.276667-2-sumit.garg@linaro.org Signed-off-by: Daniel Thompson --- kernel/debug/kdb/kdb_main.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index d8ee5647b732..5cf9867fa118 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -654,7 +654,7 @@ static void kdb_cmderror(int diag) * Returns: * zero for success, a kdb diagnostic if error */ -struct defcmd_set { +struct kdb_macro { int count; bool usable; char *name; @@ -662,8 +662,8 @@ struct defcmd_set { char *help; char **command; }; -static struct defcmd_set *defcmd_set; -static int defcmd_set_count; +static struct kdb_macro *kdb_macro; +static int kdb_macro_count; static bool defcmd_in_progress; /* Forward references */ @@ -671,7 +671,7 @@ static int kdb_exec_defcmd(int argc, const char **argv); static int kdb_defcmd2(const char *cmdstr, const char *argv0) { - struct defcmd_set *s = defcmd_set + defcmd_set_count - 1; + struct kdb_macro *s = kdb_macro + kdb_macro_count - 1; char **save_command = s->command; if (strcmp(argv0, "endefcmd") == 0) { defcmd_in_progress = false; @@ -704,7 +704,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) static int kdb_defcmd(int argc, const char **argv) { - struct defcmd_set *save_defcmd_set = defcmd_set, *s; + struct kdb_macro *save_kdb_macro = kdb_macro, *s; if (defcmd_in_progress) { kdb_printf("kdb: nested defcmd detected, assuming missing " "endefcmd\n"); @@ -712,7 +712,7 @@ static int kdb_defcmd(int argc, const char **argv) } if (argc == 0) { int i; - for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) { + for (s = kdb_macro; s < kdb_macro + kdb_macro_count; ++s) { kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, s->usage, s->help); for (i = 0; i < s->count; ++i) @@ -727,13 +727,13 @@ static int kdb_defcmd(int argc, const char **argv) kdb_printf("Command only available during kdb_init()\n"); return KDB_NOTIMP; } - defcmd_set = kmalloc_array(defcmd_set_count + 1, sizeof(*defcmd_set), - GFP_KDB); - if (!defcmd_set) + kdb_macro = kmalloc_array(kdb_macro_count + 1, sizeof(*kdb_macro), + GFP_KDB); + if (!kdb_macro) goto fail_defcmd; - memcpy(defcmd_set, save_defcmd_set, - defcmd_set_count * sizeof(*defcmd_set)); - s = defcmd_set + defcmd_set_count; + memcpy(kdb_macro, save_kdb_macro, + kdb_macro_count * sizeof(*kdb_macro)); + s = kdb_macro + kdb_macro_count; memset(s, 0, sizeof(*s)); s->usable = true; s->name = kdb_strdup(argv[1], GFP_KDB); @@ -753,19 +753,19 @@ static int kdb_defcmd(int argc, const char **argv) strcpy(s->help, argv[3]+1); s->help[strlen(s->help)-1] = '\0'; } - ++defcmd_set_count; + ++kdb_macro_count; defcmd_in_progress = true; - kfree(save_defcmd_set); + kfree(save_kdb_macro); return 0; fail_help: kfree(s->usage); fail_usage: kfree(s->name); fail_name: - kfree(defcmd_set); + kfree(kdb_macro); fail_defcmd: - kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]); - defcmd_set = save_defcmd_set; + kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); + kdb_macro = save_kdb_macro; return KDB_NOTIMP; } @@ -781,14 +781,14 @@ fail_defcmd: static int kdb_exec_defcmd(int argc, const char **argv) { int i, ret; - struct defcmd_set *s; + struct kdb_macro *s; if (argc != 0) return KDB_ARGCOUNT; - for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) { + for (s = kdb_macro, i = 0; i < kdb_macro_count; ++i, ++s) { if (strcmp(s->name, argv[0]) == 0) break; } - if (i == defcmd_set_count) { + if (i == kdb_macro_count) { kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", argv[0]); return KDB_NOTIMP; -- cgit v1.2.3-70-g09d2 From c25abcd625505f53b72dc156bac32b5120826742 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Mon, 12 Jul 2021 19:16:18 +0530 Subject: kdb: Get rid of redundant kdb_register_flags() Commit e4f291b3f7bb ("kdb: Simplify kdb commands registration") allowed registration of pre-allocated kdb commands with pointer to struct kdbtab_t. Lets switch other users as well to register pre- allocated kdb commands via: - Changing prototype for kdb_register() to pass a pointer to struct kdbtab_t instead. - Embed kdbtab_t structure in kdb_macro_t rather than individual params. With these changes kdb_register_flags() becomes redundant and hence removed. Also, since we have switched all users to register pre-allocated commands, "is_dynamic" flag in struct kdbtab_t becomes redundant and hence removed as well. Suggested-by: Daniel Thompson Signed-off-by: Sumit Garg Acked-by: Steven Rostedt (VMware) Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20210712134620.276667-3-sumit.garg@linaro.org Signed-off-by: Daniel Thompson --- include/linux/kdb.h | 27 ++++--- kernel/debug/kdb/kdb_main.c | 167 +++++++++++++---------------------------- kernel/debug/kdb/kdb_private.h | 13 ---- kernel/trace/trace_kdb.c | 12 ++- samples/kdb/kdb_hello.c | 20 +++-- 5 files changed, 88 insertions(+), 151 deletions(-) diff --git a/include/linux/kdb.h b/include/linux/kdb.h index 0125a677b67f..de858edfb3b8 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -13,6 +13,8 @@ * Copyright (C) 2009 Jason Wessel */ +#include + /* Shifted versions of the command enable bits are be used if the command * has no arguments (see kdb_check_flags). This allows commands, such as * go, to have different permissions depending upon whether it is called @@ -64,6 +66,17 @@ typedef enum { typedef int (*kdb_func_t)(int, const char **); +/* The KDB shell command table */ +typedef struct _kdbtab { + char *cmd_name; /* Command name */ + kdb_func_t cmd_func; /* Function to execute command */ + char *cmd_usage; /* Usage String for this command */ + char *cmd_help; /* Help message for this command */ + short cmd_minlen; /* Minimum legal # cmd chars required */ + kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ + struct list_head list_node; /* Command list */ +} kdbtab_t; + #ifdef CONFIG_KGDB_KDB #include #include @@ -193,19 +206,13 @@ static inline const char *kdb_walk_kallsyms(loff_t *pos) #endif /* ! CONFIG_KALLSYMS */ /* Dynamic kdb shell command registration */ -extern int kdb_register(char *, kdb_func_t, char *, char *, short); -extern int kdb_register_flags(char *, kdb_func_t, char *, char *, - short, kdb_cmdflags_t); -extern int kdb_unregister(char *); +extern int kdb_register(kdbtab_t *cmd); +extern void kdb_unregister(kdbtab_t *cmd); #else /* ! CONFIG_KGDB_KDB */ static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } static inline void kdb_init(int level) {} -static inline int kdb_register(char *cmd, kdb_func_t func, char *usage, - char *help, short minlen) { return 0; } -static inline int kdb_register_flags(char *cmd, kdb_func_t func, char *usage, - char *help, short minlen, - kdb_cmdflags_t flags) { return 0; } -static inline int kdb_unregister(char *cmd) { return 0; } +static inline int kdb_register(kdbtab_t *cmd) { return 0; } +static inline void kdb_unregister(kdbtab_t *cmd) {} #endif /* CONFIG_KGDB_KDB */ enum { KDB_NOT_INITIALIZED, diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 5cf9867fa118..b2880fad26d4 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -657,9 +656,7 @@ static void kdb_cmderror(int diag) struct kdb_macro { int count; bool usable; - char *name; - char *usage; - char *help; + kdbtab_t cmd; char **command; }; static struct kdb_macro *kdb_macro; @@ -678,13 +675,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) if (!s->count) s->usable = false; if (s->usable) - /* macros are always safe because when executed each - * internal command re-enters kdb_parse() and is - * safety checked individually. - */ - kdb_register_flags(s->name, kdb_exec_defcmd, s->usage, - s->help, 0, - KDB_ENABLE_ALWAYS_SAFE); + kdb_register(&s->cmd); return 0; } if (!s->usable) @@ -705,6 +696,8 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) static int kdb_defcmd(int argc, const char **argv) { struct kdb_macro *save_kdb_macro = kdb_macro, *s; + kdbtab_t *mp; + if (defcmd_in_progress) { kdb_printf("kdb: nested defcmd detected, assuming missing " "endefcmd\n"); @@ -713,8 +706,8 @@ static int kdb_defcmd(int argc, const char **argv) if (argc == 0) { int i; for (s = kdb_macro; s < kdb_macro + kdb_macro_count; ++s) { - kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, - s->usage, s->help); + kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->cmd.cmd_name, + s->cmd.cmd_usage, s->cmd.cmd_help); for (i = 0; i < s->count; ++i) kdb_printf("%s", s->command[i]); kdb_printf("endefcmd\n"); @@ -736,31 +729,36 @@ static int kdb_defcmd(int argc, const char **argv) s = kdb_macro + kdb_macro_count; memset(s, 0, sizeof(*s)); s->usable = true; - s->name = kdb_strdup(argv[1], GFP_KDB); - if (!s->name) + + mp = &s->cmd; + mp->cmd_func = kdb_exec_defcmd; + mp->cmd_minlen = 0; + mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; + mp->cmd_name = kdb_strdup(argv[1], GFP_KDB); + if (!mp->cmd_name) goto fail_name; - s->usage = kdb_strdup(argv[2], GFP_KDB); - if (!s->usage) + mp->cmd_usage = kdb_strdup(argv[2], GFP_KDB); + if (!mp->cmd_usage) goto fail_usage; - s->help = kdb_strdup(argv[3], GFP_KDB); - if (!s->help) + mp->cmd_help = kdb_strdup(argv[3], GFP_KDB); + if (!mp->cmd_help) goto fail_help; - if (s->usage[0] == '"') { - strcpy(s->usage, argv[2]+1); - s->usage[strlen(s->usage)-1] = '\0'; + if (mp->cmd_usage[0] == '"') { + strcpy(mp->cmd_usage, argv[2]+1); + mp->cmd_usage[strlen(mp->cmd_usage)-1] = '\0'; } - if (s->help[0] == '"') { - strcpy(s->help, argv[3]+1); - s->help[strlen(s->help)-1] = '\0'; + if (mp->cmd_help[0] == '"') { + strcpy(mp->cmd_help, argv[3]+1); + mp->cmd_help[strlen(mp->cmd_help)-1] = '\0'; } ++kdb_macro_count; defcmd_in_progress = true; kfree(save_kdb_macro); return 0; fail_help: - kfree(s->usage); + kfree(mp->cmd_usage); fail_usage: - kfree(s->name); + kfree(mp->cmd_name); fail_name: kfree(kdb_macro); fail_defcmd: @@ -785,7 +783,7 @@ static int kdb_exec_defcmd(int argc, const char **argv) if (argc != 0) return KDB_ARGCOUNT; for (s = kdb_macro, i = 0; i < kdb_macro_count; ++i, ++s) { - if (strcmp(s->name, argv[0]) == 0) + if (strcmp(s->cmd.cmd_name, argv[0]) == 0) break; } if (i == kdb_macro_count) { @@ -797,7 +795,7 @@ static int kdb_exec_defcmd(int argc, const char **argv) /* Recursive use of kdb_parse, do not use argv after * this point */ argv = NULL; - kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]); + kdb_printf("[%s]kdb> %s\n", s->cmd.cmd_name, s->command[i]); ret = kdb_parse(s->command[i]); if (ret) return ret; @@ -2613,56 +2611,32 @@ static int kdb_grep_help(int argc, const char **argv) return 0; } -/* - * kdb_register_flags - This function is used to register a kernel - * debugger command. - * Inputs: - * cmd Command name - * func Function to execute the command - * usage A simple usage string showing arguments - * help A simple help string describing command - * repeat Does the command auto repeat on enter? - * Returns: - * zero for success, one if a duplicate command. +/** + * kdb_register() - This function is used to register a kernel debugger + * command. + * @cmd: pointer to kdb command + * + * Note that it's the job of the caller to keep the memory for the cmd + * allocated until unregister is called. */ -int kdb_register_flags(char *cmd, - kdb_func_t func, - char *usage, - char *help, - short minlen, - kdb_cmdflags_t flags) +int kdb_register(kdbtab_t *cmd) { kdbtab_t *kp; list_for_each_entry(kp, &kdb_cmds_head, list_node) { - if (strcmp(kp->cmd_name, cmd) == 0) { - kdb_printf("Duplicate kdb command registered: " - "%s, func %px help %s\n", cmd, func, help); + if (strcmp(kp->cmd_name, cmd->cmd_name) == 0) { + kdb_printf("Duplicate kdb cmd: %s, func %p help %s\n", + cmd->cmd_name, cmd->cmd_func, cmd->cmd_help); return 1; } } - kp = kmalloc(sizeof(*kp), GFP_KDB); - if (!kp) { - kdb_printf("Could not allocate new kdb_command table\n"); - return 1; - } - - kp->cmd_name = cmd; - kp->cmd_func = func; - kp->cmd_usage = usage; - kp->cmd_help = help; - kp->cmd_minlen = minlen; - kp->cmd_flags = flags; - kp->is_dynamic = true; - - list_add_tail(&kp->list_node, &kdb_cmds_head); - + list_add_tail(&cmd->list_node, &kdb_cmds_head); return 0; } -EXPORT_SYMBOL_GPL(kdb_register_flags); +EXPORT_SYMBOL_GPL(kdb_register); -/* +/** * kdb_register_table() - This function is used to register a kdb command * table. * @kp: pointer to kdb command table @@ -2676,55 +2650,15 @@ void kdb_register_table(kdbtab_t *kp, size_t len) } } -/* - * kdb_register - Compatibility register function for commands that do - * not need to specify a repeat state. Equivalent to - * kdb_register_flags with flags set to 0. - * Inputs: - * cmd Command name - * func Function to execute the command - * usage A simple usage string showing arguments - * help A simple help string describing command - * Returns: - * zero for success, one if a duplicate command. - */ -int kdb_register(char *cmd, - kdb_func_t func, - char *usage, - char *help, - short minlen) -{ - return kdb_register_flags(cmd, func, usage, help, minlen, 0); -} -EXPORT_SYMBOL_GPL(kdb_register); - -/* - * kdb_unregister - This function is used to unregister a kernel - * debugger command. It is generally called when a module which - * implements kdb commands is unloaded. - * Inputs: - * cmd Command name - * Returns: - * zero for success, one command not registered. +/** + * kdb_unregister() - This function is used to unregister a kernel debugger + * command. It is generally called when a module which + * implements kdb command is unloaded. + * @cmd: pointer to kdb command */ -int kdb_unregister(char *cmd) +void kdb_unregister(kdbtab_t *cmd) { - kdbtab_t *kp; - - /* - * find the command. - */ - list_for_each_entry(kp, &kdb_cmds_head, list_node) { - if (strcmp(kp->cmd_name, cmd) == 0) { - list_del(&kp->list_node); - if (kp->is_dynamic) - kfree(kp); - return 0; - } - } - - /* Couldn't find it. */ - return 1; + list_del(&cmd->list_node); } EXPORT_SYMBOL_GPL(kdb_unregister); @@ -2900,6 +2834,11 @@ static kdbtab_t maintab[] = { .cmd_func = kdb_defcmd, .cmd_usage = "name \"usage\" \"help\"", .cmd_help = "Define a set of commands, down to endefcmd", + /* + * Macros are always safe because when executed each + * internal command re-enters kdb_parse() and is safety + * checked individually. + */ .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, }, { .cmd_name = "kill", diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 8dbc840113c9..629590084a0d 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -164,19 +164,6 @@ typedef struct _kdb_bp { #ifdef CONFIG_KGDB_KDB extern kdb_bp_t kdb_breakpoints[/* KDB_MAXBPT */]; -/* The KDB shell command table */ -typedef struct _kdbtab { - char *cmd_name; /* Command name */ - kdb_func_t cmd_func; /* Function to execute command */ - char *cmd_usage; /* Usage String for this command */ - char *cmd_help; /* Help message for this command */ - short cmd_minlen; /* Minimum legal # command - * chars required */ - kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ - struct list_head list_node; /* Command list */ - bool is_dynamic; /* Command table allocation type */ -} kdbtab_t; - extern void kdb_register_table(kdbtab_t *kp, size_t len); extern int kdb_bt(int, const char **); /* KDB display back trace */ diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 9da76104f7a2..6c4f92c79e43 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -147,11 +147,17 @@ static int kdb_ftdump(int argc, const char **argv) return 0; } +static kdbtab_t ftdump_cmd = { + .cmd_name = "ftdump", + .cmd_func = kdb_ftdump, + .cmd_usage = "[skip_#entries] [cpu]", + .cmd_help = "Dump ftrace log; -skip dumps last #entries", + .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, +}; + static __init int kdb_ftrace_register(void) { - kdb_register_flags("ftdump", kdb_ftdump, "[skip_#entries] [cpu]", - "Dump ftrace log; -skip dumps last #entries", 0, - KDB_ENABLE_ALWAYS_SAFE); + kdb_register(&ftdump_cmd); return 0; } diff --git a/samples/kdb/kdb_hello.c b/samples/kdb/kdb_hello.c index c1c2fa0f62c2..9ad514a6648b 100644 --- a/samples/kdb/kdb_hello.c +++ b/samples/kdb/kdb_hello.c @@ -28,28 +28,26 @@ static int kdb_hello_cmd(int argc, const char **argv) return 0; } +static kdbtab_t hello_cmd = { + .cmd_name = "hello", + .cmd_func = kdb_hello_cmd, + .cmd_usage = "[string]", + .cmd_help = "Say Hello World or Hello [string]", +}; static int __init kdb_hello_cmd_init(void) { /* * Registration of a dynamically added kdb command is done with - * kdb_register() with the arguments being: - * 1: The name of the shell command - * 2: The function that processes the command - * 3: Description of the usage of any arguments - * 4: Descriptive text when you run help - * 5: Number of characters to complete the command - * 0 == type the whole command - * 1 == match both "g" and "go" for example + * kdb_register(). */ - kdb_register("hello", kdb_hello_cmd, "[string]", - "Say Hello World or Hello [string]", 0); + kdb_register(&hello_cmd); return 0; } static void __exit kdb_hello_cmd_exit(void) { - kdb_unregister("hello"); + kdb_unregister(&hello_cmd); } module_init(kdb_hello_cmd_init); -- cgit v1.2.3-70-g09d2 From 9a5db530aa7d98b10c4f5104027565c98cca49e6 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Mon, 12 Jul 2021 19:16:19 +0530 Subject: kdb: Simplify kdb_defcmd macro logic Switch to use a linked list instead of dynamic array which makes allocation of kdb macro and traversing the kdb macro commands list simpler. Suggested-by: Daniel Thompson Signed-off-by: Sumit Garg Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20210712134620.276667-4-sumit.garg@linaro.org Signed-off-by: Daniel Thompson --- kernel/debug/kdb/kdb_main.c | 107 ++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 49 deletions(-) diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index b2880fad26d4..7c7a2ef834fc 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -654,13 +654,16 @@ static void kdb_cmderror(int diag) * zero for success, a kdb diagnostic if error */ struct kdb_macro { - int count; - bool usable; - kdbtab_t cmd; - char **command; + kdbtab_t cmd; /* Macro command */ + struct list_head statements; /* Associated statement list */ }; + +struct kdb_macro_statement { + char *statement; /* Statement text */ + struct list_head list_node; /* Statement list node */ +}; + static struct kdb_macro *kdb_macro; -static int kdb_macro_count; static bool defcmd_in_progress; /* Forward references */ @@ -668,34 +671,33 @@ static int kdb_exec_defcmd(int argc, const char **argv); static int kdb_defcmd2(const char *cmdstr, const char *argv0) { - struct kdb_macro *s = kdb_macro + kdb_macro_count - 1; - char **save_command = s->command; + struct kdb_macro_statement *kms; + + if (!kdb_macro) + return KDB_NOTIMP; + if (strcmp(argv0, "endefcmd") == 0) { defcmd_in_progress = false; - if (!s->count) - s->usable = false; - if (s->usable) - kdb_register(&s->cmd); + if (!list_empty(&kdb_macro->statements)) + kdb_register(&kdb_macro->cmd); return 0; } - if (!s->usable) - return KDB_NOTIMP; - s->command = kcalloc(s->count + 1, sizeof(*(s->command)), GFP_KDB); - if (!s->command) { - kdb_printf("Could not allocate new kdb_defcmd table for %s\n", + + kms = kmalloc(sizeof(*kms), GFP_KDB); + if (!kms) { + kdb_printf("Could not allocate new kdb macro command: %s\n", cmdstr); - s->usable = false; return KDB_NOTIMP; } - memcpy(s->command, save_command, s->count * sizeof(*(s->command))); - s->command[s->count++] = kdb_strdup(cmdstr, GFP_KDB); - kfree(save_command); + + kms->statement = kdb_strdup(cmdstr, GFP_KDB); + list_add_tail(&kms->list_node, &kdb_macro->statements); + return 0; } static int kdb_defcmd(int argc, const char **argv) { - struct kdb_macro *save_kdb_macro = kdb_macro, *s; kdbtab_t *mp; if (defcmd_in_progress) { @@ -704,13 +706,21 @@ static int kdb_defcmd(int argc, const char **argv) kdb_defcmd2("endefcmd", "endefcmd"); } if (argc == 0) { - int i; - for (s = kdb_macro; s < kdb_macro + kdb_macro_count; ++s) { - kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->cmd.cmd_name, - s->cmd.cmd_usage, s->cmd.cmd_help); - for (i = 0; i < s->count; ++i) - kdb_printf("%s", s->command[i]); - kdb_printf("endefcmd\n"); + kdbtab_t *kp; + struct kdb_macro *kmp; + struct kdb_macro_statement *kms; + + list_for_each_entry(kp, &kdb_cmds_head, list_node) { + if (kp->cmd_func == kdb_exec_defcmd) { + kdb_printf("defcmd %s \"%s\" \"%s\"\n", + kp->cmd_name, kp->cmd_usage, + kp->cmd_help); + kmp = container_of(kp, struct kdb_macro, cmd); + list_for_each_entry(kms, &kmp->statements, + list_node) + kdb_printf("%s", kms->statement); + kdb_printf("endefcmd\n"); + } } return 0; } @@ -720,17 +730,11 @@ static int kdb_defcmd(int argc, const char **argv) kdb_printf("Command only available during kdb_init()\n"); return KDB_NOTIMP; } - kdb_macro = kmalloc_array(kdb_macro_count + 1, sizeof(*kdb_macro), - GFP_KDB); + kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); if (!kdb_macro) goto fail_defcmd; - memcpy(kdb_macro, save_kdb_macro, - kdb_macro_count * sizeof(*kdb_macro)); - s = kdb_macro + kdb_macro_count; - memset(s, 0, sizeof(*s)); - s->usable = true; - mp = &s->cmd; + mp = &kdb_macro->cmd; mp->cmd_func = kdb_exec_defcmd; mp->cmd_minlen = 0; mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; @@ -751,9 +755,9 @@ static int kdb_defcmd(int argc, const char **argv) strcpy(mp->cmd_help, argv[3]+1); mp->cmd_help[strlen(mp->cmd_help)-1] = '\0'; } - ++kdb_macro_count; + + INIT_LIST_HEAD(&kdb_macro->statements); defcmd_in_progress = true; - kfree(save_kdb_macro); return 0; fail_help: kfree(mp->cmd_usage); @@ -763,7 +767,6 @@ fail_name: kfree(kdb_macro); fail_defcmd: kdb_printf("Could not allocate new kdb_macro entry for %s\n", argv[1]); - kdb_macro = save_kdb_macro; return KDB_NOTIMP; } @@ -778,25 +781,31 @@ fail_defcmd: */ static int kdb_exec_defcmd(int argc, const char **argv) { - int i, ret; - struct kdb_macro *s; + int ret; + kdbtab_t *kp; + struct kdb_macro *kmp; + struct kdb_macro_statement *kms; + if (argc != 0) return KDB_ARGCOUNT; - for (s = kdb_macro, i = 0; i < kdb_macro_count; ++i, ++s) { - if (strcmp(s->cmd.cmd_name, argv[0]) == 0) + + list_for_each_entry(kp, &kdb_cmds_head, list_node) { + if (strcmp(kp->cmd_name, argv[0]) == 0) break; } - if (i == kdb_macro_count) { + if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", argv[0]); return KDB_NOTIMP; } - for (i = 0; i < s->count; ++i) { - /* Recursive use of kdb_parse, do not use argv after - * this point */ + kmp = container_of(kp, struct kdb_macro, cmd); + list_for_each_entry(kms, &kmp->statements, list_node) { + /* + * Recursive use of kdb_parse, do not use argv after this point. + */ argv = NULL; - kdb_printf("[%s]kdb> %s\n", s->cmd.cmd_name, s->command[i]); - ret = kdb_parse(s->command[i]); + kdb_printf("[%s]kdb> %s\n", kmp->cmd.cmd_name, kms->statement); + ret = kdb_parse(kms->statement); if (ret) return ret; } -- cgit v1.2.3-70-g09d2 From e868f0a3c4b9c1d7721f08b703142a876814a3f8 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Mon, 12 Jul 2021 19:16:20 +0530 Subject: kdb: Rename members of struct kdbtab_t Remove redundant prefix "cmd_" from name of members in struct kdbtab_t for better readibility. Suggested-by: Doug Anderson Signed-off-by: Sumit Garg Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20210712134620.276667-5-sumit.garg@linaro.org Signed-off-by: Daniel Thompson --- include/linux/kdb.h | 12 +- kernel/debug/kdb/kdb_bp.c | 72 ++++---- kernel/debug/kdb/kdb_main.c | 404 ++++++++++++++++++++++---------------------- kernel/trace/trace_kdb.c | 10 +- samples/kdb/kdb_hello.c | 8 +- 5 files changed, 252 insertions(+), 254 deletions(-) diff --git a/include/linux/kdb.h b/include/linux/kdb.h index de858edfb3b8..ea0f5e580fac 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -68,12 +68,12 @@ typedef int (*kdb_func_t)(int, const char **); /* The KDB shell command table */ typedef struct _kdbtab { - char *cmd_name; /* Command name */ - kdb_func_t cmd_func; /* Function to execute command */ - char *cmd_usage; /* Usage String for this command */ - char *cmd_help; /* Help message for this command */ - short cmd_minlen; /* Minimum legal # cmd chars required */ - kdb_cmdflags_t cmd_flags; /* Command behaviour flags */ + char *name; /* Command name */ + kdb_func_t func; /* Function to execute command */ + char *usage; /* Usage String for this command */ + char *help; /* Help message for this command */ + short minlen; /* Minimum legal # cmd chars required */ + kdb_cmdflags_t flags; /* Command behaviour flags */ struct list_head list_node; /* Command list */ } kdbtab_t; diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 2168f8dacb99..372025cf1ca3 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c @@ -523,51 +523,51 @@ static int kdb_ss(int argc, const char **argv) } static kdbtab_t bptab[] = { - { .cmd_name = "bp", - .cmd_func = kdb_bp, - .cmd_usage = "[]", - .cmd_help = "Set/Display breakpoints", - .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, + { .name = "bp", + .func = kdb_bp, + .usage = "[]", + .help = "Set/Display breakpoints", + .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "bl", - .cmd_func = kdb_bp, - .cmd_usage = "[]", - .cmd_help = "Display breakpoints", - .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, + { .name = "bl", + .func = kdb_bp, + .usage = "[]", + .help = "Display breakpoints", + .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "bc", - .cmd_func = kdb_bc, - .cmd_usage = "", - .cmd_help = "Clear Breakpoint", - .cmd_flags = KDB_ENABLE_FLOW_CTRL, + { .name = "bc", + .func = kdb_bc, + .usage = "", + .help = "Clear Breakpoint", + .flags = KDB_ENABLE_FLOW_CTRL, }, - { .cmd_name = "be", - .cmd_func = kdb_bc, - .cmd_usage = "", - .cmd_help = "Enable Breakpoint", - .cmd_flags = KDB_ENABLE_FLOW_CTRL, + { .name = "be", + .func = kdb_bc, + .usage = "", + .help = "Enable Breakpoint", + .flags = KDB_ENABLE_FLOW_CTRL, }, - { .cmd_name = "bd", - .cmd_func = kdb_bc, - .cmd_usage = "", - .cmd_help = "Disable Breakpoint", - .cmd_flags = KDB_ENABLE_FLOW_CTRL, + { .name = "bd", + .func = kdb_bc, + .usage = "", + .help = "Disable Breakpoint", + .flags = KDB_ENABLE_FLOW_CTRL, }, - { .cmd_name = "ss", - .cmd_func = kdb_ss, - .cmd_usage = "", - .cmd_help = "Single Step", - .cmd_minlen = 1, - .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, + { .name = "ss", + .func = kdb_ss, + .usage = "", + .help = "Single Step", + .minlen = 1, + .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, }, }; static kdbtab_t bphcmd = { - .cmd_name = "bph", - .cmd_func = kdb_bp, - .cmd_usage = "[]", - .cmd_help = "[datar [length]|dataw [length]] Set hw brk", - .cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, + .name = "bph", + .func = kdb_bp, + .usage = "[]", + .help = "[datar [length]|dataw [length]] Set hw brk", + .flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS, }; /* Initialize the breakpoint table and register breakpoint commands. */ diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 7c7a2ef834fc..fa6deda894a1 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -711,10 +711,9 @@ static int kdb_defcmd(int argc, const char **argv) struct kdb_macro_statement *kms; list_for_each_entry(kp, &kdb_cmds_head, list_node) { - if (kp->cmd_func == kdb_exec_defcmd) { + if (kp->func == kdb_exec_defcmd) { kdb_printf("defcmd %s \"%s\" \"%s\"\n", - kp->cmd_name, kp->cmd_usage, - kp->cmd_help); + kp->name, kp->usage, kp->help); kmp = container_of(kp, struct kdb_macro, cmd); list_for_each_entry(kms, &kmp->statements, list_node) @@ -735,34 +734,34 @@ static int kdb_defcmd(int argc, const char **argv) goto fail_defcmd; mp = &kdb_macro->cmd; - mp->cmd_func = kdb_exec_defcmd; - mp->cmd_minlen = 0; - mp->cmd_flags = KDB_ENABLE_ALWAYS_SAFE; - mp->cmd_name = kdb_strdup(argv[1], GFP_KDB); - if (!mp->cmd_name) + mp->func = kdb_exec_defcmd; + mp->minlen = 0; + mp->flags = KDB_ENABLE_ALWAYS_SAFE; + mp->name = kdb_strdup(argv[1], GFP_KDB); + if (!mp->name) goto fail_name; - mp->cmd_usage = kdb_strdup(argv[2], GFP_KDB); - if (!mp->cmd_usage) + mp->usage = kdb_strdup(argv[2], GFP_KDB); + if (!mp->usage) goto fail_usage; - mp->cmd_help = kdb_strdup(argv[3], GFP_KDB); - if (!mp->cmd_help) + mp->help = kdb_strdup(argv[3], GFP_KDB); + if (!mp->help) goto fail_help; - if (mp->cmd_usage[0] == '"') { - strcpy(mp->cmd_usage, argv[2]+1); - mp->cmd_usage[strlen(mp->cmd_usage)-1] = '\0'; + if (mp->usage[0] == '"') { + strcpy(mp->usage, argv[2]+1); + mp->usage[strlen(mp->usage)-1] = '\0'; } - if (mp->cmd_help[0] == '"') { - strcpy(mp->cmd_help, argv[3]+1); - mp->cmd_help[strlen(mp->cmd_help)-1] = '\0'; + if (mp->help[0] == '"') { + strcpy(mp->help, argv[3]+1); + mp->help[strlen(mp->help)-1] = '\0'; } INIT_LIST_HEAD(&kdb_macro->statements); defcmd_in_progress = true; return 0; fail_help: - kfree(mp->cmd_usage); + kfree(mp->usage); fail_usage: - kfree(mp->cmd_name); + kfree(mp->name); fail_name: kfree(kdb_macro); fail_defcmd: @@ -790,7 +789,7 @@ static int kdb_exec_defcmd(int argc, const char **argv) return KDB_ARGCOUNT; list_for_each_entry(kp, &kdb_cmds_head, list_node) { - if (strcmp(kp->cmd_name, argv[0]) == 0) + if (strcmp(kp->name, argv[0]) == 0) break; } if (list_entry_is_head(kp, &kdb_cmds_head, list_node)) { @@ -804,7 +803,7 @@ static int kdb_exec_defcmd(int argc, const char **argv) * Recursive use of kdb_parse, do not use argv after this point. */ argv = NULL; - kdb_printf("[%s]kdb> %s\n", kmp->cmd.cmd_name, kms->statement); + kdb_printf("[%s]kdb> %s\n", kmp->cmd.name, kms->statement); ret = kdb_parse(kms->statement); if (ret) return ret; @@ -1016,11 +1015,11 @@ int kdb_parse(const char *cmdstr) * If this command is allowed to be abbreviated, * check to see if this is it. */ - if (tp->cmd_minlen && (strlen(argv[0]) <= tp->cmd_minlen) && - (strncmp(argv[0], tp->cmd_name, tp->cmd_minlen) == 0)) + if (tp->minlen && (strlen(argv[0]) <= tp->minlen) && + (strncmp(argv[0], tp->name, tp->minlen) == 0)) break; - if (strcmp(argv[0], tp->cmd_name) == 0) + if (strcmp(argv[0], tp->name) == 0) break; } @@ -1031,8 +1030,7 @@ int kdb_parse(const char *cmdstr) */ if (list_entry_is_head(tp, &kdb_cmds_head, list_node)) { list_for_each_entry(tp, &kdb_cmds_head, list_node) { - if (strncmp(argv[0], tp->cmd_name, - strlen(tp->cmd_name)) == 0) + if (strncmp(argv[0], tp->name, strlen(tp->name)) == 0) break; } } @@ -1040,19 +1038,19 @@ int kdb_parse(const char *cmdstr) if (!list_entry_is_head(tp, &kdb_cmds_head, list_node)) { int result; - if (!kdb_check_flags(tp->cmd_flags, kdb_cmd_enabled, argc <= 1)) + if (!kdb_check_flags(tp->flags, kdb_cmd_enabled, argc <= 1)) return KDB_NOPERM; KDB_STATE_SET(CMD); - result = (*tp->cmd_func)(argc-1, (const char **)argv); + result = (*tp->func)(argc-1, (const char **)argv); if (result && ignore_errors && result > KDB_CMD_GO) result = 0; KDB_STATE_CLEAR(CMD); - if (tp->cmd_flags & KDB_REPEAT_WITH_ARGS) + if (tp->flags & KDB_REPEAT_WITH_ARGS) return result; - argc = tp->cmd_flags & KDB_REPEAT_NO_ARGS ? 1 : 0; + argc = tp->flags & KDB_REPEAT_NO_ARGS ? 1 : 0; if (argv[argc]) *(argv[argc]) = '\0'; return result; @@ -2419,12 +2417,12 @@ static int kdb_help(int argc, const char **argv) char *space = ""; if (KDB_FLAG(CMD_INTERRUPT)) return 0; - if (!kdb_check_flags(kt->cmd_flags, kdb_cmd_enabled, true)) + if (!kdb_check_flags(kt->flags, kdb_cmd_enabled, true)) continue; - if (strlen(kt->cmd_usage) > 20) + if (strlen(kt->usage) > 20) space = "\n "; - kdb_printf("%-15.15s %-20s%s%s\n", kt->cmd_name, - kt->cmd_usage, space, kt->cmd_help); + kdb_printf("%-15.15s %-20s%s%s\n", kt->name, + kt->usage, space, kt->help); } return 0; } @@ -2633,9 +2631,9 @@ int kdb_register(kdbtab_t *cmd) kdbtab_t *kp; list_for_each_entry(kp, &kdb_cmds_head, list_node) { - if (strcmp(kp->cmd_name, cmd->cmd_name) == 0) { + if (strcmp(kp->name, cmd->name) == 0) { kdb_printf("Duplicate kdb cmd: %s, func %p help %s\n", - cmd->cmd_name, cmd->cmd_func, cmd->cmd_help); + cmd->name, cmd->func, cmd->help); return 1; } } @@ -2672,218 +2670,218 @@ void kdb_unregister(kdbtab_t *cmd) EXPORT_SYMBOL_GPL(kdb_unregister); static kdbtab_t maintab[] = { - { .cmd_name = "md", - .cmd_func = kdb_md, - .cmd_usage = "", - .cmd_help = "Display Memory Contents, also mdWcN, e.g. md8c1", - .cmd_minlen = 1, - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, + { .name = "md", + .func = kdb_md, + .usage = "", + .help = "Display Memory Contents, also mdWcN, e.g. md8c1", + .minlen = 1, + .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "mdr", - .cmd_func = kdb_md, - .cmd_usage = " ", - .cmd_help = "Display Raw Memory", - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, + { .name = "mdr", + .func = kdb_md, + .usage = " ", + .help = "Display Raw Memory", + .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "mdp", - .cmd_func = kdb_md, - .cmd_usage = " ", - .cmd_help = "Display Physical Memory", - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, + { .name = "mdp", + .func = kdb_md, + .usage = " ", + .help = "Display Physical Memory", + .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "mds", - .cmd_func = kdb_md, - .cmd_usage = "", - .cmd_help = "Display Memory Symbolically", - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, + { .name = "mds", + .func = kdb_md, + .usage = "", + .help = "Display Memory Symbolically", + .flags = KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "mm", - .cmd_func = kdb_mm, - .cmd_usage = " ", - .cmd_help = "Modify Memory Contents", - .cmd_flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, + { .name = "mm", + .func = kdb_mm, + .usage = " ", + .help = "Modify Memory Contents", + .flags = KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS, }, - { .cmd_name = "go", - .cmd_func = kdb_go, - .cmd_usage = "[]", - .cmd_help = "Continue Execution", - .cmd_minlen = 1, - .cmd_flags = KDB_ENABLE_REG_WRITE | + { .name = "go", + .func = kdb_go, + .usage = "[]", + .help = "Continue Execution", + .minlen = 1, + .flags = KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, }, - { .cmd_name = "rd", - .cmd_func = kdb_rd, - .cmd_usage = "", - .cmd_help = "Display Registers", - .cmd_flags = KDB_ENABLE_REG_READ, + { .name = "rd", + .func = kdb_rd, + .usage = "", + .help = "Display Registers", + .flags = KDB_ENABLE_REG_READ, }, - { .cmd_name = "rm", - .cmd_func = kdb_rm, - .cmd_usage = " ", - .cmd_help = "Modify Registers", - .cmd_flags = KDB_ENABLE_REG_WRITE, + { .name = "rm", + .func = kdb_rm, + .usage = " ", + .help = "Modify Registers", + .flags = KDB_ENABLE_REG_WRITE, }, - { .cmd_name = "ef", - .cmd_func = kdb_ef, - .cmd_usage = "", - .cmd_help = "Display exception frame", - .cmd_flags = KDB_ENABLE_MEM_READ, + { .name = "ef", + .func = kdb_ef, + .usage = "", + .help = "Display exception frame", + .flags = KDB_ENABLE_MEM_READ, }, - { .cmd_name = "bt", - .cmd_func = kdb_bt, - .cmd_usage = "[]", - .cmd_help = "Stack traceback", - .cmd_minlen = 1, - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, + { .name = "bt", + .func = kdb_bt, + .usage = "[]", + .help = "Stack traceback", + .minlen = 1, + .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, }, - { .cmd_name = "btp", - .cmd_func = kdb_bt, - .cmd_usage = "", - .cmd_help = "Display stack for process ", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "btp", + .func = kdb_bt, + .usage = "", + .help = "Display stack for process ", + .flags = KDB_ENABLE_INSPECT, }, - { .cmd_name = "bta", - .cmd_func = kdb_bt, - .cmd_usage = "[D|R|S|T|C|Z|E|U|I|M|A]", - .cmd_help = "Backtrace all processes matching state flag", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "bta", + .func = kdb_bt, + .usage = "[D|R|S|T|C|Z|E|U|I|M|A]", + .help = "Backtrace all processes matching state flag", + .flags = KDB_ENABLE_INSPECT, }, - { .cmd_name = "btc", - .cmd_func = kdb_bt, - .cmd_usage = "", - .cmd_help = "Backtrace current process on each cpu", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "btc", + .func = kdb_bt, + .usage = "", + .help = "Backtrace current process on each cpu", + .flags = KDB_ENABLE_INSPECT, }, - { .cmd_name = "btt", - .cmd_func = kdb_bt, - .cmd_usage = "", - .cmd_help = "Backtrace process given its struct task address", - .cmd_flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, + { .name = "btt", + .func = kdb_bt, + .usage = "", + .help = "Backtrace process given its struct task address", + .flags = KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS, }, - { .cmd_name = "env", - .cmd_func = kdb_env, - .cmd_usage = "", - .cmd_help = "Show environment variables", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "env", + .func = kdb_env, + .usage = "", + .help = "Show environment variables", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "set", - .cmd_func = kdb_set, - .cmd_usage = "", - .cmd_help = "Set environment variables", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "set", + .func = kdb_set, + .usage = "", + .help = "Set environment variables", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "help", - .cmd_func = kdb_help, - .cmd_usage = "", - .cmd_help = "Display Help Message", - .cmd_minlen = 1, - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "help", + .func = kdb_help, + .usage = "", + .help = "Display Help Message", + .minlen = 1, + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "?", - .cmd_func = kdb_help, - .cmd_usage = "", - .cmd_help = "Display Help Message", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "?", + .func = kdb_help, + .usage = "", + .help = "Display Help Message", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "cpu", - .cmd_func = kdb_cpu, - .cmd_usage = "", - .cmd_help = "Switch to new cpu", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, + { .name = "cpu", + .func = kdb_cpu, + .usage = "", + .help = "Switch to new cpu", + .flags = KDB_ENABLE_ALWAYS_SAFE_NO_ARGS, }, - { .cmd_name = "kgdb", - .cmd_func = kdb_kgdb, - .cmd_usage = "", - .cmd_help = "Enter kgdb mode", - .cmd_flags = 0, + { .name = "kgdb", + .func = kdb_kgdb, + .usage = "", + .help = "Enter kgdb mode", + .flags = 0, }, - { .cmd_name = "ps", - .cmd_func = kdb_ps, - .cmd_usage = "[|A]", - .cmd_help = "Display active task list", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "ps", + .func = kdb_ps, + .usage = "[|A]", + .help = "Display active task list", + .flags = KDB_ENABLE_INSPECT, }, - { .cmd_name = "pid", - .cmd_func = kdb_pid, - .cmd_usage = "", - .cmd_help = "Switch to another task", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "pid", + .func = kdb_pid, + .usage = "", + .help = "Switch to another task", + .flags = KDB_ENABLE_INSPECT, }, - { .cmd_name = "reboot", - .cmd_func = kdb_reboot, - .cmd_usage = "", - .cmd_help = "Reboot the machine immediately", - .cmd_flags = KDB_ENABLE_REBOOT, + { .name = "reboot", + .func = kdb_reboot, + .usage = "", + .help = "Reboot the machine immediately", + .flags = KDB_ENABLE_REBOOT, }, #if defined(CONFIG_MODULES) - { .cmd_name = "lsmod", - .cmd_func = kdb_lsmod, - .cmd_usage = "", - .cmd_help = "List loaded kernel modules", - .cmd_flags = KDB_ENABLE_INSPECT, + { .name = "lsmod", + .func = kdb_lsmod, + .usage = "", + .help = "List loaded kernel modules", + .flags = KDB_ENABLE_INSPECT, }, #endif #if defined(CONFIG_MAGIC_SYSRQ) - { .cmd_name = "sr", - .cmd_func = kdb_sr, - .cmd_usage = "", - .cmd_help = "Magic SysRq key", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "sr", + .func = kdb_sr, + .usage = "", + .help = "Magic SysRq key", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, #endif #if defined(CONFIG_PRINTK) - { .cmd_name = "dmesg", - .cmd_func = kdb_dmesg, - .cmd_usage = "[lines]", - .cmd_help = "Display syslog buffer", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "dmesg", + .func = kdb_dmesg, + .usage = "[lines]", + .help = "Display syslog buffer", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, #endif - { .cmd_name = "defcmd", - .cmd_func = kdb_defcmd, - .cmd_usage = "name \"usage\" \"help\"", - .cmd_help = "Define a set of commands, down to endefcmd", + { .name = "defcmd", + .func = kdb_defcmd, + .usage = "name \"usage\" \"help\"", + .help = "Define a set of commands, down to endefcmd", /* * Macros are always safe because when executed each * internal command re-enters kdb_parse() and is safety * checked individually. */ - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "kill", - .cmd_func = kdb_kill, - .cmd_usage = "<-signal> ", - .cmd_help = "Send a signal to a process", - .cmd_flags = KDB_ENABLE_SIGNAL, + { .name = "kill", + .func = kdb_kill, + .usage = "<-signal> ", + .help = "Send a signal to a process", + .flags = KDB_ENABLE_SIGNAL, }, - { .cmd_name = "summary", - .cmd_func = kdb_summary, - .cmd_usage = "", - .cmd_help = "Summarize the system", - .cmd_minlen = 4, - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "summary", + .func = kdb_summary, + .usage = "", + .help = "Summarize the system", + .minlen = 4, + .flags = KDB_ENABLE_ALWAYS_SAFE, }, - { .cmd_name = "per_cpu", - .cmd_func = kdb_per_cpu, - .cmd_usage = " [] []", - .cmd_help = "Display per_cpu variables", - .cmd_minlen = 3, - .cmd_flags = KDB_ENABLE_MEM_READ, + { .name = "per_cpu", + .func = kdb_per_cpu, + .usage = " [] []", + .help = "Display per_cpu variables", + .minlen = 3, + .flags = KDB_ENABLE_MEM_READ, }, - { .cmd_name = "grephelp", - .cmd_func = kdb_grep_help, - .cmd_usage = "", - .cmd_help = "Display help on | grep", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + { .name = "grephelp", + .func = kdb_grep_help, + .usage = "", + .help = "Display help on | grep", + .flags = KDB_ENABLE_ALWAYS_SAFE, }, }; static kdbtab_t nmicmd = { - .cmd_name = "disable_nmi", - .cmd_func = kdb_disable_nmi, - .cmd_usage = "", - .cmd_help = "Disable NMI entry to KDB", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + .name = "disable_nmi", + .func = kdb_disable_nmi, + .usage = "", + .help = "Disable NMI entry to KDB", + .flags = KDB_ENABLE_ALWAYS_SAFE, }; /* Initialize the kdb command table. */ diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 6c4f92c79e43..59857a1ee44c 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -148,11 +148,11 @@ static int kdb_ftdump(int argc, const char **argv) } static kdbtab_t ftdump_cmd = { - .cmd_name = "ftdump", - .cmd_func = kdb_ftdump, - .cmd_usage = "[skip_#entries] [cpu]", - .cmd_help = "Dump ftrace log; -skip dumps last #entries", - .cmd_flags = KDB_ENABLE_ALWAYS_SAFE, + .name = "ftdump", + .func = kdb_ftdump, + .usage = "[skip_#entries] [cpu]", + .help = "Dump ftrace log; -skip dumps last #entries", + .flags = KDB_ENABLE_ALWAYS_SAFE, }; static __init int kdb_ftrace_register(void) diff --git a/samples/kdb/kdb_hello.c b/samples/kdb/kdb_hello.c index 9ad514a6648b..82736e5a5e32 100644 --- a/samples/kdb/kdb_hello.c +++ b/samples/kdb/kdb_hello.c @@ -29,10 +29,10 @@ static int kdb_hello_cmd(int argc, const char **argv) } static kdbtab_t hello_cmd = { - .cmd_name = "hello", - .cmd_func = kdb_hello_cmd, - .cmd_usage = "[string]", - .cmd_help = "Say Hello World or Hello [string]", + .name = "hello", + .func = kdb_hello_cmd, + .usage = "[string]", + .help = "Say Hello World or Hello [string]", }; static int __init kdb_hello_cmd_init(void) -- cgit v1.2.3-70-g09d2 From 4a803990aeb1582d32e7661e57863cc189a15446 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:56:59 +0800 Subject: dt-bindings: ARM: Mediatek: Add new document bindings of MT8192 clock This patch adds the new binding documentation for system clock and functional clock on Mediatek MT8192. Signed-off-by: Chun-Jie Chen Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210726105719.15793-2-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- .../arm/mediatek/mediatek,mt8192-clock.yaml | 199 +++++++++++++++++++++ .../arm/mediatek/mediatek,mt8192-sys-clock.yaml | 65 +++++++ 2 files changed, 264 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml new file mode 100644 index 000000000000..c8c67c033f8c --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-clock.yaml @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8192-clock.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: MediaTek Functional Clock Controller for MT8192 + +maintainers: + - Chun-Jie Chen + +description: + The Mediatek functional clock controller provides various clocks on MT8192. + +properties: + compatible: + items: + - enum: + - mediatek,mt8192-scp_adsp + - mediatek,mt8192-imp_iic_wrap_c + - mediatek,mt8192-imp_iic_wrap_e + - mediatek,mt8192-imp_iic_wrap_s + - mediatek,mt8192-imp_iic_wrap_ws + - mediatek,mt8192-imp_iic_wrap_w + - mediatek,mt8192-imp_iic_wrap_n + - mediatek,mt8192-msdc_top + - mediatek,mt8192-msdc + - mediatek,mt8192-mfgcfg + - mediatek,mt8192-imgsys + - mediatek,mt8192-imgsys2 + - mediatek,mt8192-vdecsys_soc + - mediatek,mt8192-vdecsys + - mediatek,mt8192-vencsys + - mediatek,mt8192-camsys + - mediatek,mt8192-camsys_rawa + - mediatek,mt8192-camsys_rawb + - mediatek,mt8192-camsys_rawc + - mediatek,mt8192-ipesys + - mediatek,mt8192-mdpsys + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + scp_adsp: clock-controller@10720000 { + compatible = "mediatek,mt8192-scp_adsp"; + reg = <0x10720000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_c: clock-controller@11007000 { + compatible = "mediatek,mt8192-imp_iic_wrap_c"; + reg = <0x11007000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_e: clock-controller@11cb1000 { + compatible = "mediatek,mt8192-imp_iic_wrap_e"; + reg = <0x11cb1000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_s: clock-controller@11d03000 { + compatible = "mediatek,mt8192-imp_iic_wrap_s"; + reg = <0x11d03000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_ws: clock-controller@11d23000 { + compatible = "mediatek,mt8192-imp_iic_wrap_ws"; + reg = <0x11d23000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_w: clock-controller@11e01000 { + compatible = "mediatek,mt8192-imp_iic_wrap_w"; + reg = <0x11e01000 0x1000>; + #clock-cells = <1>; + }; + + - | + imp_iic_wrap_n: clock-controller@11f02000 { + compatible = "mediatek,mt8192-imp_iic_wrap_n"; + reg = <0x11f02000 0x1000>; + #clock-cells = <1>; + }; + + - | + msdc_top: clock-controller@11f10000 { + compatible = "mediatek,mt8192-msdc_top"; + reg = <0x11f10000 0x1000>; + #clock-cells = <1>; + }; + + - | + msdc: clock-controller@11f60000 { + compatible = "mediatek,mt8192-msdc"; + reg = <0x11f60000 0x1000>; + #clock-cells = <1>; + }; + + - | + mfgcfg: clock-controller@13fbf000 { + compatible = "mediatek,mt8192-mfgcfg"; + reg = <0x13fbf000 0x1000>; + #clock-cells = <1>; + }; + + - | + imgsys: clock-controller@15020000 { + compatible = "mediatek,mt8192-imgsys"; + reg = <0x15020000 0x1000>; + #clock-cells = <1>; + }; + + - | + imgsys2: clock-controller@15820000 { + compatible = "mediatek,mt8192-imgsys2"; + reg = <0x15820000 0x1000>; + #clock-cells = <1>; + }; + + - | + vdecsys_soc: clock-controller@1600f000 { + compatible = "mediatek,mt8192-vdecsys_soc"; + reg = <0x1600f000 0x1000>; + #clock-cells = <1>; + }; + + - | + vdecsys: clock-controller@1602f000 { + compatible = "mediatek,mt8192-vdecsys"; + reg = <0x1602f000 0x1000>; + #clock-cells = <1>; + }; + + - | + vencsys: clock-controller@17000000 { + compatible = "mediatek,mt8192-vencsys"; + reg = <0x17000000 0x1000>; + #clock-cells = <1>; + }; + + - | + camsys: clock-controller@1a000000 { + compatible = "mediatek,mt8192-camsys"; + reg = <0x1a000000 0x1000>; + #clock-cells = <1>; + }; + + - | + camsys_rawa: clock-controller@1a04f000 { + compatible = "mediatek,mt8192-camsys_rawa"; + reg = <0x1a04f000 0x1000>; + #clock-cells = <1>; + }; + + - | + camsys_rawb: clock-controller@1a06f000 { + compatible = "mediatek,mt8192-camsys_rawb"; + reg = <0x1a06f000 0x1000>; + #clock-cells = <1>; + }; + + - | + camsys_rawc: clock-controller@1a08f000 { + compatible = "mediatek,mt8192-camsys_rawc"; + reg = <0x1a08f000 0x1000>; + #clock-cells = <1>; + }; + + - | + ipesys: clock-controller@1b000000 { + compatible = "mediatek,mt8192-ipesys"; + reg = <0x1b000000 0x1000>; + #clock-cells = <1>; + }; + + - | + mdpsys: clock-controller@1f000000 { + compatible = "mediatek,mt8192-mdpsys"; + reg = <0x1f000000 0x1000>; + #clock-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml new file mode 100644 index 000000000000..5705bcf1fe47 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8192-sys-clock.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8192-sys-clock.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: MediaTek System Clock Controller for MT8192 + +maintainers: + - Chun-Jie Chen + +description: + The Mediatek system clock controller provides various clocks and system configuration + like reset and bus protection on MT8192. + +properties: + compatible: + items: + - enum: + - mediatek,mt8192-topckgen + - mediatek,mt8192-infracfg + - mediatek,mt8192-pericfg + - mediatek,mt8192-apmixedsys + - const: syscon + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + topckgen: syscon@10000000 { + compatible = "mediatek,mt8192-topckgen", "syscon"; + reg = <0x10000000 0x1000>; + #clock-cells = <1>; + }; + + - | + infracfg: syscon@10001000 { + compatible = "mediatek,mt8192-infracfg", "syscon"; + reg = <0x10001000 0x1000>; + #clock-cells = <1>; + }; + + - | + pericfg: syscon@10003000 { + compatible = "mediatek,mt8192-pericfg", "syscon"; + reg = <0x10003000 0x1000>; + #clock-cells = <1>; + }; + + - | + apmixedsys: syscon@1000c000 { + compatible = "mediatek,mt8192-apmixedsys", "syscon"; + reg = <0x1000c000 0x1000>; + #clock-cells = <1>; + }; -- cgit v1.2.3-70-g09d2 From d18eb76bbd6998d57ca647bb0561e10afa404eef Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:00 +0800 Subject: dt-bindings: ARM: Mediatek: Add mmsys document binding for MT8192 This patch adds the mmsys document binding for MT8192 SoC. Signed-off-by: Chun-Jie Chen Reviewed-by: Chun-Kuang Hu Reviewed-by: Matthias Brugger Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210726105719.15793-3-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt index 78c50733985c..9712a6831fab 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt @@ -16,6 +16,7 @@ Required Properties: - "mediatek,mt8167-mmsys", "syscon" - "mediatek,mt8173-mmsys", "syscon" - "mediatek,mt8183-mmsys", "syscon" + - "mediatek,mt8192-mmsys", "syscon" - #clock-cells: Must be 1 For the clock control, the mmsys controller uses the common clk binding from -- cgit v1.2.3-70-g09d2 From 4af2f62d6fc65e08ca604fab7d7e3beabd927d0d Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:01 +0800 Subject: dt-bindings: ARM: Mediatek: Add audsys document binding for MT8192 This patch adds the audsys document binding for MT8192 SoC. Signed-off-by: Chun-Jie Chen Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210726105719.15793-4-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt index b32d374193c7..699776be1dd3 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.txt @@ -13,6 +13,7 @@ Required Properties: - "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon" - "mediatek,mt8167-audiosys", "syscon" - "mediatek,mt8183-audiosys", "syscon" + - "mediatek,mt8192-audsys", "syscon" - "mediatek,mt8516-audsys", "syscon" - #clock-cells: Must be 1 -- cgit v1.2.3-70-g09d2 From f35f1a23e0e12e3173e9e9dedbc150d139027189 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:02 +0800 Subject: clk: mediatek: Add dt-bindings of MT8192 clocks Add MT8192 clock dt-bindings, include topckgen, apmixedsys, infracfg, pericfg and subsystem clocks. Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210726105719.15793-5-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/mt8192-clk.h | 585 +++++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) create mode 100644 include/dt-bindings/clock/mt8192-clk.h diff --git a/include/dt-bindings/clock/mt8192-clk.h b/include/dt-bindings/clock/mt8192-clk.h new file mode 100644 index 000000000000..5ab68f15a256 --- /dev/null +++ b/include/dt-bindings/clock/mt8192-clk.h @@ -0,0 +1,585 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021 MediaTek Inc. + * Author: Chun-Jie Chen + */ + +#ifndef _DT_BINDINGS_CLK_MT8192_H +#define _DT_BINDINGS_CLK_MT8192_H + +/* TOPCKGEN */ + +#define CLK_TOP_AXI_SEL 0 +#define CLK_TOP_SPM_SEL 1 +#define CLK_TOP_SCP_SEL 2 +#define CLK_TOP_BUS_AXIMEM_SEL 3 +#define CLK_TOP_DISP_SEL 4 +#define CLK_TOP_MDP_SEL 5 +#define CLK_TOP_IMG1_SEL 6 +#define CLK_TOP_IMG2_SEL 7 +#define CLK_TOP_IPE_SEL 8 +#define CLK_TOP_DPE_SEL 9 +#define CLK_TOP_CAM_SEL 10 +#define CLK_TOP_CCU_SEL 11 +#define CLK_TOP_DSP7_SEL 12 +#define CLK_TOP_MFG_REF_SEL 13 +#define CLK_TOP_MFG_PLL_SEL 14 +#define CLK_TOP_CAMTG_SEL 15 +#define CLK_TOP_CAMTG2_SEL 16 +#define CLK_TOP_CAMTG3_SEL 17 +#define CLK_TOP_CAMTG4_SEL 18 +#define CLK_TOP_CAMTG5_SEL 19 +#define CLK_TOP_CAMTG6_SEL 20 +#define CLK_TOP_UART_SEL 21 +#define CLK_TOP_SPI_SEL 22 +#define CLK_TOP_MSDC50_0_H_SEL 23 +#define CLK_TOP_MSDC50_0_SEL 24 +#define CLK_TOP_MSDC30_1_SEL 25 +#define CLK_TOP_MSDC30_2_SEL 26 +#define CLK_TOP_AUDIO_SEL 27 +#define CLK_TOP_AUD_INTBUS_SEL 28 +#define CLK_TOP_PWRAP_ULPOSC_SEL 29 +#define CLK_TOP_ATB_SEL 30 +#define CLK_TOP_DPI_SEL 31 +#define CLK_TOP_SCAM_SEL 32 +#define CLK_TOP_DISP_PWM_SEL 33 +#define CLK_TOP_USB_TOP_SEL 34 +#define CLK_TOP_SSUSB_XHCI_SEL 35 +#define CLK_TOP_I2C_SEL 36 +#define CLK_TOP_SENINF_SEL 37 +#define CLK_TOP_SENINF1_SEL 38 +#define CLK_TOP_SENINF2_SEL 39 +#define CLK_TOP_SENINF3_SEL 40 +#define CLK_TOP_TL_SEL 41 +#define CLK_TOP_DXCC_SEL 42 +#define CLK_TOP_AUD_ENGEN1_SEL 43 +#define CLK_TOP_AUD_ENGEN2_SEL 44 +#define CLK_TOP_AES_UFSFDE_SEL 45 +#define CLK_TOP_UFS_SEL 46 +#define CLK_TOP_AUD_1_SEL 47 +#define CLK_TOP_AUD_2_SEL 48 +#define CLK_TOP_ADSP_SEL 49 +#define CLK_TOP_DPMAIF_MAIN_SEL 50 +#define CLK_TOP_VENC_SEL 51 +#define CLK_TOP_VDEC_SEL 52 +#define CLK_TOP_CAMTM_SEL 53 +#define CLK_TOP_PWM_SEL 54 +#define CLK_TOP_AUDIO_H_SEL 55 +#define CLK_TOP_SPMI_MST_SEL 56 +#define CLK_TOP_AES_MSDCFDE_SEL 57 +#define CLK_TOP_SFLASH_SEL 58 +#define CLK_TOP_APLL_I2S0_M_SEL 59 +#define CLK_TOP_APLL_I2S1_M_SEL 60 +#define CLK_TOP_APLL_I2S2_M_SEL 61 +#define CLK_TOP_APLL_I2S3_M_SEL 62 +#define CLK_TOP_APLL_I2S4_M_SEL 63 +#define CLK_TOP_APLL_I2S5_M_SEL 64 +#define CLK_TOP_APLL_I2S6_M_SEL 65 +#define CLK_TOP_APLL_I2S7_M_SEL 66 +#define CLK_TOP_APLL_I2S8_M_SEL 67 +#define CLK_TOP_APLL_I2S9_M_SEL 68 +#define CLK_TOP_MAINPLL_D3 69 +#define CLK_TOP_MAINPLL_D4 70 +#define CLK_TOP_MAINPLL_D4_D2 71 +#define CLK_TOP_MAINPLL_D4_D4 72 +#define CLK_TOP_MAINPLL_D4_D8 73 +#define CLK_TOP_MAINPLL_D4_D16 74 +#define CLK_TOP_MAINPLL_D5 75 +#define CLK_TOP_MAINPLL_D5_D2 76 +#define CLK_TOP_MAINPLL_D5_D4 77 +#define CLK_TOP_MAINPLL_D5_D8 78 +#define CLK_TOP_MAINPLL_D6 79 +#define CLK_TOP_MAINPLL_D6_D2 80 +#define CLK_TOP_MAINPLL_D6_D4 81 +#define CLK_TOP_MAINPLL_D7 82 +#define CLK_TOP_MAINPLL_D7_D2 83 +#define CLK_TOP_MAINPLL_D7_D4 84 +#define CLK_TOP_MAINPLL_D7_D8 85 +#define CLK_TOP_UNIVPLL_D3 86 +#define CLK_TOP_UNIVPLL_D4 87 +#define CLK_TOP_UNIVPLL_D4_D2 88 +#define CLK_TOP_UNIVPLL_D4_D4 89 +#define CLK_TOP_UNIVPLL_D4_D8 90 +#define CLK_TOP_UNIVPLL_D5 91 +#define CLK_TOP_UNIVPLL_D5_D2 92 +#define CLK_TOP_UNIVPLL_D5_D4 93 +#define CLK_TOP_UNIVPLL_D5_D8 94 +#define CLK_TOP_UNIVPLL_D6 95 +#define CLK_TOP_UNIVPLL_D6_D2 96 +#define CLK_TOP_UNIVPLL_D6_D4 97 +#define CLK_TOP_UNIVPLL_D6_D8 98 +#define CLK_TOP_UNIVPLL_D6_D16 99 +#define CLK_TOP_UNIVPLL_D7 100 +#define CLK_TOP_APLL1 101 +#define CLK_TOP_APLL1_D2 102 +#define CLK_TOP_APLL1_D4 103 +#define CLK_TOP_APLL1_D8 104 +#define CLK_TOP_APLL2 105 +#define CLK_TOP_APLL2_D2 106 +#define CLK_TOP_APLL2_D4 107 +#define CLK_TOP_APLL2_D8 108 +#define CLK_TOP_MMPLL_D4 109 +#define CLK_TOP_MMPLL_D4_D2 110 +#define CLK_TOP_MMPLL_D5 111 +#define CLK_TOP_MMPLL_D5_D2 112 +#define CLK_TOP_MMPLL_D6 113 +#define CLK_TOP_MMPLL_D6_D2 114 +#define CLK_TOP_MMPLL_D7 115 +#define CLK_TOP_MMPLL_D9 116 +#define CLK_TOP_APUPLL 117 +#define CLK_TOP_NPUPLL 118 +#define CLK_TOP_TVDPLL 119 +#define CLK_TOP_TVDPLL_D2 120 +#define CLK_TOP_TVDPLL_D4 121 +#define CLK_TOP_TVDPLL_D8 122 +#define CLK_TOP_TVDPLL_D16 123 +#define CLK_TOP_MSDCPLL 124 +#define CLK_TOP_MSDCPLL_D2 125 +#define CLK_TOP_MSDCPLL_D4 126 +#define CLK_TOP_ULPOSC 127 +#define CLK_TOP_OSC_D2 128 +#define CLK_TOP_OSC_D4 129 +#define CLK_TOP_OSC_D8 130 +#define CLK_TOP_OSC_D10 131 +#define CLK_TOP_OSC_D16 132 +#define CLK_TOP_OSC_D20 133 +#define CLK_TOP_CSW_F26M_D2 134 +#define CLK_TOP_ADSPPLL 135 +#define CLK_TOP_UNIVPLL_192M 136 +#define CLK_TOP_UNIVPLL_192M_D2 137 +#define CLK_TOP_UNIVPLL_192M_D4 138 +#define CLK_TOP_UNIVPLL_192M_D8 139 +#define CLK_TOP_UNIVPLL_192M_D16 140 +#define CLK_TOP_UNIVPLL_192M_D32 141 +#define CLK_TOP_APLL12_DIV0 142 +#define CLK_TOP_APLL12_DIV1 143 +#define CLK_TOP_APLL12_DIV2 144 +#define CLK_TOP_APLL12_DIV3 145 +#define CLK_TOP_APLL12_DIV4 146 +#define CLK_TOP_APLL12_DIVB 147 +#define CLK_TOP_APLL12_DIV5 148 +#define CLK_TOP_APLL12_DIV6 149 +#define CLK_TOP_APLL12_DIV7 150 +#define CLK_TOP_APLL12_DIV8 151 +#define CLK_TOP_APLL12_DIV9 152 +#define CLK_TOP_SSUSB_TOP_REF 153 +#define CLK_TOP_SSUSB_PHY_REF 154 +#define CLK_TOP_NR_CLK 155 + +/* INFRACFG */ + +#define CLK_INFRA_PMIC_TMR 0 +#define CLK_INFRA_PMIC_AP 1 +#define CLK_INFRA_PMIC_MD 2 +#define CLK_INFRA_PMIC_CONN 3 +#define CLK_INFRA_SCPSYS 4 +#define CLK_INFRA_SEJ 5 +#define CLK_INFRA_APXGPT 6 +#define CLK_INFRA_GCE 7 +#define CLK_INFRA_GCE2 8 +#define CLK_INFRA_THERM 9 +#define CLK_INFRA_I2C0 10 +#define CLK_INFRA_AP_DMA_PSEUDO 11 +#define CLK_INFRA_I2C2 12 +#define CLK_INFRA_I2C3 13 +#define CLK_INFRA_PWM_H 14 +#define CLK_INFRA_PWM1 15 +#define CLK_INFRA_PWM2 16 +#define CLK_INFRA_PWM3 17 +#define CLK_INFRA_PWM4 18 +#define CLK_INFRA_PWM 19 +#define CLK_INFRA_UART0 20 +#define CLK_INFRA_UART1 21 +#define CLK_INFRA_UART2 22 +#define CLK_INFRA_UART3 23 +#define CLK_INFRA_GCE_26M 24 +#define CLK_INFRA_CQ_DMA_FPC 25 +#define CLK_INFRA_BTIF 26 +#define CLK_INFRA_SPI0 27 +#define CLK_INFRA_MSDC0 28 +#define CLK_INFRA_MSDC1 29 +#define CLK_INFRA_MSDC2 30 +#define CLK_INFRA_MSDC0_SRC 31 +#define CLK_INFRA_GCPU 32 +#define CLK_INFRA_TRNG 33 +#define CLK_INFRA_AUXADC 34 +#define CLK_INFRA_CPUM 35 +#define CLK_INFRA_CCIF1_AP 36 +#define CLK_INFRA_CCIF1_MD 37 +#define CLK_INFRA_AUXADC_MD 38 +#define CLK_INFRA_PCIE_TL_26M 39 +#define CLK_INFRA_MSDC1_SRC 40 +#define CLK_INFRA_MSDC2_SRC 41 +#define CLK_INFRA_PCIE_TL_96M 42 +#define CLK_INFRA_PCIE_PL_P_250M 43 +#define CLK_INFRA_DEVICE_APC 44 +#define CLK_INFRA_CCIF_AP 45 +#define CLK_INFRA_DEBUGSYS 46 +#define CLK_INFRA_AUDIO 47 +#define CLK_INFRA_CCIF_MD 48 +#define CLK_INFRA_DXCC_SEC_CORE 49 +#define CLK_INFRA_DXCC_AO 50 +#define CLK_INFRA_DBG_TRACE 51 +#define CLK_INFRA_DEVMPU_B 52 +#define CLK_INFRA_DRAMC_F26M 53 +#define CLK_INFRA_IRTX 54 +#define CLK_INFRA_SSUSB 55 +#define CLK_INFRA_DISP_PWM 56 +#define CLK_INFRA_CLDMA_B 57 +#define CLK_INFRA_AUDIO_26M_B 58 +#define CLK_INFRA_MODEM_TEMP_SHARE 59 +#define CLK_INFRA_SPI1 60 +#define CLK_INFRA_I2C4 61 +#define CLK_INFRA_SPI2 62 +#define CLK_INFRA_SPI3 63 +#define CLK_INFRA_UNIPRO_SYS 64 +#define CLK_INFRA_UNIPRO_TICK 65 +#define CLK_INFRA_UFS_MP_SAP_B 66 +#define CLK_INFRA_MD32_B 67 +#define CLK_INFRA_UNIPRO_MBIST 68 +#define CLK_INFRA_I2C5 69 +#define CLK_INFRA_I2C5_ARBITER 70 +#define CLK_INFRA_I2C5_IMM 71 +#define CLK_INFRA_I2C1_ARBITER 72 +#define CLK_INFRA_I2C1_IMM 73 +#define CLK_INFRA_I2C2_ARBITER 74 +#define CLK_INFRA_I2C2_IMM 75 +#define CLK_INFRA_SPI4 76 +#define CLK_INFRA_SPI5 77 +#define CLK_INFRA_CQ_DMA 78 +#define CLK_INFRA_UFS 79 +#define CLK_INFRA_AES_UFSFDE 80 +#define CLK_INFRA_UFS_TICK 81 +#define CLK_INFRA_SSUSB_XHCI 82 +#define CLK_INFRA_MSDC0_SELF 83 +#define CLK_INFRA_MSDC1_SELF 84 +#define CLK_INFRA_MSDC2_SELF 85 +#define CLK_INFRA_UFS_AXI 86 +#define CLK_INFRA_I2C6 87 +#define CLK_INFRA_AP_MSDC0 88 +#define CLK_INFRA_MD_MSDC0 89 +#define CLK_INFRA_CCIF5_AP 90 +#define CLK_INFRA_CCIF5_MD 91 +#define CLK_INFRA_PCIE_TOP_H_133M 92 +#define CLK_INFRA_FLASHIF_TOP_H_133M 93 +#define CLK_INFRA_PCIE_PERI_26M 94 +#define CLK_INFRA_CCIF2_AP 95 +#define CLK_INFRA_CCIF2_MD 96 +#define CLK_INFRA_CCIF3_AP 97 +#define CLK_INFRA_CCIF3_MD 98 +#define CLK_INFRA_SEJ_F13M 99 +#define CLK_INFRA_AES 100 +#define CLK_INFRA_I2C7 101 +#define CLK_INFRA_I2C8 102 +#define CLK_INFRA_FBIST2FPC 103 +#define CLK_INFRA_DEVICE_APC_SYNC 104 +#define CLK_INFRA_DPMAIF_MAIN 105 +#define CLK_INFRA_PCIE_TL_32K 106 +#define CLK_INFRA_CCIF4_AP 107 +#define CLK_INFRA_CCIF4_MD 108 +#define CLK_INFRA_SPI6 109 +#define CLK_INFRA_SPI7 110 +#define CLK_INFRA_133M 111 +#define CLK_INFRA_66M 112 +#define CLK_INFRA_66M_PERI_BUS 113 +#define CLK_INFRA_FREE_DCM_133M 114 +#define CLK_INFRA_FREE_DCM_66M 115 +#define CLK_INFRA_PERI_BUS_DCM_133M 116 +#define CLK_INFRA_PERI_BUS_DCM_66M 117 +#define CLK_INFRA_FLASHIF_PERI_26M 118 +#define CLK_INFRA_FLASHIF_SFLASH 119 +#define CLK_INFRA_AP_DMA 120 +#define CLK_INFRA_NR_CLK 121 + +/* PERICFG */ + +#define CLK_PERI_PERIAXI 0 +#define CLK_PERI_NR_CLK 1 + +/* APMIXEDSYS */ + +#define CLK_APMIXED_MAINPLL 0 +#define CLK_APMIXED_UNIVPLL 1 +#define CLK_APMIXED_USBPLL 2 +#define CLK_APMIXED_MSDCPLL 3 +#define CLK_APMIXED_MMPLL 4 +#define CLK_APMIXED_ADSPPLL 5 +#define CLK_APMIXED_MFGPLL 6 +#define CLK_APMIXED_TVDPLL 7 +#define CLK_APMIXED_APLL1 8 +#define CLK_APMIXED_APLL2 9 +#define CLK_APMIXED_MIPID26M 10 +#define CLK_APMIXED_NR_CLK 11 + +/* SCP_ADSP */ + +#define CLK_SCP_ADSP_AUDIODSP 0 +#define CLK_SCP_ADSP_NR_CLK 1 + +/* IMP_IIC_WRAP_C */ + +#define CLK_IMP_IIC_WRAP_C_I2C10 0 +#define CLK_IMP_IIC_WRAP_C_I2C11 1 +#define CLK_IMP_IIC_WRAP_C_I2C12 2 +#define CLK_IMP_IIC_WRAP_C_I2C13 3 +#define CLK_IMP_IIC_WRAP_C_NR_CLK 4 + +/* AUDSYS */ + +#define CLK_AUD_AFE 0 +#define CLK_AUD_22M 1 +#define CLK_AUD_24M 2 +#define CLK_AUD_APLL2_TUNER 3 +#define CLK_AUD_APLL_TUNER 4 +#define CLK_AUD_TDM 5 +#define CLK_AUD_ADC 6 +#define CLK_AUD_DAC 7 +#define CLK_AUD_DAC_PREDIS 8 +#define CLK_AUD_TML 9 +#define CLK_AUD_NLE 10 +#define CLK_AUD_I2S1_B 11 +#define CLK_AUD_I2S2_B 12 +#define CLK_AUD_I2S3_B 13 +#define CLK_AUD_I2S4_B 14 +#define CLK_AUD_CONNSYS_I2S_ASRC 15 +#define CLK_AUD_GENERAL1_ASRC 16 +#define CLK_AUD_GENERAL2_ASRC 17 +#define CLK_AUD_DAC_HIRES 18 +#define CLK_AUD_ADC_HIRES 19 +#define CLK_AUD_ADC_HIRES_TML 20 +#define CLK_AUD_ADDA6_ADC 21 +#define CLK_AUD_ADDA6_ADC_HIRES 22 +#define CLK_AUD_3RD_DAC 23 +#define CLK_AUD_3RD_DAC_PREDIS 24 +#define CLK_AUD_3RD_DAC_TML 25 +#define CLK_AUD_3RD_DAC_HIRES 26 +#define CLK_AUD_I2S5_B 27 +#define CLK_AUD_I2S6_B 28 +#define CLK_AUD_I2S7_B 29 +#define CLK_AUD_I2S8_B 30 +#define CLK_AUD_I2S9_B 31 +#define CLK_AUD_NR_CLK 32 + +/* IMP_IIC_WRAP_E */ + +#define CLK_IMP_IIC_WRAP_E_I2C3 0 +#define CLK_IMP_IIC_WRAP_E_NR_CLK 1 + +/* IMP_IIC_WRAP_S */ + +#define CLK_IMP_IIC_WRAP_S_I2C7 0 +#define CLK_IMP_IIC_WRAP_S_I2C8 1 +#define CLK_IMP_IIC_WRAP_S_I2C9 2 +#define CLK_IMP_IIC_WRAP_S_NR_CLK 3 + +/* IMP_IIC_WRAP_WS */ + +#define CLK_IMP_IIC_WRAP_WS_I2C1 0 +#define CLK_IMP_IIC_WRAP_WS_I2C2 1 +#define CLK_IMP_IIC_WRAP_WS_I2C4 2 +#define CLK_IMP_IIC_WRAP_WS_NR_CLK 3 + +/* IMP_IIC_WRAP_W */ + +#define CLK_IMP_IIC_WRAP_W_I2C5 0 +#define CLK_IMP_IIC_WRAP_W_NR_CLK 1 + +/* IMP_IIC_WRAP_N */ + +#define CLK_IMP_IIC_WRAP_N_I2C0 0 +#define CLK_IMP_IIC_WRAP_N_I2C6 1 +#define CLK_IMP_IIC_WRAP_N_NR_CLK 2 + +/* MSDC_TOP */ + +#define CLK_MSDC_TOP_AES_0P 0 +#define CLK_MSDC_TOP_SRC_0P 1 +#define CLK_MSDC_TOP_SRC_1P 2 +#define CLK_MSDC_TOP_SRC_2P 3 +#define CLK_MSDC_TOP_P_MSDC0 4 +#define CLK_MSDC_TOP_P_MSDC1 5 +#define CLK_MSDC_TOP_P_MSDC2 6 +#define CLK_MSDC_TOP_P_CFG 7 +#define CLK_MSDC_TOP_AXI 8 +#define CLK_MSDC_TOP_H_MST_0P 9 +#define CLK_MSDC_TOP_H_MST_1P 10 +#define CLK_MSDC_TOP_H_MST_2P 11 +#define CLK_MSDC_TOP_MEM_OFF_DLY_26M 12 +#define CLK_MSDC_TOP_32K 13 +#define CLK_MSDC_TOP_AHB2AXI_BRG_AXI 14 +#define CLK_MSDC_TOP_NR_CLK 15 + +/* MSDC */ + +#define CLK_MSDC_AXI_WRAP 0 +#define CLK_MSDC_NR_CLK 1 + +/* MFGCFG */ + +#define CLK_MFG_BG3D 0 +#define CLK_MFG_NR_CLK 1 + +/* MMSYS */ + +#define CLK_MM_DISP_MUTEX0 0 +#define CLK_MM_DISP_CONFIG 1 +#define CLK_MM_DISP_OVL0 2 +#define CLK_MM_DISP_RDMA0 3 +#define CLK_MM_DISP_OVL0_2L 4 +#define CLK_MM_DISP_WDMA0 5 +#define CLK_MM_DISP_UFBC_WDMA0 6 +#define CLK_MM_DISP_RSZ0 7 +#define CLK_MM_DISP_AAL0 8 +#define CLK_MM_DISP_CCORR0 9 +#define CLK_MM_DISP_DITHER0 10 +#define CLK_MM_SMI_INFRA 11 +#define CLK_MM_DISP_GAMMA0 12 +#define CLK_MM_DISP_POSTMASK0 13 +#define CLK_MM_DISP_DSC_WRAP0 14 +#define CLK_MM_DSI0 15 +#define CLK_MM_DISP_COLOR0 16 +#define CLK_MM_SMI_COMMON 17 +#define CLK_MM_DISP_FAKE_ENG0 18 +#define CLK_MM_DISP_FAKE_ENG1 19 +#define CLK_MM_MDP_TDSHP4 20 +#define CLK_MM_MDP_RSZ4 21 +#define CLK_MM_MDP_AAL4 22 +#define CLK_MM_MDP_HDR4 23 +#define CLK_MM_MDP_RDMA4 24 +#define CLK_MM_MDP_COLOR4 25 +#define CLK_MM_DISP_Y2R0 26 +#define CLK_MM_SMI_GALS 27 +#define CLK_MM_DISP_OVL2_2L 28 +#define CLK_MM_DISP_RDMA4 29 +#define CLK_MM_DISP_DPI0 30 +#define CLK_MM_SMI_IOMMU 31 +#define CLK_MM_DSI_DSI0 32 +#define CLK_MM_DPI_DPI0 33 +#define CLK_MM_26MHZ 34 +#define CLK_MM_32KHZ 35 +#define CLK_MM_NR_CLK 36 + +/* IMGSYS */ + +#define CLK_IMG_LARB9 0 +#define CLK_IMG_LARB10 1 +#define CLK_IMG_DIP 2 +#define CLK_IMG_GALS 3 +#define CLK_IMG_NR_CLK 4 + +/* IMGSYS2 */ + +#define CLK_IMG2_LARB11 0 +#define CLK_IMG2_LARB12 1 +#define CLK_IMG2_MFB 2 +#define CLK_IMG2_WPE 3 +#define CLK_IMG2_MSS 4 +#define CLK_IMG2_GALS 5 +#define CLK_IMG2_NR_CLK 6 + +/* VDECSYS_SOC */ + +#define CLK_VDEC_SOC_LARB1 0 +#define CLK_VDEC_SOC_LAT 1 +#define CLK_VDEC_SOC_LAT_ACTIVE 2 +#define CLK_VDEC_SOC_VDEC 3 +#define CLK_VDEC_SOC_VDEC_ACTIVE 4 +#define CLK_VDEC_SOC_NR_CLK 5 + +/* VDECSYS */ + +#define CLK_VDEC_LARB1 0 +#define CLK_VDEC_LAT 1 +#define CLK_VDEC_LAT_ACTIVE 2 +#define CLK_VDEC_VDEC 3 +#define CLK_VDEC_ACTIVE 4 +#define CLK_VDEC_NR_CLK 5 + +/* VENCSYS */ + +#define CLK_VENC_SET0_LARB 0 +#define CLK_VENC_SET1_VENC 1 +#define CLK_VENC_SET2_JPGENC 2 +#define CLK_VENC_SET5_GALS 3 +#define CLK_VENC_NR_CLK 4 + +/* CAMSYS */ + +#define CLK_CAM_LARB13 0 +#define CLK_CAM_DFP_VAD 1 +#define CLK_CAM_LARB14 2 +#define CLK_CAM_CAM 3 +#define CLK_CAM_CAMTG 4 +#define CLK_CAM_SENINF 5 +#define CLK_CAM_CAMSV0 6 +#define CLK_CAM_CAMSV1 7 +#define CLK_CAM_CAMSV2 8 +#define CLK_CAM_CAMSV3 9 +#define CLK_CAM_CCU0 10 +#define CLK_CAM_CCU1 11 +#define CLK_CAM_MRAW0 12 +#define CLK_CAM_FAKE_ENG 13 +#define CLK_CAM_CCU_GALS 14 +#define CLK_CAM_CAM2MM_GALS 15 +#define CLK_CAM_NR_CLK 16 + +/* CAMSYS_RAWA */ + +#define CLK_CAM_RAWA_LARBX 0 +#define CLK_CAM_RAWA_CAM 1 +#define CLK_CAM_RAWA_CAMTG 2 +#define CLK_CAM_RAWA_NR_CLK 3 + +/* CAMSYS_RAWB */ + +#define CLK_CAM_RAWB_LARBX 0 +#define CLK_CAM_RAWB_CAM 1 +#define CLK_CAM_RAWB_CAMTG 2 +#define CLK_CAM_RAWB_NR_CLK 3 + +/* CAMSYS_RAWC */ + +#define CLK_CAM_RAWC_LARBX 0 +#define CLK_CAM_RAWC_CAM 1 +#define CLK_CAM_RAWC_CAMTG 2 +#define CLK_CAM_RAWC_NR_CLK 3 + +/* IPESYS */ + +#define CLK_IPE_LARB19 0 +#define CLK_IPE_LARB20 1 +#define CLK_IPE_SMI_SUBCOM 2 +#define CLK_IPE_FD 3 +#define CLK_IPE_FE 4 +#define CLK_IPE_RSC 5 +#define CLK_IPE_DPE 6 +#define CLK_IPE_GALS 7 +#define CLK_IPE_NR_CLK 8 + +/* MDPSYS */ + +#define CLK_MDP_RDMA0 0 +#define CLK_MDP_TDSHP0 1 +#define CLK_MDP_IMG_DL_ASYNC0 2 +#define CLK_MDP_IMG_DL_ASYNC1 3 +#define CLK_MDP_RDMA1 4 +#define CLK_MDP_TDSHP1 5 +#define CLK_MDP_SMI0 6 +#define CLK_MDP_APB_BUS 7 +#define CLK_MDP_WROT0 8 +#define CLK_MDP_RSZ0 9 +#define CLK_MDP_HDR0 10 +#define CLK_MDP_MUTEX0 11 +#define CLK_MDP_WROT1 12 +#define CLK_MDP_RSZ1 13 +#define CLK_MDP_HDR1 14 +#define CLK_MDP_FAKE_ENG0 15 +#define CLK_MDP_AAL0 16 +#define CLK_MDP_AAL1 17 +#define CLK_MDP_COLOR0 18 +#define CLK_MDP_COLOR1 19 +#define CLK_MDP_IMG_DL_RELAY0_ASYNC0 20 +#define CLK_MDP_IMG_DL_RELAY1_ASYNC1 21 +#define CLK_MDP_NR_CLK 22 + +#endif /* _DT_BINDINGS_CLK_MT8192_H */ -- cgit v1.2.3-70-g09d2 From 197ee5436be5e4c8b55d7d0f449db8c8a81d22b3 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:03 +0800 Subject: clk: mediatek: Get regmap without syscon compatible check Not all clock providers need to be marked compatible with "syscon" for system configuration usage, so use device_node_to_regmap() to skip "syscon" check. Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-6-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-cpumux.c | 2 +- drivers/clk/mediatek/clk-mtk.c | 2 +- drivers/clk/mediatek/clk-mux.c | 2 +- drivers/clk/mediatek/reset.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index 79fe09028742..61eeae4e60fb 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -84,7 +84,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node, struct clk *clk; struct regmap *regmap; - regmap = syscon_node_to_regmap(node); + regmap = device_node_to_regmap(node); if (IS_ERR(regmap)) { pr_err("Cannot find regmap for %pOF: %ld\n", node, PTR_ERR(regmap)); diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index cec1c8a27211..37d2aa32175e 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -106,7 +106,7 @@ int mtk_clk_register_gates_with_dev(struct device_node *node, if (!clk_data) return -ENOMEM; - regmap = syscon_node_to_regmap(node); + regmap = device_node_to_regmap(node); if (IS_ERR(regmap)) { pr_err("Cannot find regmap for %pOF: %ld\n", node, PTR_ERR(regmap)); diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index b0c61709bacc..e97d58db28cc 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -165,7 +165,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes, struct clk *clk; int i; - regmap = syscon_node_to_regmap(node); + regmap = device_node_to_regmap(node); if (IS_ERR(regmap)) { pr_err("Cannot find regmap for %pOF: %ld\n", node, PTR_ERR(regmap)); diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index cb939c071b0c..e562dc3c10a4 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -98,7 +98,7 @@ static void mtk_register_reset_controller_common(struct device_node *np, int ret; struct regmap *regmap; - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) { pr_err("Cannot find regmap for %pOF: %ld\n", np, PTR_ERR(regmap)); -- cgit v1.2.3-70-g09d2 From 7cc4e1bbe300c5cf610ece8eca6c6751b8bc74db Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:04 +0800 Subject: clk: mediatek: Fix asymmetrical PLL enable and disable control In fact, the en_mask is a combination of divider enable mask and pll enable bit(bit0). Before this patch, we enabled both divider mask and bit0 in prepare(), but only cleared the bit0 in unprepare(). In the future, we hope en_mask will only be used as divider enable mask. The enable register(CON0) will be set in 2 steps: first is divider mask, and then bit0 during prepare(), and vice versa. But considering backward compatibility, at this stage we allow en_mask to be a combination or a pure divider enable mask. And then we will make en_mask a pure divider enable mask in another following patch series. Reviewed-by: Ikjoon Jang Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-7-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-pll.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index f440f2cd0b69..11ed5d1d1c36 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -238,6 +238,7 @@ static int mtk_pll_prepare(struct clk_hw *hw) { struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); u32 r; + u32 div_en_mask; r = readl(pll->pwr_addr) | CON0_PWR_ON; writel(r, pll->pwr_addr); @@ -247,10 +248,15 @@ static int mtk_pll_prepare(struct clk_hw *hw) writel(r, pll->pwr_addr); udelay(1); - r = readl(pll->base_addr + REG_CON0); - r |= pll->data->en_mask; + r = readl(pll->base_addr + REG_CON0) | CON0_BASE_EN; writel(r, pll->base_addr + REG_CON0); + div_en_mask = pll->data->en_mask & ~CON0_BASE_EN; + if (div_en_mask) { + r = readl(pll->base_addr + REG_CON0) | div_en_mask; + writel(r, pll->base_addr + REG_CON0); + } + __mtk_pll_tuner_enable(pll); udelay(20); @@ -268,6 +274,7 @@ static void mtk_pll_unprepare(struct clk_hw *hw) { struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); u32 r; + u32 div_en_mask; if (pll->data->flags & HAVE_RST_BAR) { r = readl(pll->base_addr + REG_CON0); @@ -277,8 +284,13 @@ static void mtk_pll_unprepare(struct clk_hw *hw) __mtk_pll_tuner_disable(pll); - r = readl(pll->base_addr + REG_CON0); - r &= ~CON0_BASE_EN; + div_en_mask = pll->data->en_mask & ~CON0_BASE_EN; + if (div_en_mask) { + r = readl(pll->base_addr + REG_CON0) & ~div_en_mask; + writel(r, pll->base_addr + REG_CON0); + } + + r = readl(pll->base_addr + REG_CON0) & ~CON0_BASE_EN; writel(r, pll->base_addr + REG_CON0); r = readl(pll->pwr_addr) | CON0_ISO_EN; -- cgit v1.2.3-70-g09d2 From f384c44754b7de2eceb0789a8837a11b0a80cdba Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:05 +0800 Subject: clk: mediatek: Add configurable enable control to mtk_pll_data In all MediaTek PLL design, bit0 of CON0 register is always the enable bit. However, there's a special case of usbpll on MT8192. The enable bit of usbpll is moved to bit2 of other register. Add configurable en_reg and pll_en_bit for enable control or default 0 where pll data are static variables. Hence, CON0_BASE_EN could also be removed. And there might have another special case on other chips, the enable bit is still on CON0 register but not at bit0. Reviewed-by: Ikjoon Jang Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-8-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mtk.h | 20 +++++++++++--------- drivers/clk/mediatek/clk-pll.c | 15 ++++++++++----- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index c3d6756b0c7e..31c7cb304508 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -213,13 +213,13 @@ struct mtk_pll_div_table { struct mtk_pll_data { int id; const char *name; - uint32_t reg; - uint32_t pwr_reg; - uint32_t en_mask; - uint32_t pd_reg; - uint32_t tuner_reg; - uint32_t tuner_en_reg; - uint8_t tuner_en_bit; + u32 reg; + u32 pwr_reg; + u32 en_mask; + u32 pd_reg; + u32 tuner_reg; + u32 tuner_en_reg; + u8 tuner_en_bit; int pd_shift; unsigned int flags; const struct clk_ops *ops; @@ -228,11 +228,13 @@ struct mtk_pll_data { unsigned long fmax; int pcwbits; int pcwibits; - uint32_t pcw_reg; + u32 pcw_reg; int pcw_shift; - uint32_t pcw_chg_reg; + u32 pcw_chg_reg; const struct mtk_pll_div_table *div_table; const char *parent_name; + u32 en_reg; + u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */ }; void mtk_clk_register_plls(struct device_node *node, diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 11ed5d1d1c36..7fb001a4e7d8 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -44,6 +44,7 @@ struct mtk_clk_pll { void __iomem *tuner_en_addr; void __iomem *pcw_addr; void __iomem *pcw_chg_addr; + void __iomem *en_addr; const struct mtk_pll_data *data; }; @@ -56,7 +57,7 @@ static int mtk_pll_is_prepared(struct clk_hw *hw) { struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); - return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0; + return (readl(pll->en_addr) & BIT(pll->data->pll_en_bit)) != 0; } static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin, @@ -248,8 +249,8 @@ static int mtk_pll_prepare(struct clk_hw *hw) writel(r, pll->pwr_addr); udelay(1); - r = readl(pll->base_addr + REG_CON0) | CON0_BASE_EN; - writel(r, pll->base_addr + REG_CON0); + r = readl(pll->en_addr) | BIT(pll->data->pll_en_bit); + writel(r, pll->en_addr); div_en_mask = pll->data->en_mask & ~CON0_BASE_EN; if (div_en_mask) { @@ -290,8 +291,8 @@ static void mtk_pll_unprepare(struct clk_hw *hw) writel(r, pll->base_addr + REG_CON0); } - r = readl(pll->base_addr + REG_CON0) & ~CON0_BASE_EN; - writel(r, pll->base_addr + REG_CON0); + r = readl(pll->en_addr) & ~BIT(pll->data->pll_en_bit); + writel(r, pll->en_addr); r = readl(pll->pwr_addr) | CON0_ISO_EN; writel(r, pll->pwr_addr); @@ -333,6 +334,10 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data, pll->tuner_addr = base + data->tuner_reg; if (data->tuner_en_reg) pll->tuner_en_addr = base + data->tuner_en_reg; + if (data->en_reg) + pll->en_addr = base + data->en_reg; + else + pll->en_addr = pll->base_addr + REG_CON0; pll->hw.init = &init; pll->data = data; -- cgit v1.2.3-70-g09d2 From c58cd0e40ffac67961b945793876b973728f9b80 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:06 +0800 Subject: clk: mediatek: Add mtk_clk_simple_probe() to simplify clock providers Most of subsystem clock providers only need to register clock gates in their probe() function. To reduce the duplicated code by add a generic function. Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-9-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mtk.c | 23 +++++++++++++++++++++++ drivers/clk/mediatek/clk-mtk.h | 8 ++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 37d2aa32175e..4b6096c44d74 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "clk-mtk.h" #include "clk-gate.h" @@ -286,3 +287,25 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, clk_data->clks[mcd->id] = clk; } } + +int mtk_clk_simple_probe(struct platform_device *pdev) +{ + const struct mtk_clk_desc *mcd; + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + mcd = of_device_get_match_data(&pdev->dev); + if (!mcd) + return -EINVAL; + + clk_data = mtk_alloc_clk_data(mcd->num_clks); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 31c7cb304508..7de41c3b3206 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -10,6 +10,7 @@ #include #include #include +#include struct clk; struct clk_onecell_data; @@ -250,4 +251,11 @@ void mtk_register_reset_controller(struct device_node *np, void mtk_register_reset_controller_set_clr(struct device_node *np, unsigned int num_regs, int regofs); +struct mtk_clk_desc { + const struct mtk_gate *clks; + size_t num_clks; +}; + +int mtk_clk_simple_probe(struct platform_device *pdev); + #endif /* __DRV_CLK_MTK_H */ -- cgit v1.2.3-70-g09d2 From 710573dee31b4ca34abeb384c6e3db499c0af65f Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:07 +0800 Subject: clk: mediatek: Add MT8192 basic clocks support Add MT8192 basic clock providers, include topckgen, apmixedsys, infracfg and pericfg. Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-10-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 8 + drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192.c | 1326 +++++++++++++++++++++++++++++++++++++ drivers/clk/mediatek/clk-mux.c | 9 +- drivers/clk/mediatek/clk-mux.h | 18 +- 5 files changed, 1358 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/mediatek/clk-mt8192.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 886e2d9fced5..6075b48377d5 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -500,6 +500,14 @@ config COMMON_CLK_MT8183_VENCSYS help This driver supports MediaTek MT8183 vencsys clocks. +config COMMON_CLK_MT8192 + bool "Clock driver for MediaTek MT8192" + depends on ARM64 || COMPILE_TEST + select COMMON_CLK_MEDIATEK + default ARM64 + help + This driver supports MediaTek MT8192 basic clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 3b0c2be73824..fcde42160720 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -67,5 +67,6 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o +obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c new file mode 100644 index 000000000000..cbc7c6dbe0f4 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192.c @@ -0,0 +1,1326 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-mux.h" +#include "clk-gate.h" + +#include + +static DEFINE_SPINLOCK(mt8192_clk_lock); + +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CLK_TOP_ULPOSC, "ulposc", NULL, 260000000), +}; + +static const struct mtk_fixed_factor top_early_divs[] = { + FACTOR(CLK_TOP_CSW_F26M_D2, "csw_f26m_d2", "clk26m", 1, 2), +}; + +static const struct mtk_fixed_factor top_divs[] = { + FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3), + FACTOR(CLK_TOP_MAINPLL_D4, "mainpll_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D4_D2, "mainpll_d4_d2", "mainpll_d4", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D4_D4, "mainpll_d4_d4", "mainpll_d4", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D4_D8, "mainpll_d4_d8", "mainpll_d4", 1, 8), + FACTOR(CLK_TOP_MAINPLL_D4_D16, "mainpll_d4_d16", "mainpll_d4", 1, 16), + FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D5_D8, "mainpll_d5_d8", "mainpll_d5", 1, 8), + FACTOR(CLK_TOP_MAINPLL_D6, "mainpll_d6", "mainpll", 1, 6), + FACTOR(CLK_TOP_MAINPLL_D6_D2, "mainpll_d6_d2", "mainpll_d6", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D6_D4, "mainpll_d6_d4", "mainpll_d6", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7), + FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2), + FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4), + FACTOR(CLK_TOP_MAINPLL_D7_D8, "mainpll_d7_d8", "mainpll_d7", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), + FACTOR(CLK_TOP_UNIVPLL_D4, "univpll_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D4_D2, "univpll_d4_d2", "univpll_d4", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D4_D4, "univpll_d4_d4", "univpll_d4", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D4_D8, "univpll_d4_d8", "univpll_d4", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D5_D8, "univpll_d5_d8", "univpll_d5", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D6, "univpll_d6", "univpll", 1, 6), + FACTOR(CLK_TOP_UNIVPLL_D6_D2, "univpll_d6_d2", "univpll_d6", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D6_D4, "univpll_d6_d4", "univpll_d6", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D6_D8, "univpll_d6_d8", "univpll_d6", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_D6_D16, "univpll_d6_d16", "univpll_d6", 1, 16), + FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7), + FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1), + FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1, 2), + FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4), + FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1, 8), + FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1), + FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2), + FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4), + FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1, 8), + FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4), + FACTOR(CLK_TOP_MMPLL_D4_D2, "mmpll_d4_d2", "mmpll_d4", 1, 2), + FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5), + FACTOR(CLK_TOP_MMPLL_D5_D2, "mmpll_d5_d2", "mmpll_d5", 1, 2), + FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll", 1, 6), + FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll_d6", 1, 2), + FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7), + FACTOR(CLK_TOP_MMPLL_D9, "mmpll_d9", "mmpll", 1, 9), + FACTOR(CLK_TOP_APUPLL, "apupll_ck", "apupll", 1, 2), + FACTOR(CLK_TOP_NPUPLL, "npupll_ck", "npupll", 1, 1), + FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll", 1, 1), + FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2), + FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), + FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1, 8), + FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1, 16), + FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1), + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), + FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), + FACTOR(CLK_TOP_OSC_D2, "osc_d2", "ulposc", 1, 2), + FACTOR(CLK_TOP_OSC_D4, "osc_d4", "ulposc", 1, 4), + FACTOR(CLK_TOP_OSC_D8, "osc_d8", "ulposc", 1, 8), + FACTOR(CLK_TOP_OSC_D10, "osc_d10", "ulposc", 1, 10), + FACTOR(CLK_TOP_OSC_D16, "osc_d16", "ulposc", 1, 16), + FACTOR(CLK_TOP_OSC_D20, "osc_d20", "ulposc", 1, 20), + FACTOR(CLK_TOP_ADSPPLL, "adsppll_ck", "adsppll", 1, 1), + FACTOR(CLK_TOP_UNIVPLL_192M, "univpll_192m", "univpll", 1, 13), + FACTOR(CLK_TOP_UNIVPLL_192M_D2, "univpll_192m_d2", "univpll_192m", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4", "univpll_192m", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8", "univpll_192m", 1, 8), + FACTOR(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16", "univpll_192m", 1, 16), + FACTOR(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32", "univpll_192m", 1, 32), +}; + +static const char * const axi_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d7_d2", + "mainpll_d4_d2", + "mainpll_d5_d2", + "mainpll_d6_d2", + "osc_d4" +}; + +static const char * const spm_parents[] = { + "clk26m", + "osc_d10", + "mainpll_d7_d4", + "clk32k" +}; + +static const char * const scp_parents[] = { + "clk26m", + "univpll_d5", + "mainpll_d6_d2", + "mainpll_d6", + "univpll_d6", + "mainpll_d4_d2", + "mainpll_d5_d2", + "univpll_d4_d2" +}; + +static const char * const bus_aximem_parents[] = { + "clk26m", + "mainpll_d7_d2", + "mainpll_d4_d2", + "mainpll_d5_d2", + "mainpll_d6" +}; + +static const char * const disp_parents[] = { + "clk26m", + "univpll_d6_d2", + "mainpll_d5_d2", + "mmpll_d6_d2", + "univpll_d5_d2", + "univpll_d4_d2", + "mmpll_d7", + "univpll_d6", + "mainpll_d4", + "mmpll_d5_d2" +}; + +static const char * const mdp_parents[] = { + "clk26m", + "mainpll_d5_d2", + "mmpll_d6_d2", + "mainpll_d4_d2", + "mmpll_d4_d2", + "mainpll_d6", + "univpll_d6", + "mainpll_d4", + "tvdpll_ck", + "univpll_d4", + "mmpll_d5_d2" +}; + +static const char * const img1_parents[] = { + "clk26m", + "univpll_d4", + "tvdpll_ck", + "mainpll_d4", + "univpll_d5", + "mmpll_d6", + "univpll_d6", + "mainpll_d6", + "mmpll_d4_d2", + "mainpll_d4_d2", + "mmpll_d6_d2", + "mmpll_d5_d2" +}; + +static const char * const img2_parents[] = { + "clk26m", + "univpll_d4", + "tvdpll_ck", + "mainpll_d4", + "univpll_d5", + "mmpll_d6", + "univpll_d6", + "mainpll_d6", + "mmpll_d4_d2", + "mainpll_d4_d2", + "mmpll_d6_d2", + "mmpll_d5_d2" +}; + +static const char * const ipe_parents[] = { + "clk26m", + "mainpll_d4", + "mmpll_d6", + "univpll_d6", + "mainpll_d6", + "univpll_d4_d2", + "mainpll_d4_d2", + "mmpll_d6_d2", + "mmpll_d5_d2" +}; + +static const char * const dpe_parents[] = { + "clk26m", + "mainpll_d4", + "mmpll_d6", + "univpll_d6", + "mainpll_d6", + "univpll_d4_d2", + "univpll_d5_d2", + "mmpll_d6_d2" +}; + +static const char * const cam_parents[] = { + "clk26m", + "mainpll_d4", + "mmpll_d6", + "univpll_d4", + "univpll_d5", + "univpll_d6", + "mmpll_d7", + "univpll_d4_d2", + "mainpll_d4_d2", + "univpll_d6_d2" +}; + +static const char * const ccu_parents[] = { + "clk26m", + "mainpll_d4", + "mmpll_d6", + "mainpll_d6", + "mmpll_d7", + "univpll_d4_d2", + "mmpll_d6_d2", + "mmpll_d5_d2", + "univpll_d5", + "univpll_d6_d2" +}; + +static const char * const dsp7_parents[] = { + "clk26m", + "mainpll_d4_d2", + "mainpll_d6", + "mmpll_d6", + "univpll_d5", + "mmpll_d5", + "univpll_d4", + "mmpll_d4" +}; + +static const char * const mfg_ref_parents[] = { + "clk26m", + "clk26m", + "univpll_d6", + "mainpll_d5_d2" +}; + +static const char * const mfg_pll_parents[] = { + "mfg_ref_sel", + "mfgpll" +}; + +static const char * const camtg_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg2_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg3_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg4_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg5_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const camtg6_parents[] = { + "clk26m", + "univpll_192m_d8", + "univpll_d6_d8", + "univpll_192m_d4", + "univpll_d6_d16", + "csw_f26m_d2", + "univpll_192m_d16", + "univpll_192m_d32" +}; + +static const char * const uart_parents[] = { + "clk26m", + "univpll_d6_d8" +}; + +static const char * const spi_parents[] = { + "clk26m", + "mainpll_d5_d4", + "mainpll_d6_d4", + "msdcpll_d4" +}; + +static const char * const msdc50_0_h_parents[] = { + "clk26m", + "mainpll_d4_d2", + "mainpll_d6_d2" +}; + +static const char * const msdc50_0_parents[] = { + "clk26m", + "msdcpll_ck", + "msdcpll_d2", + "univpll_d4_d4", + "mainpll_d6_d2", + "univpll_d4_d2" +}; + +static const char * const msdc30_1_parents[] = { + "clk26m", + "univpll_d6_d2", + "mainpll_d6_d2", + "mainpll_d7_d2", + "msdcpll_d2" +}; + +static const char * const msdc30_2_parents[] = { + "clk26m", + "univpll_d6_d2", + "mainpll_d6_d2", + "mainpll_d7_d2", + "msdcpll_d2" +}; + +static const char * const audio_parents[] = { + "clk26m", + "mainpll_d5_d8", + "mainpll_d7_d8", + "mainpll_d4_d16" +}; + +static const char * const aud_intbus_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d7_d4" +}; + +static const char * const pwrap_ulposc_parents[] = { + "osc_d10", + "clk26m", + "osc_d4", + "osc_d8", + "osc_d16" +}; + +static const char * const atb_parents[] = { + "clk26m", + "mainpll_d4_d2", + "mainpll_d5_d2" +}; + +static const char * const dpi_parents[] = { + "clk26m", + "tvdpll_d2", + "tvdpll_d4", + "tvdpll_d8", + "tvdpll_d16" +}; + +static const char * const scam_parents[] = { + "clk26m", + "mainpll_d5_d4" +}; + +static const char * const disp_pwm_parents[] = { + "clk26m", + "univpll_d6_d4", + "osc_d2", + "osc_d4", + "osc_d16" +}; + +static const char * const usb_top_parents[] = { + "clk26m", + "univpll_d5_d4", + "univpll_d6_d4", + "univpll_d5_d2" +}; + +static const char * const ssusb_xhci_parents[] = { + "clk26m", + "univpll_d5_d4", + "univpll_d6_d4", + "univpll_d5_d2" +}; + +static const char * const i2c_parents[] = { + "clk26m", + "mainpll_d4_d8", + "univpll_d5_d4" +}; + +static const char * const seninf_parents[] = { + "clk26m", + "univpll_d4_d4", + "univpll_d6_d2", + "univpll_d4_d2", + "univpll_d7", + "univpll_d6", + "mmpll_d6", + "univpll_d5" +}; + +static const char * const seninf1_parents[] = { + "clk26m", + "univpll_d4_d4", + "univpll_d6_d2", + "univpll_d4_d2", + "univpll_d7", + "univpll_d6", + "mmpll_d6", + "univpll_d5" +}; + +static const char * const seninf2_parents[] = { + "clk26m", + "univpll_d4_d4", + "univpll_d6_d2", + "univpll_d4_d2", + "univpll_d7", + "univpll_d6", + "mmpll_d6", + "univpll_d5" +}; + +static const char * const seninf3_parents[] = { + "clk26m", + "univpll_d4_d4", + "univpll_d6_d2", + "univpll_d4_d2", + "univpll_d7", + "univpll_d6", + "mmpll_d6", + "univpll_d5" +}; + +static const char * const tl_parents[] = { + "clk26m", + "univpll_192m_d2", + "mainpll_d6_d4" +}; + +static const char * const dxcc_parents[] = { + "clk26m", + "mainpll_d4_d2", + "mainpll_d4_d4", + "mainpll_d4_d8" +}; + +static const char * const aud_engen1_parents[] = { + "clk26m", + "apll1_d2", + "apll1_d4", + "apll1_d8" +}; + +static const char * const aud_engen2_parents[] = { + "clk26m", + "apll2_d2", + "apll2_d4", + "apll2_d8" +}; + +static const char * const aes_ufsfde_parents[] = { + "clk26m", + "mainpll_d4", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d4_d4", + "univpll_d4_d2", + "univpll_d6" +}; + +static const char * const ufs_parents[] = { + "clk26m", + "mainpll_d4_d4", + "mainpll_d4_d8", + "univpll_d4_d4", + "mainpll_d6_d2", + "mainpll_d5_d2", + "msdcpll_d2" +}; + +static const char * const aud_1_parents[] = { + "clk26m", + "apll1_ck" +}; + +static const char * const aud_2_parents[] = { + "clk26m", + "apll2_ck" +}; + +static const char * const adsp_parents[] = { + "clk26m", + "mainpll_d6", + "mainpll_d5_d2", + "univpll_d4_d4", + "univpll_d4", + "univpll_d6", + "ulposc", + "adsppll_ck" +}; + +static const char * const dpmaif_main_parents[] = { + "clk26m", + "univpll_d4_d4", + "mainpll_d6", + "mainpll_d4_d2", + "univpll_d4_d2" +}; + +static const char * const venc_parents[] = { + "clk26m", + "mmpll_d7", + "mainpll_d6", + "univpll_d4_d2", + "mainpll_d4_d2", + "univpll_d6", + "mmpll_d6", + "mainpll_d5_d2", + "mainpll_d6_d2", + "mmpll_d9", + "univpll_d4_d4", + "mainpll_d4", + "univpll_d4", + "univpll_d5", + "univpll_d5_d2", + "mainpll_d5" +}; + +static const char * const vdec_parents[] = { + "clk26m", + "univpll_192m_d2", + "univpll_d5_d4", + "mainpll_d5", + "mainpll_d5_d2", + "mmpll_d6_d2", + "univpll_d5_d2", + "mainpll_d4_d2", + "univpll_d4_d2", + "univpll_d7", + "mmpll_d7", + "mmpll_d6", + "univpll_d5", + "mainpll_d4", + "univpll_d4", + "univpll_d6" +}; + +static const char * const camtm_parents[] = { + "clk26m", + "univpll_d7", + "univpll_d6_d2", + "univpll_d4_d2" +}; + +static const char * const pwm_parents[] = { + "clk26m", + "univpll_d4_d8" +}; + +static const char * const audio_h_parents[] = { + "clk26m", + "univpll_d7", + "apll1_ck", + "apll2_ck" +}; + +static const char * const spmi_mst_parents[] = { + "clk26m", + "csw_f26m_d2", + "osc_d8", + "osc_d10", + "osc_d16", + "osc_d20", + "clk32k" +}; + +static const char * const aes_msdcfde_parents[] = { + "clk26m", + "mainpll_d4_d2", + "mainpll_d6", + "mainpll_d4_d4", + "univpll_d4_d2", + "univpll_d6" +}; + +static const char * const sflash_parents[] = { + "clk26m", + "mainpll_d7_d8", + "univpll_d6_d8", + "univpll_d5_d8" +}; + +static const char * const apll_i2s0_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s1_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s2_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s3_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s4_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s5_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s6_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s7_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s8_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +static const char * const apll_i2s9_m_parents[] = { + "aud_1_sel", + "aud_2_sel" +}; + +/* + * CRITICAL CLOCK: + * axi_sel is the main bus clock of whole SOC. + * spm_sel is the clock of the always-on co-processor. + * bus_aximem_sel is clock of the bus that access emi. + */ +static const struct mtk_mux top_mtk_muxes[] = { + /* CLK_CFG_0 */ + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", + axi_parents, 0x010, 0x014, 0x018, 0, 3, 7, 0x004, 0, + CLK_IS_CRITICAL), + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM_SEL, "spm_sel", + spm_parents, 0x010, 0x014, 0x018, 8, 2, 15, 0x004, 1, + CLK_IS_CRITICAL), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", + scp_parents, 0x010, 0x014, 0x018, 16, 3, 23, 0x004, 2), + MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_BUS_AXIMEM_SEL, "bus_aximem_sel", + bus_aximem_parents, 0x010, 0x014, 0x018, 24, 3, 31, 0x004, 3, + CLK_IS_CRITICAL), + /* CLK_CFG_1 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_SEL, "disp_sel", + disp_parents, 0x020, 0x024, 0x028, 0, 4, 7, 0x004, 4), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MDP_SEL, "mdp_sel", + mdp_parents, 0x020, 0x024, 0x028, 8, 4, 15, 0x004, 5), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG1_SEL, "img1_sel", + img1_parents, 0x020, 0x024, 0x028, 16, 4, 23, 0x004, 6), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG2_SEL, "img2_sel", + img2_parents, 0x020, 0x024, 0x028, 24, 4, 31, 0x004, 7), + /* CLK_CFG_2 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE_SEL, "ipe_sel", + ipe_parents, 0x030, 0x034, 0x038, 0, 4, 7, 0x004, 8), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPE_SEL, "dpe_sel", + dpe_parents, 0x030, 0x034, 0x038, 8, 3, 15, 0x004, 9), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM_SEL, "cam_sel", + cam_parents, 0x030, 0x034, 0x038, 16, 4, 23, 0x004, 10), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CCU_SEL, "ccu_sel", + ccu_parents, 0x030, 0x034, 0x038, 24, 4, 31, 0x004, 11), + /* CLK_CFG_4 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DSP7_SEL, "dsp7_sel", + dsp7_parents, 0x050, 0x054, 0x058, 0, 3, 7, 0x004, 16), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_REF_SEL, "mfg_ref_sel", + mfg_ref_parents, 0x050, 0x054, 0x058, 16, 2, 23, 0x004, 18), + MUX_CLR_SET_UPD(CLK_TOP_MFG_PLL_SEL, "mfg_pll_sel", + mfg_pll_parents, 0x050, 0x054, 0x058, 18, 1, -1, -1), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel", + camtg_parents, 0x050, 0x054, 0x058, 24, 3, 31, 0x004, 19), + /* CLK_CFG_5 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2_SEL, "camtg2_sel", + camtg2_parents, 0x060, 0x064, 0x068, 0, 3, 7, 0x004, 20), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3_SEL, "camtg3_sel", + camtg3_parents, 0x060, 0x064, 0x068, 8, 3, 15, 0x004, 21), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4_SEL, "camtg4_sel", + camtg4_parents, 0x060, 0x064, 0x068, 16, 3, 23, 0x004, 22), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5_SEL, "camtg5_sel", + camtg5_parents, 0x060, 0x064, 0x068, 24, 3, 31, 0x004, 23), + /* CLK_CFG_6 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG6_SEL, "camtg6_sel", + camtg6_parents, 0x070, 0x074, 0x078, 0, 3, 7, 0x004, 24), + MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", + uart_parents, 0x070, 0x074, 0x078, 8, 1, 15, 0x004, 25), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", + spi_parents, 0x070, 0x074, 0x078, 16, 2, 23, 0x004, 26), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", + msdc50_0_h_parents, 0x070, 0x074, 0x078, 24, 2, 31, 0x004, 27), + /* CLK_CFG_7 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", + msdc50_0_parents, 0x080, 0x084, 0x088, 0, 3, 7, 0x004, 28), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", + msdc30_1_parents, 0x080, 0x084, 0x088, 8, 3, 15, 0x004, 29), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", + msdc30_2_parents, 0x080, 0x084, 0x088, 16, 3, 23, 0x004, 30), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", + audio_parents, 0x080, 0x084, 0x088, 24, 2, 31, 0x008, 0), + /* CLK_CFG_8 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", + aud_intbus_parents, 0x090, 0x094, 0x098, 0, 2, 7, 0x008, 1), + MUX_GATE_CLR_SET_UPD(CLK_TOP_PWRAP_ULPOSC_SEL, "pwrap_ulposc_sel", + pwrap_ulposc_parents, 0x090, 0x094, 0x098, 8, 3, 15, 0x008, 2), + MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", + atb_parents, 0x090, 0x094, 0x098, 16, 2, 23, 0x008, 3), + /* CLK_CFG_9 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI_SEL, "dpi_sel", + dpi_parents, 0x0a0, 0x0a4, 0x0a8, 0, 3, 7, 0x008, 5), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM_SEL, "scam_sel", + scam_parents, 0x0a0, 0x0a4, 0x0a8, 8, 1, 15, 0x008, 6), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM_SEL, "disp_pwm_sel", + disp_pwm_parents, 0x0a0, 0x0a4, 0x0a8, 16, 3, 23, 0x008, 7), + MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP_SEL, "usb_top_sel", + usb_top_parents, 0x0a0, 0x0a4, 0x0a8, 24, 2, 31, 0x008, 8), + /* CLK_CFG_10 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_SEL, "ssusb_xhci_sel", + ssusb_xhci_parents, 0x0b0, 0x0b4, 0x0b8, 0, 2, 7, 0x008, 9), + MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", + i2c_parents, 0x0b0, 0x0b4, 0x0b8, 8, 2, 15, 0x008, 10), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF_SEL, "seninf_sel", + seninf_parents, 0x0b0, 0x0b4, 0x0b8, 16, 3, 23, 0x008, 11), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1_SEL, "seninf1_sel", + seninf1_parents, 0x0b0, 0x0b4, 0x0b8, 24, 3, 31, 0x008, 12), + /* CLK_CFG_11 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2_SEL, "seninf2_sel", + seninf2_parents, 0x0c0, 0x0c4, 0x0c8, 0, 3, 7, 0x008, 13), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3_SEL, "seninf3_sel", + seninf3_parents, 0x0c0, 0x0c4, 0x0c8, 8, 3, 15, 0x008, 14), + MUX_GATE_CLR_SET_UPD(CLK_TOP_TL_SEL, "tl_sel", + tl_parents, 0x0c0, 0x0c4, 0x0c8, 16, 2, 23, 0x008, 15), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC_SEL, "dxcc_sel", + dxcc_parents, 0x0c0, 0x0c4, 0x0c8, 24, 2, 31, 0x008, 16), + /* CLK_CFG_12 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1_SEL, "aud_engen1_sel", + aud_engen1_parents, 0x0d0, 0x0d4, 0x0d8, 0, 2, 7, 0x008, 17), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN2_SEL, "aud_engen2_sel", + aud_engen2_parents, 0x0d0, 0x0d4, 0x0d8, 8, 2, 15, 0x008, 18), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_UFSFDE_SEL, "aes_ufsfde_sel", + aes_ufsfde_parents, 0x0d0, 0x0d4, 0x0d8, 16, 3, 23, 0x008, 19), + MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS_SEL, "ufs_sel", + ufs_parents, 0x0d0, 0x0d4, 0x0d8, 24, 3, 31, 0x008, 20), + /* CLK_CFG_13 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1_SEL, "aud_1_sel", + aud_1_parents, 0x0e0, 0x0e4, 0x0e8, 0, 1, 7, 0x008, 21), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2_SEL, "aud_2_sel", + aud_2_parents, 0x0e0, 0x0e4, 0x0e8, 8, 1, 15, 0x008, 22), + MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP_SEL, "adsp_sel", + adsp_parents, 0x0e0, 0x0e4, 0x0e8, 16, 3, 23, 0x008, 23), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF_MAIN_SEL, "dpmaif_main_sel", + dpmaif_main_parents, 0x0e0, 0x0e4, 0x0e8, 24, 3, 31, 0x008, 24), + /* CLK_CFG_14 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC_SEL, "venc_sel", + venc_parents, 0x0f0, 0x0f4, 0x0f8, 0, 4, 7, 0x008, 25), + MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC_SEL, "vdec_sel", + vdec_parents, 0x0f0, 0x0f4, 0x0f8, 8, 4, 15, 0x008, 26), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM_SEL, "camtm_sel", + camtm_parents, 0x0f0, 0x0f4, 0x0f8, 16, 2, 23, 0x008, 27), + MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", + pwm_parents, 0x0f0, 0x0f4, 0x0f8, 24, 1, 31, 0x008, 28), + /* CLK_CFG_15 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_H_SEL, "audio_h_sel", + audio_h_parents, 0x100, 0x104, 0x108, 0, 2, 7, 0x008, 29), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_MST_SEL, "spmi_mst_sel", + spmi_mst_parents, 0x100, 0x104, 0x108, 8, 3, 15, 0x008, 30), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE_SEL, "aes_msdcfde_sel", + aes_msdcfde_parents, 0x100, 0x104, 0x108, 24, 3, 31, 0x00c, 1), + /* CLK_CFG_16 */ + MUX_GATE_CLR_SET_UPD(CLK_TOP_SFLASH_SEL, "sflash_sel", + sflash_parents, 0x110, 0x114, 0x118, 8, 2, 15, 0x00c, 3), +}; + +static struct mtk_composite top_muxes[] = { + /* CLK_AUDDIV_0 */ + MUX(CLK_TOP_APLL_I2S0_M_SEL, "apll_i2s0_m_sel", apll_i2s0_m_parents, 0x320, 16, 1), + MUX(CLK_TOP_APLL_I2S1_M_SEL, "apll_i2s1_m_sel", apll_i2s1_m_parents, 0x320, 17, 1), + MUX(CLK_TOP_APLL_I2S2_M_SEL, "apll_i2s2_m_sel", apll_i2s2_m_parents, 0x320, 18, 1), + MUX(CLK_TOP_APLL_I2S3_M_SEL, "apll_i2s3_m_sel", apll_i2s3_m_parents, 0x320, 19, 1), + MUX(CLK_TOP_APLL_I2S4_M_SEL, "apll_i2s4_m_sel", apll_i2s4_m_parents, 0x320, 20, 1), + MUX(CLK_TOP_APLL_I2S5_M_SEL, "apll_i2s5_m_sel", apll_i2s5_m_parents, 0x320, 21, 1), + MUX(CLK_TOP_APLL_I2S6_M_SEL, "apll_i2s6_m_sel", apll_i2s6_m_parents, 0x320, 22, 1), + MUX(CLK_TOP_APLL_I2S7_M_SEL, "apll_i2s7_m_sel", apll_i2s7_m_parents, 0x320, 23, 1), + MUX(CLK_TOP_APLL_I2S8_M_SEL, "apll_i2s8_m_sel", apll_i2s8_m_parents, 0x320, 24, 1), + MUX(CLK_TOP_APLL_I2S9_M_SEL, "apll_i2s9_m_sel", apll_i2s9_m_parents, 0x320, 25, 1), +}; + +static const struct mtk_composite top_adj_divs[] = { + DIV_GATE(CLK_TOP_APLL12_DIV0, "apll12_div0", "apll_i2s0_m_sel", 0x320, 0, 0x328, 8, 0), + DIV_GATE(CLK_TOP_APLL12_DIV1, "apll12_div1", "apll_i2s1_m_sel", 0x320, 1, 0x328, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV2, "apll12_div2", "apll_i2s2_m_sel", 0x320, 2, 0x328, 8, 16), + DIV_GATE(CLK_TOP_APLL12_DIV3, "apll12_div3", "apll_i2s3_m_sel", 0x320, 3, 0x328, 8, 24), + DIV_GATE(CLK_TOP_APLL12_DIV4, "apll12_div4", "apll_i2s4_m_sel", 0x320, 4, 0x334, 8, 0), + DIV_GATE(CLK_TOP_APLL12_DIVB, "apll12_divb", "apll12_div4", 0x320, 5, 0x334, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV5, "apll12_div5", "apll_i2s5_m_sel", 0x320, 6, 0x334, 8, 16), + DIV_GATE(CLK_TOP_APLL12_DIV6, "apll12_div6", "apll_i2s6_m_sel", 0x320, 7, 0x334, 8, 24), + DIV_GATE(CLK_TOP_APLL12_DIV7, "apll12_div7", "apll_i2s7_m_sel", 0x320, 8, 0x338, 8, 0), + DIV_GATE(CLK_TOP_APLL12_DIV8, "apll12_div8", "apll_i2s8_m_sel", 0x320, 9, 0x338, 8, 8), + DIV_GATE(CLK_TOP_APLL12_DIV9, "apll12_div9", "apll_i2s9_m_sel", 0x320, 10, 0x338, 8, 16), +}; + +static const struct mtk_gate_regs apmixed_cg_regs = { + .set_ofs = 0x14, + .clr_ofs = 0x14, + .sta_ofs = 0x14, +}; + +#define GATE_APMIXED(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &apmixed_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv) + +static const struct mtk_gate apmixed_clks[] = { + GATE_APMIXED(CLK_APMIXED_MIPID26M, "mipid26m", "clk26m", 16), +}; + +static const struct mtk_gate_regs infra0_cg_regs = { + .set_ofs = 0x80, + .clr_ofs = 0x84, + .sta_ofs = 0x90, +}; + +static const struct mtk_gate_regs infra1_cg_regs = { + .set_ofs = 0x88, + .clr_ofs = 0x8c, + .sta_ofs = 0x94, +}; + +static const struct mtk_gate_regs infra2_cg_regs = { + .set_ofs = 0xa4, + .clr_ofs = 0xa8, + .sta_ofs = 0xac, +}; + +static const struct mtk_gate_regs infra3_cg_regs = { + .set_ofs = 0xc0, + .clr_ofs = 0xc4, + .sta_ofs = 0xc8, +}; + +static const struct mtk_gate_regs infra4_cg_regs = { + .set_ofs = 0xd0, + .clr_ofs = 0xd4, + .sta_ofs = 0xd8, +}; + +static const struct mtk_gate_regs infra5_cg_regs = { + .set_ofs = 0xe0, + .clr_ofs = 0xe4, + .sta_ofs = 0xe8, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flag) \ + GATE_MTK_FLAGS(_id, _name, _parent, &infra1_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, _flag) + +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0) + +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra2_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flag) \ + GATE_MTK_FLAGS(_id, _name, _parent, &infra3_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, _flag) + +#define GATE_INFRA3(_id, _name, _parent, _shift) \ + GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0) + +#define GATE_INFRA4(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &infra4_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_INFRA5_FLAGS(_id, _name, _parent, _shift, _flag) \ + GATE_MTK_FLAGS(_id, _name, _parent, &infra5_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, _flag) + +#define GATE_INFRA5(_id, _name, _parent, _shift) \ + GATE_INFRA5_FLAGS(_id, _name, _parent, _shift, 0) + +/* + * CRITICAL CLOCK: + * infra_133m and infra_66m are main peripheral bus clocks of SOC. + * infra_device_apc and infra_device_apc_sync are for device access permission control module. + */ +static const struct mtk_gate infra_clks[] = { + /* INFRA0 */ + GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr", "pwrap_ulposc_sel", 0), + GATE_INFRA0(CLK_INFRA_PMIC_AP, "infra_pmic_ap", "pwrap_ulposc_sel", 1), + GATE_INFRA0(CLK_INFRA_PMIC_MD, "infra_pmic_md", "pwrap_ulposc_sel", 2), + GATE_INFRA0(CLK_INFRA_PMIC_CONN, "infra_pmic_conn", "pwrap_ulposc_sel", 3), + GATE_INFRA0(CLK_INFRA_SCPSYS, "infra_scpsys", "scp_sel", 4), + GATE_INFRA0(CLK_INFRA_SEJ, "infra_sej", "axi_sel", 5), + GATE_INFRA0(CLK_INFRA_APXGPT, "infra_apxgpt", "axi_sel", 6), + GATE_INFRA0(CLK_INFRA_GCE, "infra_gce", "axi_sel", 8), + GATE_INFRA0(CLK_INFRA_GCE2, "infra_gce2", "axi_sel", 9), + GATE_INFRA0(CLK_INFRA_THERM, "infra_therm", "axi_sel", 10), + GATE_INFRA0(CLK_INFRA_I2C0, "infra_i2c0", "i2c_sel", 11), + GATE_INFRA0(CLK_INFRA_AP_DMA_PSEUDO, "infra_ap_dma_pseudo", "axi_sel", 12), + GATE_INFRA0(CLK_INFRA_I2C2, "infra_i2c2", "i2c_sel", 13), + GATE_INFRA0(CLK_INFRA_I2C3, "infra_i2c3", "i2c_sel", 14), + GATE_INFRA0(CLK_INFRA_PWM_H, "infra_pwm_h", "axi_sel", 15), + GATE_INFRA0(CLK_INFRA_PWM1, "infra_pwm1", "pwm_sel", 16), + GATE_INFRA0(CLK_INFRA_PWM2, "infra_pwm2", "pwm_sel", 17), + GATE_INFRA0(CLK_INFRA_PWM3, "infra_pwm3", "pwm_sel", 18), + GATE_INFRA0(CLK_INFRA_PWM4, "infra_pwm4", "pwm_sel", 19), + GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm", "pwm_sel", 21), + GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0", "uart_sel", 22), + GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23), + GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2", "uart_sel", 24), + GATE_INFRA0(CLK_INFRA_UART3, "infra_uart3", "uart_sel", 25), + GATE_INFRA0(CLK_INFRA_GCE_26M, "infra_gce_26m", "axi_sel", 27), + GATE_INFRA0(CLK_INFRA_CQ_DMA_FPC, "infra_cq_dma_fpc", "axi_sel", 28), + GATE_INFRA0(CLK_INFRA_BTIF, "infra_btif", "axi_sel", 31), + /* INFRA1 */ + GATE_INFRA1(CLK_INFRA_SPI0, "infra_spi0", "spi_sel", 1), + GATE_INFRA1(CLK_INFRA_MSDC0, "infra_msdc0", "msdc50_0_h_sel", 2), + GATE_INFRA1(CLK_INFRA_MSDC1, "infra_msdc1", "msdc50_0_h_sel", 4), + GATE_INFRA1(CLK_INFRA_MSDC2, "infra_msdc2", "msdc50_0_h_sel", 5), + GATE_INFRA1(CLK_INFRA_MSDC0_SRC, "infra_msdc0_src", "msdc50_0_sel", 6), + GATE_INFRA1(CLK_INFRA_GCPU, "infra_gcpu", "axi_sel", 8), + GATE_INFRA1(CLK_INFRA_TRNG, "infra_trng", "axi_sel", 9), + GATE_INFRA1(CLK_INFRA_AUXADC, "infra_auxadc", "clk26m", 10), + GATE_INFRA1(CLK_INFRA_CPUM, "infra_cpum", "axi_sel", 11), + GATE_INFRA1(CLK_INFRA_CCIF1_AP, "infra_ccif1_ap", "axi_sel", 12), + GATE_INFRA1(CLK_INFRA_CCIF1_MD, "infra_ccif1_md", "axi_sel", 13), + GATE_INFRA1(CLK_INFRA_AUXADC_MD, "infra_auxadc_md", "clk26m", 14), + GATE_INFRA1(CLK_INFRA_PCIE_TL_26M, "infra_pcie_tl_26m", "axi_sel", 15), + GATE_INFRA1(CLK_INFRA_MSDC1_SRC, "infra_msdc1_src", "msdc30_1_sel", 16), + GATE_INFRA1(CLK_INFRA_MSDC2_SRC, "infra_msdc2_src", "msdc30_2_sel", 17), + GATE_INFRA1(CLK_INFRA_PCIE_TL_96M, "infra_pcie_tl_96m", "tl_sel", 18), + GATE_INFRA1(CLK_INFRA_PCIE_PL_P_250M, "infra_pcie_pl_p_250m", "axi_sel", 19), + GATE_INFRA1_FLAGS(CLK_INFRA_DEVICE_APC, "infra_device_apc", "axi_sel", 20, CLK_IS_CRITICAL), + GATE_INFRA1(CLK_INFRA_CCIF_AP, "infra_ccif_ap", "axi_sel", 23), + GATE_INFRA1(CLK_INFRA_DEBUGSYS, "infra_debugsys", "axi_sel", 24), + GATE_INFRA1(CLK_INFRA_AUDIO, "infra_audio", "axi_sel", 25), + GATE_INFRA1(CLK_INFRA_CCIF_MD, "infra_ccif_md", "axi_sel", 26), + GATE_INFRA1(CLK_INFRA_DXCC_SEC_CORE, "infra_dxcc_sec_core", "dxcc_sel", 27), + GATE_INFRA1(CLK_INFRA_DXCC_AO, "infra_dxcc_ao", "dxcc_sel", 28), + GATE_INFRA1(CLK_INFRA_DBG_TRACE, "infra_dbg_trace", "axi_sel", 29), + GATE_INFRA1(CLK_INFRA_DEVMPU_B, "infra_devmpu_b", "axi_sel", 30), + GATE_INFRA1(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m", "clk26m", 31), + /* INFRA2 */ + GATE_INFRA2(CLK_INFRA_IRTX, "infra_irtx", "clk26m", 0), + GATE_INFRA2(CLK_INFRA_SSUSB, "infra_ssusb", "usb_top_sel", 1), + GATE_INFRA2(CLK_INFRA_DISP_PWM, "infra_disp_pwm", "axi_sel", 2), + GATE_INFRA2(CLK_INFRA_CLDMA_B, "infra_cldma_b", "axi_sel", 3), + GATE_INFRA2(CLK_INFRA_AUDIO_26M_B, "infra_audio_26m_b", "clk26m", 4), + GATE_INFRA2(CLK_INFRA_MODEM_TEMP_SHARE, "infra_modem_temp_share", "clk26m", 5), + GATE_INFRA2(CLK_INFRA_SPI1, "infra_spi1", "spi_sel", 6), + GATE_INFRA2(CLK_INFRA_I2C4, "infra_i2c4", "i2c_sel", 7), + GATE_INFRA2(CLK_INFRA_SPI2, "infra_spi2", "spi_sel", 9), + GATE_INFRA2(CLK_INFRA_SPI3, "infra_spi3", "spi_sel", 10), + GATE_INFRA2(CLK_INFRA_UNIPRO_SYS, "infra_unipro_sys", "ufs_sel", 11), + GATE_INFRA2(CLK_INFRA_UNIPRO_TICK, "infra_unipro_tick", "clk26m", 12), + GATE_INFRA2(CLK_INFRA_UFS_MP_SAP_B, "infra_ufs_mp_sap_b", "clk26m", 13), + GATE_INFRA2(CLK_INFRA_MD32_B, "infra_md32_b", "axi_sel", 14), + GATE_INFRA2(CLK_INFRA_UNIPRO_MBIST, "infra_unipro_mbist", "axi_sel", 16), + GATE_INFRA2(CLK_INFRA_I2C5, "infra_i2c5", "i2c_sel", 18), + GATE_INFRA2(CLK_INFRA_I2C5_ARBITER, "infra_i2c5_arbiter", "i2c_sel", 19), + GATE_INFRA2(CLK_INFRA_I2C5_IMM, "infra_i2c5_imm", "i2c_sel", 20), + GATE_INFRA2(CLK_INFRA_I2C1_ARBITER, "infra_i2c1_arbiter", "i2c_sel", 21), + GATE_INFRA2(CLK_INFRA_I2C1_IMM, "infra_i2c1_imm", "i2c_sel", 22), + GATE_INFRA2(CLK_INFRA_I2C2_ARBITER, "infra_i2c2_arbiter", "i2c_sel", 23), + GATE_INFRA2(CLK_INFRA_I2C2_IMM, "infra_i2c2_imm", "i2c_sel", 24), + GATE_INFRA2(CLK_INFRA_SPI4, "infra_spi4", "spi_sel", 25), + GATE_INFRA2(CLK_INFRA_SPI5, "infra_spi5", "spi_sel", 26), + GATE_INFRA2(CLK_INFRA_CQ_DMA, "infra_cq_dma", "axi_sel", 27), + GATE_INFRA2(CLK_INFRA_UFS, "infra_ufs", "ufs_sel", 28), + GATE_INFRA2(CLK_INFRA_AES_UFSFDE, "infra_aes_ufsfde", "aes_ufsfde_sel", 29), + GATE_INFRA2(CLK_INFRA_UFS_TICK, "infra_ufs_tick", "ufs_sel", 30), + GATE_INFRA2(CLK_INFRA_SSUSB_XHCI, "infra_ssusb_xhci", "ssusb_xhci_sel", 31), + /* INFRA3 */ + GATE_INFRA3(CLK_INFRA_MSDC0_SELF, "infra_msdc0_self", "msdc50_0_sel", 0), + GATE_INFRA3(CLK_INFRA_MSDC1_SELF, "infra_msdc1_self", "msdc50_0_sel", 1), + GATE_INFRA3(CLK_INFRA_MSDC2_SELF, "infra_msdc2_self", "msdc50_0_sel", 2), + GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5), + GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6), + GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_0_sel", 7), + GATE_INFRA3(CLK_INFRA_MD_MSDC0, "infra_md_msdc0", "msdc50_0_sel", 8), + GATE_INFRA3(CLK_INFRA_CCIF5_AP, "infra_ccif5_ap", "axi_sel", 9), + GATE_INFRA3(CLK_INFRA_CCIF5_MD, "infra_ccif5_md", "axi_sel", 10), + GATE_INFRA3(CLK_INFRA_PCIE_TOP_H_133M, "infra_pcie_top_h_133m", "axi_sel", 11), + GATE_INFRA3(CLK_INFRA_FLASHIF_TOP_H_133M, "infra_flashif_top_h_133m", "axi_sel", 14), + GATE_INFRA3(CLK_INFRA_PCIE_PERI_26M, "infra_pcie_peri_26m", "axi_sel", 15), + GATE_INFRA3(CLK_INFRA_CCIF2_AP, "infra_ccif2_ap", "axi_sel", 16), + GATE_INFRA3(CLK_INFRA_CCIF2_MD, "infra_ccif2_md", "axi_sel", 17), + GATE_INFRA3(CLK_INFRA_CCIF3_AP, "infra_ccif3_ap", "axi_sel", 18), + GATE_INFRA3(CLK_INFRA_CCIF3_MD, "infra_ccif3_md", "axi_sel", 19), + GATE_INFRA3(CLK_INFRA_SEJ_F13M, "infra_sej_f13m", "clk26m", 20), + GATE_INFRA3(CLK_INFRA_AES, "infra_aes", "axi_sel", 21), + GATE_INFRA3(CLK_INFRA_I2C7, "infra_i2c7", "i2c_sel", 22), + GATE_INFRA3(CLK_INFRA_I2C8, "infra_i2c8", "i2c_sel", 23), + GATE_INFRA3(CLK_INFRA_FBIST2FPC, "infra_fbist2fpc", "msdc50_0_sel", 24), + GATE_INFRA3_FLAGS(CLK_INFRA_DEVICE_APC_SYNC, "infra_device_apc_sync", "axi_sel", 25, + CLK_IS_CRITICAL), + GATE_INFRA3(CLK_INFRA_DPMAIF_MAIN, "infra_dpmaif_main", "dpmaif_main_sel", 26), + GATE_INFRA3(CLK_INFRA_PCIE_TL_32K, "infra_pcie_tl_32k", "axi_sel", 27), + GATE_INFRA3(CLK_INFRA_CCIF4_AP, "infra_ccif4_ap", "axi_sel", 28), + GATE_INFRA3(CLK_INFRA_CCIF4_MD, "infra_ccif4_md", "axi_sel", 29), + GATE_INFRA3(CLK_INFRA_SPI6, "infra_spi6", "spi_sel", 30), + GATE_INFRA3(CLK_INFRA_SPI7, "infra_spi7", "spi_sel", 31), + /* INFRA4 */ + GATE_INFRA4(CLK_INFRA_AP_DMA, "infra_ap_dma", "infra_ap_dma_pseudo", 31), + /* INFRA5 */ + GATE_INFRA5_FLAGS(CLK_INFRA_133M, "infra_133m", "axi_sel", 0, CLK_IS_CRITICAL), + GATE_INFRA5_FLAGS(CLK_INFRA_66M, "infra_66m", "axi_sel", 1, CLK_IS_CRITICAL), + GATE_INFRA5(CLK_INFRA_66M_PERI_BUS, "infra_66m_peri_bus", "axi_sel", 2), + GATE_INFRA5(CLK_INFRA_FREE_DCM_133M, "infra_free_dcm_133m", "axi_sel", 3), + GATE_INFRA5(CLK_INFRA_FREE_DCM_66M, "infra_free_dcm_66m", "axi_sel", 4), + GATE_INFRA5(CLK_INFRA_PERI_BUS_DCM_133M, "infra_peri_bus_dcm_133m", "axi_sel", 5), + GATE_INFRA5(CLK_INFRA_PERI_BUS_DCM_66M, "infra_peri_bus_dcm_66m", "axi_sel", 6), + GATE_INFRA5(CLK_INFRA_FLASHIF_PERI_26M, "infra_flashif_peri_26m", "axi_sel", 30), + GATE_INFRA5(CLK_INFRA_FLASHIF_SFLASH, "infra_flashif_fsflash", "axi_sel", 31), +}; + +static const struct mtk_gate_regs peri_cg_regs = { + .set_ofs = 0x20c, + .clr_ofs = 0x20c, + .sta_ofs = 0x20c, +}; + +#define GATE_PERI(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &peri_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv) + +static const struct mtk_gate peri_clks[] = { + GATE_PERI(CLK_PERI_PERIAXI, "peri_periaxi", "axi_sel", 31), +}; + +static const struct mtk_gate_regs top_cg_regs = { + .set_ofs = 0x150, + .clr_ofs = 0x150, + .sta_ofs = 0x150, +}; + +#define GATE_TOP(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &top_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv) + +static const struct mtk_gate top_clks[] = { + GATE_TOP(CLK_TOP_SSUSB_TOP_REF, "ssusb_top_ref", "clk26m", 24), + GATE_TOP(CLK_TOP_SSUSB_PHY_REF, "ssusb_phy_ref", "clk26m", 25), +}; + +#define MT8192_PLL_FMAX (3800UL * MHZ) +#define MT8192_PLL_FMIN (1500UL * MHZ) +#define MT8192_INTEGER_BITS 8 + +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift, \ + _tuner_reg, _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, _pcw_chg_reg, \ + _en_reg, _pll_en_bit) { \ + .id = _id, \ + .name = _name, \ + .reg = _reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .flags = _flags, \ + .rst_bar_mask = _rst_bar_mask, \ + .fmax = MT8192_PLL_FMAX, \ + .fmin = MT8192_PLL_FMIN, \ + .pcwbits = _pcwbits, \ + .pcwibits = MT8192_INTEGER_BITS, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .pcw_chg_reg = _pcw_chg_reg, \ + .en_reg = _en_reg, \ + .pll_en_bit = _pll_en_bit, \ + } + +#define PLL_B(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift, \ + _tuner_reg, _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift) \ + PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, \ + _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift, \ + _tuner_reg, _tuner_en_reg, _tuner_en_bit, \ + _pcw_reg, _pcw_shift, 0, 0, 0) + +static const struct mtk_pll_data plls[] = { + PLL_B(CLK_APMIXED_MAINPLL, "mainpll", 0x0340, 0x034c, 0xff000000, + HAVE_RST_BAR, BIT(23), 22, 0x0344, 24, 0, 0, 0, 0x0344, 0), + PLL_B(CLK_APMIXED_UNIVPLL, "univpll", 0x0308, 0x0314, 0xff000000, + HAVE_RST_BAR, BIT(23), 22, 0x030c, 24, 0, 0, 0, 0x030c, 0), + PLL(CLK_APMIXED_USBPLL, "usbpll", 0x03c4, 0x03cc, 0x00000000, + 0, 0, 22, 0x03c4, 24, 0, 0, 0, 0x03c4, 0, 0x03c4, 0x03cc, 2), + PLL_B(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0350, 0x035c, 0x00000000, + 0, 0, 22, 0x0354, 24, 0, 0, 0, 0x0354, 0), + PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0360, 0x036c, 0xff000000, + HAVE_RST_BAR, BIT(23), 22, 0x0364, 24, 0, 0, 0, 0x0364, 0), + PLL_B(CLK_APMIXED_ADSPPLL, "adsppll", 0x0370, 0x037c, 0xff000000, + HAVE_RST_BAR, BIT(23), 22, 0x0374, 24, 0, 0, 0, 0x0374, 0), + PLL_B(CLK_APMIXED_MFGPLL, "mfgpll", 0x0268, 0x0274, 0x00000000, + 0, 0, 22, 0x026c, 24, 0, 0, 0, 0x026c, 0), + PLL_B(CLK_APMIXED_TVDPLL, "tvdpll", 0x0380, 0x038c, 0x00000000, + 0, 0, 22, 0x0384, 24, 0, 0, 0, 0x0384, 0), + PLL_B(CLK_APMIXED_APLL1, "apll1", 0x0318, 0x0328, 0x00000000, + 0, 0, 32, 0x031c, 24, 0x0040, 0x000c, 0, 0x0320, 0), + PLL_B(CLK_APMIXED_APLL2, "apll2", 0x032c, 0x033c, 0x00000000, + 0, 0, 32, 0x0330, 24, 0, 0, 0, 0x0334, 0), +}; + +static struct clk_onecell_data *top_clk_data; + +static void clk_mt8192_top_init_early(struct device_node *node) +{ + int i; + + top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + if (!top_clk_data) + return; + + for (i = 0; i < CLK_TOP_NR_CLK; i++) + top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER); + + mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data); + + of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data); +} + +CLK_OF_DECLARE_DRIVER(mt8192_topckgen, "mediatek,mt8192-topckgen", + clk_mt8192_top_init_early); + +static int clk_mt8192_top_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + int r; + void __iomem *base; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data); + mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data); + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data); + mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node, &mt8192_clk_lock, + top_clk_data); + mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, &mt8192_clk_lock, + top_clk_data); + mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base, &mt8192_clk_lock, + top_clk_data); + r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data); +} + +static int clk_mt8192_infra_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static int clk_mt8192_peri_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static int clk_mt8192_apmixed_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); + if (!clk_data) + return -ENOMEM; + + mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static const struct of_device_id of_match_clk_mt8192[] = { + { + .compatible = "mediatek,mt8192-apmixedsys", + .data = clk_mt8192_apmixed_probe, + }, { + .compatible = "mediatek,mt8192-topckgen", + .data = clk_mt8192_top_probe, + }, { + .compatible = "mediatek,mt8192-infracfg", + .data = clk_mt8192_infra_probe, + }, { + .compatible = "mediatek,mt8192-pericfg", + .data = clk_mt8192_peri_probe, + }, { + /* sentinel */ + } +}; + +static int clk_mt8192_probe(struct platform_device *pdev) +{ + int (*clk_probe)(struct platform_device *pdev); + int r; + + clk_probe = of_device_get_match_data(&pdev->dev); + if (!clk_probe) + return -EINVAL; + + r = clk_probe(pdev); + if (r) + dev_err(&pdev->dev, "could not register clock provider: %s: %d\n", pdev->name, r); + + return r; +} + +static struct platform_driver clk_mt8192_drv = { + .probe = clk_mt8192_probe, + .driver = { + .name = "clk-mt8192", + .of_match_table = of_match_clk_mt8192, + }, +}; + +static int __init clk_mt8192_init(void) +{ + return platform_driver_register(&clk_mt8192_drv); +} + +arch_initcall(clk_mt8192_init); diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index e97d58db28cc..855b0a1f7eb9 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -116,7 +116,12 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index) return 0; } -static const struct clk_ops mtk_mux_ops = { +const struct clk_ops mtk_mux_clr_set_upd_ops = { + .get_parent = mtk_clk_mux_get_parent, + .set_parent = mtk_clk_mux_set_parent_setclr_lock, +}; + +const struct clk_ops mtk_mux_gate_clr_set_upd_ops = { .enable = mtk_clk_mux_enable_setclr, .disable = mtk_clk_mux_disable_setclr, .is_enabled = mtk_clk_mux_is_enabled, @@ -140,7 +145,7 @@ static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, init.flags = mux->flags | CLK_SET_RATE_PARENT; init.parent_names = mux->parent_names; init.num_parents = mux->num_parents; - init.ops = &mtk_mux_ops; + init.ops = mux->ops; clk_mux->regmap = regmap; clk_mux->data = mux; diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h index f1946161ade1..27841d649118 100644 --- a/drivers/clk/mediatek/clk-mux.h +++ b/drivers/clk/mediatek/clk-mux.h @@ -33,12 +33,13 @@ struct mtk_mux { u8 gate_shift; s8 upd_shift; + const struct clk_ops *ops; signed char num_parents; }; #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ - _gate, _upd_ofs, _upd, _flags) { \ + _gate, _upd_ofs, _upd, _flags, _ops) { \ .id = _id, \ .name = _name, \ .mux_ofs = _mux_ofs, \ @@ -52,14 +53,19 @@ struct mtk_mux { .parent_names = _parents, \ .num_parents = ARRAY_SIZE(_parents), \ .flags = _flags, \ + .ops = &_ops, \ } +extern const struct clk_ops mtk_mux_clr_set_upd_ops; +extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops; + #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ _gate, _upd_ofs, _upd, _flags) \ GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ - _gate, _upd_ofs, _upd, _flags) \ + _gate, _upd_ofs, _upd, _flags, \ + mtk_mux_gate_clr_set_upd_ops) #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ @@ -69,6 +75,14 @@ struct mtk_mux { _width, _gate, _upd_ofs, _upd, \ CLK_SET_RATE_PARENT) +#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \ + _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ + _upd_ofs, _upd) \ + GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \ + _mux_set_ofs, _mux_clr_ofs, _shift, _width, \ + 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \ + mtk_mux_clr_set_upd_ops) + int mtk_clk_register_muxes(const struct mtk_mux *muxes, int num, struct device_node *node, spinlock_t *lock, -- cgit v1.2.3-70-g09d2 From f61e83488df777e570acf7ba1e1ca5024aef6611 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:08 +0800 Subject: clk: mediatek: Add MT8192 audio clock support Add MT8192 audio clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-11-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-aud.c | 118 ++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-aud.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 6075b48377d5..909f423d7c4c 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -508,6 +508,12 @@ config COMMON_CLK_MT8192 help This driver supports MediaTek MT8192 basic clocks. +config COMMON_CLK_MT8192_AUDSYS + bool "Clock driver for MediaTek MT8192 audsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 audsys clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index fcde42160720..1d0f2e8e9661 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -68,5 +68,6 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o +obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-aud.c b/drivers/clk/mediatek/clk-mt8192-aud.c new file mode 100644 index 000000000000..f28d56628045 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-aud.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs aud0_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x0, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs aud1_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x4, + .sta_ofs = 0x4, +}; + +static const struct mtk_gate_regs aud2_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0x8, + .sta_ofs = 0x8, +}; + +#define GATE_AUD0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &aud0_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) + +#define GATE_AUD1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &aud1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) + +#define GATE_AUD2(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &aud2_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) + +static const struct mtk_gate aud_clks[] = { + /* AUD0 */ + GATE_AUD0(CLK_AUD_AFE, "aud_afe", "audio_sel", 2), + GATE_AUD0(CLK_AUD_22M, "aud_22m", "aud_engen1_sel", 8), + GATE_AUD0(CLK_AUD_24M, "aud_24m", "aud_engen2_sel", 9), + GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "aud_engen2_sel", 18), + GATE_AUD0(CLK_AUD_APLL_TUNER, "aud_apll_tuner", "aud_engen1_sel", 19), + GATE_AUD0(CLK_AUD_TDM, "aud_tdm", "aud_1_sel", 20), + GATE_AUD0(CLK_AUD_ADC, "aud_adc", "audio_sel", 24), + GATE_AUD0(CLK_AUD_DAC, "aud_dac", "audio_sel", 25), + GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "audio_sel", 26), + GATE_AUD0(CLK_AUD_TML, "aud_tml", "audio_sel", 27), + GATE_AUD0(CLK_AUD_NLE, "aud_nle", "audio_sel", 28), + /* AUD1 */ + GATE_AUD1(CLK_AUD_I2S1_B, "aud_i2s1_b", "audio_sel", 4), + GATE_AUD1(CLK_AUD_I2S2_B, "aud_i2s2_b", "audio_sel", 5), + GATE_AUD1(CLK_AUD_I2S3_B, "aud_i2s3_b", "audio_sel", 6), + GATE_AUD1(CLK_AUD_I2S4_B, "aud_i2s4_b", "audio_sel", 7), + GATE_AUD1(CLK_AUD_CONNSYS_I2S_ASRC, "aud_connsys_i2s_asrc", "audio_sel", 12), + GATE_AUD1(CLK_AUD_GENERAL1_ASRC, "aud_general1_asrc", "audio_sel", 13), + GATE_AUD1(CLK_AUD_GENERAL2_ASRC, "aud_general2_asrc", "audio_sel", 14), + GATE_AUD1(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 15), + GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 16), + GATE_AUD1(CLK_AUD_ADC_HIRES_TML, "aud_adc_hires_tml", "audio_h_sel", 17), + GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "audio_sel", 20), + GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 21), + GATE_AUD1(CLK_AUD_3RD_DAC, "aud_3rd_dac", "audio_sel", 28), + GATE_AUD1(CLK_AUD_3RD_DAC_PREDIS, "aud_3rd_dac_predis", "audio_sel", 29), + GATE_AUD1(CLK_AUD_3RD_DAC_TML, "aud_3rd_dac_tml", "audio_sel", 30), + GATE_AUD1(CLK_AUD_3RD_DAC_HIRES, "aud_3rd_dac_hires", "audio_h_sel", 31), + /* AUD2 */ + GATE_AUD2(CLK_AUD_I2S5_B, "aud_i2s5_b", "audio_sel", 0), + GATE_AUD2(CLK_AUD_I2S6_B, "aud_i2s6_b", "audio_sel", 1), + GATE_AUD2(CLK_AUD_I2S7_B, "aud_i2s7_b", "audio_sel", 2), + GATE_AUD2(CLK_AUD_I2S8_B, "aud_i2s8_b", "audio_sel", 3), + GATE_AUD2(CLK_AUD_I2S9_B, "aud_i2s9_b", "audio_sel", 4), +}; + +static int clk_mt8192_aud_probe(struct platform_device *pdev) +{ + struct clk_onecell_data *clk_data; + struct device_node *node = pdev->dev.of_node; + int r; + + clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_gates(node, aud_clks, ARRAY_SIZE(aud_clks), clk_data); + if (r) + return r; + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) + return r; + + r = devm_of_platform_populate(&pdev->dev); + if (r) + of_clk_del_provider(node); + + return r; +} + +static const struct of_device_id of_match_clk_mt8192_aud[] = { + { .compatible = "mediatek,mt8192-audsys", }, + {} +}; + +static struct platform_driver clk_mt8192_aud_drv = { + .probe = clk_mt8192_aud_probe, + .driver = { + .name = "clk-mt8192-aud", + .of_match_table = of_match_clk_mt8192_aud, + }, +}; + +builtin_platform_driver(clk_mt8192_aud_drv); -- cgit v1.2.3-70-g09d2 From cebef18833e2db7f65a6c6bc436bd057807e94ee Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:09 +0800 Subject: clk: mediatek: Add MT8192 camsys clock support Add MT8192 camsys and camsys raw clock providers Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-12-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-cam.c | 107 ++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-cam.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 909f423d7c4c..a39a4c201c9e 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -514,6 +514,12 @@ config COMMON_CLK_MT8192_AUDSYS help This driver supports MediaTek MT8192 audsys clocks. +config COMMON_CLK_MT8192_CAMSYS + bool "Clock driver for MediaTek MT8192 camsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 camsys and camsys_raw clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 1d0f2e8e9661..94bf7a03fd88 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -69,5 +69,6 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o +obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-cam.c b/drivers/clk/mediatek/clk-mt8192-cam.c new file mode 100644 index 000000000000..fc74cd80b4b0 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-cam.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs cam_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_CAM(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate cam_clks[] = { + GATE_CAM(CLK_CAM_LARB13, "cam_larb13", "cam_sel", 0), + GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "cam_sel", 1), + GATE_CAM(CLK_CAM_LARB14, "cam_larb14", "cam_sel", 2), + GATE_CAM(CLK_CAM_CAM, "cam_cam", "cam_sel", 6), + GATE_CAM(CLK_CAM_CAMTG, "cam_camtg", "cam_sel", 7), + GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "cam_sel", 8), + GATE_CAM(CLK_CAM_CAMSV0, "cam_camsv0", "cam_sel", 9), + GATE_CAM(CLK_CAM_CAMSV1, "cam_camsv1", "cam_sel", 10), + GATE_CAM(CLK_CAM_CAMSV2, "cam_camsv2", "cam_sel", 11), + GATE_CAM(CLK_CAM_CAMSV3, "cam_camsv3", "cam_sel", 12), + GATE_CAM(CLK_CAM_CCU0, "cam_ccu0", "cam_sel", 13), + GATE_CAM(CLK_CAM_CCU1, "cam_ccu1", "cam_sel", 14), + GATE_CAM(CLK_CAM_MRAW0, "cam_mraw0", "cam_sel", 15), + GATE_CAM(CLK_CAM_FAKE_ENG, "cam_fake_eng", "cam_sel", 17), + GATE_CAM(CLK_CAM_CCU_GALS, "cam_ccu_gals", "cam_sel", 18), + GATE_CAM(CLK_CAM_CAM2MM_GALS, "cam2mm_gals", "cam_sel", 19), +}; + +static const struct mtk_gate cam_rawa_clks[] = { + GATE_CAM(CLK_CAM_RAWA_LARBX, "cam_rawa_larbx", "cam_sel", 0), + GATE_CAM(CLK_CAM_RAWA_CAM, "cam_rawa_cam", "cam_sel", 1), + GATE_CAM(CLK_CAM_RAWA_CAMTG, "cam_rawa_camtg", "cam_sel", 2), +}; + +static const struct mtk_gate cam_rawb_clks[] = { + GATE_CAM(CLK_CAM_RAWB_LARBX, "cam_rawb_larbx", "cam_sel", 0), + GATE_CAM(CLK_CAM_RAWB_CAM, "cam_rawb_cam", "cam_sel", 1), + GATE_CAM(CLK_CAM_RAWB_CAMTG, "cam_rawb_camtg", "cam_sel", 2), +}; + +static const struct mtk_gate cam_rawc_clks[] = { + GATE_CAM(CLK_CAM_RAWC_LARBX, "cam_rawc_larbx", "cam_sel", 0), + GATE_CAM(CLK_CAM_RAWC_CAM, "cam_rawc_cam", "cam_sel", 1), + GATE_CAM(CLK_CAM_RAWC_CAMTG, "cam_rawc_camtg", "cam_sel", 2), +}; + +static const struct mtk_clk_desc cam_desc = { + .clks = cam_clks, + .num_clks = ARRAY_SIZE(cam_clks), +}; + +static const struct mtk_clk_desc cam_rawa_desc = { + .clks = cam_rawa_clks, + .num_clks = ARRAY_SIZE(cam_rawa_clks), +}; + +static const struct mtk_clk_desc cam_rawb_desc = { + .clks = cam_rawb_clks, + .num_clks = ARRAY_SIZE(cam_rawb_clks), +}; + +static const struct mtk_clk_desc cam_rawc_desc = { + .clks = cam_rawc_clks, + .num_clks = ARRAY_SIZE(cam_rawc_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_cam[] = { + { + .compatible = "mediatek,mt8192-camsys", + .data = &cam_desc, + }, { + .compatible = "mediatek,mt8192-camsys_rawa", + .data = &cam_rawa_desc, + }, { + .compatible = "mediatek,mt8192-camsys_rawb", + .data = &cam_rawb_desc, + }, { + .compatible = "mediatek,mt8192-camsys_rawc", + .data = &cam_rawc_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_cam_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-cam", + .of_match_table = of_match_clk_mt8192_cam, + }, +}; + +builtin_platform_driver(clk_mt8192_cam_drv); -- cgit v1.2.3-70-g09d2 From 014a4881a23f31d245d65df1c6ee5a39c6c05504 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:10 +0800 Subject: clk: mediatek: Add MT8192 imgsys clock support Add MT8192 imgsys and imgsys2 clock providers Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-13-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 +++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-img.c | 70 +++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-img.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index a39a4c201c9e..38011dccfe47 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -520,6 +520,12 @@ config COMMON_CLK_MT8192_CAMSYS help This driver supports MediaTek MT8192 camsys and camsys_raw clocks. +config COMMON_CLK_MT8192_IMGSYS + bool "Clock driver for MediaTek MT8192 imgsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 imgsys and imgsys2 clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 94bf7a03fd88..91392cb333fd 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -70,5 +70,6 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o +obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-img.c b/drivers/clk/mediatek/clk-mt8192-img.c new file mode 100644 index 000000000000..7ce3abe42577 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-img.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs img_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_IMG(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate img_clks[] = { + GATE_IMG(CLK_IMG_LARB9, "img_larb9", "img1_sel", 0), + GATE_IMG(CLK_IMG_LARB10, "img_larb10", "img1_sel", 1), + GATE_IMG(CLK_IMG_DIP, "img_dip", "img1_sel", 2), + GATE_IMG(CLK_IMG_GALS, "img_gals", "img1_sel", 12), +}; + +static const struct mtk_gate img2_clks[] = { + GATE_IMG(CLK_IMG2_LARB11, "img2_larb11", "img1_sel", 0), + GATE_IMG(CLK_IMG2_LARB12, "img2_larb12", "img1_sel", 1), + GATE_IMG(CLK_IMG2_MFB, "img2_mfb", "img1_sel", 6), + GATE_IMG(CLK_IMG2_WPE, "img2_wpe", "img1_sel", 7), + GATE_IMG(CLK_IMG2_MSS, "img2_mss", "img1_sel", 8), + GATE_IMG(CLK_IMG2_GALS, "img2_gals", "img1_sel", 12), +}; + +static const struct mtk_clk_desc img_desc = { + .clks = img_clks, + .num_clks = ARRAY_SIZE(img_clks), +}; + +static const struct mtk_clk_desc img2_desc = { + .clks = img2_clks, + .num_clks = ARRAY_SIZE(img2_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_img[] = { + { + .compatible = "mediatek,mt8192-imgsys", + .data = &img_desc, + }, { + .compatible = "mediatek,mt8192-imgsys2", + .data = &img2_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_img_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-img", + .of_match_table = of_match_clk_mt8192_img, + }, +}; + +builtin_platform_driver(clk_mt8192_img_drv); -- cgit v1.2.3-70-g09d2 From 71193c46bdbd82f89214407c5943b2decfb0ab6f Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:11 +0800 Subject: clk: mediatek: Add MT8192 imp i2c wrapper clock support Add MT8192 imp i2c wrapper clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-14-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c | 119 +++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 38011dccfe47..5becf049d9fa 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -526,6 +526,12 @@ config COMMON_CLK_MT8192_IMGSYS help This driver supports MediaTek MT8192 imgsys and imgsys2 clocks. +config COMMON_CLK_MT8192_IMP_IIC_WRAP + bool "Clock driver for MediaTek MT8192 imp_iic_wrap" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 imp_iic_wrap clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 91392cb333fd..37981626b775 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -71,5 +71,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o +obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c new file mode 100644 index 000000000000..700356ac6a58 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs imp_iic_wrap_cg_regs = { + .set_ofs = 0xe08, + .clr_ofs = 0xe04, + .sta_ofs = 0xe00, +}; + +#define GATE_IMP_IIC_WRAP(_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &imp_iic_wrap_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_OPS_PARENT_ENABLE) + +static const struct mtk_gate imp_iic_wrap_c_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C10, "imp_iic_wrap_c_i2c10", "infra_i2c0", 0), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C11, "imp_iic_wrap_c_i2c11", "infra_i2c0", 1), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C12, "imp_iic_wrap_c_i2c12", "infra_i2c0", 2), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_C_I2C13, "imp_iic_wrap_c_i2c13", "infra_i2c0", 3), +}; + +static const struct mtk_gate imp_iic_wrap_e_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_E_I2C3, "imp_iic_wrap_e_i2c3", "infra_i2c0", 0), +}; + +static const struct mtk_gate imp_iic_wrap_n_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_N_I2C0, "imp_iic_wrap_n_i2c0", "infra_i2c0", 0), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_N_I2C6, "imp_iic_wrap_n_i2c6", "infra_i2c0", 1), +}; + +static const struct mtk_gate imp_iic_wrap_s_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C7, "imp_iic_wrap_s_i2c7", "infra_i2c0", 0), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C8, "imp_iic_wrap_s_i2c8", "infra_i2c0", 1), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_S_I2C9, "imp_iic_wrap_s_i2c9", "infra_i2c0", 2), +}; + +static const struct mtk_gate imp_iic_wrap_w_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_W_I2C5, "imp_iic_wrap_w_i2c5", "infra_i2c0", 0), +}; + +static const struct mtk_gate imp_iic_wrap_ws_clks[] = { + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C1, "imp_iic_wrap_ws_i2c1", "infra_i2c0", 0), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C2, "imp_iic_wrap_ws_i2c2", "infra_i2c0", 1), + GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_WS_I2C4, "imp_iic_wrap_ws_i2c4", "infra_i2c0", 2), +}; + +static const struct mtk_clk_desc imp_iic_wrap_c_desc = { + .clks = imp_iic_wrap_c_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_c_clks), +}; + +static const struct mtk_clk_desc imp_iic_wrap_e_desc = { + .clks = imp_iic_wrap_e_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_e_clks), +}; + +static const struct mtk_clk_desc imp_iic_wrap_n_desc = { + .clks = imp_iic_wrap_n_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_n_clks), +}; + +static const struct mtk_clk_desc imp_iic_wrap_s_desc = { + .clks = imp_iic_wrap_s_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_s_clks), +}; + +static const struct mtk_clk_desc imp_iic_wrap_w_desc = { + .clks = imp_iic_wrap_w_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_w_clks), +}; + +static const struct mtk_clk_desc imp_iic_wrap_ws_desc = { + .clks = imp_iic_wrap_ws_clks, + .num_clks = ARRAY_SIZE(imp_iic_wrap_ws_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_imp_iic_wrap[] = { + { + .compatible = "mediatek,mt8192-imp_iic_wrap_c", + .data = &imp_iic_wrap_c_desc, + }, { + .compatible = "mediatek,mt8192-imp_iic_wrap_e", + .data = &imp_iic_wrap_e_desc, + }, { + .compatible = "mediatek,mt8192-imp_iic_wrap_n", + .data = &imp_iic_wrap_n_desc, + }, { + .compatible = "mediatek,mt8192-imp_iic_wrap_s", + .data = &imp_iic_wrap_s_desc, + }, { + .compatible = "mediatek,mt8192-imp_iic_wrap_w", + .data = &imp_iic_wrap_w_desc, + }, { + .compatible = "mediatek,mt8192-imp_iic_wrap_ws", + .data = &imp_iic_wrap_ws_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_imp_iic_wrap_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-imp_iic_wrap", + .of_match_table = of_match_clk_mt8192_imp_iic_wrap, + }, +}; + +builtin_platform_driver(clk_mt8192_imp_iic_wrap_drv); -- cgit v1.2.3-70-g09d2 From 7f621d25d9b88e777f3c4dbfe41e58458219a5d0 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:12 +0800 Subject: clk: mediatek: Add MT8192 ipesys clock support Add MT8192 ipesys clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-15-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-ipe.c | 57 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-ipe.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 5becf049d9fa..02e626270ee7 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -532,6 +532,12 @@ config COMMON_CLK_MT8192_IMP_IIC_WRAP help This driver supports MediaTek MT8192 imp_iic_wrap clocks. +config COMMON_CLK_MT8192_IPESYS + bool "Clock driver for MediaTek MT8192 ipesys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 ipesys clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 37981626b775..33dc974c6638 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -72,5 +72,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o +obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-ipe.c b/drivers/clk/mediatek/clk-mt8192-ipe.c new file mode 100644 index 000000000000..730d91b64b3f --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-ipe.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs ipe_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_IPE(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate ipe_clks[] = { + GATE_IPE(CLK_IPE_LARB19, "ipe_larb19", "ipe_sel", 0), + GATE_IPE(CLK_IPE_LARB20, "ipe_larb20", "ipe_sel", 1), + GATE_IPE(CLK_IPE_SMI_SUBCOM, "ipe_smi_subcom", "ipe_sel", 2), + GATE_IPE(CLK_IPE_FD, "ipe_fd", "ipe_sel", 3), + GATE_IPE(CLK_IPE_FE, "ipe_fe", "ipe_sel", 4), + GATE_IPE(CLK_IPE_RSC, "ipe_rsc", "ipe_sel", 5), + GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "ipe_sel", 6), + GATE_IPE(CLK_IPE_GALS, "ipe_gals", "ipe_sel", 8), +}; + +static const struct mtk_clk_desc ipe_desc = { + .clks = ipe_clks, + .num_clks = ARRAY_SIZE(ipe_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_ipe[] = { + { + .compatible = "mediatek,mt8192-ipesys", + .data = &ipe_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_ipe_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-ipe", + .of_match_table = of_match_clk_mt8192_ipe, + }, +}; + +builtin_platform_driver(clk_mt8192_ipe_drv); -- cgit v1.2.3-70-g09d2 From b565d41f8c2fbdf4d609dfeb4e055b717c8b79cd Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:13 +0800 Subject: clk: mediatek: Add MT8192 mdpsys clock support Add MT8192 mdpsys clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-16-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 +++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-mdp.c | 82 +++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-mdp.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 02e626270ee7..59104b8cd7dc 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -538,6 +538,12 @@ config COMMON_CLK_MT8192_IPESYS help This driver supports MediaTek MT8192 ipesys clocks. +config COMMON_CLK_MT8192_MDPSYS + bool "Clock driver for MediaTek MT8192 mdpsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 mdpsys clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 33dc974c6638..7b258cb1f914 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -73,5 +73,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o +obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-mdp.c b/drivers/clk/mediatek/clk-mt8192-mdp.c new file mode 100644 index 000000000000..93c87ae2f332 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-mdp.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mdp0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mdp1_cg_regs = { + .set_ofs = 0x124, + .clr_ofs = 0x128, + .sta_ofs = 0x120, +}; + +#define GATE_MDP0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mdp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_MDP1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mdp_clks[] = { + /* MDP0 */ + GATE_MDP0(CLK_MDP_RDMA0, "mdp_mdp_rdma0", "mdp_sel", 0), + GATE_MDP0(CLK_MDP_TDSHP0, "mdp_mdp_tdshp0", "mdp_sel", 1), + GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0", "mdp_sel", 2), + GATE_MDP0(CLK_MDP_IMG_DL_ASYNC1, "mdp_img_dl_async1", "mdp_sel", 3), + GATE_MDP0(CLK_MDP_RDMA1, "mdp_mdp_rdma1", "mdp_sel", 4), + GATE_MDP0(CLK_MDP_TDSHP1, "mdp_mdp_tdshp1", "mdp_sel", 5), + GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0", "mdp_sel", 6), + GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus", "mdp_sel", 7), + GATE_MDP0(CLK_MDP_WROT0, "mdp_mdp_wrot0", "mdp_sel", 8), + GATE_MDP0(CLK_MDP_RSZ0, "mdp_mdp_rsz0", "mdp_sel", 9), + GATE_MDP0(CLK_MDP_HDR0, "mdp_mdp_hdr0", "mdp_sel", 10), + GATE_MDP0(CLK_MDP_MUTEX0, "mdp_mdp_mutex0", "mdp_sel", 11), + GATE_MDP0(CLK_MDP_WROT1, "mdp_mdp_wrot1", "mdp_sel", 12), + GATE_MDP0(CLK_MDP_RSZ1, "mdp_mdp_rsz1", "mdp_sel", 13), + GATE_MDP0(CLK_MDP_HDR1, "mdp_mdp_hdr1", "mdp_sel", 14), + GATE_MDP0(CLK_MDP_FAKE_ENG0, "mdp_mdp_fake_eng0", "mdp_sel", 15), + GATE_MDP0(CLK_MDP_AAL0, "mdp_mdp_aal0", "mdp_sel", 16), + GATE_MDP0(CLK_MDP_AAL1, "mdp_mdp_aal1", "mdp_sel", 17), + GATE_MDP0(CLK_MDP_COLOR0, "mdp_mdp_color0", "mdp_sel", 18), + GATE_MDP0(CLK_MDP_COLOR1, "mdp_mdp_color1", "mdp_sel", 19), + /* MDP1 */ + GATE_MDP1(CLK_MDP_IMG_DL_RELAY0_ASYNC0, "mdp_img_dl_relay0_async0", "mdp_sel", 0), + GATE_MDP1(CLK_MDP_IMG_DL_RELAY1_ASYNC1, "mdp_img_dl_relay1_async1", "mdp_sel", 8), +}; + +static const struct mtk_clk_desc mdp_desc = { + .clks = mdp_clks, + .num_clks = ARRAY_SIZE(mdp_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_mdp[] = { + { + .compatible = "mediatek,mt8192-mdpsys", + .data = &mdp_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_mdp_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-mdp", + .of_match_table = of_match_clk_mt8192_mdp, + }, +}; + +builtin_platform_driver(clk_mt8192_mdp_drv); -- cgit v1.2.3-70-g09d2 From 34e1b85549455ec95c46b140526db00447983986 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:14 +0800 Subject: clk: mediatek: Add MT8192 mfgcfg clock support Add MT8192 mfgcfg clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-17-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 +++++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-mfg.c | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-mfg.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 59104b8cd7dc..e212f3416855 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -544,6 +544,12 @@ config COMMON_CLK_MT8192_MDPSYS help This driver supports MediaTek MT8192 mdpsys clocks. +config COMMON_CLK_MT8192_MFGCFG + bool "Clock driver for MediaTek MT8192 mfgcfg" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 mfgcfg clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 7b258cb1f914..024841a79f1c 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -74,5 +74,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_IMGSYS) += clk-mt8192-img.o obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o +obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-mfg.c b/drivers/clk/mediatek/clk-mt8192-mfg.c new file mode 100644 index 000000000000..3bbc7469f0e4 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-mfg.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mfg_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_MFG(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mfg_clks[] = { + GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_pll_sel", 0), +}; + +static const struct mtk_clk_desc mfg_desc = { + .clks = mfg_clks, + .num_clks = ARRAY_SIZE(mfg_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_mfg[] = { + { + .compatible = "mediatek,mt8192-mfgcfg", + .data = &mfg_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_mfg_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-mfg", + .of_match_table = of_match_clk_mt8192_mfg, + }, +}; + +builtin_platform_driver(clk_mt8192_mfg_drv); -- cgit v1.2.3-70-g09d2 From 9d44859bfe1fc118012fe24033003d1be92bd05b Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:15 +0800 Subject: clk: mediatek: Add MT8192 mmsys clock support Add MT8192 mmsys clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Reviewed-by: Matthias Brugger Link: https://lore.kernel.org/r/20210726105719.15793-18-chun-jie.chen@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-mm.c | 108 +++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-mm.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index e212f3416855..5b89a4dbe2b9 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -550,6 +550,12 @@ config COMMON_CLK_MT8192_MFGCFG help This driver supports MediaTek MT8192 mfgcfg clocks. +config COMMON_CLK_MT8192_MMSYS + bool "Clock driver for MediaTek MT8192 mmsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 mmsys clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 024841a79f1c..838bb0131c97 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -75,5 +75,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP) += clk-mt8192-imp_iic_wrap.o obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o +obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-mm.c b/drivers/clk/mediatek/clk-mt8192-mm.c new file mode 100644 index 000000000000..4a0b4c4bc06a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-mm.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs mm0_cg_regs = { + .set_ofs = 0x104, + .clr_ofs = 0x108, + .sta_ofs = 0x100, +}; + +static const struct mtk_gate_regs mm1_cg_regs = { + .set_ofs = 0x114, + .clr_ofs = 0x118, + .sta_ofs = 0x110, +}; + +static const struct mtk_gate_regs mm2_cg_regs = { + .set_ofs = 0x1a4, + .clr_ofs = 0x1a8, + .sta_ofs = 0x1a0, +}; + +#define GATE_MM0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_MM1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +#define GATE_MM2(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &mm2_cg_regs, _shift, &mtk_clk_gate_ops_setclr) + +static const struct mtk_gate mm_clks[] = { + /* MM0 */ + GATE_MM0(CLK_MM_DISP_MUTEX0, "mm_disp_mutex0", "disp_sel", 0), + GATE_MM0(CLK_MM_DISP_CONFIG, "mm_disp_config", "disp_sel", 1), + GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "disp_sel", 2), + GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "disp_sel", 3), + GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "disp_sel", 4), + GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "disp_sel", 5), + GATE_MM0(CLK_MM_DISP_UFBC_WDMA0, "mm_disp_ufbc_wdma0", "disp_sel", 6), + GATE_MM0(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "disp_sel", 7), + GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "disp_sel", 8), + GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "disp_sel", 9), + GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "disp_sel", 10), + GATE_MM0(CLK_MM_SMI_INFRA, "mm_smi_infra", "disp_sel", 11), + GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "disp_sel", 12), + GATE_MM0(CLK_MM_DISP_POSTMASK0, "mm_disp_postmask0", "disp_sel", 13), + GATE_MM0(CLK_MM_DISP_DSC_WRAP0, "mm_disp_dsc_wrap0", "disp_sel", 14), + GATE_MM0(CLK_MM_DSI0, "mm_dsi0", "disp_sel", 15), + GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "disp_sel", 16), + GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "disp_sel", 17), + GATE_MM0(CLK_MM_DISP_FAKE_ENG0, "mm_disp_fake_eng0", "disp_sel", 18), + GATE_MM0(CLK_MM_DISP_FAKE_ENG1, "mm_disp_fake_eng1", "disp_sel", 19), + GATE_MM0(CLK_MM_MDP_TDSHP4, "mm_mdp_tdshp4", "disp_sel", 20), + GATE_MM0(CLK_MM_MDP_RSZ4, "mm_mdp_rsz4", "disp_sel", 21), + GATE_MM0(CLK_MM_MDP_AAL4, "mm_mdp_aal4", "disp_sel", 22), + GATE_MM0(CLK_MM_MDP_HDR4, "mm_mdp_hdr4", "disp_sel", 23), + GATE_MM0(CLK_MM_MDP_RDMA4, "mm_mdp_rdma4", "disp_sel", 24), + GATE_MM0(CLK_MM_MDP_COLOR4, "mm_mdp_color4", "disp_sel", 25), + GATE_MM0(CLK_MM_DISP_Y2R0, "mm_disp_y2r0", "disp_sel", 26), + GATE_MM0(CLK_MM_SMI_GALS, "mm_smi_gals", "disp_sel", 27), + GATE_MM0(CLK_MM_DISP_OVL2_2L, "mm_disp_ovl2_2l", "disp_sel", 28), + GATE_MM0(CLK_MM_DISP_RDMA4, "mm_disp_rdma4", "disp_sel", 29), + GATE_MM0(CLK_MM_DISP_DPI0, "mm_disp_dpi0", "disp_sel", 30), + /* MM1 */ + GATE_MM1(CLK_MM_SMI_IOMMU, "mm_smi_iommu", "disp_sel", 0), + /* MM2 */ + GATE_MM2(CLK_MM_DSI_DSI0, "mm_dsi_dsi0", "disp_sel", 0), + GATE_MM2(CLK_MM_DPI_DPI0, "mm_dpi_dpi0", "dpi_sel", 8), + GATE_MM2(CLK_MM_26MHZ, "mm_26mhz", "clk26m", 24), + GATE_MM2(CLK_MM_32KHZ, "mm_32khz", "clk32k", 25), +}; + +static int clk_mt8192_mm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->parent->of_node; + struct clk_onecell_data *clk_data; + int r; + + clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK); + if (!clk_data) + return -ENOMEM; + + r = mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data); + if (r) + return r; + + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); +} + +static struct platform_driver clk_mt8192_mm_drv = { + .probe = clk_mt8192_mm_probe, + .driver = { + .name = "clk-mt8192-mm", + }, +}; + +builtin_platform_driver(clk_mt8192_mm_drv); -- cgit v1.2.3-70-g09d2 From a1a5b6b0a840dbcd4baa0e775489a52d1e9c2156 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:16 +0800 Subject: clk: mediatek: Add MT8192 msdc clock support Add MT8192 msdc and msdc top clock providers Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-19-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 +++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-msdc.c | 85 ++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-msdc.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 5b89a4dbe2b9..88b24f74aff2 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -556,6 +556,12 @@ config COMMON_CLK_MT8192_MMSYS help This driver supports MediaTek MT8192 mmsys clocks. +config COMMON_CLK_MT8192_MSDC + bool "Clock driver for MediaTek MT8192 msdc" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 msdc and msdc_top clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 838bb0131c97..8e4e343d4af4 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -76,5 +76,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_IPESYS) += clk-mt8192-ipe.o obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o +obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-msdc.c b/drivers/clk/mediatek/clk-mt8192-msdc.c new file mode 100644 index 000000000000..87c3b79b79cf --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-msdc.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs msdc_cg_regs = { + .set_ofs = 0xb4, + .clr_ofs = 0xb4, + .sta_ofs = 0xb4, +}; + +static const struct mtk_gate_regs msdc_top_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x0, + .sta_ofs = 0x0, +}; + +#define GATE_MSDC(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &msdc_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv) + +#define GATE_MSDC_TOP(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &msdc_top_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv) + +static const struct mtk_gate msdc_clks[] = { + GATE_MSDC(CLK_MSDC_AXI_WRAP, "msdc_axi_wrap", "axi_sel", 22), +}; + +static const struct mtk_gate msdc_top_clks[] = { + GATE_MSDC_TOP(CLK_MSDC_TOP_AES_0P, "msdc_top_aes_0p", "aes_msdcfde_sel", 0), + GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_0P, "msdc_top_src_0p", "infra_msdc0_src", 1), + GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_1P, "msdc_top_src_1p", "infra_msdc1_src", 2), + GATE_MSDC_TOP(CLK_MSDC_TOP_SRC_2P, "msdc_top_src_2p", "infra_msdc2_src", 3), + GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC0, "msdc_top_p_msdc0", "axi_sel", 4), + GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC1, "msdc_top_p_msdc1", "axi_sel", 5), + GATE_MSDC_TOP(CLK_MSDC_TOP_P_MSDC2, "msdc_top_p_msdc2", "axi_sel", 6), + GATE_MSDC_TOP(CLK_MSDC_TOP_P_CFG, "msdc_top_p_cfg", "axi_sel", 7), + GATE_MSDC_TOP(CLK_MSDC_TOP_AXI, "msdc_top_axi", "axi_sel", 8), + GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_0P, "msdc_top_h_mst_0p", "infra_msdc0", 9), + GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_1P, "msdc_top_h_mst_1p", "infra_msdc1", 10), + GATE_MSDC_TOP(CLK_MSDC_TOP_H_MST_2P, "msdc_top_h_mst_2p", "infra_msdc2", 11), + GATE_MSDC_TOP(CLK_MSDC_TOP_MEM_OFF_DLY_26M, "msdc_top_mem_off_dly_26m", "clk26m", 12), + GATE_MSDC_TOP(CLK_MSDC_TOP_32K, "msdc_top_32k", "clk32k", 13), + GATE_MSDC_TOP(CLK_MSDC_TOP_AHB2AXI_BRG_AXI, "msdc_top_ahb2axi_brg_axi", "axi_sel", 14), +}; + +static const struct mtk_clk_desc msdc_desc = { + .clks = msdc_clks, + .num_clks = ARRAY_SIZE(msdc_clks), +}; + +static const struct mtk_clk_desc msdc_top_desc = { + .clks = msdc_top_clks, + .num_clks = ARRAY_SIZE(msdc_top_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_msdc[] = { + { + .compatible = "mediatek,mt8192-msdc", + .data = &msdc_desc, + }, { + .compatible = "mediatek,mt8192-msdc_top", + .data = &msdc_top_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_msdc_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-msdc", + .of_match_table = of_match_clk_mt8192_msdc, + }, +}; + +builtin_platform_driver(clk_mt8192_msdc_drv); -- cgit v1.2.3-70-g09d2 From aff125adc00c80d59c3ebd71fc17242e65b37b76 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:17 +0800 Subject: clk: mediatek: Add MT8192 scp adsp clock support Add MT8192 scp adsp clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-20-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-scp_adsp.c | 50 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-scp_adsp.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 88b24f74aff2..eb4aa29d8106 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -562,6 +562,12 @@ config COMMON_CLK_MT8192_MSDC help This driver supports MediaTek MT8192 msdc and msdc_top clocks. +config COMMON_CLK_MT8192_SCP_ADSP + bool "Clock driver for MediaTek MT8192 scp_adsp" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 scp_adsp clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 8e4e343d4af4..a336fe753e9a 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -77,5 +77,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MDPSYS) += clk-mt8192-mdp.o obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o +obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-scp_adsp.c b/drivers/clk/mediatek/clk-mt8192-scp_adsp.c new file mode 100644 index 000000000000..58725d79dd13 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-scp_adsp.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs scp_adsp_cg_regs = { + .set_ofs = 0x180, + .clr_ofs = 0x180, + .sta_ofs = 0x180, +}; + +#define GATE_SCP_ADSP(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &scp_adsp_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr) + +static const struct mtk_gate scp_adsp_clks[] = { + GATE_SCP_ADSP(CLK_SCP_ADSP_AUDIODSP, "scp_adsp_audiodsp", "adsp_sel", 0), +}; + +static const struct mtk_clk_desc scp_adsp_desc = { + .clks = scp_adsp_clks, + .num_clks = ARRAY_SIZE(scp_adsp_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_scp_adsp[] = { + { + .compatible = "mediatek,mt8192-scp_adsp", + .data = &scp_adsp_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_scp_adsp_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-scp_adsp", + .of_match_table = of_match_clk_mt8192_scp_adsp, + }, +}; + +builtin_platform_driver(clk_mt8192_scp_adsp_drv); -- cgit v1.2.3-70-g09d2 From 25f3d97e39a58fd7f057ce3da787adaf9239484a Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:18 +0800 Subject: clk: mediatek: Add MT8192 vdecsys clock support Add MT8192 vdecsys and vdecsys soc clock providers Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-21-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 +++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-vdec.c | 94 ++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-vdec.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index eb4aa29d8106..31779f2c5c83 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -568,6 +568,12 @@ config COMMON_CLK_MT8192_SCP_ADSP help This driver supports MediaTek MT8192 scp_adsp clocks. +config COMMON_CLK_MT8192_VDECSYS + bool "Clock driver for MediaTek MT8192 vdecsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 vdecsys and vdecsys_soc clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index a336fe753e9a..887dd6bcf7f2 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -78,5 +78,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MFGCFG) += clk-mt8192-mfg.o obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o +obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-vdec.c b/drivers/clk/mediatek/clk-mt8192-vdec.c new file mode 100644 index 000000000000..b1d95cfbf22a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-vdec.c @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs vdec0_cg_regs = { + .set_ofs = 0x0, + .clr_ofs = 0x4, + .sta_ofs = 0x0, +}; + +static const struct mtk_gate_regs vdec1_cg_regs = { + .set_ofs = 0x200, + .clr_ofs = 0x204, + .sta_ofs = 0x200, +}; + +static const struct mtk_gate_regs vdec2_cg_regs = { + .set_ofs = 0x8, + .clr_ofs = 0xc, + .sta_ofs = 0x8, +}; + +#define GATE_VDEC0(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + +#define GATE_VDEC1(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + +#define GATE_VDEC2(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &vdec2_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + +static const struct mtk_gate vdec_clks[] = { + /* VDEC0 */ + GATE_VDEC0(CLK_VDEC_VDEC, "vdec_vdec", "vdec_sel", 0), + GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "vdec_sel", 4), + /* VDEC1 */ + GATE_VDEC1(CLK_VDEC_LAT, "vdec_lat", "vdec_sel", 0), + GATE_VDEC1(CLK_VDEC_LAT_ACTIVE, "vdec_lat_active", "vdec_sel", 4), + /* VDEC2 */ + GATE_VDEC2(CLK_VDEC_LARB1, "vdec_larb1", "vdec_sel", 0), +}; + +static const struct mtk_gate vdec_soc_clks[] = { + /* VDEC_SOC0 */ + GATE_VDEC0(CLK_VDEC_SOC_VDEC, "vdec_soc_vdec", "vdec_sel", 0), + GATE_VDEC0(CLK_VDEC_SOC_VDEC_ACTIVE, "vdec_soc_vdec_active", "vdec_sel", 4), + /* VDEC_SOC1 */ + GATE_VDEC1(CLK_VDEC_SOC_LAT, "vdec_soc_lat", "vdec_sel", 0), + GATE_VDEC1(CLK_VDEC_SOC_LAT_ACTIVE, "vdec_soc_lat_active", "vdec_sel", 4), + /* VDEC_SOC2 */ + GATE_VDEC2(CLK_VDEC_SOC_LARB1, "vdec_soc_larb1", "vdec_sel", 0), +}; + +static const struct mtk_clk_desc vdec_desc = { + .clks = vdec_clks, + .num_clks = ARRAY_SIZE(vdec_clks), +}; + +static const struct mtk_clk_desc vdec_soc_desc = { + .clks = vdec_soc_clks, + .num_clks = ARRAY_SIZE(vdec_soc_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_vdec[] = { + { + .compatible = "mediatek,mt8192-vdecsys", + .data = &vdec_desc, + }, { + .compatible = "mediatek,mt8192-vdecsys_soc", + .data = &vdec_soc_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_vdec_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-vdec", + .of_match_table = of_match_clk_mt8192_vdec, + }, +}; + +builtin_platform_driver(clk_mt8192_vdec_drv); -- cgit v1.2.3-70-g09d2 From 441decf91ef01bf2d62f893c33f7ab7d654c5aa1 Mon Sep 17 00:00:00 2001 From: Chun-Jie Chen Date: Mon, 26 Jul 2021 18:57:19 +0800 Subject: clk: mediatek: Add MT8192 vencsys clock support Add MT8192 vencsys clock provider Signed-off-by: Weiyi Lu Signed-off-by: Chun-Jie Chen Link: https://lore.kernel.org/r/20210726105719.15793-22-chun-jie.chen@mediatek.com Reviewed-by: Ikjoon Jang Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 6 ++++ drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt8192-venc.c | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt8192-venc.c diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 31779f2c5c83..576babd86f98 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -574,6 +574,12 @@ config COMMON_CLK_MT8192_VDECSYS help This driver supports MediaTek MT8192 vdecsys and vdecsys_soc clocks. +config COMMON_CLK_MT8192_VENCSYS + bool "Clock driver for MediaTek MT8192 vencsys" + depends on COMMON_CLK_MT8192 + help + This driver supports MediaTek MT8192 vencsys clocks. + config COMMON_CLK_MT8516 bool "Clock driver for MediaTek MT8516" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 887dd6bcf7f2..15bc045f0b71 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -79,5 +79,6 @@ obj-$(CONFIG_COMMON_CLK_MT8192_MMSYS) += clk-mt8192-mm.o obj-$(CONFIG_COMMON_CLK_MT8192_MSDC) += clk-mt8192-msdc.o obj-$(CONFIG_COMMON_CLK_MT8192_SCP_ADSP) += clk-mt8192-scp_adsp.o obj-$(CONFIG_COMMON_CLK_MT8192_VDECSYS) += clk-mt8192-vdec.o +obj-$(CONFIG_COMMON_CLK_MT8192_VENCSYS) += clk-mt8192-venc.o obj-$(CONFIG_COMMON_CLK_MT8516) += clk-mt8516.o obj-$(CONFIG_COMMON_CLK_MT8516_AUDSYS) += clk-mt8516-aud.o diff --git a/drivers/clk/mediatek/clk-mt8192-venc.c b/drivers/clk/mediatek/clk-mt8192-venc.c new file mode 100644 index 000000000000..c0d867bff09e --- /dev/null +++ b/drivers/clk/mediatek/clk-mt8192-venc.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Chun-Jie Chen + +#include +#include +#include + +#include "clk-mtk.h" +#include "clk-gate.h" + +#include + +static const struct mtk_gate_regs venc_cg_regs = { + .set_ofs = 0x4, + .clr_ofs = 0x8, + .sta_ofs = 0x0, +}; + +#define GATE_VENC(_id, _name, _parent, _shift) \ + GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv) + +static const struct mtk_gate venc_clks[] = { + GATE_VENC(CLK_VENC_SET0_LARB, "venc_set0_larb", "venc_sel", 0), + GATE_VENC(CLK_VENC_SET1_VENC, "venc_set1_venc", "venc_sel", 4), + GATE_VENC(CLK_VENC_SET2_JPGENC, "venc_set2_jpgenc", "venc_sel", 8), + GATE_VENC(CLK_VENC_SET5_GALS, "venc_set5_gals", "venc_sel", 28), +}; + +static const struct mtk_clk_desc venc_desc = { + .clks = venc_clks, + .num_clks = ARRAY_SIZE(venc_clks), +}; + +static const struct of_device_id of_match_clk_mt8192_venc[] = { + { + .compatible = "mediatek,mt8192-vencsys", + .data = &venc_desc, + }, { + /* sentinel */ + } +}; + +static struct platform_driver clk_mt8192_venc_drv = { + .probe = mtk_clk_simple_probe, + .driver = { + .name = "clk-mt8192-venc", + .of_match_table = of_match_clk_mt8192_venc, + }, +}; + +builtin_platform_driver(clk_mt8192_venc_drv); -- cgit v1.2.3-70-g09d2 From 17fef808ed746972fa5849c6a162d740f41febd7 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 21 Jul 2021 15:46:10 -0700 Subject: clk: qcom: dispcc-sm8250: Add additional parent clocks for DP The clock controller has two additional clock source pairs, in order to support more than a single DisplayPort PHY. List these, so it's possible to describe them all. Also drop the unnecessary freq_tbl for the link clock sources, to allow these parents to be used. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210721224610.3035258-1-bjorn.andersson@linaro.org Reviewed-by: Dmitry Baryshkov Signed-off-by: Stephen Boyd --- drivers/clk/qcom/dispcc-sm8250.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index 601c7c0ba483..bf9ffe1a1cf4 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -26,6 +26,10 @@ enum { P_DISP_CC_PLL1_OUT_MAIN, P_DP_PHY_PLL_LINK_CLK, P_DP_PHY_PLL_VCO_DIV_CLK, + P_DPTX1_PHY_PLL_LINK_CLK, + P_DPTX1_PHY_PLL_VCO_DIV_CLK, + P_DPTX2_PHY_PLL_LINK_CLK, + P_DPTX2_PHY_PLL_VCO_DIV_CLK, P_EDP_PHY_PLL_LINK_CLK, P_EDP_PHY_PLL_VCO_DIV_CLK, P_DSI0_PHY_PLL_OUT_BYTECLK, @@ -98,12 +102,20 @@ static const struct parent_map disp_cc_parent_map_0[] = { { P_BI_TCXO, 0 }, { P_DP_PHY_PLL_LINK_CLK, 1 }, { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DPTX1_PHY_PLL_LINK_CLK, 3 }, + { P_DPTX1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DPTX2_PHY_PLL_LINK_CLK, 5 }, + { P_DPTX2_PHY_PLL_VCO_DIV_CLK, 6 }, }; static const struct clk_parent_data disp_cc_parent_data_0[] = { { .fw_name = "bi_tcxo" }, { .fw_name = "dp_phy_pll_link_clk" }, { .fw_name = "dp_phy_pll_vco_div_clk" }, + { .fw_name = "dptx1_phy_pll_link_clk" }, + { .fw_name = "dptx1_phy_pll_vco_div_clk" }, + { .fw_name = "dptx2_phy_pll_link_clk" }, + { .fw_name = "dptx2_phy_pll_vco_div_clk" }, }; static const struct parent_map disp_cc_parent_map_1[] = { @@ -269,20 +281,11 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { }, }; -static const struct freq_tbl ftbl_disp_cc_mdss_dp_link1_clk_src[] = { - F(162000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(270000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(540000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - F(810000000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), - { } -}; - static struct clk_rcg2 disp_cc_mdss_dp_link1_clk_src = { .cmd_rcgr = 0x220c, .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, - .freq_tbl = ftbl_disp_cc_mdss_dp_link1_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_dp_link1_clk_src", .parent_data = disp_cc_parent_data_0, @@ -296,7 +299,6 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, - .freq_tbl = ftbl_disp_cc_mdss_dp_link1_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_dp_link_clk_src", .parent_data = disp_cc_parent_data_0, -- cgit v1.2.3-70-g09d2 From d17e4e62df328a5a9e64c014fbeab732ed9d87c4 Mon Sep 17 00:00:00 2001 From: Miles Chen Date: Fri, 16 Jul 2021 13:17:32 +0800 Subject: clk: mediatek: make COMMON_CLK_MT8167* depend on COMMON_CLK_MT8167 I found that COMMON_CLK_MT8167* do not depend on COMMON_CLK_MT8167, so it is possible to config: CONFIG_COMMON_CLK_MT8167=n CONFIG_COMMON_CLK_MT8167_*=y Although it does not cause build breaks with such configuration, I think it is clearer to make COMMON_CLK_MT8167* depend on COMMON_CLK_MT8167. Signed-off-by: Miles Chen Link: https://lore.kernel.org/r/20210716051732.3422-1-miles.chen@mediatek.com Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/Kconfig | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 576babd86f98..439b7c8d0d07 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -362,41 +362,36 @@ config COMMON_CLK_MT8167 config COMMON_CLK_MT8167_AUDSYS bool "Clock driver for MediaTek MT8167 audsys" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK + depends on COMMON_CLK_MT8167 + default COMMON_CLK_MT8167 help This driver supports MediaTek MT8167 audsys clocks. config COMMON_CLK_MT8167_IMGSYS bool "Clock driver for MediaTek MT8167 imgsys" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK + depends on COMMON_CLK_MT8167 + default COMMON_CLK_MT8167 help This driver supports MediaTek MT8167 imgsys clocks. config COMMON_CLK_MT8167_MFGCFG bool "Clock driver for MediaTek MT8167 mfgcfg" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK + depends on COMMON_CLK_MT8167 + default COMMON_CLK_MT8167 help This driver supports MediaTek MT8167 mfgcfg clocks. config COMMON_CLK_MT8167_MMSYS bool "Clock driver for MediaTek MT8167 mmsys" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK + depends on COMMON_CLK_MT8167 + default COMMON_CLK_MT8167 help This driver supports MediaTek MT8167 mmsys clocks. config COMMON_CLK_MT8167_VDECSYS bool "Clock driver for MediaTek MT8167 vdecsys" - depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST - select COMMON_CLK_MEDIATEK - default ARCH_MEDIATEK + depends on COMMON_CLK_MT8167 + default COMMON_CLK_MT8167 help This driver supports MediaTek MT8167 vdecsys clocks. -- cgit v1.2.3-70-g09d2 From 436eef23c41fe10dc34ed19a00caf9f1290a8689 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 13 May 2021 14:54:58 -0700 Subject: tools/memory-model: Add example for heuristic lockless reads This commit adds example code for heuristic lockless reads, based loosely on the sem_lock() and sem_unlock() functions. [ paulmck: Apply Alan Stern and Manfred Spraul feedback. ] Reported-by: Manfred Spraul [ paulmck: Update per Manfred Spraul and Hillf Danton feedback. ] Signed-off-by: Paul E. McKenney --- .../memory-model/Documentation/access-marking.txt | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/tools/memory-model/Documentation/access-marking.txt b/tools/memory-model/Documentation/access-marking.txt index 58bff2619876..d96fe20ed582 100644 --- a/tools/memory-model/Documentation/access-marking.txt +++ b/tools/memory-model/Documentation/access-marking.txt @@ -319,6 +319,99 @@ of the ASSERT_EXCLUSIVE_WRITER() is to allow KCSAN to check for a buggy concurrent lockless write. +Lock-Protected Writes With Heuristic Lockless Reads +--------------------------------------------------- + +For another example, suppose that the code can normally make use of +a per-data-structure lock, but there are times when a global lock +is required. These times are indicated via a global flag. The code +might look as follows, and is based loosely on nf_conntrack_lock(), +nf_conntrack_all_lock(), and nf_conntrack_all_unlock(): + + bool global_flag; + DEFINE_SPINLOCK(global_lock); + struct foo { + spinlock_t f_lock; + int f_data; + }; + + /* All foo structures are in the following array. */ + int nfoo; + struct foo *foo_array; + + void do_something_locked(struct foo *fp) + { + /* This works even if data_race() returns nonsense. */ + if (!data_race(global_flag)) { + spin_lock(&fp->f_lock); + if (!smp_load_acquire(&global_flag)) { + do_something(fp); + spin_unlock(&fp->f_lock); + return; + } + spin_unlock(&fp->f_lock); + } + spin_lock(&global_lock); + /* global_lock held, thus global flag cannot be set. */ + spin_lock(&fp->f_lock); + spin_unlock(&global_lock); + /* + * global_flag might be set here, but begin_global() + * will wait for ->f_lock to be released. + */ + do_something(fp); + spin_unlock(&fp->f_lock); + } + + void begin_global(void) + { + int i; + + spin_lock(&global_lock); + WRITE_ONCE(global_flag, true); + for (i = 0; i < nfoo; i++) { + /* + * Wait for pre-existing local locks. One at + * a time to avoid lockdep limitations. + */ + spin_lock(&fp->f_lock); + spin_unlock(&fp->f_lock); + } + } + + void end_global(void) + { + smp_store_release(&global_flag, false); + spin_unlock(&global_lock); + } + +All code paths leading from the do_something_locked() function's first +read from global_flag acquire a lock, so endless load fusing cannot +happen. + +If the value read from global_flag is true, then global_flag is +rechecked while holding ->f_lock, which, if global_flag is now false, +prevents begin_global() from completing. It is therefore safe to invoke +do_something(). + +Otherwise, if either value read from global_flag is true, then after +global_lock is acquired global_flag must be false. The acquisition of +->f_lock will prevent any call to begin_global() from returning, which +means that it is safe to release global_lock and invoke do_something(). + +For this to work, only those foo structures in foo_array[] may be passed +to do_something_locked(). The reason for this is that the synchronization +with begin_global() relies on momentarily holding the lock of each and +every foo structure. + +The smp_load_acquire() and smp_store_release() are required because +changes to a foo structure between calls to begin_global() and +end_global() are carried out without holding that structure's ->f_lock. +The smp_load_acquire() and smp_store_release() ensure that the next +invocation of do_something() from do_something_locked() will see those +changes. + + Lockless Reads and Writes ------------------------- -- cgit v1.2.3-70-g09d2 From f92975d76d537c06a2118f9c3c63432c0f7c7a88 Mon Sep 17 00:00:00 2001 From: Manfred Spraul Date: Fri, 14 May 2021 11:40:06 -0700 Subject: tools/memory-model: Heuristics using data_race() must handle all values Data loaded for use by some sorts of heuristics can tolerate the occasional erroneous value. In this case the loads may use data_race() to give the compiler full freedom to optimize while also informing KCSAN of the intent. However, for this to work, the heuristic needs to be able to tolerate any erroneous value that could possibly arise. This commit therefore adds a paragraph spelling this out. Signed-off-by: Manfred Spraul Signed-off-by: Paul E. McKenney --- tools/memory-model/Documentation/access-marking.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/memory-model/Documentation/access-marking.txt b/tools/memory-model/Documentation/access-marking.txt index d96fe20ed582..82a489988726 100644 --- a/tools/memory-model/Documentation/access-marking.txt +++ b/tools/memory-model/Documentation/access-marking.txt @@ -126,6 +126,11 @@ consistent errors, which in turn are quite capable of breaking heuristics. Therefore use of data_race() should be limited to cases where some other code (such as a barrier() call) will force the occasional reload. +Note that this use case requires that the heuristic be able to handle +any possible error. In contrast, if the heuristics might be fatally +confused by one or more of the possible erroneous values, use READ_ONCE() +instead of data_race(). + In theory, plain C-language loads can also be used for this use case. However, in practice this will have the disadvantage of causing KCSAN to generate false positives because KCSAN will have no way of knowing -- cgit v1.2.3-70-g09d2 From 87859a8e3f083bd57b34e6a962544d775a76b15f Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 18 May 2021 10:47:43 -0700 Subject: tools/memory-model: Document data_race(READ_ONCE()) It is possible to cause KCSAN to ignore marked accesses by applying __no_kcsan to the function or applying data_race() to the marked accesses. These approaches allow the developer to restrict compiler optimizations while also causing KCSAN to ignore diagnostic accesses. This commit therefore updates the documentation accordingly. Signed-off-by: Paul E. McKenney --- .../memory-model/Documentation/access-marking.txt | 49 +++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/tools/memory-model/Documentation/access-marking.txt b/tools/memory-model/Documentation/access-marking.txt index 82a489988726..65778222183e 100644 --- a/tools/memory-model/Documentation/access-marking.txt +++ b/tools/memory-model/Documentation/access-marking.txt @@ -37,7 +37,9 @@ compiler's use of code-motion and common-subexpression optimizations. Therefore, if a given access is involved in an intentional data race, using READ_ONCE() for loads and WRITE_ONCE() for stores is usually preferable to data_race(), which in turn is usually preferable to plain -C-language accesses. +C-language accesses. It is permissible to combine #2 and #3, for example, +data_race(READ_ONCE(a)), which will both restrict compiler optimizations +and disable KCSAN diagnostics. KCSAN will complain about many types of data races involving plain C-language accesses, but marking all accesses involved in a given data @@ -86,6 +88,10 @@ that fail to exclude the updates. In this case, it is important to use data_race() for the diagnostic reads because otherwise KCSAN would give false-positive warnings about these diagnostic reads. +If it is necessary to both restrict compiler optimizations and disable +KCSAN diagnostics, use both data_race() and READ_ONCE(), for example, +data_race(READ_ONCE(a)). + In theory, plain C-language loads can also be used for this use case. However, in practice this will have the disadvantage of causing KCSAN to generate false positives because KCSAN will have no way of knowing @@ -279,19 +285,34 @@ tells KCSAN that data races are expected, and should be silently ignored. This data_race() also tells the human reading the code that read_foo_diagnostic() might sometimes return a bogus value. -However, please note that your kernel must be built with -CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n in order for KCSAN to -detect a buggy lockless write. If you need KCSAN to detect such a -write even if that write did not change the value of foo, you also -need CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n. If you need KCSAN to -detect such a write happening in an interrupt handler running on the -same CPU doing the legitimate lock-protected write, you also need -CONFIG_KCSAN_INTERRUPT_WATCHER=y. With some or all of these Kconfig -options set properly, KCSAN can be quite helpful, although it is not -necessarily a full replacement for hardware watchpoints. On the other -hand, neither are hardware watchpoints a full replacement for KCSAN -because it is not always easy to tell hardware watchpoint to conditionally -trap on accesses. +If it is necessary to suppress compiler optimization and also detect +buggy lockless writes, read_foo_diagnostic() can be updated as follows: + + void read_foo_diagnostic(void) + { + pr_info("Current value of foo: %d\n", data_race(READ_ONCE(foo))); + } + +Alternatively, given that KCSAN is to ignore all accesses in this function, +this function can be marked __no_kcsan and the data_race() can be dropped: + + void __no_kcsan read_foo_diagnostic(void) + { + pr_info("Current value of foo: %d\n", READ_ONCE(foo)); + } + +However, in order for KCSAN to detect buggy lockless writes, your kernel +must be built with CONFIG_KCSAN_ASSUME_PLAIN_WRITES_ATOMIC=n. If you +need KCSAN to detect such a write even if that write did not change +the value of foo, you also need CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n. +If you need KCSAN to detect such a write happening in an interrupt handler +running on the same CPU doing the legitimate lock-protected write, you +also need CONFIG_KCSAN_INTERRUPT_WATCHER=y. With some or all of these +Kconfig options set properly, KCSAN can be quite helpful, although +it is not necessarily a full replacement for hardware watchpoints. +On the other hand, neither are hardware watchpoints a full replacement +for KCSAN because it is not always easy to tell hardware watchpoint to +conditionally trap on accesses. Lock-Protected Writes With Lockless Reads -- cgit v1.2.3-70-g09d2 From 284c537a8aceb58ebcdc5a6cf7a21645ce6c4111 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Thu, 8 Jul 2021 17:16:45 -0400 Subject: clk: lmk04832: drop redundant fallthrough statements When the body of a case statement is empty, it is well understood that it is intentional and explicit fallthrough statements are not required. Drop them. Signed-off-by: Liam Beguin Link: https://lore.kernel.org/r/20210708211645.3621902-1-liambeguin@gmail.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-lmk04832.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index c7a3a029fb1e..8f02c0b88000 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -269,23 +269,14 @@ static bool lmk04832_regmap_rd_regs(struct device *dev, unsigned int reg) { switch (reg) { case LMK04832_REG_RST3W ... LMK04832_REG_ID_MASKREV: - fallthrough; case LMK04832_REG_ID_VNDR_MSB: - fallthrough; case LMK04832_REG_ID_VNDR_LSB: - fallthrough; case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB: - fallthrough; case LMK04832_REG_PLL2_LD: - fallthrough; case LMK04832_REG_PLL2_PD: - fallthrough; case LMK04832_REG_PLL1R_RST: - fallthrough; case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB: - fallthrough; case LMK04832_REG_RB_HOLDOVER: - fallthrough; case LMK04832_REG_SPI_LOCK: return true; default: @@ -297,27 +288,18 @@ static bool lmk04832_regmap_wr_regs(struct device *dev, unsigned int reg) { switch (reg) { case LMK04832_REG_RST3W: - fallthrough; case LMK04832_REG_POWERDOWN: return true; case LMK04832_REG_ID_DEV_TYPE ... LMK04832_REG_ID_MASKREV: - fallthrough; case LMK04832_REG_ID_VNDR_MSB: - fallthrough; case LMK04832_REG_ID_VNDR_LSB: return false; case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB: - fallthrough; case LMK04832_REG_PLL2_LD: - fallthrough; case LMK04832_REG_PLL2_PD: - fallthrough; case LMK04832_REG_PLL1R_RST: - fallthrough; case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB: - fallthrough; case LMK04832_REG_RB_HOLDOVER: - fallthrough; case LMK04832_REG_SPI_LOCK: return true; default: -- cgit v1.2.3-70-g09d2 From cf0a95659e659d36838e56cc439d3986dcb46870 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Jul 2021 22:34:50 +0300 Subject: clk: x86: Rename clk-lpt to more specific clk-lpss-atom The LPT stands for Lynxpoint PCH. However the driver is used on a few Intel Atom SoCs. Rename it to reflect this in a way how another clock driver, i.e. clk-pmc-atom, is called. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210722193450.35321-1-andriy.shevchenko@linux.intel.com Acked-by: Rafael J. Wysocki Signed-off-by: Stephen Boyd --- drivers/acpi/acpi_lpss.c | 6 ++-- drivers/clk/x86/Makefile | 2 +- drivers/clk/x86/clk-lpss-atom.c | 47 ++++++++++++++++++++++++++++++ drivers/clk/x86/clk-lpt.c | 47 ------------------------------ include/linux/platform_data/x86/clk-lpss.h | 2 +- 5 files changed, 53 insertions(+), 51 deletions(-) create mode 100644 drivers/clk/x86/clk-lpss-atom.c delete mode 100644 drivers/clk/x86/clk-lpt.c diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 894b7e6ae144..7f163074e4e4 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -385,7 +385,9 @@ static struct platform_device *lpss_clk_dev; static inline void lpt_register_clock_device(void) { - lpss_clk_dev = platform_device_register_simple("clk-lpt", -1, NULL, 0); + lpss_clk_dev = platform_device_register_simple("clk-lpss-atom", + PLATFORM_DEVID_NONE, + NULL, 0); } static int register_device_clock(struct acpi_device *adev, @@ -1337,7 +1339,7 @@ void __init acpi_lpss_init(void) const struct x86_cpu_id *id; int ret; - ret = lpt_clk_init(); + ret = lpss_atom_clk_init(); if (ret) return; diff --git a/drivers/clk/x86/Makefile b/drivers/clk/x86/Makefile index 18564efdc651..1244c4e568ff 100644 --- a/drivers/clk/x86/Makefile +++ b/drivers/clk/x86/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-fch.o -clk-x86-lpss-objs := clk-lpt.o +clk-x86-lpss-y := clk-lpss-atom.o obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o obj-$(CONFIG_CLK_LGM_CGU) += clk-cgu.o clk-cgu-pll.o clk-lgm.o diff --git a/drivers/clk/x86/clk-lpss-atom.c b/drivers/clk/x86/clk-lpss-atom.c new file mode 100644 index 000000000000..aa9d0bb98f8b --- /dev/null +++ b/drivers/clk/x86/clk-lpss-atom.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Intel Low Power Subsystem clocks. + * + * Copyright (C) 2013, Intel Corporation + * Authors: Mika Westerberg + * Heikki Krogerus + */ + +#include +#include +#include +#include +#include + +static int lpss_atom_clk_probe(struct platform_device *pdev) +{ + struct lpss_clk_data *drvdata; + struct clk *clk; + + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + /* LPSS free running clock */ + drvdata->name = "lpss_clk"; + clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, + 0, 100000000); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + drvdata->clk = clk; + platform_set_drvdata(pdev, drvdata); + return 0; +} + +static struct platform_driver lpss_atom_clk_driver = { + .driver = { + .name = "clk-lpss-atom", + }, + .probe = lpss_atom_clk_probe, +}; + +int __init lpss_atom_clk_init(void) +{ + return platform_driver_register(&lpss_atom_clk_driver); +} diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c deleted file mode 100644 index fbe9fd3ed948..000000000000 --- a/drivers/clk/x86/clk-lpt.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel Low Power Subsystem clocks. - * - * Copyright (C) 2013, Intel Corporation - * Authors: Mika Westerberg - * Heikki Krogerus - */ - -#include -#include -#include -#include -#include - -static int lpt_clk_probe(struct platform_device *pdev) -{ - struct lpss_clk_data *drvdata; - struct clk *clk; - - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - - /* LPSS free running clock */ - drvdata->name = "lpss_clk"; - clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, - 0, 100000000); - if (IS_ERR(clk)) - return PTR_ERR(clk); - - drvdata->clk = clk; - platform_set_drvdata(pdev, drvdata); - return 0; -} - -static struct platform_driver lpt_clk_driver = { - .driver = { - .name = "clk-lpt", - }, - .probe = lpt_clk_probe, -}; - -int __init lpt_clk_init(void) -{ - return platform_driver_register(&lpt_clk_driver); -} diff --git a/include/linux/platform_data/x86/clk-lpss.h b/include/linux/platform_data/x86/clk-lpss.h index 207e1a317800..41df326583f9 100644 --- a/include/linux/platform_data/x86/clk-lpss.h +++ b/include/linux/platform_data/x86/clk-lpss.h @@ -15,6 +15,6 @@ struct lpss_clk_data { struct clk *clk; }; -extern int lpt_clk_init(void); +extern int lpss_atom_clk_init(void); #endif /* __CLK_LPSS_H */ -- cgit v1.2.3-70-g09d2 From 04a572c51a33bdebf9e31afb874fb36a8d2a6c17 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Sun, 27 Jun 2021 21:59:24 +0300 Subject: dt-bindings: clock: qcom: rpmcc: Document SM6115 compatible Add the dt-binding for the RPM Clock Controller on the SM4250/6115 SoCs. Signed-off-by: Iskren Chernev Link: https://lore.kernel.org/r/20210627185927.695411-3-iskren.chernev@gmail.com Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 1 + include/dt-bindings/clock/qcom,rpmcc.h | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt index 6cf5a7ec2b4c..0045583f02b5 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt @@ -25,6 +25,7 @@ Required properties : "qcom,rpmcc-msm8998", "qcom,rpmcc" "qcom,rpmcc-qcs404", "qcom,rpmcc" "qcom,rpmcc-sdm660", "qcom,rpmcc" + "qcom,rpmcc-sm6115", "qcom,rpmcc" - #clock-cells : shall contain 1 diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h index 8aaba7cd9589..aa834d516234 100644 --- a/include/dt-bindings/clock/qcom,rpmcc.h +++ b/include/dt-bindings/clock/qcom,rpmcc.h @@ -149,5 +149,15 @@ #define RPM_SMD_CE2_A_CLK 103 #define RPM_SMD_CE3_CLK 104 #define RPM_SMD_CE3_A_CLK 105 +#define RPM_SMD_QUP_CLK 106 +#define RPM_SMD_QUP_A_CLK 107 +#define RPM_SMD_MMRT_CLK 108 +#define RPM_SMD_MMRT_A_CLK 109 +#define RPM_SMD_MMNRT_CLK 110 +#define RPM_SMD_MMNRT_A_CLK 111 +#define RPM_SMD_SNOC_PERIPH_CLK 112 +#define RPM_SMD_SNOC_PERIPH_A_CLK 113 +#define RPM_SMD_SNOC_LPASS_CLK 114 +#define RPM_SMD_SNOC_LPASS_A_CLK 115 #endif -- cgit v1.2.3-70-g09d2 From 4b1ec711ec2e97fca93adf6640fa5fd61fc17827 Mon Sep 17 00:00:00 2001 From: Martin Botka Date: Tue, 29 Jun 2021 12:26:22 +0200 Subject: dt-bindings: clk: qcom: smd-rpm: Document SM6125 compatible Document the newly added compatible for sm6125 rpmcc. Signed-off-by: Martin Botka Link: https://lore.kernel.org/r/20210629102624.194378-3-martin.botka@somainline.org Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt index 0045583f02b5..0e92747e53da 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt @@ -26,6 +26,7 @@ Required properties : "qcom,rpmcc-qcs404", "qcom,rpmcc" "qcom,rpmcc-sdm660", "qcom,rpmcc" "qcom,rpmcc-sm6115", "qcom,rpmcc" + "qcom,rpmcc-sm6125", "qcom,rpmcc" - #clock-cells : shall contain 1 -- cgit v1.2.3-70-g09d2 From 75ba9a715cb65e9c3fb17f13929d8741e570795f Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Tue, 8 Jun 2021 11:09:05 +0800 Subject: dmaengine: xilinx_dma: Use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). Reported-by: Hulk Robot Signed-off-by: Baokun Li Reviewed-by: Radhey Shyam Pandey Link: https://lore.kernel.org/r/20210608030905.2818831-1-libaokun1@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 4b9530a7bf65..213e1a7314b7 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -1420,8 +1420,7 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan) chan->desc_submitcount++; chan->desc_pendingcount--; - list_del(&desc->node); - list_add_tail(&desc->node, &chan->active_list); + list_move_tail(&desc->node, &chan->active_list); if (chan->desc_submitcount == chan->num_frms) chan->desc_submitcount = 0; -- cgit v1.2.3-70-g09d2 From df208d63cfc5128529059d28565bd8754da2dbd5 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Wed, 9 Jun 2021 15:28:02 +0800 Subject: dmaengine: fsl-dpaa2-qdma: Use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). Reported-by: Hulk Robot Signed-off-by: Baokun Li Link: https://lore.kernel.org/r/20210609072802.1368785-1-libaokun1@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c index 4ae057922ef1..a0358f2c5cbb 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -291,9 +291,8 @@ static void dpaa2_qdma_issue_pending(struct dma_chan *chan) err = dpaa2_io_service_enqueue_fq(NULL, dpaa2_chan->fqid, fd); if (err) { - list_del(&dpaa2_comp->list); - list_add_tail(&dpaa2_comp->list, - &dpaa2_chan->comp_free); + list_move_tail(&dpaa2_comp->list, + &dpaa2_chan->comp_free); } } err_enqueue: @@ -626,8 +625,7 @@ static void dpaa2_qdma_free_desc(struct virt_dma_desc *vdesc) dpaa2_comp = to_fsl_qdma_comp(vdesc); qchan = dpaa2_comp->qchan; spin_lock_irqsave(&qchan->queue_lock, flags); - list_del(&dpaa2_comp->list); - list_add_tail(&dpaa2_comp->list, &qchan->comp_free); + list_move_tail(&dpaa2_comp->list, &qchan->comp_free); spin_unlock_irqrestore(&qchan->queue_lock, flags); } -- cgit v1.2.3-70-g09d2 From 48594dbf793a15ee1a63ed879691cf436c14f459 Mon Sep 17 00:00:00 2001 From: Baokun Li Date: Wed, 9 Jun 2021 15:13:49 +0800 Subject: dmaengine: zynqmp_dma: Use list_move_tail instead of list_del/list_add_tail Using list_move_tail() instead of list_del() + list_add_tail(). Reported-by: Hulk Robot Signed-off-by: Baokun Li Link: https://lore.kernel.org/r/20210609071349.1336853-1-libaokun1@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/xilinx/zynqmp_dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index 5fecf5aa6e85..97f02f8eb03a 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -434,8 +434,7 @@ static void zynqmp_dma_free_descriptor(struct zynqmp_dma_chan *chan, struct zynqmp_dma_desc_sw *child, *next; chan->desc_free_cnt++; - list_del(&sdesc->node); - list_add_tail(&sdesc->node, &chan->free_list); + list_move_tail(&sdesc->node, &chan->free_list); list_for_each_entry_safe(child, next, &sdesc->tx_list, node) { chan->desc_free_cnt++; list_move_tail(&child->node, &chan->free_list); -- cgit v1.2.3-70-g09d2 From 26f1ca91d242a506bc4461c5b8f33f457d2608ba Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 16 Jun 2021 22:34:38 +0200 Subject: dmaengine: hisi_dma: Remove some useless code When using 'pcim_enable_device()', 'pci_alloc_irq_vectors()' is auto-magically a managed function. It is useless (but harmless) to record an action to explicitly call 'pci_free_irq_vectors()'. So keep things simple, comment why and how these resources are freed, axe some useless code and save some memory. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/4f8932e2d0d8d092bf60272511100030e013bc72.1623875508.git.christophe.jaillet@wanadoo.fr Signed-off-by: Vinod Koul --- drivers/dma/hisi_dma.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index a259ee010e9b..c855a0e4f9ff 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -133,11 +133,6 @@ static inline void hisi_dma_update_bit(void __iomem *addr, u32 pos, bool val) writel_relaxed(tmp, addr); } -static void hisi_dma_free_irq_vectors(void *data) -{ - pci_free_irq_vectors(data); -} - static void hisi_dma_pause_dma(struct hisi_dma_dev *hdma_dev, u32 index, bool pause) { @@ -544,6 +539,7 @@ static int hisi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_drvdata(pdev, hdma_dev); pci_set_master(pdev); + /* This will be freed by 'pcim_release()'. See 'pcim_enable_device()' */ ret = pci_alloc_irq_vectors(pdev, HISI_DMA_MSI_NUM, HISI_DMA_MSI_NUM, PCI_IRQ_MSI); if (ret < 0) { @@ -551,10 +547,6 @@ static int hisi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } - ret = devm_add_action_or_reset(dev, hisi_dma_free_irq_vectors, pdev); - if (ret) - return ret; - dma_dev = &hdma_dev->dma_dev; dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); dma_dev->device_free_chan_resources = hisi_dma_free_chan_resources; -- cgit v1.2.3-70-g09d2 From 4aece33cacf726d34ecd8824aee369652ec2beec Mon Sep 17 00:00:00 2001 From: Olivier Dautricourt Date: Thu, 17 Jun 2021 21:52:32 +0200 Subject: dt-bindings: dma: altera-msgdma: make response port optional Response port is not required in some configuration of the IP core. Signed-off-by: Olivier Dautricourt Reviewed-by: Rob Herring Reviewed-by: Stefan Roese Link: https://lore.kernel.org/r/fb28146a23a182be9e5435c1d3e5cac36b372294.1623898678.git.olivier.dautricourt@orolia.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/altr,msgdma.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/altr,msgdma.yaml b/Documentation/devicetree/bindings/dma/altr,msgdma.yaml index a4f9fe23dcd9..b193ee2db4a7 100644 --- a/Documentation/devicetree/bindings/dma/altr,msgdma.yaml +++ b/Documentation/devicetree/bindings/dma/altr,msgdma.yaml @@ -24,13 +24,15 @@ properties: items: - description: Control and Status Register Slave Port - description: Descriptor Slave Port - - description: Response Slave Port + - description: Response Slave Port (Optional) + minItems: 2 reg-names: items: - const: csr - const: desc - const: resp + minItems: 2 interrupts: maxItems: 1 -- cgit v1.2.3-70-g09d2 From af2eec750281e581a16b6449b83ce5e994b79d89 Mon Sep 17 00:00:00 2001 From: Olivier Dautricourt Date: Thu, 17 Jun 2021 21:53:18 +0200 Subject: dmaengine: altera-msgdma: make response port optional The response slave port can be disabled in some configuration [1] and csr + MSGDMA_CSR_RESP_FILL_LEVEL will be 0 even if transfer has suceeded. We have to only rely on the interrupts in that scenario. This was tested on cyclone V with the controller resp port disabled. [1] https://www.intel.com/content/www/us/en/programmable/documentation/sfo1400787952932.html 30.3.1.2 30.3.1.3 30.5.5 Fixes: https://forum.rocketboards.org/t/ip-msgdma-linux-driver/1919 Signed-off-by: Olivier Dautricourt Reviewed-by: Stefan Roese Link: https://lore.kernel.org/r/8220756f2191ca08cb21702252d1f2d4f753a7f5.1623898678.git.olivier.dautricourt@orolia.com Signed-off-by: Vinod Koul --- drivers/dma/altera-msgdma.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index 0fe0676f8e1d..5a2c7573b692 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -691,10 +691,14 @@ static void msgdma_tasklet(struct tasklet_struct *t) spin_lock_irqsave(&mdev->lock, flags); - /* Read number of responses that are available */ - count = ioread32(mdev->csr + MSGDMA_CSR_RESP_FILL_LEVEL); - dev_dbg(mdev->dev, "%s (%d): response count=%d\n", - __func__, __LINE__, count); + if (mdev->resp) { + /* Read number of responses that are available */ + count = ioread32(mdev->csr + MSGDMA_CSR_RESP_FILL_LEVEL); + dev_dbg(mdev->dev, "%s (%d): response count=%d\n", + __func__, __LINE__, count); + } else { + count = 1; + } while (count--) { /* @@ -703,8 +707,12 @@ static void msgdma_tasklet(struct tasklet_struct *t) * have any real values, like transferred bytes or error * bits. So we need to just drop these values. */ - size = ioread32(mdev->resp + MSGDMA_RESP_BYTES_TRANSFERRED); - status = ioread32(mdev->resp + MSGDMA_RESP_STATUS); + if (mdev->resp) { + size = ioread32(mdev->resp + + MSGDMA_RESP_BYTES_TRANSFERRED); + status = ioread32(mdev->resp + + MSGDMA_RESP_STATUS); + } msgdma_complete_descriptor(mdev); msgdma_chan_desc_cleanup(mdev); @@ -757,14 +765,21 @@ static void msgdma_dev_remove(struct msgdma_device *mdev) } static int request_and_map(struct platform_device *pdev, const char *name, - struct resource **res, void __iomem **ptr) + struct resource **res, void __iomem **ptr, + bool optional) { struct resource *region; struct device *device = &pdev->dev; *res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); if (*res == NULL) { - dev_err(device, "resource %s not defined\n", name); + if (optional) { + *ptr = NULL; + dev_info(device, "optional resource %s not defined\n", + name); + return 0; + } + dev_err(device, "mandatory resource %s not defined\n", name); return -ENODEV; } @@ -805,17 +820,17 @@ static int msgdma_probe(struct platform_device *pdev) mdev->dev = &pdev->dev; /* Map CSR space */ - ret = request_and_map(pdev, "csr", &dma_res, &mdev->csr); + ret = request_and_map(pdev, "csr", &dma_res, &mdev->csr, false); if (ret) return ret; /* Map (extended) descriptor space */ - ret = request_and_map(pdev, "desc", &dma_res, &mdev->desc); + ret = request_and_map(pdev, "desc", &dma_res, &mdev->desc, false); if (ret) return ret; /* Map response space */ - ret = request_and_map(pdev, "resp", &dma_res, &mdev->resp); + ret = request_and_map(pdev, "resp", &dma_res, &mdev->resp, true); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From ef94b0413bf4e0d328989fecf5b773e82c8794ac Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Thu, 24 Jun 2021 11:39:58 +0200 Subject: dt-bindings: dma: add alternative REQ/ACK protocol selection in stm32-dma Default REQ/ACK protocol consists in maintaining ACK signal up to the removal of REQuest and the transfer completion. In case of alternative REQ/ACK protocol, ACK de-assertion does not wait the removal of the REQuest, but only the transfer completion. Due to a possible DMA stream lock when transferring data to/from STM32 USART/UART, this new bindings allow to select this alternative protocol in device tree, especially for STM32 USART/UART nodes. Signed-off-by: Amelie Delaunay Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210624093959.142265-2-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/dma/st,stm32-dma.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml index 2a5325f480f6..4bf676fd25dc 100644 --- a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml +++ b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml @@ -40,6 +40,13 @@ description: | 0x0: FIFO mode with threshold selectable with bit 0-1 0x1: Direct mode: each DMA request immediately initiates a transfer from/to the memory, FIFO is bypassed. + -bit 4: alternative DMA request/acknowledge protocol + 0x0: Use standard DMA ACK management, where ACK signal is maintained + up to the removal of request and transfer completion + 0x1: Use alternative DMA ACK management, where ACK de-assertion does + not wait for the de-assertion of the REQuest, ACK is only managed + by transfer completion. This must only be used on channels + managing transfers for STM32 USART/UART. maintainers: -- cgit v1.2.3-70-g09d2 From 2b5b74054c214ed2192713b88799fbc4cda8a1fe Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Thu, 24 Jun 2021 11:39:59 +0200 Subject: dmaengine: stm32-dma: add alternate REQ/ACK protocol management STM32 USART/UART is not managing correctly the default DMA REQ/ACK protocol leading to possibly lock the DMA stream. Default protocol consists in maintaining ACK signal up to the removal of REQuest and the transfer completion. In case of alternative REQ/ACK protocol, ACK de-assertion does not wait the removal of the REQuest, but only the transfer completion. This patch retrieves the need of the alternative protocol through the device tree, and sets the protocol accordingly. It also unwrap STM32_DMA_DIRECT_MODE_GET macro definition for consistency with new STM32_DMA_ALT_ACK_MODE_GET macro definition. Signed-off-by: Amelie Delaunay Link: https://lore.kernel.org/r/20210624093959.142265-3-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul --- drivers/dma/stm32-dma.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index f54ecb123a52..d3aa34b3d2f7 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -60,6 +60,7 @@ #define STM32_DMA_SCR_PSIZE_GET(n) ((n & STM32_DMA_SCR_PSIZE_MASK) >> 11) #define STM32_DMA_SCR_DIR_MASK GENMASK(7, 6) #define STM32_DMA_SCR_DIR(n) ((n & 0x3) << 6) +#define STM32_DMA_SCR_TRBUFF BIT(20) /* Bufferable transfer for USART/UART */ #define STM32_DMA_SCR_CT BIT(19) /* Target in double buffer */ #define STM32_DMA_SCR_DBM BIT(18) /* Double Buffer Mode */ #define STM32_DMA_SCR_PINCOS BIT(15) /* Peripheral inc offset size */ @@ -138,8 +139,9 @@ #define STM32_DMA_THRESHOLD_FTR_MASK GENMASK(1, 0) #define STM32_DMA_THRESHOLD_FTR_GET(n) ((n) & STM32_DMA_THRESHOLD_FTR_MASK) #define STM32_DMA_DIRECT_MODE_MASK BIT(2) -#define STM32_DMA_DIRECT_MODE_GET(n) (((n) & STM32_DMA_DIRECT_MODE_MASK) \ - >> 2) +#define STM32_DMA_DIRECT_MODE_GET(n) (((n) & STM32_DMA_DIRECT_MODE_MASK) >> 2) +#define STM32_DMA_ALT_ACK_MODE_MASK BIT(4) +#define STM32_DMA_ALT_ACK_MODE_GET(n) (((n) & STM32_DMA_ALT_ACK_MODE_MASK) >> 4) enum stm32_dma_width { STM32_DMA_BYTE, @@ -1252,6 +1254,8 @@ static void stm32_dma_set_config(struct stm32_dma_chan *chan, chan->threshold = STM32_DMA_THRESHOLD_FTR_GET(cfg->features); if (STM32_DMA_DIRECT_MODE_GET(cfg->features)) chan->threshold = STM32_DMA_FIFO_THRESHOLD_NONE; + if (STM32_DMA_ALT_ACK_MODE_GET(cfg->features)) + chan->chan_reg.dma_scr |= STM32_DMA_SCR_TRBUFF; } static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec, -- cgit v1.2.3-70-g09d2 From 48ae638be56b43cde9ddca20fc5678401886f5db Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Sat, 10 Jul 2021 17:54:32 +0100 Subject: ppc4xx: replace sscanf() by kstrtoul() Fix the checkpatch.pl warning: "Prefer kstrto to single variable sscanf". Signed-off-by: Salah Triki Link: https://lore.kernel.org/r/20210710165432.GA690401@pc Signed-off-by: Vinod Koul --- drivers/dma/ppc4xx/adma.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index df7704053d91..e2b5129c5f84 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4319,6 +4319,7 @@ static ssize_t enable_store(struct device_driver *dev, const char *buf, size_t count) { unsigned long val; + int err; if (!count || count > 11) return -EINVAL; @@ -4327,7 +4328,10 @@ static ssize_t enable_store(struct device_driver *dev, const char *buf, return -EFAULT; /* Write a key */ - sscanf(buf, "%lx", &val); + err = kstrtoul(buf, 16, &val); + if (err) + return err; + dcr_write(ppc440spe_mq_dcr_host, DCRN_MQ0_XORBA, val); isync(); @@ -4368,7 +4372,7 @@ static ssize_t poly_store(struct device_driver *dev, const char *buf, size_t count) { unsigned long reg, val; - + int err; #ifdef CONFIG_440SP /* 440SP uses default 0x14D polynomial only */ return -EINVAL; @@ -4378,7 +4382,9 @@ static ssize_t poly_store(struct device_driver *dev, const char *buf, return -EINVAL; /* e.g., 0x14D or 0x11D */ - sscanf(buf, "%lx", &val); + err = kstrtoul(buf, 16, &val); + if (err) + return err; if (val & ~0x1FF) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 059e969c2a7d9efb463c0d8c574f1b3f1e010bed Mon Sep 17 00:00:00 2001 From: Zhang Qilong Date: Mon, 7 Jun 2021 14:46:40 +0800 Subject: dmaengine: tegra210-adma: Using pm_runtime_resume_and_get to replace open coding use pm_runtime_resume_and_get() to replace pm_runtime_get_sync and pm_runtime_put_noidle. this change is just to simplify the code, there is no actual functional change. Signed-off-by: Zhang Qilong Link: https://lore.kernel.org/r/20210607064640.121394-4-zhangqilong3@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/tegra210-adma.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index 4735742e826d..b1115a6d1935 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -655,9 +655,8 @@ static int tegra_adma_alloc_chan_resources(struct dma_chan *dc) return ret; } - ret = pm_runtime_get_sync(tdc2dev(tdc)); + ret = pm_runtime_resume_and_get(tdc2dev(tdc)); if (ret < 0) { - pm_runtime_put_noidle(tdc2dev(tdc)); free_irq(tdc->irq, tdc); return ret; } @@ -869,10 +868,8 @@ static int tegra_adma_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) { - pm_runtime_put_noidle(&pdev->dev); + if (ret < 0) goto rpm_disable; - } ret = tegra_adma_init(tdma); if (ret) -- cgit v1.2.3-70-g09d2 From 16df55ce104125b4bf1070467973070fb6fc16ff Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 25 Jul 2021 09:02:56 -0700 Subject: mips: clean up (remove) kernel-doc in cavium-octeon/executive/ Remove all kernel-doc notation in arch/mips/cavium-octeon/executive/. This removes dozens of kernel-doc warnings. Most of these functions are static and don't need to be documented with kernel-doc. The function comments are still present for anyone who wants to read them. These files are part of the OCTEON SDK so presumably they are documented there as well. arch/mips/cavium-octeon/executive/cvmx-bootmem.c:61: warning: Function parameter or member 'addr' not described in 'CVMX_BOOTMEM_NAMED_GET_FIELD' arch/mips/cavium-octeon/executive/cvmx-bootmem.c:61: warning: Function parameter or member 'field' not described in 'CVMX_BOOTMEM_NAMED_GET_FIELD' arch/mips/cavium-octeon/executive/cvmx-bootmem.c:61: warning: expecting prototype for This macro returns a member of the(). Prototype was for CVMX_BOOTMEM_NAMED_GET_FIELD() instead arch/mips/cavium-octeon/executive/cvmx-bootmem.c:77: warning: Function parameter or member 'base' not described in '__cvmx_bootmem_desc_get' arch/mips/cavium-octeon/executive/cvmx-bootmem.c:77: warning: Function parameter or member 'offset' not described in '__cvmx_bootmem_desc_get' arch/mips/cavium-octeon/executive/cvmx-bootmem.c:77: warning: Function parameter or member 'size' not described in '__cvmx_bootmem_desc_get' arch/mips/cavium-octeon/executive/cvmx-bootmem.c:77: warning: expecting prototype for This function is the implementation of the get macros defined(). Prototype was for __cvmx_bootmem_desc_get() instead arch/mips/cavium-octeon/executive/cvmx-bootmem.c:133: warning: expecting prototype for Allocate a block of memory from the free list that was(). Prototype was for cvmx_bootmem_alloc_range() instead arch/mips/cavium-octeon/executive/cvmx-bootmem.c:554: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Finds a named memory block by name. arch/mips/cavium-octeon/executive/cvmx-bootmem.c:661: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Frees a named block. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-helper-board.c:64: warning: expecting prototype for Return the MII PHY address associated with the given IPD(). Prototype was for cvmx_helper_board_get_mii_address() instead arch/mips/cavium-octeon/executive/cvmx-helper-board.c:211: warning: expecting prototype for This function is the board specific method of determining an(). Prototype was for __cvmx_helper_board_link_get() instead arch/mips/cavium-octeon/executive/cvmx-helper-board.c:278: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * This function is called by cvmx_helper_interface_probe() after it arch/mips/cavium-octeon/executive/cvmx-helper-board.c:324: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Get the clock type used for the USB block based on board type. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-spi.c:77: warning: expecting prototype for Get current SPI4 initialization callbacks(). Prototype was for cvmx_spi_get_callbacks() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:87: warning: expecting prototype for Set new SPI4 initialization callbacks(). Prototype was for cvmx_spi_set_callbacks() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:92: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Initialize and start the SPI interface. arch/mips/cavium-octeon/executive/cvmx-spi.c:151: warning: expecting prototype for This routine restarts the SPI interface after it has lost synchronization(). Prototype was for cvmx_spi_restart_interface() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:196: warning: expecting prototype for Callback to perform SPI4 reset(). Prototype was for cvmx_spi_reset_cb() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:313: warning: expecting prototype for Callback to setup calendar and miscellaneous settings before clock detection(). Prototype was for cvmx_spi_calendar_setup_cb() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:431: warning: expecting prototype for Callback to perform clock detection(). Prototype was for cvmx_spi_clock_detect_cb() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:509: warning: expecting prototype for Callback to perform link training(). Prototype was for cvmx_spi_training_cb() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:578: warning: expecting prototype for Callback to perform calendar data synchronization(). Prototype was for cvmx_spi_calendar_sync_cb() instead arch/mips/cavium-octeon/executive/cvmx-spi.c:634: warning: expecting prototype for Callback to handle interface up(). Prototype was for cvmx_spi_interface_up_cb() instead ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c:67: warning: expecting prototype for Probe a XAUI interface and determine the number of ports(). Prototype was for __cvmx_helper_xaui_probe() instead arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c:106: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Bringup and enable a XAUI interface. After this call packet arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c:253: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return the link state of an IPD/PKO port as returned by arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c:292: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Configure an IPD/PKO port for the specified link state. This ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-pko.c:43: warning: Function parameter or member 'interface' not described in '__cvmx_pko_int' arch/mips/cavium-octeon/executive/cvmx-pko.c:43: warning: Function parameter or member 'index' not described in '__cvmx_pko_int' arch/mips/cavium-octeon/executive/cvmx-pko.c:43: warning: expecting prototype for Internal state of packet output(). Prototype was for __cvmx_pko_int() instead arch/mips/cavium-octeon/executive/cvmx-pko.c:186: warning: expecting prototype for Call before any other calls to initialize the packet(). Prototype was for cvmx_pko_initialize_global() instead arch/mips/cavium-octeon/executive/cvmx-pko.c:241: warning: expecting prototype for This function does per(). Prototype was for cvmx_pko_initialize_local() instead arch/mips/cavium-octeon/executive/cvmx-pko.c:247: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Enables the packet output hardware. It must already be arch/mips/cavium-octeon/executive/cvmx-pko.c:270: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Disables the packet output. Does not affect any configuration. arch/mips/cavium-octeon/executive/cvmx-pko.c:282: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Reset the packet output. arch/mips/cavium-octeon/executive/cvmx-pko.c:293: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Shutdown and free resources required by packet output. arch/mips/cavium-octeon/executive/cvmx-pko.c:324: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Configure a output port and the associated queues for use. arch/mips/cavium-octeon/executive/cvmx-pko.c:555: warning: expecting prototype for Show map of ports(). Prototype was for cvmx_pko_show_queue_map() instead arch/mips/cavium-octeon/executive/cvmx-pko.c:577: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Rate limit a PKO port to a max packets/sec. This function is only arch/mips/cavium-octeon/executive/cvmx-pko.c:610: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Rate limit a PKO port to a max bits/sec. This function is only ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:49: warning: cannot understand function prototype: '__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr; ' arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:53: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Initialize the Global queue state pointer. arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:101: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Initialize a command queue for use. The initial FPA buffer is arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:199: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Shutdown a queue a free it's command buffers to the FPA. The arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:235: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return the number of command words pending in the queue. This arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c:291: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return the command buffer to be written to. The purpose of this ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:53: warning: expecting prototype for Probe RGMII ports and determine the number present(). Prototype was for __cvmx_helper_rgmii_probe() instead arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:92: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Put an RGMII interface in loopback mode. Internal packets sent arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:135: warning: expecting prototype for Workaround ASX setup errata with CN38XX pass1(). Prototype was for __cvmx_helper_errata_asx_pass1() instead arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:152: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Configure all of the ASX, GMX, and PKO registers required arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:255: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return the link state of an IPD/PKO port as returned by arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c:284: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Configure an IPD/PKO port for the specified link state. This -- arch/mips/cavium-octeon/executive/cvmx-l2c.c:768: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return log base 2 of the number of sets in the L2 cache arch/mips/cavium-octeon/executive/cvmx-l2c.c:861: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Flush a line from the L2 cache Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Aditya Srivastava Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- arch/mips/cavium-octeon/executive/cvmx-bootmem.c | 10 +++++----- arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c | 12 ++++++------ .../cavium-octeon/executive/cvmx-helper-board.c | 8 ++++---- .../cavium-octeon/executive/cvmx-helper-rgmii.c | 12 ++++++------ .../cavium-octeon/executive/cvmx-helper-xaui.c | 8 ++++---- arch/mips/cavium-octeon/executive/cvmx-l2c.c | 9 ++++----- arch/mips/cavium-octeon/executive/cvmx-pko.c | 22 +++++++++++----------- arch/mips/cavium-octeon/executive/cvmx-spi.c | 20 ++++++++++---------- 8 files changed, 50 insertions(+), 51 deletions(-) diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c index e794b2d53adf..b63ad5d42cc7 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c @@ -44,7 +44,7 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc; /* See header file for descriptions of functions */ -/** +/* * This macro returns a member of the * cvmx_bootmem_named_block_desc_t structure. These members can't * be directly addressed as they might be in memory not directly @@ -60,7 +60,7 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc; offsetof(struct cvmx_bootmem_named_block_desc, field), \ sizeof_field(struct cvmx_bootmem_named_block_desc, field)) -/** +/* * This function is the implementation of the get macros defined * for individual structure members. The argument are generated * by the macros inorder to read only the needed memory. @@ -115,7 +115,7 @@ static uint64_t cvmx_bootmem_phy_get_next(uint64_t addr) return cvmx_read64_uint64((addr + NEXT_OFFSET) | (1ull << 63)); } -/** +/* * Allocate a block of memory from the free list that was * passed to the application by the bootloader within a specified * address range. This is an allocate-only algorithm, so @@ -550,7 +550,7 @@ bootmem_free_done: } -/** +/* * Finds a named memory block by name. * Also used for finding an unused entry in the named block table. * @@ -657,7 +657,7 @@ struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name) } EXPORT_SYMBOL(cvmx_bootmem_find_named_block); -/** +/* * Frees a named block. * * @name: name of block to free diff --git a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c index fb42e8e21ea0..20189e9ad94d 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c +++ b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c @@ -42,14 +42,14 @@ #include #include -/** +/* * This application uses this pointer to access the global queue * state. It points to a bootmem named block. */ __cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr; EXPORT_SYMBOL_GPL(__cvmx_cmd_queue_state_ptr); -/** +/* * Initialize the Global queue state pointer. * * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code @@ -84,7 +84,7 @@ static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void) return CVMX_CMD_QUEUE_SUCCESS; } -/** +/* * Initialize a command queue for use. The initial FPA buffer is * allocated and the hardware unit is configured to point to the * new command queue. @@ -182,7 +182,7 @@ cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id, } } -/** +/* * Shutdown a queue a free it's command buffers to the FPA. The * hardware connected to the queue must be stopped before this * function is called. @@ -218,7 +218,7 @@ cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id) return CVMX_CMD_QUEUE_SUCCESS; } -/** +/* * Return the number of command words pending in the queue. This * function may be relatively slow for some hardware units. * @@ -274,7 +274,7 @@ int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id) return CVMX_CMD_QUEUE_INVALID_PARAM; } -/** +/* * Return the command buffer to be written to. The purpose of this * function is to allow CVMX routine access t othe low level buffer * for initial hardware setup. User applications should not call this diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index abd11b7af22f..1daa0c6b6f4e 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -44,7 +44,7 @@ #include #include -/** +/* * Return the MII PHY address associated with the given IPD * port. A result of -1 means there isn't a MII capable PHY * connected to this port. On chips supporting multiple MII @@ -189,7 +189,7 @@ int cvmx_helper_board_get_mii_address(int ipd_port) return -1; } -/** +/* * This function is the board specific method of determining an * ethernet ports link speed. Most Octeon boards have Marvell PHYs * and are handled by the fall through case. This function must be @@ -274,7 +274,7 @@ union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port) return result; } -/** +/* * This function is called by cvmx_helper_interface_probe() after it * determines the number of ports Octeon can support on a specific * interface. This function is the per board location to override @@ -320,7 +320,7 @@ int __cvmx_helper_board_interface_probe(int interface, int supported_ports) return supported_ports; } -/** +/* * Get the clock type used for the USB block based on board type. * Used by the USB code for auto configuration of clock type. * diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c index c4b58598aa9d..a8c3be4eb6f0 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c @@ -42,7 +42,7 @@ #include #include -/** +/* * Probe RGMII ports and determine the number present * * @interface: Interface to probe @@ -88,7 +88,7 @@ int __cvmx_helper_rgmii_probe(int interface) return num_ports; } -/** +/* * Put an RGMII interface in loopback mode. Internal packets sent * out will be received back again on the same port. Externally * received packets will echo back out. @@ -120,7 +120,7 @@ void cvmx_helper_rgmii_internal_loopback(int port) cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); } -/** +/* * Workaround ASX setup errata with CN38XX pass1 * * @interface: Interface to setup @@ -148,7 +148,7 @@ static int __cvmx_helper_errata_asx_pass1(int interface, int port, return 0; } -/** +/* * Configure all of the ASX, GMX, and PKO registers required * to get RGMII to function on the supplied interface. * @@ -251,7 +251,7 @@ int __cvmx_helper_rgmii_enable(int interface) return 0; } -/** +/* * Return the link state of an IPD/PKO port as returned by * auto negotiation. The result of this function may not match * Octeon's link config if auto negotiation has changed since @@ -280,7 +280,7 @@ union cvmx_helper_link_info __cvmx_helper_rgmii_link_get(int ipd_port) return __cvmx_helper_board_link_get(ipd_port); } -/** +/* * Configure an IPD/PKO port for the specified link state. This * function does not influence auto negotiation at the PHY level. * The passed link state must always match the link state returned diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c index 842990e8404f..fea71a85bb29 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c @@ -54,7 +54,7 @@ int __cvmx_helper_xaui_enumerate(int interface) return 1; } -/** +/* * Probe a XAUI interface and determine the number of ports * connected to it. The XAUI interface should still be down * after this call. @@ -102,7 +102,7 @@ int __cvmx_helper_xaui_probe(int interface) return __cvmx_helper_xaui_enumerate(interface); } -/** +/* * Bringup and enable a XAUI interface. After this call packet * I/O should be fully functional. This is called with IPD * enabled but PKO disabled. @@ -249,7 +249,7 @@ int __cvmx_helper_xaui_enable(int interface) return 0; } -/** +/* * Return the link state of an IPD/PKO port as returned by * auto negotiation. The result of this function may not match * Octeon's link config if auto negotiation has changed since @@ -288,7 +288,7 @@ union cvmx_helper_link_info __cvmx_helper_xaui_link_get(int ipd_port) return result; } -/** +/* * Configure an IPD/PKO port for the specified link state. This * function does not influence auto negotiation at the PHY level. * The passed link state must always match the link state returned diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index 83df0a963a8b..33b303691bc2 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -281,7 +281,7 @@ uint64_t cvmx_l2c_read_perf(uint32_t counter) } } -/** +/* * @INTERNAL * Helper function use to fault in cache lines for L2 cache locking * @@ -575,7 +575,7 @@ union __cvmx_l2c_tag { }; -/** +/* * @INTERNAL * Function to read a L2C tag. This code make the current core * the 'debug core' for the L2. This code must only be executed by @@ -764,9 +764,8 @@ int cvmx_l2c_get_cache_size_bytes(void) CVMX_CACHE_LINE_SIZE; } -/** +/* * Return log base 2 of the number of sets in the L2 cache - * Returns */ int cvmx_l2c_get_set_bits(void) { @@ -857,7 +856,7 @@ int cvmx_l2c_get_num_assoc(void) return l2_assoc; } -/** +/* * Flush a line from the L2 cache * This should only be called from one core at a time, as this routine * sets the core to the 'debug' core in order to flush the line. diff --git a/arch/mips/cavium-octeon/executive/cvmx-pko.c b/arch/mips/cavium-octeon/executive/cvmx-pko.c index b0efc35e95c4..7c4879e74318 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-pko.c +++ b/arch/mips/cavium-octeon/executive/cvmx-pko.c @@ -35,7 +35,7 @@ #include #include -/** +/* * Internal state of packet output */ @@ -176,7 +176,7 @@ static void __cvmx_pko_chip_init(void) } } -/** +/* * Call before any other calls to initialize the packet * output system. This does chip global config, and should only be * done by one core. @@ -229,7 +229,7 @@ void cvmx_pko_initialize_global(void) } } -/** +/* * This function does per-core initialization required by the PKO routines. * This must be called on all cores that will do packet output, and must * be called after the FPA has been initialized and filled with pages. @@ -243,7 +243,7 @@ int cvmx_pko_initialize_local(void) return 0; } -/** +/* * Enables the packet output hardware. It must already be * configured. */ @@ -266,7 +266,7 @@ void cvmx_pko_enable(void) cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64); } -/** +/* * Disables the packet output. Does not affect any configuration. */ void cvmx_pko_disable(void) @@ -278,7 +278,7 @@ void cvmx_pko_disable(void) } EXPORT_SYMBOL_GPL(cvmx_pko_disable); -/** +/* * Reset the packet output. */ static void __cvmx_pko_reset(void) @@ -289,7 +289,7 @@ static void __cvmx_pko_reset(void) cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64); } -/** +/* * Shutdown and free resources required by packet output. */ void cvmx_pko_shutdown(void) @@ -320,7 +320,7 @@ void cvmx_pko_shutdown(void) } EXPORT_SYMBOL_GPL(cvmx_pko_shutdown); -/** +/* * Configure a output port and the associated queues for use. * * @port: Port to configure. @@ -548,7 +548,7 @@ cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue, } #ifdef PKO_DEBUG -/** +/* * Show map of ports -> queues for different cores. */ void cvmx_pko_show_queue_map() @@ -573,7 +573,7 @@ void cvmx_pko_show_queue_map() } #endif -/** +/* * Rate limit a PKO port to a max packets/sec. This function is only * supported on CN51XX and higher, excluding CN58XX. * @@ -606,7 +606,7 @@ int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst) return 0; } -/** +/* * Rate limit a PKO port to a max bits/sec. This function is only * supported on CN51XX and higher, excluding CN58XX. * diff --git a/arch/mips/cavium-octeon/executive/cvmx-spi.c b/arch/mips/cavium-octeon/executive/cvmx-spi.c index f51957a3e915..eb9333e84a6b 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-spi.c +++ b/arch/mips/cavium-octeon/executive/cvmx-spi.c @@ -66,7 +66,7 @@ static cvmx_spi_callbacks_t cvmx_spi_callbacks = { .interface_up_cb = cvmx_spi_interface_up_cb }; -/** +/* * Get current SPI4 initialization callbacks * * @callbacks: Pointer to the callbacks structure.to fill @@ -78,7 +78,7 @@ void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks) memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks)); } -/** +/* * Set new SPI4 initialization callbacks * * @new_callbacks: Pointer to an updated callbacks structure. @@ -88,7 +88,7 @@ void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks) memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks)); } -/** +/* * Initialize and start the SPI interface. * * @interface: The identifier of the packet interface to configure and @@ -133,7 +133,7 @@ int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout, return res; } -/** +/* * This routine restarts the SPI interface after it has lost synchronization * with its correspondent system. * @@ -179,7 +179,7 @@ int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout) } EXPORT_SYMBOL_GPL(cvmx_spi_restart_interface); -/** +/* * Callback to perform SPI4 reset * * @interface: The identifier of the packet interface to configure and @@ -294,7 +294,7 @@ int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode) return 0; } -/** +/* * Callback to setup calendar and miscellaneous settings before clock detection * * @interface: The identifier of the packet interface to configure and @@ -413,7 +413,7 @@ int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode, return 0; } -/** +/* * Callback to perform clock detection * * @interface: The identifier of the packet interface to configure and @@ -491,7 +491,7 @@ int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout) return 0; } -/** +/* * Callback to perform link training * * @interface: The identifier of the packet interface to configure and @@ -560,7 +560,7 @@ int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout) return 0; } -/** +/* * Callback to perform calendar data synchronization * * @interface: The identifier of the packet interface to configure and @@ -617,7 +617,7 @@ int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout) return 0; } -/** +/* * Callback to handle interface up * * @interface: The identifier of the packet interface to configure and -- cgit v1.2.3-70-g09d2 From 64c888ce33602c66f1a043c1f7943e3d453186c2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 25 Jul 2021 09:02:57 -0700 Subject: mips: clean up kernel-doc in cavium-octeon/*.c Convert function comments to kernel-doc notation to remove kernel-doc warnings in arch/mips/cavium-octeon/*.c. Also clean up the comments in a few places. arch/mips/cavium-octeon/flash_setup.c:66: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Module/ driver initialization. -- arch/mips/cavium-octeon/setup.c:308: warning: expecting prototype for Return non zero if we are currently running in the Octeon simulator(). Prototype was for octeon_is_simulation() instead arch/mips/cavium-octeon/setup.c:314: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Return true if Octeon is in PCI Host mode. This means arch/mips/cavium-octeon/setup.c:334: warning: expecting prototype for Get the clock rate of Octeon(). Prototype was for octeon_get_clock_rate() instead arch/mips/cavium-octeon/setup.c:351: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Write to the LCD display connected to the bootbus. This display arch/mips/cavium-octeon/setup.c:380: warning: expecting prototype for Return the console uart passed by the bootloader(). Prototype was for octeon_get_boot_uart() instead arch/mips/cavium-octeon/setup.c:386: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Get the coremask Linux was booted on. arch/mips/cavium-octeon/setup.c:399: warning: expecting prototype for Check the hardware BIST results for a CPU(). Prototype was for octeon_check_cpu_bist() instead arch/mips/cavium-octeon/setup.c:432: warning: expecting prototype for Reboot Octeon(). Prototype was for octeon_restart() instead arch/mips/cavium-octeon/setup.c:452: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Permanently stop a core. arch/mips/cavium-octeon/setup.c:475: warning: expecting prototype for Halt the system(). Prototype was for octeon_halt() instead arch/mips/cavium-octeon/setup.c:520: warning: expecting prototype for Return a string representing the system type(). Prototype was for octeon_board_type_string() instead arch/mips/cavium-octeon/setup.c:661: warning: expecting prototype for Early entry point for arch setup(). Prototype was for prom_init() instead -- arch/mips/cavium-octeon/smp.c:100: warning: Function parameter or member 'cpu' not described in 'octeon_send_ipi_single' arch/mips/cavium-octeon/smp.c:100: warning: Function parameter or member 'action' not described in 'octeon_send_ipi_single' arch/mips/cavium-octeon/smp.c:100: warning: expecting prototype for Cause the function described by call_data to be executed on the passed(). Prototype was for octeon_send_ipi_single() instead arch/mips/cavium-octeon/smp.c:119: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Detect available CPUs, populate cpu_possible_mask arch/mips/cavium-octeon/smp.c:210: warning: Function parameter or member 'cpu' not described in 'octeon_boot_secondary' arch/mips/cavium-octeon/smp.c:210: warning: Function parameter or member 'idle' not described in 'octeon_boot_secondary' arch/mips/cavium-octeon/smp.c:210: warning: expecting prototype for Firmware CPU startup hook(). Prototype was for octeon_boot_secondary() instead arch/mips/cavium-octeon/smp.c:236: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * After we've done initial boot, this function is called to allow the arch/mips/cavium-octeon/smp.c:258: warning: Function parameter or member 'max_cpus' not described in 'octeon_prepare_cpus' arch/mips/cavium-octeon/smp.c:258: warning: expecting prototype for Callout to firmware before smp_init(). Prototype was for octeon_prepare_cpus() instead arch/mips/cavium-octeon/smp.c:276: warning: expecting prototype for Last chance for the board code to finish SMP initialization before(). Prototype was for octeon_smp_finish() instead Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Aditya Srivastava Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- arch/mips/cavium-octeon/flash_setup.c | 2 +- arch/mips/cavium-octeon/setup.c | 43 ++++++++++++++++++----------------- arch/mips/cavium-octeon/smp.c | 14 +++++------- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c index a5e8f4a784af..c8a8c6d359b9 100644 --- a/arch/mips/cavium-octeon/flash_setup.c +++ b/arch/mips/cavium-octeon/flash_setup.c @@ -62,7 +62,7 @@ static void octeon_flash_map_copy_to(struct map_info *map, unsigned long to, up(&octeon_bootbus_sem); } -/** +/* * Module/ driver initialization. * * Returns Zero on success diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 0ddd3cc16ee4..00bf269763cf 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -295,9 +295,10 @@ static int octeon_uart; extern asmlinkage void handle_int(void); /** - * Return non zero if we are currently running in the Octeon simulator + * octeon_is_simulation - Return non-zero if we are currently running + * in the Octeon simulator * - * Returns + * Return: non-0 if running in the Octeon simulator, 0 otherwise */ int octeon_is_simulation(void) { @@ -306,10 +307,10 @@ int octeon_is_simulation(void) EXPORT_SYMBOL(octeon_is_simulation); /** - * Return true if Octeon is in PCI Host mode. This means + * octeon_is_pci_host - Return true if Octeon is in PCI Host mode. This means * Linux can control the PCI bus. * - * Returns Non zero if Octeon in host mode. + * Return: Non-zero if Octeon is in host mode. */ int octeon_is_pci_host(void) { @@ -321,9 +322,9 @@ int octeon_is_pci_host(void) } /** - * Get the clock rate of Octeon + * octeon_get_clock_rate - Get the clock rate of Octeon * - * Returns Clock rate in HZ + * Return: Clock rate in HZ */ uint64_t octeon_get_clock_rate(void) { @@ -343,11 +344,11 @@ EXPORT_SYMBOL(octeon_get_io_clock_rate); /** - * Write to the LCD display connected to the bootbus. This display - * exists on most Cavium evaluation boards. If it doesn't exist, then - * this function doesn't do anything. - * + * octeon_write_lcd - Write to the LCD display connected to the bootbus. * @s: String to write + * + * This display exists on most Cavium evaluation boards. If it doesn't exist, + * then this function doesn't do anything. */ static void octeon_write_lcd(const char *s) { @@ -367,9 +368,9 @@ static void octeon_write_lcd(const char *s) } /** - * Return the console uart passed by the bootloader + * octeon_get_boot_uart - Return the console uart passed by the bootloader * - * Returns uart (0 or 1) + * Return: uart number (0 or 1) */ static int octeon_get_boot_uart(void) { @@ -378,9 +379,9 @@ static int octeon_get_boot_uart(void) } /** - * Get the coremask Linux was booted on. + * octeon_get_boot_coremask - Get the coremask Linux was booted on. * - * Returns Core mask + * Return: Core mask */ int octeon_get_boot_coremask(void) { @@ -388,7 +389,7 @@ int octeon_get_boot_coremask(void) } /** - * Check the hardware BIST results for a CPU + * octeon_check_cpu_bist - Check the hardware BIST results for a CPU */ void octeon_check_cpu_bist(void) { @@ -419,7 +420,7 @@ void octeon_check_cpu_bist(void) } /** - * Reboot Octeon + * octeon_restart - Reboot Octeon * * @command: Command to pass to the bootloader. Currently ignored. */ @@ -444,7 +445,7 @@ static void octeon_restart(char *command) /** - * Permanently stop a core. + * octeon_kill_core - Permanently stop a core. * * @arg: Ignored. */ @@ -464,7 +465,7 @@ static void octeon_kill_core(void *arg) /** - * Halt the system + * octeon_halt - Halt the system */ static void octeon_halt(void) { @@ -507,9 +508,9 @@ static void __init init_octeon_system_type(void) } /** - * Return a string representing the system type + * octeon_board_type_string - Return a string representing the system type * - * Returns + * Return: system type string */ const char *octeon_board_type_string(void) { @@ -650,7 +651,7 @@ void octeon_user_io_init(void) } /** - * Early entry point for arch setup + * prom_init - Early entry point for arch setup */ void __init prom_init(void) { diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 66ce5527da54..89954f5f87fb 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -91,7 +91,7 @@ static irqreturn_t mailbox_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -/** +/* * Cause the function described by call_data to be executed on the passed * cpu. When the function has finished, increment the finished field of * call_data. @@ -115,7 +115,7 @@ static inline void octeon_send_ipi_mask(const struct cpumask *mask, octeon_send_ipi_single(i, action); } -/** +/* * Detect available CPUs, populate cpu_possible_mask */ static void octeon_smp_hotplug_setup(void) @@ -202,9 +202,8 @@ int plat_post_relocation(long offset) } #endif /* CONFIG_RELOCATABLE */ -/** +/* * Firmware CPU startup hook - * */ static int octeon_boot_secondary(int cpu, struct task_struct *idle) { @@ -232,7 +231,7 @@ static int octeon_boot_secondary(int cpu, struct task_struct *idle) return 0; } -/** +/* * After we've done initial boot, this function is called to allow the * board code to clean up state, if needed */ @@ -250,9 +249,8 @@ static void octeon_init_secondary(void) octeon_irq_setup_secondary(); } -/** +/* * Callout to firmware before smp_init - * */ static void __init octeon_prepare_cpus(unsigned int max_cpus) { @@ -268,7 +266,7 @@ static void __init octeon_prepare_cpus(unsigned int max_cpus) } } -/** +/* * Last chance for the board code to finish SMP initialization before * the CPU is "online". */ -- cgit v1.2.3-70-g09d2 From d2ac3a11cba23454516ba17f03e078a6831b8be5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 25 Jul 2021 09:02:58 -0700 Subject: mips: clean up kernel-doc in mm/c-octeon.c Clean up kernel-doc warnings in arch/mips/mm/c-octeon.c. arch/mips/mm/c-octeon.c:34: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Octeon automatically flushes the dcache on tlb changes, so arch/mips/mm/c-octeon.c:65: warning: expecting prototype for Flush caches as necessary for all cores affected by a(). Prototype was for octeon_flush_icache_all_cores() instead arch/mips/mm/c-octeon.c:99: warning: expecting prototype for Called to flush the icache on all cores(). Prototype was for octeon_flush_icache_all() instead arch/mips/mm/c-octeon.c:111: warning: expecting prototype for Called to flush all memory associated with a memory(). Prototype was for octeon_flush_cache_mm() instead arch/mips/mm/c-octeon.c:124: warning: Function parameter or member 'start' not described in 'octeon_flush_icache_range' arch/mips/mm/c-octeon.c:124: warning: Function parameter or member 'end' not described in 'octeon_flush_icache_range' arch/mips/mm/c-octeon.c:124: warning: expecting prototype for Flush a range of kernel addresses out of the icache(). Prototype was for octeon_flush_icache_range() instead arch/mips/mm/c-octeon.c:138: warning: expecting prototype for Flush a range out of a vma(). Prototype was for octeon_flush_cache_range() instead arch/mips/mm/c-octeon.c:153: warning: expecting prototype for Flush a specific page of a vma(). Prototype was for octeon_flush_cache_page() instead arch/mips/mm/c-octeon.c:164: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Probe Octeon's caches arch/mips/mm/c-octeon.c:264: warning: expecting prototype for Setup the Octeon cache flush routines(). Prototype was for octeon_cache_init() instead arch/mips/mm/c-octeon.c:349: warning: expecting prototype for Called when the the exception is not recoverable(). Prototype was for cache_parity_error_octeon_non_recoverable() instead Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Aditya Srivastava Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- arch/mips/mm/c-octeon.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 8ae181e08311..ec2ae501539a 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -30,7 +30,7 @@ unsigned long long cache_err_dcache[NR_CPUS]; EXPORT_SYMBOL_GPL(cache_err_dcache); -/** +/* * Octeon automatically flushes the dcache on tlb changes, so * from Linux's viewpoint it acts much like a physically * tagged cache. No flushing is needed @@ -56,8 +56,8 @@ static void local_octeon_flush_icache_range(unsigned long start, } /** - * Flush caches as necessary for all cores affected by a - * vma. If no vma is supplied, all cores are flushed. + * octeon_flush_icache_all_cores - Flush caches as necessary for all cores + * affected by a vma. If no vma is supplied, all cores are flushed. * * @vma: VMA to flush or NULL to flush all icaches. */ @@ -92,7 +92,7 @@ static void octeon_flush_icache_all_cores(struct vm_area_struct *vma) } -/** +/* * Called to flush the icache on all cores */ static void octeon_flush_icache_all(void) @@ -102,8 +102,7 @@ static void octeon_flush_icache_all(void) /** - * Called to flush all memory associated with a memory - * context. + * octeon_flush_cache_mm - flush all memory associated with a memory context. * * @mm: Memory context to flush */ @@ -116,7 +115,7 @@ static void octeon_flush_cache_mm(struct mm_struct *mm) } -/** +/* * Flush a range of kernel addresses out of the icache * */ @@ -127,11 +126,11 @@ static void octeon_flush_icache_range(unsigned long start, unsigned long end) /** - * Flush a range out of a vma + * octeon_flush_cache_range - Flush a range out of a vma * * @vma: VMA to flush - * @start: - * @end: + * @start: beginning address for flush + * @end: ending address for flush */ static void octeon_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) @@ -142,11 +141,11 @@ static void octeon_flush_cache_range(struct vm_area_struct *vma, /** - * Flush a specific page of a vma + * octeon_flush_cache_page - Flush a specific page of a vma * * @vma: VMA to flush page for * @page: Page to flush - * @pfn: + * @pfn: Page frame number */ static void octeon_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn) @@ -160,7 +159,7 @@ static void octeon_flush_kernel_vmap_range(unsigned long vaddr, int size) BUG(); } -/** +/* * Probe Octeon's caches * */ @@ -256,7 +255,7 @@ static void octeon_cache_error_setup(void) set_handler(0x100, &except_vec2_octeon, 0x80); } -/** +/* * Setup the Octeon cache flush routines * */ @@ -341,7 +340,7 @@ asmlinkage void cache_parity_error_octeon_recoverable(void) co_cache_error_call_notifiers(0); } -/** +/* * Called when the the exception is not recoverable */ -- cgit v1.2.3-70-g09d2 From f7744fa16b96da57187dc8e5634152d3b63d72de Mon Sep 17 00:00:00 2001 From: Anirudh Rayabharam Date: Thu, 24 Jun 2021 00:10:29 +0530 Subject: HID: usbhid: free raw_report buffers in usbhid_stop Free the unsent raw_report buffers when the device is removed. Fixes a memory leak reported by syzbot at: https://syzkaller.appspot.com/bug?id=7b4fa7cb1a7c2d3342a2a8a6c53371c8c418ab47 Reported-by: syzbot+47b26cd837ececfc666d@syzkaller.appspotmail.com Tested-by: syzbot+47b26cd837ececfc666d@syzkaller.appspotmail.com Signed-off-by: Anirudh Rayabharam Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 06130dc431a0..0bf123bf2ef8 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -505,7 +505,7 @@ static void hid_ctrl(struct urb *urb) if (unplug) { usbhid->ctrltail = usbhid->ctrlhead; - } else { + } else if (usbhid->ctrlhead != usbhid->ctrltail) { usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); if (usbhid->ctrlhead != usbhid->ctrltail && @@ -1223,9 +1223,20 @@ static void usbhid_stop(struct hid_device *hid) mutex_lock(&usbhid->mutex); clear_bit(HID_STARTED, &usbhid->iofl); + spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ set_bit(HID_DISCONNECTED, &usbhid->iofl); + while (usbhid->ctrltail != usbhid->ctrlhead) { + if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_OUT) { + kfree(usbhid->ctrl[usbhid->ctrltail].raw_report); + usbhid->ctrl[usbhid->ctrltail].raw_report = NULL; + } + + usbhid->ctrltail = (usbhid->ctrltail + 1) & + (HID_CONTROL_FIFO_SIZE - 1); + } spin_unlock_irq(&usbhid->lock); + usb_kill_urb(usbhid->urbin); usb_kill_urb(usbhid->urbout); usb_kill_urb(usbhid->urbctrl); -- cgit v1.2.3-70-g09d2 From dc9dc864f35dd3b87d52fbe9809773576ac77d32 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Mon, 19 Jul 2021 13:55:29 -0700 Subject: HID: wacom: set initial hardware touch switch state to 'off' Wacom touch devices have two types of touch switches: softkey touch toggle and hardware touch switch. For softkey toggle, we assume touch is on by default in the driver. However the hardware touch switch is controlled by end users. We don't know if it's on or off before getting the status event. This patch sets touch off for devices with a hardware switch until we get the status. This is a bit safer for users who leave the switch "off" and don't want any accidental touches. The tradeoff is a slight delay between device connection and touch becoming enabled for users who leave the switch "on". Signed-off-by: Ping Cheng Reviewed-by: Jason Gerecke Tested-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 8 +++++++- drivers/hid/wacom_wac.c | 12 ++++++++---- drivers/hid/wacom_wac.h | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 57bfa0ae9836..713a2504092f 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2287,7 +2287,13 @@ static void wacom_set_shared_values(struct wacom_wac *wacom_wac) if (wacom_wac->has_mute_touch_switch) { wacom_wac->shared->has_mute_touch_switch = true; - wacom_wac->shared->is_touch_on = true; + /* Hardware touch switch may be off. Wait until + * we know the switch state to decide is_touch_on. + * Softkey state should be initialized to "on" to + * match historic default. + */ + if (wacom_wac->is_soft_touch_switch) + wacom_wac->shared->is_touch_on = true; } if (wacom_wac->shared->has_mute_touch_switch && diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 81ba642adcb7..fa2b4222bcad 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1987,14 +1987,17 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, features->numbered_buttons++; features->device_type |= WACOM_DEVICETYPE_PAD; break; - case WACOM_HID_WD_TOUCHONOFF: case WACOM_HID_WD_MUTE_DEVICE: + /* softkey touch switch */ + wacom_wac->is_soft_touch_switch = true; + fallthrough; + case WACOM_HID_WD_TOUCHONOFF: /* - * This usage, which is used to mute touch events, comes - * from the pad packet, but is reported on the touch + * These two usages, which are used to mute touch events, come + * from the pad packet, but are reported on the touch * interface. Because the touch interface may not have * been created yet, we cannot call wacom_map_usage(). In - * order to process this usage when we receive it, we set + * order to process the usages when we receive them, we set * the usage type and code directly. */ wacom_wac->has_mute_touch_switch = true; @@ -3835,6 +3838,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); wacom_wac->has_mute_touch_switch = true; + wacom_wac->is_soft_touch_switch = true; } fallthrough; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 8f16654eca09..4e9eb0c1eff6 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -352,6 +352,7 @@ struct wacom_wac { int mode_value; struct hid_data hid_data; bool has_mute_touch_switch; + bool is_soft_touch_switch; bool has_mode_change; bool is_direct_mode; bool is_invalid_bt_frame; -- cgit v1.2.3-70-g09d2 From 5bed0128868ce0e71f243973b3fc7b3bfca902b5 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 19 Jul 2021 13:55:30 -0700 Subject: HID: wacom: Short-circuit processing of touch when it is disabled Avoid doing unnecessary work when touch is disabled by detecting this condition and returning early. Note that the probe process sends GET FEATURE requests to discover e.g. HID_DG_CONTACTMAX, so we can't start ignoring touch reports until probe finishes. Signed-off-by: Ping Cheng Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 1 + drivers/hid/wacom_wac.c | 12 ++++++++++++ drivers/hid/wacom_wac.h | 1 + 3 files changed, 14 insertions(+) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 713a2504092f..93f49b766376 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2797,6 +2797,7 @@ static int wacom_probe(struct hid_device *hdev, error); } + wacom_wac->probe_complete = true; return 0; } diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index fa2b4222bcad..ce9e8e9b48b6 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2584,6 +2584,12 @@ static void wacom_wac_finger_event(struct hid_device *hdev, unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); struct wacom_features *features = &wacom->wacom_wac.features; + /* don't process touch events when touch is off */ + if (wacom_wac->probe_complete && + !wacom_wac->shared->is_touch_on && + !wacom_wac->shared->touch_down) + return; + if (wacom_wac->is_invalid_bt_frame) return; @@ -2633,6 +2639,12 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, struct hid_data* hid_data = &wacom_wac->hid_data; int i; + /* don't process touch events when touch is off */ + if (wacom_wac->probe_complete && + !wacom_wac->shared->is_touch_on && + !wacom_wac->shared->touch_down) + return; + wacom_wac->is_invalid_bt_frame = false; for (i = 0; i < report->maxfield; i++) { diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 4e9eb0c1eff6..8b2d4e5b2303 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -337,6 +337,7 @@ struct wacom_wac { int tool[2]; int id[2]; __u64 serial[2]; + bool probe_complete; bool reporting_data; struct wacom_features features; struct wacom_shared *shared; -- cgit v1.2.3-70-g09d2 From ccb51c2e3f0598934c3698f3645a3cb99add201c Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 19 Jul 2021 13:55:32 -0700 Subject: HID: wacom: Avoid sending empty sync events Empty sync events clutter up logs and are a waste of CPU cycles. We can avoid sending mt_sync events if touch is disabled or a specific slot is unused. We can avoid sending full sync events if no events were generated. Signed-off-by: Ping Cheng Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ce9e8e9b48b6..3f992c9dca4d 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2551,8 +2551,17 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, int slot; slot = input_mt_get_slot_by_key(input, hid_data->id); - if (slot < 0) + if (slot < 0) { return; + } else { + struct input_mt_slot *ps = &input->mt->slots[slot]; + int mt_id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); + + if (!prox && mt_id < 0) { + // No data to send for this slot; short-circuit + return; + } + } input_mt_slot(input, slot); input_mt_report_slot_state(input, MT_TOOL_FINGER, prox); @@ -2696,6 +2705,10 @@ static void wacom_wac_finger_report(struct hid_device *hdev, struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; + /* if there was nothing to process, don't send an empty sync */ + if (wacom_wac->hid_data.num_expected == 0) + return; + /* If more packets of data are expected, give us a chance to * process them rather than immediately syncing a partial * update. -- cgit v1.2.3-70-g09d2 From 9d339fe4cbd5de150f2d9fd554cc7e7213d09f08 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 19 Jul 2021 13:55:33 -0700 Subject: HID: wacom: Refactor touch input mute checks into a common function We perform this same set of tests to see if touch input is muted in several places. We might as well replace these independent copies with an inline function. Signed-off-by: Jason Gerecke Signed-off-by: Jiri Kosina --- drivers/hid/wacom_wac.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 3f992c9dca4d..fd51769d0994 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -824,6 +824,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) return 0; } +static inline bool touch_is_muted(struct wacom_wac *wacom_wac) +{ + return wacom_wac->probe_complete && + wacom_wac->shared->has_mute_touch_switch && + !wacom_wac->shared->is_touch_on; +} + static inline bool report_touch_events(struct wacom_wac *wacom) { return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); @@ -1525,11 +1532,8 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET; int y_offset = 2; - if (wacom->shared->has_mute_touch_switch && - !wacom->shared->is_touch_on) { - if (!wacom->shared->touch_down) - return 0; - } + if (touch_is_muted(wacom) && !wacom->shared->touch_down) + return 0; if (wacom->features.type == WACOM_27QHDT) { current_num_contacts = data[63]; @@ -2536,8 +2540,7 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, bool prox = hid_data->tipswitch && report_touch_events(wacom_wac); - if (wacom_wac->shared->has_mute_touch_switch && - !wacom_wac->shared->is_touch_on) { + if (touch_is_muted(wacom_wac)) { if (!wacom_wac->shared->touch_down) return; prox = false; @@ -2593,10 +2596,7 @@ static void wacom_wac_finger_event(struct hid_device *hdev, unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); struct wacom_features *features = &wacom->wacom_wac.features; - /* don't process touch events when touch is off */ - if (wacom_wac->probe_complete && - !wacom_wac->shared->is_touch_on && - !wacom_wac->shared->touch_down) + if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down) return; if (wacom_wac->is_invalid_bt_frame) @@ -2648,10 +2648,7 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, struct hid_data* hid_data = &wacom_wac->hid_data; int i; - /* don't process touch events when touch is off */ - if (wacom_wac->probe_complete && - !wacom_wac->shared->is_touch_on && - !wacom_wac->shared->touch_down) + if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down) return; wacom_wac->is_invalid_bt_frame = false; -- cgit v1.2.3-70-g09d2 From 25ddd7cfc582d6001c3b9e18e96c9b3a58523d66 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 20 Jul 2021 09:07:49 -0700 Subject: HID: i2c-hid: goodix: Use the devm variant of regulator_register_notifier() In commit 18eeef46d359 ("HID: i2c-hid: goodix: Tie the reset line to true state of the regulator") I added a call to regulator_register_notifier() but no call to unregister. That's a bug. Let's use the devm variant to handle the unregistering. Fixes: 18eeef46d359 ("HID: i2c-hid: goodix: Tie the reset line to true state of the regulator") Signed-off-by: Douglas Anderson Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-of-goodix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c index 31a4c229fdb7..52674149a275 100644 --- a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c +++ b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c @@ -132,7 +132,7 @@ static int i2c_hid_of_goodix_probe(struct i2c_client *client, */ mutex_lock(&ihid_goodix->regulator_mutex); ihid_goodix->nb.notifier_call = ihid_goodix_vdd_notify; - ret = regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb); + ret = devm_regulator_register_notifier(ihid_goodix->vdd, &ihid_goodix->nb); if (ret) { mutex_unlock(&ihid_goodix->regulator_mutex); return dev_err_probe(&client->dev, ret, -- cgit v1.2.3-70-g09d2 From bebf8820b355e6ac00487f3f36440d502eb4a44c Mon Sep 17 00:00:00 2001 From: Thomas Weißschuh Date: Tue, 20 Jul 2021 22:27:08 +0200 Subject: HID: cmedia: add support for HS-100B mute button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These chips report mute button events in bit 4 of their report without it being part of the report descriptor. Use a custom descriptor that maps this bit. Signed-off-by: Thomas Weißschuh Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 5 +-- drivers/hid/hid-cmedia.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++-- drivers/hid/hid-ids.h | 1 + 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 160554903ef9..6f72ecd79db0 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -259,10 +259,11 @@ config HID_PRODIKEYS and some additional multimedia keys. config HID_CMEDIA - tristate "CMedia CM6533 HID audio jack controls" + tristate "CMedia audio chips" depends on HID help - Support for CMedia CM6533 HID audio jack controls. + Support for CMedia CM6533 HID audio jack controls + and HS100B mute buttons. config HID_CP2112 tristate "Silicon Labs CP2112 HID USB-to-SMBus Bridge support" diff --git a/drivers/hid/hid-cmedia.c b/drivers/hid/hid-cmedia.c index 3296c5050264..cab42047bc99 100644 --- a/drivers/hid/hid-cmedia.c +++ b/drivers/hid/hid-cmedia.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0-only /* * HID driver for CMedia CM6533 audio jack controls + * and HS100B mute buttons * * Copyright (C) 2015 Ben Chen + * Copyright (C) 2021 Thomas Weißschuh */ #include @@ -11,13 +13,53 @@ #include "hid-ids.h" MODULE_AUTHOR("Ben Chen"); -MODULE_DESCRIPTION("CM6533 HID jack controls"); +MODULE_AUTHOR("Thomas Weißschuh"); +MODULE_DESCRIPTION("CM6533 HID jack controls and HS100B mute button"); MODULE_LICENSE("GPL"); #define CM6533_JD_TYPE_COUNT 1 #define CM6533_JD_RAWEV_LEN 16 #define CM6533_JD_SFX_OFFSET 8 +#define HS100B_RDESC_ORIG_SIZE 60 + +/* Fixed report descriptor of HS-100B audio chip + * Bit 4 is an abolute Microphone mute usage instead of being unassigned. + */ +static __u8 hs100b_rdesc_fixed[] = { + 0x05, 0x0C, /* Usage Page (Consumer), */ + 0x09, 0x01, /* Usage (Consumer Control), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x09, 0xE9, /* Usage (Volume Inc), */ + 0x09, 0xEA, /* Usage (Volume Dec), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x02, /* Report Count (2), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0xE2, /* Usage (Mute), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x06, /* Input (Variable, Relative), */ + 0x05, 0x0B, /* Usage Page (Telephony), */ + 0x09, 0x2F, /* Usage (2Fh), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x20, /* Usage (20h), */ + 0x81, 0x06, /* Input (Variable, Relative), */ + 0x05, 0x0C, /* Usage Page (Consumer), */ + 0x09, 0x00, /* Usage (00h), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Variable), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x09, 0x00, /* Usage (00h), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x00, /* Usage (00h), */ + 0x95, 0x04, /* Report Count (4), */ + 0x91, 0x02, /* Output (Variable), */ + 0xC0 /* End Collection */ +}; + /* * *CM6533 audio jack HID raw events: @@ -156,5 +198,49 @@ static struct hid_driver cmhid_driver = { .remove = cmhid_remove, .input_mapping = cmhid_input_mapping, }; -module_hid_driver(cmhid_driver); +static __u8 *cmhid_hs100b_report_fixup(struct hid_device *hid, __u8 *rdesc, + unsigned int *rsize) +{ + if (*rsize == HS100B_RDESC_ORIG_SIZE) { + hid_info(hid, "Fixing CMedia HS-100B report descriptor\n"); + rdesc = hs100b_rdesc_fixed; + *rsize = sizeof(hs100b_rdesc_fixed); + } + return rdesc; +} + +static const struct hid_device_id cmhid_hs100b_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CMEDIA_HS100B) }, + { } +}; +MODULE_DEVICE_TABLE(hid, cmhid_hs100b_devices); + +static struct hid_driver cmhid_hs100b_driver = { + .name = "cmedia_hs100b", + .id_table = cmhid_hs100b_devices, + .report_fixup = cmhid_hs100b_report_fixup, +}; + +static int cmedia_init(void) +{ + int ret; + + ret = hid_register_driver(&cmhid_driver); + if (ret) + return ret; + + ret = hid_register_driver(&cmhid_hs100b_driver); + if (ret) + hid_unregister_driver(&cmhid_driver); + + return ret; +} +module_init(cmedia_init); + +static void cmedia_exit(void) +{ + hid_unregister_driver(&cmhid_driver); + hid_unregister_driver(&cmhid_hs100b_driver); +} +module_exit(cmedia_exit); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 8f1893e68112..6864e4e6ac8b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -292,6 +292,7 @@ #define USB_VENDOR_ID_CMEDIA 0x0d8c #define USB_DEVICE_ID_CM109 0x000e +#define USB_DEVICE_ID_CMEDIA_HS100B 0x0014 #define USB_DEVICE_ID_CM6533 0x0022 #define USB_VENDOR_ID_CODEMERCS 0x07c0 -- cgit v1.2.3-70-g09d2 From 3b41fb4094914903fd8e50a13def9e47763dc101 Mon Sep 17 00:00:00 2001 From: Vincent Lefevre Date: Thu, 22 Jul 2021 03:25:44 +0200 Subject: HID: apple: Add missing scan code event for keys handled by hid-apple When an EV_KEY event is generated by hid-apple due to special key mapping, the usual associated scan code event (EV_MSC) is missing. This issue can be seen with the evtest utility. Add the scan code event for these special keys. BugLink: https://bugs.debian.org/757356 Co-developed-by: Daniel Lin Signed-off-by: Daniel Lin Signed-off-by: Vincent Lefevre Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 6b8f0d004d34..cde92de7fca7 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -187,6 +187,15 @@ static const struct apple_key_translation *apple_find_translation( return NULL; } +static void input_event_with_scancode(struct input_dev *input, + __u8 type, __u16 code, unsigned int hid, __s32 value) +{ + if (type == EV_KEY && + (!test_bit(code, input->key)) == value) + input_event(input, EV_MSC, MSC_SCAN, hid); + input_event(input, type, code, value); +} + static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, struct hid_usage *usage, __s32 value) { @@ -199,7 +208,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (usage->code == fn_keycode) { asc->fn_on = !!value; - input_event(input, usage->type, KEY_FN, value); + input_event_with_scancode(input, usage->type, KEY_FN, + usage->hid, value); return 1; } @@ -240,7 +250,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, code = do_translate ? trans->to : trans->from; } - input_event(input, usage->type, code, value); + input_event_with_scancode(input, usage->type, code, + usage->hid, value); return 1; } @@ -258,8 +269,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, clear_bit(usage->code, asc->pressed_numlock); - input_event(input, usage->type, trans->to, - value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); } return 1; @@ -270,7 +281,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (hid->country == HID_COUNTRY_INTERNATIONAL_ISO) { trans = apple_find_translation(apple_iso_keyboard, usage->code); if (trans) { - input_event(input, usage->type, trans->to, value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } } @@ -279,7 +291,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (swap_opt_cmd) { trans = apple_find_translation(swapped_option_cmd_keys, usage->code); if (trans) { - input_event(input, usage->type, trans->to, value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } } @@ -287,7 +300,8 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (swap_fn_leftctrl) { trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code); if (trans) { - input_event(input, usage->type, trans->to, value); + input_event_with_scancode(input, usage->type, + trans->to, usage->hid, value); return 1; } } @@ -306,8 +320,8 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field, if ((asc->quirks & APPLE_INVERT_HWHEEL) && usage->code == REL_HWHEEL) { - input_event(field->hidinput->input, usage->type, usage->code, - -value); + input_event_with_scancode(field->hidinput->input, usage->type, + usage->code, usage->hid, -value); return 1; } -- cgit v1.2.3-70-g09d2 From 258cb692b82025d0e6e1cccb72baa60ff78d0ce8 Mon Sep 17 00:00:00 2001 From: Clément Léger Date: Wed, 28 Jul 2021 11:46:07 +0200 Subject: dmaengine: at_xdmac: use platform_driver_register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using SCMI clocks, the clocks are probed later than subsys initcall level. This driver uses platform_driver_probe which is not compatible with deferred probing and won't be probed again later if probe function fails due to clocks not being available at that time. This patch replaces the use of platform_driver_probe with platform_driver_register which will allow probing the driver later again when clocks will be available. Signed-off-by: Clément Léger Link: https://lore.kernel.org/r/20210728094607.50589-1-clement.leger@bootlin.com Signed-off-by: Vinod Koul --- drivers/dma/at_xdmac.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 64a52bf4d737..ab78e0f6afd7 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -2240,10 +2240,16 @@ static struct platform_driver at_xdmac_driver = { static int __init at_xdmac_init(void) { - return platform_driver_probe(&at_xdmac_driver, at_xdmac_probe); + return platform_driver_register(&at_xdmac_driver); } subsys_initcall(at_xdmac_init); +static void __exit at_xdmac_exit(void) +{ + platform_driver_unregister(&at_xdmac_driver); +} +module_exit(at_xdmac_exit); + MODULE_DESCRIPTION("Atmel Extended DMA Controller driver"); MODULE_AUTHOR("Ludovic Desroches "); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From ade8a86b512cf8db0d0e975a971ce356953cfcb3 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 20 Jul 2021 13:42:10 -0700 Subject: dmaengine: idxd: Set defaults for GRPCFG traffic class Set GRPCFG traffic class to value of 1 for best performance on current generation of accelerators. Also add override option to allow experimentation. Sysfs knobs are disabled for DSA/IAX gen1 devices. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162681373005.1968485.3761065664382799202.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- Documentation/admin-guide/kernel-parameters.txt | 5 +++++ drivers/dma/idxd/idxd.h | 1 + drivers/dma/idxd/init.c | 13 +++++++++++-- drivers/dma/idxd/registers.h | 3 +++ drivers/dma/idxd/sysfs.c | 6 ++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index bdb22006f713..ec5411cdec20 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1747,6 +1747,11 @@ support for the idxd driver. By default it is set to true (1). + idxd.tc_override= [HW] + Format: + Allow override of default traffic class configuration + for the device. By default it is set to false (0). + ieee754= [MIPS] Select IEEE Std 754 conformance mode Format: { strict | legacy | 2008 | relaxed } Default: strict diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index d0874d8877d9..4e4dc0110e77 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -16,6 +16,7 @@ #define IDXD_DRIVER_VERSION "1.00" extern struct kmem_cache *idxd_desc_pool; +extern bool tc_override; struct idxd_wq; struct idxd_dev; diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 8db56f98059f..eb09bc591c31 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -32,6 +32,10 @@ static bool sva = true; module_param(sva, bool, 0644); MODULE_PARM_DESC(sva, "Toggle SVA support on/off"); +bool tc_override; +module_param(tc_override, bool, 0644); +MODULE_PARM_DESC(tc_override, "Override traffic class defaults"); + #define DRV_NAME "idxd" bool support_enqcmd; @@ -336,8 +340,13 @@ static int idxd_setup_groups(struct idxd_device *idxd) } idxd->groups[i] = group; - group->tc_a = -1; - group->tc_b = -1; + if (idxd->hw.version < DEVICE_VERSION_2 && !tc_override) { + group->tc_a = 1; + group->tc_b = 1; + } else { + group->tc_a = -1; + group->tc_b = -1; + } } return 0; diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h index 7343a8f48819..ffc7550a77ee 100644 --- a/drivers/dma/idxd/registers.h +++ b/drivers/dma/idxd/registers.h @@ -7,6 +7,9 @@ #define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25 #define PCI_DEVICE_ID_INTEL_IAX_SPR0 0x0cfe +#define DEVICE_VERSION_1 0x100 +#define DEVICE_VERSION_2 0x200 + #define IDXD_MMIO_BAR 0 #define IDXD_WQ_BAR 2 #define IDXD_PORTAL_SIZE PAGE_SIZE diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index b883e9f16e7f..881a12596d4b 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -327,6 +327,9 @@ static ssize_t group_traffic_class_a_store(struct device *dev, if (idxd->state == IDXD_DEV_ENABLED) return -EPERM; + if (idxd->hw.version < DEVICE_VERSION_2 && !tc_override) + return -EPERM; + if (val < 0 || val > 7) return -EINVAL; @@ -366,6 +369,9 @@ static ssize_t group_traffic_class_b_store(struct device *dev, if (idxd->state == IDXD_DEV_ENABLED) return -EPERM; + if (idxd->hw.version < DEVICE_VERSION_2 && !tc_override) + return -EPERM; + if (val < 0 || val > 7) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 568b2126466f926a10be0b53b40c2d6ae056d8d6 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Wed, 21 Jul 2021 11:35:03 -0700 Subject: dmaengine: idxd: fix uninit var for alt_drv 0-day detected uninitialized alt_drv variable in the bind_store() function. The branch can be taken when device is not idxd device or wq 'struct device'. Init alt_drv to NULL. Fixes: 6e7f3ee97bbe ("dmaengine: idxd: move dsa_drv support to compatible mode") Reported-by: kernel test robot Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162689250332.2114335.636367120454420852.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index d67746ee0c1a..d7616c240dcd 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -34,7 +34,7 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou { struct bus_type *bus = drv->bus; struct device *dev; - struct device_driver *alt_drv; + struct device_driver *alt_drv = NULL; int rc = -ENODEV; struct idxd_dev *idxd_dev; -- cgit v1.2.3-70-g09d2 From 673d812d30be67942762bb9e8548abb26a3ba4a7 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 22 Jul 2021 10:54:10 -0700 Subject: dmaengine: idxd: fix wq slot allocation index check The sbitmap wait and allocate routine checks the index that is returned from sbitmap_queue_get(). It should be idxd >= 0 as 0 is also a valid index. This fixes issue where submission path hangs when WQ size is 1. Fixes: 0705107fcc80 ("dmaengine: idxd: move submission to sbitmap_queue") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162697645067.3478714.506720687816951762.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/submit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index 6ef704dd4d0b..65b0130ab2db 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -59,7 +59,7 @@ struct idxd_desc *idxd_alloc_desc(struct idxd_wq *wq, enum idxd_op_type optype) if (signal_pending_state(TASK_INTERRUPTIBLE, current)) break; idx = sbitmap_queue_get(sbq, &cpu); - if (idx > 0) + if (idx >= 0) break; schedule(); } -- cgit v1.2.3-70-g09d2 From a9c171527a3403cae6c1907744b1bc9ca301f912 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 20 Jul 2021 13:42:04 -0700 Subject: dmaengine: idxd: rotate portal address for better performance The device submission portal is on a 4k page and any of those 64bit aligned address on the page can be used for descriptor submission. By rotating the offset through the 4k range and prevent successive writes to the same MMIO address, performance improvement is observed through testing. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162681372446.1968485.10634280461681015569.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 1 + drivers/dma/idxd/idxd.h | 20 ++++++++++++++++++++ drivers/dma/idxd/submit.c | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 99350ac9a292..41f67a195eb6 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -320,6 +320,7 @@ void idxd_wq_unmap_portal(struct idxd_wq *wq) devm_iounmap(dev, wq->portal); wq->portal = NULL; + wq->portal_offset = 0; } void idxd_wqs_unmap_portal(struct idxd_device *idxd) diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 4e4dc0110e77..94983bced189 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "registers.h" #define IDXD_DRIVER_VERSION "1.00" @@ -162,6 +163,7 @@ struct idxd_dma_chan { struct idxd_wq { void __iomem *portal; + u32 portal_offset; struct percpu_ref wq_active; struct completion wq_dead; struct idxd_dev idxd_dev; @@ -468,6 +470,24 @@ static inline int idxd_get_wq_portal_full_offset(int wq_id, return ((wq_id * 4) << PAGE_SHIFT) + idxd_get_wq_portal_offset(prot); } +#define IDXD_PORTAL_MASK (PAGE_SIZE - 1) + +/* + * Even though this function can be accessed by multiple threads, it is safe to use. + * At worst the address gets used more than once before it gets incremented. We don't + * hit a threshold until iops becomes many million times a second. So the occasional + * reuse of the same address is tolerable compare to using an atomic variable. This is + * safe on a system that has atomic load/store for 32bit integers. Given that this is an + * Intel iEP device, that should not be a problem. + */ +static inline void __iomem *idxd_wq_portal_addr(struct idxd_wq *wq) +{ + int ofs = wq->portal_offset; + + wq->portal_offset = (ofs + sizeof(struct dsa_raw_desc)) & IDXD_PORTAL_MASK; + return wq->portal + ofs; +} + static inline void idxd_wq_get(struct idxd_wq *wq) { wq->client_count++; diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index 65b0130ab2db..92ae9a157cc9 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -146,7 +146,7 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc) if (!percpu_ref_tryget_live(&wq->wq_active)) return -ENXIO; - portal = wq->portal; + portal = idxd_wq_portal_addr(wq); /* * The wmb() flushes writes to coherent DMA data before -- cgit v1.2.3-70-g09d2 From 125d10373ad991888c9e94d2da49bcc5ccba2127 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 20 Jul 2021 13:42:15 -0700 Subject: dmanegine: idxd: add software command status Enabling device and wq returns standard errno and that does not provide enough details to indicate what exactly failed. The hardware command status is only 8bits. Expand the command status to 32bits and use the upper 16 bits to define software errors to provide more details on the exact failure. Bit 31 will be used to indicate the error is software set as the driver is using some of the spec defined hardware error as well. Cc: Ramesh Thomas Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162681373579.1968485.5891788397526827892.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- Documentation/ABI/stable/sysfs-driver-dma-idxd | 2 ++ drivers/dma/idxd/cdev.c | 5 ++++- drivers/dma/idxd/device.c | 22 +++++++++++++++++++--- drivers/dma/idxd/dma.c | 4 ++++ drivers/dma/idxd/idxd.h | 2 +- drivers/dma/idxd/sysfs.c | 11 ++++++++++- include/uapi/linux/idxd.h | 23 +++++++++++++++++++++++ 7 files changed, 63 insertions(+), 6 deletions(-) diff --git a/Documentation/ABI/stable/sysfs-driver-dma-idxd b/Documentation/ABI/stable/sysfs-driver-dma-idxd index adb0c93e8dfc..df4afbccf037 100644 --- a/Documentation/ABI/stable/sysfs-driver-dma-idxd +++ b/Documentation/ABI/stable/sysfs-driver-dma-idxd @@ -128,6 +128,8 @@ Date: Aug 28, 2020 KernelVersion: 5.10.0 Contact: dmaengine@vger.kernel.org Description: The last executed device administrative command's status/error. + Also last configuration error overloaded. + Writing to it will clear the status. What: /sys/bus/dsa/devices/wq./block_on_fault Date: Oct 27, 2020 diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index f6a4603517ba..4d2ecdb130e7 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -320,9 +320,12 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) goto err; rc = idxd_wq_add_cdev(wq); - if (rc < 0) + if (rc < 0) { + idxd->cmd_status = IDXD_SCMD_CDEV_ERR; goto err_cdev; + } + idxd->cmd_status = 0; mutex_unlock(&wq->wq_lock); return 0; diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 41f67a195eb6..86fa4b4590f9 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -840,6 +840,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq) wq->wqcfg->wq_size = wq->size; if (wq->size == 0) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_SIZE; dev_warn(dev, "Incorrect work queue size: 0\n"); return -EINVAL; } @@ -975,6 +976,7 @@ static int idxd_wqs_setup(struct idxd_device *idxd) continue; if (wq_shared(wq) && !device_swq_supported(idxd)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_SWQ_SUPPORT; dev_warn(dev, "No shared wq support but configured.\n"); return -EINVAL; } @@ -983,8 +985,10 @@ static int idxd_wqs_setup(struct idxd_device *idxd) configured++; } - if (configured == 0) + if (configured == 0) { + idxd->cmd_status = IDXD_SCMD_WQ_NONE_CONFIGURED; return -EINVAL; + } return 0; } @@ -1140,21 +1144,26 @@ int __drv_enable_wq(struct idxd_wq *wq) lockdep_assert_held(&wq->wq_lock); - if (idxd->state != IDXD_DEV_ENABLED) + if (idxd->state != IDXD_DEV_ENABLED) { + idxd->cmd_status = IDXD_SCMD_DEV_NOT_ENABLED; goto err; + } if (wq->state != IDXD_WQ_DISABLED) { dev_dbg(dev, "wq %d already enabled.\n", wq->id); + idxd->cmd_status = IDXD_SCMD_WQ_ENABLED; rc = -EBUSY; goto err; } if (!wq->group) { dev_dbg(dev, "wq %d not attached to group.\n", wq->id); + idxd->cmd_status = IDXD_SCMD_WQ_NO_GRP; goto err; } if (strlen(wq->name) == 0) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_NAME; dev_dbg(dev, "wq %d name not set.\n", wq->id); goto err; } @@ -1162,6 +1171,7 @@ int __drv_enable_wq(struct idxd_wq *wq) /* Shared WQ checks */ if (wq_shared(wq)) { if (!device_swq_supported(idxd)) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_SVM; dev_dbg(dev, "PASID not enabled and shared wq.\n"); goto err; } @@ -1174,6 +1184,7 @@ int __drv_enable_wq(struct idxd_wq *wq) * threshold via sysfs. */ if (wq->threshold == 0) { + idxd->cmd_status = IDXD_SCMD_WQ_NO_THRESH; dev_dbg(dev, "Shared wq and threshold 0.\n"); goto err; } @@ -1197,6 +1208,7 @@ int __drv_enable_wq(struct idxd_wq *wq) rc = idxd_wq_map_portal(wq); if (rc < 0) { + idxd->cmd_status = IDXD_SCMD_WQ_PORTAL_ERR; dev_dbg(dev, "wq %d portal mapping failed: %d\n", wq->id, rc); goto err_map_portal; } @@ -1259,8 +1271,10 @@ int idxd_device_drv_probe(struct idxd_dev *idxd_dev) * enabled state, then the device was altered outside of driver's control. * If the state is in halted state, then we don't want to proceed. */ - if (idxd->state != IDXD_DEV_DISABLED) + if (idxd->state != IDXD_DEV_DISABLED) { + idxd->cmd_status = IDXD_SCMD_DEV_ENABLED; return -ENXIO; + } /* Device configuration */ spin_lock_irqsave(&idxd->dev_lock, flags); @@ -1279,9 +1293,11 @@ int idxd_device_drv_probe(struct idxd_dev *idxd_dev) rc = idxd_register_dma_device(idxd); if (rc < 0) { idxd_device_disable(idxd); + idxd->cmd_status = IDXD_SCMD_DEV_DMA_ERR; return rc; } + idxd->cmd_status = 0; return 0; } diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index 2fd7ec29a08f..a195225687bb 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -284,22 +284,26 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev) rc = idxd_wq_alloc_resources(wq); if (rc < 0) { + idxd->cmd_status = IDXD_SCMD_WQ_RES_ALLOC_ERR; dev_dbg(dev, "WQ resource alloc failed\n"); goto err_res_alloc; } rc = idxd_wq_init_percpu_ref(wq); if (rc < 0) { + idxd->cmd_status = IDXD_SCMD_PERCPU_ERR; dev_dbg(dev, "percpu_ref setup failed\n"); goto err_ref; } rc = idxd_register_dma_channel(wq); if (rc < 0) { + idxd->cmd_status = IDXD_SCMD_DMA_CHAN_ERR; dev_dbg(dev, "Failed to register dma channel\n"); goto err_dma; } + idxd->cmd_status = 0; mutex_unlock(&wq->wq_lock); return 0; diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 94983bced189..bfcb03329f77 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -252,7 +252,7 @@ struct idxd_device { unsigned long flags; int id; int major; - u8 cmd_status; + u32 cmd_status; struct pci_dev *pdev; void __iomem *reg_base; diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 881a12596d4b..4c01587c9d4a 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -1217,7 +1217,16 @@ static ssize_t cmd_status_show(struct device *dev, return sysfs_emit(buf, "%#x\n", idxd->cmd_status); } -static DEVICE_ATTR_RO(cmd_status); + +static ssize_t cmd_status_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct idxd_device *idxd = confdev_to_idxd(dev); + + idxd->cmd_status = 0; + return count; +} +static DEVICE_ATTR_RW(cmd_status); static struct attribute *idxd_device_attributes[] = { &dev_attr_version.attr, diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h index e33997b4d750..1c0175aa0e42 100644 --- a/include/uapi/linux/idxd.h +++ b/include/uapi/linux/idxd.h @@ -9,6 +9,29 @@ #include #endif +/* Driver command error status */ +enum idxd_scmd_stat { + IDXD_SCMD_DEV_ENABLED = 0x80000010, + IDXD_SCMD_DEV_NOT_ENABLED = 0x80000020, + IDXD_SCMD_WQ_ENABLED = 0x80000021, + IDXD_SCMD_DEV_DMA_ERR = 0x80020000, + IDXD_SCMD_WQ_NO_GRP = 0x80030000, + IDXD_SCMD_WQ_NO_NAME = 0x80040000, + IDXD_SCMD_WQ_NO_SVM = 0x80050000, + IDXD_SCMD_WQ_NO_THRESH = 0x80060000, + IDXD_SCMD_WQ_PORTAL_ERR = 0x80070000, + IDXD_SCMD_WQ_RES_ALLOC_ERR = 0x80080000, + IDXD_SCMD_PERCPU_ERR = 0x80090000, + IDXD_SCMD_DMA_CHAN_ERR = 0x800a0000, + IDXD_SCMD_CDEV_ERR = 0x800b0000, + IDXD_SCMD_WQ_NO_SWQ_SUPPORT = 0x800c0000, + IDXD_SCMD_WQ_NONE_CONFIGURED = 0x800d0000, + IDXD_SCMD_WQ_NO_SIZE = 0x800e0000, +}; + +#define IDXD_SCMD_SOFTERR_MASK 0x80000000 +#define IDXD_SCMD_SOFTERR_SHIFT 16 + /* Descriptor flags */ #define IDXD_OP_FLAG_FENCE 0x0001 #define IDXD_OP_FLAG_BOF 0x0002 -- cgit v1.2.3-70-g09d2 From 1fcef985c8bdd542c43da0d87bd9d51980c3859b Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Thu, 11 Mar 2021 16:22:51 -0800 Subject: remoteproc: qcom: wcnss: Fix race with iris probe The remoteproc driver is split between the responsibilities of getting the SoC-internal ARM core up and running and the external RF (aka "Iris") part configured. In order to satisfy the regulator framework's need of a struct device * to look up supplies this was implemented as two different drivers, using of_platform_populate() in the remoteproc part to probe the iris part. Unfortunately it's possible that the iris part probe defers on yet not available regulators and an attempt to start the remoteproc will have to be rejected, until this has been resolved. But there's no useful mechanism of knowing when this would be. Instead replace the of_platform_populate() and the iris probe with a function that rolls its own struct device, with the relevant of_node associated that is enough to acquire regulators and clocks specified in the DT node and that may propagate the EPROBE_DEFER back to the wcnss device's probe. Acked-by: Mathieu Poirier Reported-by: Anibal Limon Reported-by: Loic Poulain Tested-by: Anibal Limon Link: https://lore.kernel.org/r/20210312002251.3273013-1-bjorn.andersson@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_wcnss.c | 49 ++++---------- drivers/remoteproc/qcom_wcnss.h | 4 +- drivers/remoteproc/qcom_wcnss_iris.c | 120 ++++++++++++++++++++++------------- 3 files changed, 89 insertions(+), 84 deletions(-) diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index f1cbc6b2edbb..ebadc6c08e11 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -142,18 +142,6 @@ static const struct wcnss_data pronto_v2_data = { .num_vregs = 1, }; -void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, - struct qcom_iris *iris, - bool use_48mhz_xo) -{ - mutex_lock(&wcnss->iris_lock); - - wcnss->iris = iris; - wcnss->use_48mhz_xo = use_48mhz_xo; - - mutex_unlock(&wcnss->iris_lock); -} - static int wcnss_load(struct rproc *rproc, const struct firmware *fw) { struct qcom_wcnss *wcnss = (struct qcom_wcnss *)rproc->priv; @@ -639,12 +627,20 @@ static int wcnss_probe(struct platform_device *pdev) goto detach_pds; } + wcnss->iris = qcom_iris_probe(&pdev->dev, &wcnss->use_48mhz_xo); + if (IS_ERR(wcnss->iris)) { + ret = PTR_ERR(wcnss->iris); + goto detach_pds; + } + ret = rproc_add(rproc); if (ret) - goto detach_pds; + goto remove_iris; - return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + return 0; +remove_iris: + qcom_iris_remove(wcnss->iris); detach_pds: wcnss_release_pds(wcnss); free_rproc: @@ -657,7 +653,7 @@ static int wcnss_remove(struct platform_device *pdev) { struct qcom_wcnss *wcnss = platform_get_drvdata(pdev); - of_platform_depopulate(&pdev->dev); + qcom_iris_remove(wcnss->iris); rproc_del(wcnss->rproc); @@ -686,28 +682,7 @@ static struct platform_driver wcnss_driver = { }, }; -static int __init wcnss_init(void) -{ - int ret; - - ret = platform_driver_register(&wcnss_driver); - if (ret) - return ret; - - ret = platform_driver_register(&qcom_iris_driver); - if (ret) - platform_driver_unregister(&wcnss_driver); - - return ret; -} -module_init(wcnss_init); - -static void __exit wcnss_exit(void) -{ - platform_driver_unregister(&qcom_iris_driver); - platform_driver_unregister(&wcnss_driver); -} -module_exit(wcnss_exit); +module_platform_driver(wcnss_driver); MODULE_DESCRIPTION("Qualcomm Peripheral Image Loader for Wireless Subsystem"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/remoteproc/qcom_wcnss.h b/drivers/remoteproc/qcom_wcnss.h index 62c8682d0a92..6d01ee6afa7f 100644 --- a/drivers/remoteproc/qcom_wcnss.h +++ b/drivers/remoteproc/qcom_wcnss.h @@ -17,9 +17,9 @@ struct wcnss_vreg_info { bool super_turbo; }; +struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo); +void qcom_iris_remove(struct qcom_iris *iris); int qcom_iris_enable(struct qcom_iris *iris); void qcom_iris_disable(struct qcom_iris *iris); -void qcom_wcnss_assign_iris(struct qcom_wcnss *wcnss, struct qcom_iris *iris, bool use_48mhz_xo); - #endif diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c index 169acd305ae3..09720ddddc85 100644 --- a/drivers/remoteproc/qcom_wcnss_iris.c +++ b/drivers/remoteproc/qcom_wcnss_iris.c @@ -17,7 +17,7 @@ #include "qcom_wcnss.h" struct qcom_iris { - struct device *dev; + struct device dev; struct clk *xo_clk; @@ -75,7 +75,7 @@ int qcom_iris_enable(struct qcom_iris *iris) ret = clk_prepare_enable(iris->xo_clk); if (ret) { - dev_err(iris->dev, "failed to enable xo clk\n"); + dev_err(&iris->dev, "failed to enable xo clk\n"); goto disable_regulators; } @@ -93,43 +93,90 @@ void qcom_iris_disable(struct qcom_iris *iris) regulator_bulk_disable(iris->num_vregs, iris->vregs); } -static int qcom_iris_probe(struct platform_device *pdev) +static const struct of_device_id iris_of_match[] = { + { .compatible = "qcom,wcn3620", .data = &wcn3620_data }, + { .compatible = "qcom,wcn3660", .data = &wcn3660_data }, + { .compatible = "qcom,wcn3660b", .data = &wcn3680_data }, + { .compatible = "qcom,wcn3680", .data = &wcn3680_data }, + {} +}; + +static void qcom_iris_release(struct device *dev) +{ + struct qcom_iris *iris = container_of(dev, struct qcom_iris, dev); + + of_node_put(iris->dev.of_node); + kfree(iris); +} + +struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo) { + const struct of_device_id *match; const struct iris_data *data; - struct qcom_wcnss *wcnss; + struct device_node *of_node; struct qcom_iris *iris; int ret; int i; - iris = devm_kzalloc(&pdev->dev, sizeof(struct qcom_iris), GFP_KERNEL); - if (!iris) - return -ENOMEM; + of_node = of_get_child_by_name(parent->of_node, "iris"); + if (!of_node) { + dev_err(parent, "No child node \"iris\" found\n"); + return ERR_PTR(-EINVAL); + } + + iris = kzalloc(sizeof(*iris), GFP_KERNEL); + if (!iris) { + of_node_put(of_node); + return ERR_PTR(-ENOMEM); + } + + device_initialize(&iris->dev); + iris->dev.parent = parent; + iris->dev.release = qcom_iris_release; + iris->dev.of_node = of_node; + + dev_set_name(&iris->dev, "%s.iris", dev_name(parent)); + + ret = device_add(&iris->dev); + if (ret) { + put_device(&iris->dev); + return ERR_PTR(ret); + } + + match = of_match_device(iris_of_match, &iris->dev); + if (!match) { + dev_err(&iris->dev, "no matching compatible for iris\n"); + ret = -EINVAL; + goto err_device_del; + } - data = of_device_get_match_data(&pdev->dev); - wcnss = dev_get_drvdata(pdev->dev.parent); + data = match->data; - iris->xo_clk = devm_clk_get(&pdev->dev, "xo"); + iris->xo_clk = devm_clk_get(&iris->dev, "xo"); if (IS_ERR(iris->xo_clk)) { - if (PTR_ERR(iris->xo_clk) != -EPROBE_DEFER) - dev_err(&pdev->dev, "failed to acquire xo clk\n"); - return PTR_ERR(iris->xo_clk); + ret = PTR_ERR(iris->xo_clk); + if (ret != -EPROBE_DEFER) + dev_err(&iris->dev, "failed to acquire xo clk\n"); + goto err_device_del; } iris->num_vregs = data->num_vregs; - iris->vregs = devm_kcalloc(&pdev->dev, + iris->vregs = devm_kcalloc(&iris->dev, iris->num_vregs, sizeof(struct regulator_bulk_data), GFP_KERNEL); - if (!iris->vregs) - return -ENOMEM; + if (!iris->vregs) { + ret = -ENOMEM; + goto err_device_del; + } for (i = 0; i < iris->num_vregs; i++) iris->vregs[i].supply = data->vregs[i].name; - ret = devm_regulator_bulk_get(&pdev->dev, iris->num_vregs, iris->vregs); + ret = devm_regulator_bulk_get(&iris->dev, iris->num_vregs, iris->vregs); if (ret) { - dev_err(&pdev->dev, "failed to get regulators\n"); - return ret; + dev_err(&iris->dev, "failed to get regulators\n"); + goto err_device_del; } for (i = 0; i < iris->num_vregs; i++) { @@ -143,34 +190,17 @@ static int qcom_iris_probe(struct platform_device *pdev) data->vregs[i].load_uA); } - qcom_wcnss_assign_iris(wcnss, iris, data->use_48mhz_xo); - - return 0; -} + *use_48mhz_xo = data->use_48mhz_xo; -static int qcom_iris_remove(struct platform_device *pdev) -{ - struct qcom_wcnss *wcnss = dev_get_drvdata(pdev->dev.parent); + return iris; - qcom_wcnss_assign_iris(wcnss, NULL, false); +err_device_del: + device_del(&iris->dev); - return 0; + return ERR_PTR(ret); } -static const struct of_device_id iris_of_match[] = { - { .compatible = "qcom,wcn3620", .data = &wcn3620_data }, - { .compatible = "qcom,wcn3660", .data = &wcn3660_data }, - { .compatible = "qcom,wcn3660b", .data = &wcn3680_data }, - { .compatible = "qcom,wcn3680", .data = &wcn3680_data }, - {} -}; -MODULE_DEVICE_TABLE(of, iris_of_match); - -struct platform_driver qcom_iris_driver = { - .probe = qcom_iris_probe, - .remove = qcom_iris_remove, - .driver = { - .name = "qcom-iris", - .of_match_table = iris_of_match, - }, -}; +void qcom_iris_remove(struct qcom_iris *iris) +{ + device_del(&iris->dev); +} -- cgit v1.2.3-70-g09d2 From c080128b6f05cb803d830e6bf2ec0b214435ce38 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 6 Jul 2021 22:21:55 +0800 Subject: remoteproc: fix an typo in fw_elf_get_class code comments Drop 'and' which looks like unnecessary. Fixes: 73516a33588c ("remoteproc: Add elf helpers to access elf64 and elf32 fields") Signed-off-by: Dong Aisheng Link: https://lore.kernel.org/r/20210706142156.952794-1-aisheng.dong@nxp.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_elf_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/remoteproc/remoteproc_elf_helpers.h b/drivers/remoteproc/remoteproc_elf_helpers.h index 26404e68e17a..e6de53a5000c 100644 --- a/drivers/remoteproc/remoteproc_elf_helpers.h +++ b/drivers/remoteproc/remoteproc_elf_helpers.h @@ -15,7 +15,7 @@ * fw_elf_get_class - Get elf class * @fw: the ELF firmware image * - * Note that we use and elf32_hdr to access the class since the start of the + * Note that we use elf32_hdr to access the class since the start of the * struct is the same for both elf class * * Return: elf class of the firmware -- cgit v1.2.3-70-g09d2 From 147b589c5f446d602215577835356a96c40a4044 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 6 Jul 2021 22:21:56 +0800 Subject: remoteproc: fix kernel doc for struct rproc_ops The load_rsc_table was removed since the commit c1d35c1ab424 ("remoteproc: Rename "load_rsc_table" to "parse_fw"") but got added back again by mistake in the below commit: commit b1a17513a2d6 ("remoteproc: add vendor resources handling"). The patch fixed a small code indent issue which not worth a separate patch. Fixes: b1a17513a2d6 ("remoteproc: add vendor resources handling") Signed-off-by: Dong Aisheng Link: https://lore.kernel.org/r/20210706142156.952794-2-aisheng.dong@nxp.com Signed-off-by: Bjorn Andersson --- include/linux/remoteproc.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index a5b37bc10865..83c09ac36b13 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -369,9 +369,8 @@ enum rsc_handling_status { * @da_to_va: optional platform hook to perform address translations * @parse_fw: parse firmware to extract information (e.g. resource table) * @handle_rsc: optional platform hook to handle vendor resources. Should return - * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled and a - * negative value on error - * @load_rsc_table: load resource table from firmware image + * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled + * and a negative value on error * @find_loaded_rsc_table: find the loaded resource table from firmware image * @get_loaded_rsc_table: get resource table installed in memory * by external entity -- cgit v1.2.3-70-g09d2 From 3ad51c1743ebd23ec3b5ebc6195dafe867eaebb1 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Wed, 19 May 2021 18:44:18 -0500 Subject: remoteproc: use freezable workqueue for crash notifications When a remoteproc has crashed, rproc_report_crash() is called to handle whatever recovery is desired. This can happen at almost any time, often triggered by an interrupt, though it can also be initiated by a write to debugfs file remoteproc/remoteproc*/crash. When a crash is reported, the crash handler worker is scheduled to run (rproc_crash_handler_work()). One thing that worker does is call rproc_trigger_recovery(), which calls rproc_stop(). That calls the ->stop method for any remoteproc subdevices before making the remote processor go offline. The Q6V5 modem remoteproc driver implements an SSR subdevice that notifies registered drivers when the modem changes operational state (prepare, started, stop/crash, unprepared). The IPA driver registers to receive these notifications. With that as context, I'll now describe the problem. There was a situation in which buggy modem firmware led to a modem crash very soon after system (AP) resume had begun. The crash caused a remoteproc SSR crash notification to be sent to the IPA driver. The problem was that, although system resume had begun, it had not yet completed, and the IPA driver was still in a suspended state. This scenario could happen to any driver that registers for these SSR notifications, because they are delivered without knowledge of the (suspend) state of registered recipient drivers. This patch offers a simple fix for this, by having the crash handling worker function run on the system freezable workqueue. This workqueue does not operate if user space is frozen (for suspend). As a result, the SSR subdevice only delivers its crash notification when the system is fully operational (i.e., neither suspended nor in suspend/resume transition). Tested-by: Siddharth Gupta Reviewed-by: Bjorn Andersson Reviewed-by: Mathieu Poirier Signed-off-by: Alex Elder Link: https://lore.kernel.org/r/20210519234418.1196387-2-elder@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 7de5905d276a..502b6604b757 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2750,8 +2750,8 @@ void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type) dev_err(&rproc->dev, "crash detected in %s: type %s\n", rproc->name, rproc_crash_to_string(type)); - /* create a new task to handle the error */ - schedule_work(&rproc->crash_handler); + /* Have a worker handle the error; ensure system is not suspended */ + queue_work(system_freezable_wq, &rproc->crash_handler); } EXPORT_SYMBOL(rproc_report_crash); -- cgit v1.2.3-70-g09d2 From beec64d0c9749afedf51c3c10cf52de1d9a89cc0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:10 +0200 Subject: scsi: bsg: Remove support for SCSI_IOCTL_SEND_COMMAND SCSI_IOCTL_SEND_COMMAND has been deprecated longer than bsg exists and has been warning for just as long. More importantly it harcodes SCSI CDBs and thus will do the wrong thing on non-SCSI bsg nodes. Link: https://lore.kernel.org/r/20210724072033.1284840-2-hch@lst.de Fixes: aa387cc89567 ("block: add bsg helper library") Reviewed-by: Bart Van Assche Acked-by: Jens Axboe Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/bsg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block/bsg.c b/block/bsg.c index 1f196563ae6c..79b42c5cafeb 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -373,10 +373,13 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_GET_RESERVED_SIZE: case SG_SET_RESERVED_SIZE: case SG_EMULATED_HOST: - case SCSI_IOCTL_SEND_COMMAND: return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg); case SG_IO: return bsg_sg_io(bd->queue, file->f_mode, uarg); + case SCSI_IOCTL_SEND_COMMAND: + pr_warn_ratelimited("%s: calling unsupported SCSI_IOCTL_SEND_COMMAND\n", + current->comm); + return -EINVAL; default: return -ENOTTY; } -- cgit v1.2.3-70-g09d2 From 558e3fbe228a495166eda5f594d5976ee7cb18fc Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:11 +0200 Subject: scsi: sr: Consolidate compat ioctl handling Merge the native and compat ioctl handlers into a single one using in_compat_syscall(). Link: https://lore.kernel.org/r/20210724072033.1284840-3-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/sr.c | 64 ++++++++----------------------------------------------- 1 file changed, 9 insertions(+), 55 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 94c254e9012e..b34f06924659 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -577,68 +577,24 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, switch (cmd) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: - ret = scsi_ioctl(sdev, cmd, argp); - goto put; + break; + default: + ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); + if (ret != -ENOSYS) + goto put; } - ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); - if (ret != -ENOSYS) - goto put; - - ret = scsi_ioctl(sdev, cmd, argp); - -put: - scsi_autopm_put_device(sdev); - -out: - mutex_unlock(&cd->lock); - return ret; -} - -#ifdef CONFIG_COMPAT -static int sr_block_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, - unsigned long arg) -{ - struct scsi_cd *cd = scsi_cd(bdev->bd_disk); - struct scsi_device *sdev = cd->device; - void __user *argp = compat_ptr(arg); - int ret; - - mutex_lock(&cd->lock); - - ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, - (mode & FMODE_NDELAY) != 0); - if (ret) - goto out; - - scsi_autopm_get_device(sdev); - - /* - * Send SCSI addressing ioctls directly to mid level, send other - * ioctls to cdrom/block level. - */ - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: + if (in_compat_syscall()) ret = scsi_compat_ioctl(sdev, cmd, argp); - goto put; - } - - ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, (unsigned long)argp); - if (ret != -ENOSYS) - goto put; - - ret = scsi_compat_ioctl(sdev, cmd, argp); + else + ret = scsi_ioctl(sdev, cmd, argp); put: scsi_autopm_put_device(sdev); - out: mutex_unlock(&cd->lock); return ret; - } -#endif static unsigned int sr_block_check_events(struct gendisk *disk, unsigned int clearing) @@ -663,9 +619,7 @@ static const struct block_device_operations sr_bdops = .open = sr_block_open, .release = sr_block_release, .ioctl = sr_block_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sr_block_compat_ioctl, -#endif + .compat_ioctl = blkdev_compat_ptr_ioctl, .check_events = sr_block_check_events, }; -- cgit v1.2.3-70-g09d2 From 443283109f5c9dbcd878f4572a1b8876eae3b6c0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:12 +0200 Subject: scsi: sd: Consolidate compat ioctl handling Merge the native and compat ioctl handlers into a single one using in_compat_syscall(), and also simplify the calling conventions by merging sd_ioctl_common() into sd_ioctl(). Link: https://lore.kernel.org/r/20210724072033.1284840-4-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 63 ++++++++++++++++--------------------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e7ef4728d5eb..12faebc163ab 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1530,11 +1530,11 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /** - * sd_ioctl_common - process an ioctl + * sd_ioctl - process an ioctl * @bdev: target block device * @mode: FMODE_* mask * @cmd: ioctl command number - * @p: this is third argument given to ioctl(2) system call. + * @arg: this is third argument given to ioctl(2) system call. * Often contains a pointer. * * Returns 0 if successful (some ioctls return positive numbers on @@ -1543,12 +1543,13 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) * Note: most ioctls are forward onto the block subsystem or further * down in the scsi subsystem. **/ -static int sd_ioctl_common(struct block_device *bdev, fmode_t mode, - unsigned int cmd, void __user *p) +static int sd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) { struct gendisk *disk = bdev->bd_disk; struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdp = sdkp->device; + void __user *p = (void __user *)arg; int error; SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, " @@ -1567,7 +1568,7 @@ static int sd_ioctl_common(struct block_device *bdev, fmode_t mode, error = scsi_ioctl_block_when_processing_errors(sdp, cmd, (mode & FMODE_NDELAY) != 0); if (error) - goto out; + return error; if (is_sed_ioctl(cmd)) return sed_ioctl(sdkp->opal_dev, cmd, p); @@ -1578,16 +1579,18 @@ static int sd_ioctl_common(struct block_device *bdev, fmode_t mode, * resolved. */ switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - error = scsi_ioctl(sdp, cmd, p); - break; - default: - error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); - break; + case SCSI_IOCTL_GET_IDLUN: + case SCSI_IOCTL_GET_BUS_NUMBER: + break; + default: + error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); + if (error != -ENOTTY) + return error; } -out: - return error; + + if (in_compat_syscall()) + return scsi_compat_ioctl(sdp, cmd, p); + return scsi_ioctl(sdp, cmd, p); } static void set_media_not_present(struct scsi_disk *sdkp) @@ -1770,34 +1773,6 @@ static void sd_rescan(struct device *dev) sd_revalidate_disk(sdkp->disk); } -static int sd_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - void __user *p = (void __user *)arg; - int ret; - - ret = sd_ioctl_common(bdev, mode, cmd, p); - if (ret != -ENOTTY) - return ret; - - return scsi_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p); -} - -#ifdef CONFIG_COMPAT -static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - void __user *p = compat_ptr(arg); - int ret; - - ret = sd_ioctl_common(bdev, mode, cmd, p); - if (ret != -ENOTTY) - return ret; - - return scsi_compat_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p); -} -#endif - static char sd_pr_type(enum pr_type type) { switch (type) { @@ -1898,9 +1873,7 @@ static const struct block_device_operations sd_fops = { .release = sd_release, .ioctl = sd_ioctl, .getgeo = sd_getgeo, -#ifdef CONFIG_COMPAT - .compat_ioctl = sd_compat_ioctl, -#endif + .compat_ioctl = blkdev_compat_ptr_ioctl, .check_events = sd_check_events, .unlock_native_capacity = sd_unlock_native_capacity, .report_zones = sd_zbc_report_zones, -- cgit v1.2.3-70-g09d2 From bce96675091f2f1f98567c3566944f4009a7fbd1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:13 +0200 Subject: scsi: ch: Consolidate compat ioctl handling Merge the native and compat ioctl handlers into a single one using in_compat_syscall(). Link: https://lore.kernel.org/r/20210724072033.1284840-5-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ch.c | 73 +++++++++++++++++-------------------------------------- 1 file changed, 22 insertions(+), 51 deletions(-) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index fc7197abfcdf..cf517381cbcc 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -618,6 +618,12 @@ ch_checkrange(scsi_changer *ch, unsigned int type, unsigned int unit) return 0; } +struct changer_element_status32 { + int ces_type; + compat_uptr_t ces_data; +}; +#define CHIOGSTATUS32 _IOW('c', 8, struct changer_element_status32) + static long ch_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -748,7 +754,20 @@ static long ch_ioctl(struct file *file, return ch_gstatus(ch, ces.ces_type, ces.ces_data); } +#ifdef CONFIG_COMPAT + case CHIOGSTATUS32: + { + struct changer_element_status32 ces32; + if (copy_from_user(&ces32, argp, sizeof(ces32))) + return -EFAULT; + if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES) + return -EINVAL; + + return ch_gstatus(ch, ces32.ces_type, + compat_ptr(ces32.ces_data)); + } +#endif case CHIOGELEM: { struct changer_get_element cge; @@ -858,59 +877,13 @@ static long ch_ioctl(struct file *file, } default: + if (in_compat_syscall()) + return scsi_compat_ioctl(ch->device, cmd, argp); return scsi_ioctl(ch->device, cmd, argp); } } -#ifdef CONFIG_COMPAT - -struct changer_element_status32 { - int ces_type; - compat_uptr_t ces_data; -}; -#define CHIOGSTATUS32 _IOW('c', 8,struct changer_element_status32) - -static long ch_ioctl_compat(struct file * file, - unsigned int cmd, unsigned long arg) -{ - scsi_changer *ch = file->private_data; - int retval = scsi_ioctl_block_when_processing_errors(ch->device, cmd, - file->f_flags & O_NDELAY); - if (retval) - return retval; - - switch (cmd) { - case CHIOGPARAMS: - case CHIOGVPARAMS: - case CHIOPOSITION: - case CHIOMOVE: - case CHIOEXCHANGE: - case CHIOGELEM: - case CHIOINITELEM: - case CHIOSVOLTAG: - /* compatible */ - return ch_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); - case CHIOGSTATUS32: - { - struct changer_element_status32 ces32; - unsigned char __user *data; - - if (copy_from_user(&ces32, (void __user *)arg, sizeof (ces32))) - return -EFAULT; - if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES) - return -EINVAL; - - data = compat_ptr(ces32.ces_data); - return ch_gstatus(ch, ces32.ces_type, data); - } - default: - return scsi_compat_ioctl(ch->device, cmd, compat_ptr(arg)); - - } -} -#endif - /* ------------------------------------------------------------------------ */ static int ch_probe(struct device *dev) @@ -1015,9 +988,7 @@ static const struct file_operations changer_fops = { .open = ch_open, .release = ch_release, .unlocked_ioctl = ch_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = ch_ioctl_compat, -#endif + .compat_ioctl = compat_ptr_ioctl, .llseek = noop_llseek, }; -- cgit v1.2.3-70-g09d2 From 2c2db2c6059a426ac27f467062ff2ba6871b69e6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:14 +0200 Subject: scsi: sg: Consolidate compat ioctl handling Merge the native and compat ioctl handlers into a single one using in_compat_syscall(). Link: https://lore.kernel.org/r/20210724072033.1284840-6-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/sg.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 91e2221bbb0d..0a6655bad5a4 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1166,28 +1166,11 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) if (ret != -ENOIOCTLCMD) return ret; + if (in_compat_syscall()) + return scsi_compat_ioctl(sdp->device, cmd_in, p); return scsi_ioctl(sdp->device, cmd_in, p); } -#ifdef CONFIG_COMPAT -static long sg_compat_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) -{ - void __user *p = compat_ptr(arg); - Sg_device *sdp; - Sg_fd *sfp; - int ret; - - if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) - return -ENXIO; - - ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p); - if (ret != -ENOIOCTLCMD) - return ret; - - return scsi_compat_ioctl(sdp->device, cmd_in, p); -} -#endif - static __poll_t sg_poll(struct file *filp, poll_table * wait) { @@ -1441,9 +1424,7 @@ static const struct file_operations sg_fops = { .write = sg_write, .poll = sg_poll, .unlocked_ioctl = sg_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = sg_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, .open = sg_open, .mmap = sg_mmap, .release = sg_release, -- cgit v1.2.3-70-g09d2 From 6fade4505af898c849ebe80f54313aa9c387e6da Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:15 +0200 Subject: scsi: core: Remove scsi_compat_ioctl() Just handle the compat case in scsi_ioctl() using in_compat_syscall(). Link: https://lore.kernel.org/r/20210724072033.1284840-7-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ch.c | 2 -- drivers/scsi/scsi_ioctl.c | 60 ++++++++++++++++------------------------------- drivers/scsi/sd.c | 2 -- drivers/scsi/sg.c | 3 --- drivers/scsi/sr.c | 5 +--- drivers/scsi/st.c | 2 +- include/scsi/scsi_ioctl.h | 1 - 7 files changed, 22 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index cf517381cbcc..e354a95c56af 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -877,8 +877,6 @@ static long ch_ioctl(struct file *file, } default: - if (in_compat_syscall()) - return scsi_compat_ioctl(ch->device, cmd, argp); return scsi_ioctl(ch->device, cmd, argp); } diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 0d13610cd6bf..7b2e3cc85e66 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -189,8 +189,17 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg) ? -EFAULT: 0; } - -static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user *arg) +/** + * scsi_ioctl - Dispatch ioctl to scsi device + * @sdev: scsi device receiving ioctl + * @cmd: which ioctl is it + * @arg: data associated with ioctl + * + * Description: The scsi_ioctl() function differs from most ioctls in that it + * does not take a major/minor number as the dev field. Rather, it takes + * a pointer to a &struct scsi_device. + */ +int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) { char scsi_cmd[MAX_COMMAND_SIZE]; struct scsi_sense_hdr sense_hdr; @@ -258,48 +267,19 @@ static int scsi_ioctl_common(struct scsi_device *sdev, int cmd, void __user *arg case SG_SCSI_RESET: return scsi_ioctl_reset(sdev, arg); } - return -ENOIOCTLCMD; -} - -/** - * scsi_ioctl - Dispatch ioctl to scsi device - * @sdev: scsi device receiving ioctl - * @cmd: which ioctl is it - * @arg: data associated with ioctl - * - * Description: The scsi_ioctl() function differs from most ioctls in that it - * does not take a major/minor number as the dev field. Rather, it takes - * a pointer to a &struct scsi_device. - */ -int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) -{ - int ret = scsi_ioctl_common(sdev, cmd, arg); - - if (ret != -ENOIOCTLCMD) - return ret; - - if (sdev->host->hostt->ioctl) - return sdev->host->hostt->ioctl(sdev, cmd, arg); - - return -EINVAL; -} -EXPORT_SYMBOL(scsi_ioctl); #ifdef CONFIG_COMPAT -int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) -{ - int ret = scsi_ioctl_common(sdev, cmd, arg); - - if (ret != -ENOIOCTLCMD) - return ret; - - if (sdev->host->hostt->compat_ioctl) + if (in_compat_syscall()) { + if (!sdev->host->hostt->compat_ioctl) + return -EINVAL; return sdev->host->hostt->compat_ioctl(sdev, cmd, arg); - - return ret; -} -EXPORT_SYMBOL(scsi_compat_ioctl); + } #endif + if (!sdev->host->hostt->ioctl) + return -EINVAL; + return sdev->host->hostt->ioctl(sdev, cmd, arg); +} +EXPORT_SYMBOL(scsi_ioctl); /* * We can process a reset even when a device isn't fully operable. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12faebc163ab..0b87ca01efff 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1588,8 +1588,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, return error; } - if (in_compat_syscall()) - return scsi_compat_ioctl(sdp, cmd, p); return scsi_ioctl(sdp, cmd, p); } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 0a6655bad5a4..c3562c2d0dca 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1165,9 +1165,6 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p); if (ret != -ENOIOCTLCMD) return ret; - - if (in_compat_syscall()) - return scsi_compat_ioctl(sdp->device, cmd_in, p); return scsi_ioctl(sdp->device, cmd_in, p); } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index b34f06924659..c5e163a659d2 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -584,10 +584,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, goto put; } - if (in_compat_syscall()) - ret = scsi_compat_ioctl(sdev, cmd, argp); - else - ret = scsi_ioctl(sdev, cmd, argp); + ret = scsi_ioctl(sdev, cmd, argp); put: scsi_autopm_put_device(sdev); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index c6f14540ae03..c3fee73e018e 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3886,7 +3886,7 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned lon if (ret != -ENOTTY) return ret; - return scsi_compat_ioctl(STp->device, cmd_in, p); + return scsi_ioctl(STp->device, cmd_in, p); } #endif diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index b465799f4d2d..cdb3ba3451e7 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -44,7 +44,6 @@ typedef struct scsi_fctargaddress { int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); extern int scsi_ioctl(struct scsi_device *, int, void __user *); -extern int scsi_compat_ioctl(struct scsi_device *sdev, int cmd, void __user *arg); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ -- cgit v1.2.3-70-g09d2 From dba7688fc9037c8343ff298d32a3e56352046d37 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:16 +0200 Subject: scsi: st: Simplify ioctl handling Merge st_ioctl_common() into st_ioctl() and streamline the invocation of the common ioctl helpers. Link: https://lore.kernel.org/r/20210724072033.1284840-8-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/st.c | 78 +++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 49 deletions(-) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index c3fee73e018e..9274f665bc0f 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3499,8 +3499,9 @@ out: /* The ioctl command */ -static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user *p) +static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) { + void __user *p = (void __user *)arg; int i, cmd_nr, cmd_type, bt; int retval = 0; unsigned int blk; @@ -3820,73 +3821,52 @@ static long st_ioctl_common(struct file *file, unsigned int cmd_in, void __user goto out; } mutex_unlock(&STp->lock); + switch (cmd_in) { - case SCSI_IOCTL_STOP_UNIT: - /* unload */ - retval = scsi_ioctl(STp->device, cmd_in, p); - if (!retval) { - STp->rew_at_close = 0; - STp->ready = ST_NO_TAPE; - } + case SCSI_IOCTL_GET_IDLUN: + case SCSI_IOCTL_GET_BUS_NUMBER: + break; + case SG_IO: + case SCSI_IOCTL_SEND_COMMAND: + case CDROM_SEND_PACKET: + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + fallthrough; + default: + retval = scsi_cmd_ioctl(STp->disk->queue, STp->disk, + file->f_mode, cmd_in, p); + if (retval != -ENOTTY) return retval; + break; + } - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - break; - - default: - if ((cmd_in == SG_IO || - cmd_in == SCSI_IOCTL_SEND_COMMAND || - cmd_in == CDROM_SEND_PACKET) && - !capable(CAP_SYS_RAWIO)) - i = -EPERM; - else - i = scsi_cmd_ioctl(STp->disk->queue, STp->disk, - file->f_mode, cmd_in, p); - if (i != -ENOTTY) - return i; - break; + retval = scsi_ioctl(STp->device, cmd_in, p); + if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { + /* unload */ + STp->rew_at_close = 0; + STp->ready = ST_NO_TAPE; } - return -ENOTTY; + return retval; out: mutex_unlock(&STp->lock); return retval; } -static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) -{ - void __user *p = (void __user *)arg; - struct scsi_tape *STp = file->private_data; - int ret; - - ret = st_ioctl_common(file, cmd_in, p); - if (ret != -ENOTTY) - return ret; - - return scsi_ioctl(STp->device, cmd_in, p); -} - #ifdef CONFIG_COMPAT static long st_compat_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) { - void __user *p = compat_ptr(arg); - struct scsi_tape *STp = file->private_data; - int ret; - /* argument conversion is handled using put_user_mtpos/put_user_mtget */ switch (cmd_in) { case MTIOCPOS32: - return st_ioctl_common(file, MTIOCPOS, p); + cmd_in = MTIOCPOS; + break; case MTIOCGET32: - return st_ioctl_common(file, MTIOCGET, p); + cmd_in = MTIOCGET; + break; } - ret = st_ioctl_common(file, cmd_in, p); - if (ret != -ENOTTY) - return ret; - - return scsi_ioctl(STp->device, cmd_in, p); + return st_ioctl(file, cmd_in, arg); } #endif -- cgit v1.2.3-70-g09d2 From e9ee7fea45787d657c2e56134fa8484382a90444 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:17 +0200 Subject: scsi: cdrom: Remove the call to scsi_cmd_blk_ioctl() from cdrom_ioctl() Only the sr driver can handle SCSI passthrough requests, so move the call to scsi_cmd_blk_ioctl() there. Link: https://lore.kernel.org/r/20210724072033.1284840-9-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/block/Kconfig | 1 - drivers/block/paride/Kconfig | 1 - drivers/cdrom/cdrom.c | 7 ------- drivers/scsi/sr.c | 3 +++ 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 63056cfd4b62..4652bcdb9efb 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -74,7 +74,6 @@ config N64CART config CDROM tristate - select BLK_SCSI_REQUEST config GDROM tristate "SEGA Dreamcast GD-ROM drive" diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig index 7c6ae1036927..a295634597ba 100644 --- a/drivers/block/paride/Kconfig +++ b/drivers/block/paride/Kconfig @@ -27,7 +27,6 @@ config PARIDE_PCD tristate "Parallel port ATAPI CD-ROMs" depends on PARIDE select CDROM - select BLK_SCSI_REQUEST # only for the generic cdrom code help This option enables the high-level driver for ATAPI CD-ROM devices connected through a parallel port. If you chose to build PARIDE diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index feb827eefd1a..8882b311bafd 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -3357,13 +3357,6 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, void __user *argp = (void __user *)arg; int ret; - /* - * Try the generic SCSI command ioctl's first. - */ - ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); - if (ret != -ENOTTY) - return ret; - switch (cmd) { case CDROMMULTISESSION: return cdrom_ioctl_multisession(cdi, argp); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c5e163a659d2..7948416f40d5 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -579,6 +579,9 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: + ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + if (ret != -ENOTTY) + goto put; ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); if (ret != -ENOSYS) goto put; -- cgit v1.2.3-70-g09d2 From fb1ba406c451045f1063ace70086b4645d4e9d54 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:18 +0200 Subject: scsi: scsi_ioctl: Remove scsi_cmd_blk_ioctl() Open code scsi_cmd_blk_ioctl() in its two callers. Link: https://lore.kernel.org/r/20210724072033.1284840-10-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 13 ------------- drivers/scsi/sd.c | 5 ++++- drivers/scsi/sr.c | 8 ++++++-- include/linux/blkdev.h | 2 -- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index d247431a6853..f8138438c56f 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -854,19 +854,6 @@ int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) } EXPORT_SYMBOL(scsi_verify_blk_ioctl); -int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode, - unsigned int cmd, void __user *arg) -{ - int ret; - - ret = scsi_verify_blk_ioctl(bd, cmd); - if (ret < 0) - return ret; - - return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg); -} -EXPORT_SYMBOL(scsi_cmd_blk_ioctl); - /** * scsi_req_init - initialize certain fields of a scsi_request structure * @req: Pointer to a scsi_request structure. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0b87ca01efff..d65bfe505e08 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1583,7 +1583,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: - error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p); + error = scsi_verify_blk_ioctl(bdev, cmd); + if (error < 0) + return error; + error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); if (error != -ENOTTY) return error; } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 7948416f40d5..b903e54c57fd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -556,7 +556,8 @@ static void sr_block_release(struct gendisk *disk, fmode_t mode) static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - struct scsi_cd *cd = scsi_cd(bdev->bd_disk); + struct gendisk *disk = bdev->bd_disk; + struct scsi_cd *cd = scsi_cd(disk); struct scsi_device *sdev = cd->device; void __user *argp = (void __user *)arg; int ret; @@ -579,7 +580,10 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: - ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp); + ret = scsi_verify_blk_ioctl(bdev, cmd); + if (ret < 0) + goto put; + ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); if (ret != -ENOTTY) goto put; ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3177181c4326..19aa3d5429c0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -889,8 +889,6 @@ extern blk_status_t blk_insert_cloned_request(struct request_queue *q, int blk_rq_append_bio(struct request *rq, struct bio *bio); extern void blk_queue_split(struct bio **); extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int); -extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t, - unsigned int, void __user *); extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, unsigned int, void __user *); extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, -- cgit v1.2.3-70-g09d2 From 4f07bfc56157ebc689ef54879e90c48a47294083 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:19 +0200 Subject: scsi: scsi_ioctl: Remove scsi_verify_blk_ioctl() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manually verify that the device is not a partition and the caller has admin privіleges at the beginning of the sr ioctl method and open code the trivial check for sd as well. Link: https://lore.kernel.org/r/20210724072033.1284840-11-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 12 ------------ drivers/scsi/sd.c | 8 ++------ drivers/scsi/sr.c | 6 +++--- include/linux/blkdev.h | 1 - 4 files changed, 5 insertions(+), 22 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index f8138438c56f..ca7b84452d9d 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -842,18 +842,6 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod } EXPORT_SYMBOL(scsi_cmd_ioctl); -int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd) -{ - if (bd && !bdev_is_partition(bd)) - return 0; - - if (capable(CAP_SYS_RAWIO)) - return 0; - - return -ENOIOCTLCMD; -} -EXPORT_SYMBOL(scsi_verify_blk_ioctl); - /** * scsi_req_init - initialize certain fields of a scsi_request structure * @req: Pointer to a scsi_request structure. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d65bfe505e08..bcc4b1339e21 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1555,9 +1555,8 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, " "cmd=0x%x\n", disk->disk_name, cmd)); - error = scsi_verify_blk_ioctl(bdev, cmd); - if (error < 0) - return error; + if (bdev_is_partition(bdev) && !capable(CAP_SYS_RAWIO)) + return -ENOIOCTLCMD; /* * If we are in the middle of error recovery, don't let anyone @@ -1583,9 +1582,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: - error = scsi_verify_blk_ioctl(bdev, cmd); - if (error < 0) - return error; error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); if (error != -ENOTTY) return error; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index b903e54c57fd..e6eadba4d638 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -562,6 +562,9 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, void __user *argp = (void __user *)arg; int ret; + if (bdev_is_partition(bdev) && !capable(CAP_SYS_RAWIO)) + return -ENOIOCTLCMD; + mutex_lock(&cd->lock); ret = scsi_ioctl_block_when_processing_errors(sdev, cmd, @@ -580,9 +583,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, case SCSI_IOCTL_GET_BUS_NUMBER: break; default: - ret = scsi_verify_blk_ioctl(bdev, cmd); - if (ret < 0) - goto put; ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); if (ret != -ENOTTY) goto put; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 19aa3d5429c0..e2b972a85012 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -888,7 +888,6 @@ extern blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request *rq); int blk_rq_append_bio(struct request *rq, struct bio *bio); extern void blk_queue_split(struct bio **); -extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int); extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, unsigned int, void __user *); extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, -- cgit v1.2.3-70-g09d2 From 2e27f576abc6f056e63ef207b9911b1a04d07020 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:20 +0200 Subject: scsi: scsi_ioctl: Call scsi_cmd_ioctl() from scsi_ioctl() Ensure SCSI ULD only has to call a single ioctl helper. This also adds a bunch of missing ioctls to the ch driver, and removes the need for a duplicate implementation of SCSI_IOCTL_SEND_COMMAND command. Link: https://lore.kernel.org/r/20210724072033.1284840-12-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/ch.c | 2 +- drivers/scsi/scsi_ioctl.c | 17 ++++++++++++----- drivers/scsi/sd.c | 18 +----------------- drivers/scsi/sg.c | 2 +- drivers/scsi/sr.c | 16 ++-------------- drivers/scsi/st.c | 10 +--------- include/scsi/scsi_ioctl.h | 4 +++- 7 files changed, 21 insertions(+), 48 deletions(-) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index e354a95c56af..27012908b586 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -877,7 +877,7 @@ static long ch_ioctl(struct file *file, } default: - return scsi_ioctl(ch->device, cmd, argp); + return scsi_ioctl(ch->device, NULL, file->f_mode, cmd, argp); } } diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 7b2e3cc85e66..7739575b5229 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -192,6 +192,8 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg) /** * scsi_ioctl - Dispatch ioctl to scsi device * @sdev: scsi device receiving ioctl + * @disk: disk receiving the ioctl + * @mode: mode the block/char device is opened with * @cmd: which ioctl is it * @arg: data associated with ioctl * @@ -199,10 +201,13 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg) * does not take a major/minor number as the dev field. Rather, it takes * a pointer to a &struct scsi_device. */ -int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) +int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, + int cmd, void __user *arg) { + struct request_queue *q = sdev->request_queue; char scsi_cmd[MAX_COMMAND_SIZE]; struct scsi_sense_hdr sense_hdr; + int error; /* Check for deprecated ioctls ... all the ioctls which don't * follow the new unique numbering scheme are deprecated */ @@ -220,6 +225,12 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) break; } + if (cmd != SCSI_IOCTL_GET_IDLUN && cmd != SCSI_IOCTL_GET_BUS_NUMBER) { + error = scsi_cmd_ioctl(q, disk, mode, cmd, arg); + if (error != -ENOTTY) + return error; + } + switch (cmd) { case SCSI_IOCTL_GET_IDLUN: { struct scsi_idlun v = { @@ -237,10 +248,6 @@ int scsi_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) return put_user(sdev->host->host_no, (int __user *)arg); case SCSI_IOCTL_PROBE_HOST: return ioctl_probe(sdev->host, arg); - case SCSI_IOCTL_SEND_COMMAND: - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) - return -EACCES; - return sg_scsi_ioctl(sdev->request_queue, NULL, 0, arg); case SCSI_IOCTL_DOORLOCK: return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); case SCSI_IOCTL_DOORUNLOCK: diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bcc4b1339e21..c1b75f159e0c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1571,23 +1571,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, if (is_sed_ioctl(cmd)) return sed_ioctl(sdkp->opal_dev, cmd, p); - - /* - * Send SCSI addressing ioctls directly to mid level, send other - * ioctls to block level and then onto mid level if they can't be - * resolved. - */ - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - break; - default: - error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); - if (error != -ENOTTY) - return error; - } - - return scsi_ioctl(sdp, cmd, p); + return scsi_ioctl(sdp, disk, mode, cmd, p); } static void set_media_not_present(struct scsi_disk *sdkp) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c3562c2d0dca..6cb1e4b6eac2 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1165,7 +1165,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p); if (ret != -ENOIOCTLCMD) return ret; - return scsi_ioctl(sdp->device, cmd_in, p); + return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p); } static __poll_t diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index e6eadba4d638..b98e77fe700b 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -574,24 +574,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, scsi_autopm_get_device(sdev); - /* - * Send SCSI addressing ioctls directly to mid level, send other - * ioctls to cdrom/block level. - */ - switch (cmd) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - break; - default: - ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); - if (ret != -ENOTTY) - goto put; + if (ret != CDROMCLOSETRAY && ret != CDROMEJECT) { ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); if (ret != -ENOSYS) goto put; } - - ret = scsi_ioctl(sdev, cmd, argp); + ret = scsi_ioctl(sdev, disk, mode, cmd, argp); put: scsi_autopm_put_device(sdev); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 9274f665bc0f..2d1b0594af69 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3823,24 +3823,16 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) mutex_unlock(&STp->lock); switch (cmd_in) { - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: - break; case SG_IO: case SCSI_IOCTL_SEND_COMMAND: case CDROM_SEND_PACKET: if (!capable(CAP_SYS_RAWIO)) return -EPERM; - fallthrough; default: - retval = scsi_cmd_ioctl(STp->disk->queue, STp->disk, - file->f_mode, cmd_in, p); - if (retval != -ENOTTY) - return retval; break; } - retval = scsi_ioctl(STp->device, cmd_in, p); + retval = scsi_ioctl(STp->device, STp->disk, file->f_mode, cmd_in, p); if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */ STp->rew_at_close = 0; diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index cdb3ba3451e7..defbe8084eb8 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -18,6 +18,7 @@ #ifdef __KERNEL__ +struct gendisk; struct scsi_device; /* @@ -43,7 +44,8 @@ typedef struct scsi_fctargaddress { int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); -extern int scsi_ioctl(struct scsi_device *, int, void __user *); +int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, + int cmd, void __user *arg); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ -- cgit v1.2.3-70-g09d2 From 547e2f7093b19a993d76c249b4c3ec8af8127d09 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:21 +0200 Subject: scsi: block: Add a queue_max_bytes() helper Return the max_sectors value in bytes. Lifted from scsi_ioctl.c. Link: https://lore.kernel.org/r/20210724072033.1284840-13-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 13 ++----------- include/linux/blkdev.h | 5 +++++ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index ca7b84452d9d..c3871529e283 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -68,18 +68,9 @@ static int sg_set_timeout(struct request_queue *q, int __user *p) return err; } -static int max_sectors_bytes(struct request_queue *q) -{ - unsigned int max_sectors = queue_max_sectors(q); - - max_sectors = min_t(unsigned int, max_sectors, INT_MAX >> 9); - - return max_sectors << 9; -} - static int sg_get_reserved_size(struct request_queue *q, int __user *p) { - int val = min_t(int, q->sg_reserved_size, max_sectors_bytes(q)); + int val = min(q->sg_reserved_size, queue_max_bytes(q)); return put_user(val, p); } @@ -94,7 +85,7 @@ static int sg_set_reserved_size(struct request_queue *q, int __user *p) if (size < 0) return -EINVAL; - q->sg_reserved_size = min(size, max_sectors_bytes(q)); + q->sg_reserved_size = min_t(unsigned int, size, queue_max_bytes(q)); return 0; } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e2b972a85012..9971796819ef 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1373,6 +1373,11 @@ static inline unsigned int queue_max_sectors(const struct request_queue *q) return q->limits.max_sectors; } +static inline unsigned int queue_max_bytes(struct request_queue *q) +{ + return min_t(unsigned int, queue_max_sectors(q), INT_MAX >> 9) << 9; +} + static inline unsigned int queue_max_hw_sectors(const struct request_queue *q) { return q->limits.max_hw_sectors; -- cgit v1.2.3-70-g09d2 From d52fe8f436a6d9850b5e528cb94a651563a77374 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:22 +0200 Subject: scsi: bsg: Decouple from scsi_cmd_ioctl() Decouple bsg from scsi_cmd_ioctl(). This requires a small amount of code duplication, but will allow moving all SCSI ioctl handling into SCSI midlayer. Link: https://lore.kernel.org/r/20210724072033.1284840-14-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/bsg.c | 24 ++++++++++++++++++++++-- block/scsi_ioctl.c | 16 ---------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index 79b42c5cafeb..df21df106d3b 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -351,7 +351,10 @@ static int bsg_set_command_q(struct bsg_device *bd, int __user *uarg) static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct bsg_device *bd = file->private_data; + struct request_queue *q = bd->queue; void __user *uarg = (void __user *) arg; + int __user *intp = uarg; + int val; switch (cmd) { /* @@ -366,16 +369,33 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) * SCSI/sg ioctls */ case SG_GET_VERSION_NUM: + return put_user(30527, intp); case SCSI_IOCTL_GET_IDLUN: + return put_user(0, intp); case SCSI_IOCTL_GET_BUS_NUMBER: + return put_user(0, intp); case SG_SET_TIMEOUT: + if (get_user(val, intp)) + return -EFAULT; + q->sg_timeout = clock_t_to_jiffies(val); + return 0; case SG_GET_TIMEOUT: + return jiffies_to_clock_t(q->sg_timeout); case SG_GET_RESERVED_SIZE: + return put_user(min(q->sg_reserved_size, queue_max_bytes(q)), + intp); case SG_SET_RESERVED_SIZE: + if (get_user(val, intp)) + return -EFAULT; + if (val < 0) + return -EINVAL; + q->sg_reserved_size = + min_t(unsigned int, val, queue_max_bytes(q)); + return 0; case SG_EMULATED_HOST: - return scsi_cmd_ioctl(bd->queue, NULL, file->f_mode, cmd, uarg); + return put_user(1, intp); case SG_IO: - return bsg_sg_io(bd->queue, file->f_mode, uarg); + return bsg_sg_io(q, file->f_mode, uarg); case SCSI_IOCTL_SEND_COMMAND: pr_warn_ratelimited("%s: calling unsupported SCSI_IOCTL_SEND_COMMAND\n", current->comm); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index c3871529e283..b875feb8d6bd 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -43,16 +43,6 @@ static int sg_get_version(int __user *p) return put_user(sg_version_num, p); } -static int scsi_get_idlun(struct request_queue *q, int __user *p) -{ - return put_user(0, p); -} - -static int scsi_get_bus(struct request_queue *q, int __user *p) -{ - return put_user(0, p); -} - static int sg_get_timeout(struct request_queue *q) { return jiffies_to_clock_t(q->sg_timeout); @@ -769,12 +759,6 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod case SG_GET_VERSION_NUM: err = sg_get_version(arg); break; - case SCSI_IOCTL_GET_IDLUN: - err = scsi_get_idlun(q, arg); - break; - case SCSI_IOCTL_GET_BUS_NUMBER: - err = scsi_get_bus(q, arg); - break; case SG_SET_TIMEOUT: err = sg_set_timeout(q, arg); break; -- cgit v1.2.3-70-g09d2 From 78011042684dfbb50f7060f4623793f7a5c74a01 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:23 +0200 Subject: scsi: bsg: Move bsg_scsi_ops to drivers/scsi/ Move the SCSI-specific bsg code in the SCSI midlayer instead of in the common bsg code. This just keeps the common bsg code block/ and also allows building it as a module. Link: https://lore.kernel.org/r/20210724072033.1284840-15-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/Kconfig | 23 ++---------- block/Makefile | 2 +- block/bsg.c | 95 +---------------------------------------------- drivers/scsi/Kconfig | 13 +++++++ drivers/scsi/Makefile | 1 + drivers/scsi/scsi_bsg.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/scsi_priv.h | 10 +++++ drivers/scsi/scsi_sysfs.c | 2 +- include/linux/blkdev.h | 2 +- include/linux/bsg.h | 11 ++---- 10 files changed, 129 insertions(+), 125 deletions(-) create mode 100644 drivers/scsi/scsi_bsg.c diff --git a/block/Kconfig b/block/Kconfig index fd732aede922..88aa88241795 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -35,29 +35,12 @@ config BLK_SCSI_REQUEST config BLK_CGROUP_RWSTAT bool -config BLK_DEV_BSG - bool "Block layer SG support v4" - default y - select BLK_SCSI_REQUEST - help - Saying Y here will enable generic SG (SCSI generic) v4 support - for any block device. - - Unlike SG v3 (aka block/scsi_ioctl.c drivers/scsi/sg.c), SG v4 - can handle complicated SCSI commands: tagged variable length cdbs - with bidirectional data transfers and generic request/response - protocols (e.g. Task Management Functions and SMP in Serial - Attached SCSI). - - This option is required by recent UDEV versions to properly - access device serial numbers, etc. - - If unsure, say Y. +config BLK_DEV_BSG_COMMON + tristate config BLK_DEV_BSGLIB bool "Block layer SG support v4 helper lib" - select BLK_DEV_BSG - select BLK_SCSI_REQUEST + select BLK_DEV_BSG_COMMON help Subsystems will normally enable this if needed. Users will not normally need to manually enable this. diff --git a/block/Makefile b/block/Makefile index bfbe4e13ca1e..f37d532c8da5 100644 --- a/block/Makefile +++ b/block/Makefile @@ -13,7 +13,7 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-sysfs.o \ obj-$(CONFIG_BOUNCE) += bounce.o obj-$(CONFIG_BLK_SCSI_REQUEST) += scsi_ioctl.o -obj-$(CONFIG_BLK_DEV_BSG) += bsg.o +obj-$(CONFIG_BLK_DEV_BSG_COMMON) += bsg.o obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o obj-$(CONFIG_BLK_CGROUP_RWSTAT) += blk-cgroup-rwstat.o diff --git a/block/bsg.c b/block/bsg.c index df21df106d3b..3dbfd2c6aef3 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -15,9 +15,6 @@ #include #include -#include -#include -#include #include #define BSG_DESCRIPTION "Block layer SCSI generic (bsg) driver" @@ -54,86 +51,6 @@ static inline struct hlist_head *bsg_dev_idx_hash(int index) #define uptr64(val) ((void __user *)(uintptr_t)(val)) -static int bsg_scsi_check_proto(struct sg_io_v4 *hdr) -{ - if (hdr->protocol != BSG_PROTOCOL_SCSI || - hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD) - return -EINVAL; - return 0; -} - -static int bsg_scsi_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, - fmode_t mode) -{ - struct scsi_request *sreq = scsi_req(rq); - - if (hdr->dout_xfer_len && hdr->din_xfer_len) { - pr_warn_once("BIDI support in bsg has been removed.\n"); - return -EOPNOTSUPP; - } - - sreq->cmd_len = hdr->request_len; - if (sreq->cmd_len > BLK_MAX_CDB) { - sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL); - if (!sreq->cmd) - return -ENOMEM; - } - - if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len)) - return -EFAULT; - if (blk_verify_command(sreq->cmd, mode)) - return -EPERM; - return 0; -} - -static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr) -{ - struct scsi_request *sreq = scsi_req(rq); - int ret = 0; - - /* - * fill in all the output members - */ - hdr->device_status = sreq->result & 0xff; - hdr->transport_status = host_byte(sreq->result); - hdr->driver_status = 0; - if (scsi_status_is_check_condition(sreq->result)) - hdr->driver_status = DRIVER_SENSE; - hdr->info = 0; - if (hdr->device_status || hdr->transport_status || hdr->driver_status) - hdr->info |= SG_INFO_CHECK; - hdr->response_len = 0; - - if (sreq->sense_len && hdr->response) { - int len = min_t(unsigned int, hdr->max_response_len, - sreq->sense_len); - - if (copy_to_user(uptr64(hdr->response), sreq->sense, len)) - ret = -EFAULT; - else - hdr->response_len = len; - } - - if (rq_data_dir(rq) == READ) - hdr->din_resid = sreq->resid_len; - else - hdr->dout_resid = sreq->resid_len; - - return ret; -} - -static void bsg_scsi_free_rq(struct request *rq) -{ - scsi_req_free_cmd(scsi_req(rq)); -} - -static const struct bsg_ops bsg_scsi_ops = { - .check_proto = bsg_scsi_check_proto, - .fill_hdr = bsg_scsi_fill_hdr, - .complete_rq = bsg_scsi_complete_rq, - .free_rq = bsg_scsi_free_rq, -}; - static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) { struct request *rq; @@ -487,17 +404,7 @@ unlock: mutex_unlock(&bsg_mutex); return ret; } - -int bsg_scsi_register_queue(struct request_queue *q, struct device *parent) -{ - if (!blk_queue_scsi_passthrough(q)) { - WARN_ONCE(true, "Attempt to register a non-SCSI queue\n"); - return -EINVAL; - } - - return bsg_register_queue(q, parent, dev_name(parent), &bsg_scsi_ops); -} -EXPORT_SYMBOL_GPL(bsg_scsi_register_queue); +EXPORT_SYMBOL_GPL(bsg_register_queue); static struct cdev bsg_cdev; diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8f44d433e06e..86ecab196dfd 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -20,6 +20,7 @@ config SCSI select SCSI_DMA if HAS_DMA select SG_POOL select BLK_SCSI_REQUEST + select BLK_DEV_BSG_COMMON if BLK_DEV_BSG help If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or any other SCSI device under Linux, say Y and make sure that you know @@ -140,6 +141,18 @@ config CHR_DEV_SG If unsure, say N. +config BLK_DEV_BSG + bool "/dev/bsg support (SG v4)" + depends on SCSI + default y + help + Saying Y here will enable generic SG (SCSI generic) v4 support + for any SCSI device. + + This option is required by UDEV to access device serial numbers, etc. + + If unsure, say Y. + config CHR_DEV_SCH tristate "SCSI media changer support" depends on SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 1748d1ec1338..240b831b5a11 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -168,6 +168,7 @@ scsi_mod-$(CONFIG_BLK_DEBUG_FS) += scsi_debugfs.o scsi_mod-y += scsi_trace.o scsi_logging.o scsi_mod-$(CONFIG_PM) += scsi_pm.o scsi_mod-$(CONFIG_SCSI_DH) += scsi_dh.o +scsi_mod-$(CONFIG_BLK_DEV_BSG) += scsi_bsg.o hv_storvsc-y := storvsc_drv.o diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c new file mode 100644 index 000000000000..3bdb28940460 --- /dev/null +++ b/drivers/scsi/scsi_bsg.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include "scsi_priv.h" + +#define uptr64(val) ((void __user *)(uintptr_t)(val)) + +static int scsi_bsg_check_proto(struct sg_io_v4 *hdr) +{ + if (hdr->protocol != BSG_PROTOCOL_SCSI || + hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD) + return -EINVAL; + return 0; +} + +static int scsi_bsg_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, + fmode_t mode) +{ + struct scsi_request *sreq = scsi_req(rq); + + if (hdr->dout_xfer_len && hdr->din_xfer_len) { + pr_warn_once("BIDI support in bsg has been removed.\n"); + return -EOPNOTSUPP; + } + + sreq->cmd_len = hdr->request_len; + if (sreq->cmd_len > BLK_MAX_CDB) { + sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL); + if (!sreq->cmd) + return -ENOMEM; + } + + if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len)) + return -EFAULT; + if (blk_verify_command(sreq->cmd, mode)) + return -EPERM; + return 0; +} + +static int scsi_bsg_complete_rq(struct request *rq, struct sg_io_v4 *hdr) +{ + struct scsi_request *sreq = scsi_req(rq); + int ret = 0; + + /* + * fill in all the output members + */ + hdr->device_status = sreq->result & 0xff; + hdr->transport_status = host_byte(sreq->result); + hdr->driver_status = 0; + if (scsi_status_is_check_condition(sreq->result)) + hdr->driver_status = DRIVER_SENSE; + hdr->info = 0; + if (hdr->device_status || hdr->transport_status || hdr->driver_status) + hdr->info |= SG_INFO_CHECK; + hdr->response_len = 0; + + if (sreq->sense_len && hdr->response) { + int len = min_t(unsigned int, hdr->max_response_len, + sreq->sense_len); + + if (copy_to_user(uptr64(hdr->response), sreq->sense, len)) + ret = -EFAULT; + else + hdr->response_len = len; + } + + if (rq_data_dir(rq) == READ) + hdr->din_resid = sreq->resid_len; + else + hdr->dout_resid = sreq->resid_len; + + return ret; +} + +static void scsi_bsg_free_rq(struct request *rq) +{ + scsi_req_free_cmd(scsi_req(rq)); +} + +static const struct bsg_ops scsi_bsg_ops = { + .check_proto = scsi_bsg_check_proto, + .fill_hdr = scsi_bsg_fill_hdr, + .complete_rq = scsi_bsg_complete_rq, + .free_rq = scsi_bsg_free_rq, +}; + +int scsi_bsg_register_queue(struct request_queue *q, struct device *parent) +{ + return bsg_register_queue(q, parent, dev_name(parent), &scsi_bsg_ops); +} diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index eae2235f79b5..0a0db35bab04 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -180,6 +180,16 @@ static inline void scsi_dh_add_device(struct scsi_device *sdev) { } static inline void scsi_dh_release_device(struct scsi_device *sdev) { } #endif +#ifdef CONFIG_BLK_DEV_BSG +int scsi_bsg_register_queue(struct request_queue *q, struct device *parent); +#else +static inline int scsi_bsg_register_queue(struct request_queue *q, + struct device *parent) +{ + return 0; +} +#endif + extern int scsi_device_max_queue_depth(struct scsi_device *sdev); /* diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 32489d25158f..4ff9ac3296d8 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1366,7 +1366,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) transport_add_device(&sdev->sdev_gendev); sdev->is_visible = 1; - error = bsg_scsi_register_queue(rq, &sdev->sdev_gendev); + error = scsi_bsg_register_queue(rq, &sdev->sdev_gendev); if (error) /* we're treating error on bsg register as non-fatal, * so pretend nothing went wrong */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9971796819ef..d36b67bd7267 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -537,7 +537,7 @@ struct request_queue { int mq_freeze_depth; -#if defined(CONFIG_BLK_DEV_BSG) +#if IS_ENABLED(CONFIG_BLK_DEV_BSG_COMMON) struct bsg_class_device bsg_dev; #endif diff --git a/include/linux/bsg.h b/include/linux/bsg.h index dac37b6e00ec..b887da20bd41 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -5,8 +5,9 @@ #include struct request; +struct request_queue; -#ifdef CONFIG_BLK_DEV_BSG +#ifdef CONFIG_BLK_DEV_BSG_COMMON struct bsg_ops { int (*check_proto)(struct sg_io_v4 *hdr); int (*fill_hdr)(struct request *rq, struct sg_io_v4 *hdr, @@ -24,16 +25,10 @@ struct bsg_class_device { int bsg_register_queue(struct request_queue *q, struct device *parent, const char *name, const struct bsg_ops *ops); -int bsg_scsi_register_queue(struct request_queue *q, struct device *parent); void bsg_unregister_queue(struct request_queue *q); #else -static inline int bsg_scsi_register_queue(struct request_queue *q, - struct device *parent) -{ - return 0; -} static inline void bsg_unregister_queue(struct request_queue *q) { } -#endif /* CONFIG_BLK_DEV_BSG */ +#endif /* CONFIG_BLK_DEV_BSG_COMMON */ #endif /* _LINUX_BSG_H */ -- cgit v1.2.3-70-g09d2 From 2cece3778475abc855084d897a3cf61249798ad9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:24 +0200 Subject: scsi: scsi_ioctl: Remove scsi_req_init() Merge scsi_req_init() into its only caller. Link: https://lore.kernel.org/r/20210724072033.1284840-16-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 15 --------------- drivers/scsi/scsi_lib.c | 7 ++++++- include/scsi/scsi_request.h | 2 -- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index b875feb8d6bd..4d214f9ac8d0 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -817,21 +817,6 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod } EXPORT_SYMBOL(scsi_cmd_ioctl); -/** - * scsi_req_init - initialize certain fields of a scsi_request structure - * @req: Pointer to a scsi_request structure. - * Initializes .__cmd[], .cmd, .cmd_len and .sense_len but no other members - * of struct scsi_request. - */ -void scsi_req_init(struct scsi_request *req) -{ - memset(req->__cmd, 0, sizeof(req->__cmd)); - req->cmd = req->__cmd; - req->cmd_len = BLK_MAX_CDB; - req->sense_len = 0; -} -EXPORT_SYMBOL(scsi_req_init); - static int __init blk_scsi_ioctl_init(void) { blk_set_cmd_filter_defaults(&blk_default_cmd_filter); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7456a26aef51..77578b221a71 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1083,8 +1083,13 @@ EXPORT_SYMBOL(scsi_alloc_sgtables); static void scsi_initialize_rq(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); + struct scsi_request *req = &cmd->req; + + memset(req->__cmd, 0, sizeof(req->__cmd)); + req->cmd = req->__cmd; + req->cmd_len = BLK_MAX_CDB; + req->sense_len = 0; - scsi_req_init(&cmd->req); init_rcu_head(&cmd->rcu); cmd->jiffies_at_alloc = jiffies; cmd->retries = 0; diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h index b06f28c74908..9129b23e12bc 100644 --- a/include/scsi/scsi_request.h +++ b/include/scsi/scsi_request.h @@ -28,6 +28,4 @@ static inline void scsi_req_free_cmd(struct scsi_request *req) kfree(req->cmd); } -void scsi_req_init(struct scsi_request *req); - #endif /* _SCSI_SCSI_REQUEST_H */ -- cgit v1.2.3-70-g09d2 From b69367dffd86813495cf01e128ff2c8a8e41bb83 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:25 +0200 Subject: scsi: scsi_ioctl: Move scsi_command_size_tbl to scsi_common.c Move the SCSI command size table to common SCSI code. Link: https://lore.kernel.org/r/20210724072033.1284840-17-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 8 -------- drivers/scsi/scsi_common.c | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 4d214f9ac8d0..4d023f2f43f0 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -29,14 +29,6 @@ struct blk_cmd_filter { static struct blk_cmd_filter blk_default_cmd_filter; -/* Command group 3 is reserved and should never be used. */ -const unsigned char scsi_command_size_tbl[8] = -{ - 6, 10, 10, 12, - 16, 12, 10, 10 -}; -EXPORT_SYMBOL(scsi_command_size_tbl); - static int sg_get_version(int __user *p) { static const int sg_version_num = 30527; diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index 90349498f686..8aac4e5e8c4c 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -10,6 +10,12 @@ #include #include +/* Command group 3 is reserved and should never be used. */ +const unsigned char scsi_command_size_tbl[8] = { + 6, 10, 10, 12, 16, 12, 10, 10 +}; +EXPORT_SYMBOL(scsi_command_size_tbl); + /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. * You may not alter any existing entry (although adding new ones is * encouraged once assigned by ANSI/INCITS T10). -- cgit v1.2.3-70-g09d2 From 7353dc06c9a8e37c80da7ff986e6ef5123bec8ce Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:26 +0200 Subject: scsi: scsi_ioctl: Simplify SCSI passthrough permission checking Remove the separate command filter structure and just use a switch statement (which also cought two duplicate commands), return a bool and give the function a sensible name. Link: https://lore.kernel.org/r/20210724072033.1284840-18-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/scsi_ioctl.c | 219 ++++++++++++++++++++++-------------------------- drivers/scsi/scsi_bsg.c | 2 +- drivers/scsi/sg.c | 5 +- include/linux/blkdev.h | 2 +- 4 files changed, 104 insertions(+), 124 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 4d023f2f43f0..3642e145108a 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -22,13 +22,6 @@ #include #include -struct blk_cmd_filter { - unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; - unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; -}; - -static struct blk_cmd_filter blk_default_cmd_filter; - static int sg_get_version(int __user *p) { static const int sg_version_num = 30527; @@ -80,115 +73,108 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } -static void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter) -{ - /* Basic read-only commands */ - __set_bit(TEST_UNIT_READY, filter->read_ok); - __set_bit(REQUEST_SENSE, filter->read_ok); - __set_bit(READ_6, filter->read_ok); - __set_bit(READ_10, filter->read_ok); - __set_bit(READ_12, filter->read_ok); - __set_bit(READ_16, filter->read_ok); - __set_bit(READ_BUFFER, filter->read_ok); - __set_bit(READ_DEFECT_DATA, filter->read_ok); - __set_bit(READ_CAPACITY, filter->read_ok); - __set_bit(READ_LONG, filter->read_ok); - __set_bit(INQUIRY, filter->read_ok); - __set_bit(MODE_SENSE, filter->read_ok); - __set_bit(MODE_SENSE_10, filter->read_ok); - __set_bit(LOG_SENSE, filter->read_ok); - __set_bit(START_STOP, filter->read_ok); - __set_bit(GPCMD_VERIFY_10, filter->read_ok); - __set_bit(VERIFY_16, filter->read_ok); - __set_bit(REPORT_LUNS, filter->read_ok); - __set_bit(SERVICE_ACTION_IN_16, filter->read_ok); - __set_bit(RECEIVE_DIAGNOSTIC, filter->read_ok); - __set_bit(MAINTENANCE_IN, filter->read_ok); - __set_bit(GPCMD_READ_BUFFER_CAPACITY, filter->read_ok); - - /* Audio CD commands */ - __set_bit(GPCMD_PLAY_CD, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_10, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_MSF, filter->read_ok); - __set_bit(GPCMD_PLAY_AUDIO_TI, filter->read_ok); - __set_bit(GPCMD_PAUSE_RESUME, filter->read_ok); - - /* CD/DVD data reading */ - __set_bit(GPCMD_READ_CD, filter->read_ok); - __set_bit(GPCMD_READ_CD_MSF, filter->read_ok); - __set_bit(GPCMD_READ_DISC_INFO, filter->read_ok); - __set_bit(GPCMD_READ_CDVD_CAPACITY, filter->read_ok); - __set_bit(GPCMD_READ_DVD_STRUCTURE, filter->read_ok); - __set_bit(GPCMD_READ_HEADER, filter->read_ok); - __set_bit(GPCMD_READ_TRACK_RZONE_INFO, filter->read_ok); - __set_bit(GPCMD_READ_SUBCHANNEL, filter->read_ok); - __set_bit(GPCMD_READ_TOC_PMA_ATIP, filter->read_ok); - __set_bit(GPCMD_REPORT_KEY, filter->read_ok); - __set_bit(GPCMD_SCAN, filter->read_ok); - __set_bit(GPCMD_GET_CONFIGURATION, filter->read_ok); - __set_bit(GPCMD_READ_FORMAT_CAPACITIES, filter->read_ok); - __set_bit(GPCMD_GET_EVENT_STATUS_NOTIFICATION, filter->read_ok); - __set_bit(GPCMD_GET_PERFORMANCE, filter->read_ok); - __set_bit(GPCMD_SEEK, filter->read_ok); - __set_bit(GPCMD_STOP_PLAY_SCAN, filter->read_ok); - - /* Basic writing commands */ - __set_bit(WRITE_6, filter->write_ok); - __set_bit(WRITE_10, filter->write_ok); - __set_bit(WRITE_VERIFY, filter->write_ok); - __set_bit(WRITE_12, filter->write_ok); - __set_bit(WRITE_VERIFY_12, filter->write_ok); - __set_bit(WRITE_16, filter->write_ok); - __set_bit(WRITE_LONG, filter->write_ok); - __set_bit(WRITE_LONG_2, filter->write_ok); - __set_bit(WRITE_SAME, filter->write_ok); - __set_bit(WRITE_SAME_16, filter->write_ok); - __set_bit(WRITE_SAME_32, filter->write_ok); - __set_bit(ERASE, filter->write_ok); - __set_bit(GPCMD_MODE_SELECT_10, filter->write_ok); - __set_bit(MODE_SELECT, filter->write_ok); - __set_bit(LOG_SELECT, filter->write_ok); - __set_bit(GPCMD_BLANK, filter->write_ok); - __set_bit(GPCMD_CLOSE_TRACK, filter->write_ok); - __set_bit(GPCMD_FLUSH_CACHE, filter->write_ok); - __set_bit(GPCMD_FORMAT_UNIT, filter->write_ok); - __set_bit(GPCMD_REPAIR_RZONE_TRACK, filter->write_ok); - __set_bit(GPCMD_RESERVE_RZONE_TRACK, filter->write_ok); - __set_bit(GPCMD_SEND_DVD_STRUCTURE, filter->write_ok); - __set_bit(GPCMD_SEND_EVENT, filter->write_ok); - __set_bit(GPCMD_SEND_KEY, filter->write_ok); - __set_bit(GPCMD_SEND_OPC, filter->write_ok); - __set_bit(GPCMD_SEND_CUE_SHEET, filter->write_ok); - __set_bit(GPCMD_SET_SPEED, filter->write_ok); - __set_bit(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL, filter->write_ok); - __set_bit(GPCMD_LOAD_UNLOAD, filter->write_ok); - __set_bit(GPCMD_SET_STREAMING, filter->write_ok); - __set_bit(GPCMD_SET_READ_AHEAD, filter->write_ok); - - /* ZBC Commands */ - __set_bit(ZBC_OUT, filter->write_ok); - __set_bit(ZBC_IN, filter->read_ok); -} - -int blk_verify_command(unsigned char *cmd, fmode_t mode) +/* + * Check if the given command is allowed. + * + * For unprivileged users only a small set of whitelisted command is allowed so + * that they can't format the drive or update the firmware. + */ +bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode) { - struct blk_cmd_filter *filter = &blk_default_cmd_filter; - /* root can do any command. */ if (capable(CAP_SYS_RAWIO)) - return 0; + return true; /* Anybody who can open the device can do a read-safe command */ - if (test_bit(cmd[0], filter->read_ok)) - return 0; - - /* Write-safe commands require a writable open */ - if (test_bit(cmd[0], filter->write_ok) && (mode & FMODE_WRITE)) - return 0; - - return -EPERM; + switch (cmd[0]) { + /* Basic read-only commands */ + case TEST_UNIT_READY: + case REQUEST_SENSE: + case READ_6: + case READ_10: + case READ_12: + case READ_16: + case READ_BUFFER: + case READ_DEFECT_DATA: + case READ_CAPACITY: /* also GPCMD_READ_CDVD_CAPACITY */ + case READ_LONG: + case INQUIRY: + case MODE_SENSE: + case MODE_SENSE_10: + case LOG_SENSE: + case START_STOP: + case GPCMD_VERIFY_10: + case VERIFY_16: + case REPORT_LUNS: + case SERVICE_ACTION_IN_16: + case RECEIVE_DIAGNOSTIC: + case MAINTENANCE_IN: /* also GPCMD_SEND_KEY, which is a write command */ + case GPCMD_READ_BUFFER_CAPACITY: + /* Audio CD commands */ + case GPCMD_PLAY_CD: + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_MSF: + case GPCMD_PLAY_AUDIO_TI: + case GPCMD_PAUSE_RESUME: + /* CD/DVD data reading */ + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + case GPCMD_READ_DISC_INFO: + case GPCMD_READ_DVD_STRUCTURE: + case GPCMD_READ_HEADER: + case GPCMD_READ_TRACK_RZONE_INFO: + case GPCMD_READ_SUBCHANNEL: + case GPCMD_READ_TOC_PMA_ATIP: + case GPCMD_REPORT_KEY: + case GPCMD_SCAN: + case GPCMD_GET_CONFIGURATION: + case GPCMD_READ_FORMAT_CAPACITIES: + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + case GPCMD_GET_PERFORMANCE: + case GPCMD_SEEK: + case GPCMD_STOP_PLAY_SCAN: + /* ZBC */ + case ZBC_IN: + return true; + /* Basic writing commands */ + case WRITE_6: + case WRITE_10: + case WRITE_VERIFY: + case WRITE_12: + case WRITE_VERIFY_12: + case WRITE_16: + case WRITE_LONG: + case WRITE_LONG_2: + case WRITE_SAME: + case WRITE_SAME_16: + case WRITE_SAME_32: + case ERASE: + case GPCMD_MODE_SELECT_10: + case MODE_SELECT: + case LOG_SELECT: + case GPCMD_BLANK: + case GPCMD_CLOSE_TRACK: + case GPCMD_FLUSH_CACHE: + case GPCMD_FORMAT_UNIT: + case GPCMD_REPAIR_RZONE_TRACK: + case GPCMD_RESERVE_RZONE_TRACK: + case GPCMD_SEND_DVD_STRUCTURE: + case GPCMD_SEND_EVENT: + case GPCMD_SEND_OPC: + case GPCMD_SEND_CUE_SHEET: + case GPCMD_SET_SPEED: + case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + case GPCMD_LOAD_UNLOAD: + case GPCMD_SET_STREAMING: + case GPCMD_SET_READ_AHEAD: + /* ZBC */ + case ZBC_OUT: + return (mode & FMODE_WRITE); + default: + return false; + } } -EXPORT_SYMBOL(blk_verify_command); +EXPORT_SYMBOL(scsi_cmd_allowed); static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, struct sg_io_hdr *hdr, fmode_t mode) @@ -197,7 +183,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; - if (blk_verify_command(req->cmd, mode)) + if (!scsi_cmd_allowed(req->cmd, mode)) return -EPERM; /* @@ -428,8 +414,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) goto error; - err = blk_verify_command(req->cmd, mode); - if (err) + err = -EPERM; + if (!scsi_cmd_allowed(req->cmd, mode)) goto error; /* default. possible overriden later */ @@ -808,10 +794,3 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod return err; } EXPORT_SYMBOL(scsi_cmd_ioctl); - -static int __init blk_scsi_ioctl_init(void) -{ - blk_set_cmd_filter_defaults(&blk_default_cmd_filter); - return 0; -} -fs_initcall(blk_scsi_ioctl_init); diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index 3bdb28940460..68f60316adf1 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -36,7 +36,7 @@ static int scsi_bsg_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len)) return -EFAULT; - if (blk_verify_command(sreq->cmd, mode)) + if (!scsi_cmd_allowed(sreq->cmd, mode)) return -EPERM; return 0; } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 6cb1e4b6eac2..c86fa4476334 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -238,8 +238,9 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd) if (sfp->parentdp->device->type == TYPE_SCANNER) return 0; - - return blk_verify_command(cmd, filp->f_mode); + if (!scsi_cmd_allowed(cmd, filp->f_mode)) + return -EPERM; + return 0; } static int diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d36b67bd7267..e28679e63373 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1343,7 +1343,7 @@ static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, gfp_mask, 0); } -extern int blk_verify_command(unsigned char *cmd, fmode_t mode); +bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode); static inline bool bdev_is_partition(struct block_device *bdev) { -- cgit v1.2.3-70-g09d2 From f2542a3be3277a65c766fa6e86b930d3d839f79e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:27 +0200 Subject: scsi: scsi_ioctl: Move the "block layer" SCSI ioctl handling to drivers/scsi Merge the ioctl handling in block/scsi_ioctl.c into its only caller in drivers/scsi/scsi_ioctl.c. Link: https://lore.kernel.org/r/20210724072033.1284840-19-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/Makefile | 1 - block/scsi_ioctl.c | 796 ---------------------------------------------- drivers/scsi/scsi_ioctl.c | 740 +++++++++++++++++++++++++++++++++++++++++- include/linux/blkdev.h | 11 - include/scsi/scsi_ioctl.h | 6 + 5 files changed, 741 insertions(+), 813 deletions(-) delete mode 100644 block/scsi_ioctl.c diff --git a/block/Makefile b/block/Makefile index f37d532c8da5..640afba070fd 100644 --- a/block/Makefile +++ b/block/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_BLOCK) := bio.o elevator.o blk-core.o blk-sysfs.o \ disk-events.o obj-$(CONFIG_BOUNCE) += bounce.o -obj-$(CONFIG_BLK_SCSI_REQUEST) += scsi_ioctl.o obj-$(CONFIG_BLK_DEV_BSG_COMMON) += bsg.o obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c deleted file mode 100644 index 3642e145108a..000000000000 --- a/block/scsi_ioctl.c +++ /dev/null @@ -1,796 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2001 Jens Axboe - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static int sg_get_version(int __user *p) -{ - static const int sg_version_num = 30527; - return put_user(sg_version_num, p); -} - -static int sg_get_timeout(struct request_queue *q) -{ - return jiffies_to_clock_t(q->sg_timeout); -} - -static int sg_set_timeout(struct request_queue *q, int __user *p) -{ - int timeout, err = get_user(timeout, p); - - if (!err) - q->sg_timeout = clock_t_to_jiffies(timeout); - - return err; -} - -static int sg_get_reserved_size(struct request_queue *q, int __user *p) -{ - int val = min(q->sg_reserved_size, queue_max_bytes(q)); - - return put_user(val, p); -} - -static int sg_set_reserved_size(struct request_queue *q, int __user *p) -{ - int size, err = get_user(size, p); - - if (err) - return err; - - if (size < 0) - return -EINVAL; - - q->sg_reserved_size = min_t(unsigned int, size, queue_max_bytes(q)); - return 0; -} - -/* - * will always return that we are ATAPI even for a real SCSI drive, I'm not - * so sure this is worth doing anything about (why would you care??) - */ -static int sg_emulated_host(struct request_queue *q, int __user *p) -{ - return put_user(1, p); -} - -/* - * Check if the given command is allowed. - * - * For unprivileged users only a small set of whitelisted command is allowed so - * that they can't format the drive or update the firmware. - */ -bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode) -{ - /* root can do any command. */ - if (capable(CAP_SYS_RAWIO)) - return true; - - /* Anybody who can open the device can do a read-safe command */ - switch (cmd[0]) { - /* Basic read-only commands */ - case TEST_UNIT_READY: - case REQUEST_SENSE: - case READ_6: - case READ_10: - case READ_12: - case READ_16: - case READ_BUFFER: - case READ_DEFECT_DATA: - case READ_CAPACITY: /* also GPCMD_READ_CDVD_CAPACITY */ - case READ_LONG: - case INQUIRY: - case MODE_SENSE: - case MODE_SENSE_10: - case LOG_SENSE: - case START_STOP: - case GPCMD_VERIFY_10: - case VERIFY_16: - case REPORT_LUNS: - case SERVICE_ACTION_IN_16: - case RECEIVE_DIAGNOSTIC: - case MAINTENANCE_IN: /* also GPCMD_SEND_KEY, which is a write command */ - case GPCMD_READ_BUFFER_CAPACITY: - /* Audio CD commands */ - case GPCMD_PLAY_CD: - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_MSF: - case GPCMD_PLAY_AUDIO_TI: - case GPCMD_PAUSE_RESUME: - /* CD/DVD data reading */ - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - case GPCMD_READ_DISC_INFO: - case GPCMD_READ_DVD_STRUCTURE: - case GPCMD_READ_HEADER: - case GPCMD_READ_TRACK_RZONE_INFO: - case GPCMD_READ_SUBCHANNEL: - case GPCMD_READ_TOC_PMA_ATIP: - case GPCMD_REPORT_KEY: - case GPCMD_SCAN: - case GPCMD_GET_CONFIGURATION: - case GPCMD_READ_FORMAT_CAPACITIES: - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - case GPCMD_GET_PERFORMANCE: - case GPCMD_SEEK: - case GPCMD_STOP_PLAY_SCAN: - /* ZBC */ - case ZBC_IN: - return true; - /* Basic writing commands */ - case WRITE_6: - case WRITE_10: - case WRITE_VERIFY: - case WRITE_12: - case WRITE_VERIFY_12: - case WRITE_16: - case WRITE_LONG: - case WRITE_LONG_2: - case WRITE_SAME: - case WRITE_SAME_16: - case WRITE_SAME_32: - case ERASE: - case GPCMD_MODE_SELECT_10: - case MODE_SELECT: - case LOG_SELECT: - case GPCMD_BLANK: - case GPCMD_CLOSE_TRACK: - case GPCMD_FLUSH_CACHE: - case GPCMD_FORMAT_UNIT: - case GPCMD_REPAIR_RZONE_TRACK: - case GPCMD_RESERVE_RZONE_TRACK: - case GPCMD_SEND_DVD_STRUCTURE: - case GPCMD_SEND_EVENT: - case GPCMD_SEND_OPC: - case GPCMD_SEND_CUE_SHEET: - case GPCMD_SET_SPEED: - case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - case GPCMD_LOAD_UNLOAD: - case GPCMD_SET_STREAMING: - case GPCMD_SET_READ_AHEAD: - /* ZBC */ - case ZBC_OUT: - return (mode & FMODE_WRITE); - default: - return false; - } -} -EXPORT_SYMBOL(scsi_cmd_allowed); - -static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq, - struct sg_io_hdr *hdr, fmode_t mode) -{ - struct scsi_request *req = scsi_req(rq); - - if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) - return -EFAULT; - if (!scsi_cmd_allowed(req->cmd, mode)) - return -EPERM; - - /* - * fill in request structure - */ - req->cmd_len = hdr->cmd_len; - - rq->timeout = msecs_to_jiffies(hdr->timeout); - if (!rq->timeout) - rq->timeout = q->sg_timeout; - if (!rq->timeout) - rq->timeout = BLK_DEFAULT_SG_TIMEOUT; - if (rq->timeout < BLK_MIN_SG_TIMEOUT) - rq->timeout = BLK_MIN_SG_TIMEOUT; - - return 0; -} - -static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, - struct bio *bio) -{ - struct scsi_request *req = scsi_req(rq); - int r, ret = 0; - - /* - * fill in all the output members - */ - hdr->status = req->result & 0xff; - hdr->masked_status = status_byte(req->result); - hdr->msg_status = COMMAND_COMPLETE; - hdr->host_status = host_byte(req->result); - hdr->driver_status = 0; - if (scsi_status_is_check_condition(hdr->status)) - hdr->driver_status = DRIVER_SENSE; - hdr->info = 0; - if (hdr->masked_status || hdr->host_status || hdr->driver_status) - hdr->info |= SG_INFO_CHECK; - hdr->resid = req->resid_len; - hdr->sb_len_wr = 0; - - if (req->sense_len && hdr->sbp) { - int len = min((unsigned int) hdr->mx_sb_len, req->sense_len); - - if (!copy_to_user(hdr->sbp, req->sense, len)) - hdr->sb_len_wr = len; - else - ret = -EFAULT; - } - - r = blk_rq_unmap_user(bio); - if (!ret) - ret = r; - - return ret; -} - -static int sg_io(struct request_queue *q, struct gendisk *bd_disk, - struct sg_io_hdr *hdr, fmode_t mode) -{ - unsigned long start_time; - ssize_t ret = 0; - int writing = 0; - int at_head = 0; - struct request *rq; - struct scsi_request *req; - struct bio *bio; - - if (hdr->interface_id != 'S') - return -EINVAL; - - if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) - return -EIO; - - if (hdr->dxfer_len) - switch (hdr->dxfer_direction) { - default: - return -EINVAL; - case SG_DXFER_TO_DEV: - writing = 1; - break; - case SG_DXFER_TO_FROM_DEV: - case SG_DXFER_FROM_DEV: - break; - } - if (hdr->flags & SG_FLAG_Q_AT_HEAD) - at_head = 1; - - ret = -ENOMEM; - rq = blk_get_request(q, writing ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); - if (IS_ERR(rq)) - return PTR_ERR(rq); - req = scsi_req(rq); - - if (hdr->cmd_len > BLK_MAX_CDB) { - req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); - if (!req->cmd) - goto out_put_request; - } - - ret = blk_fill_sghdr_rq(q, rq, hdr, mode); - if (ret < 0) - goto out_free_cdb; - - ret = 0; - if (hdr->iovec_count) { - struct iov_iter i; - struct iovec *iov = NULL; - - ret = import_iovec(rq_data_dir(rq), hdr->dxferp, - hdr->iovec_count, 0, &iov, &i); - if (ret < 0) - goto out_free_cdb; - - /* SG_IO howto says that the shorter of the two wins */ - iov_iter_truncate(&i, hdr->dxfer_len); - - ret = blk_rq_map_user_iov(q, rq, NULL, &i, GFP_KERNEL); - kfree(iov); - } else if (hdr->dxfer_len) - ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, - GFP_KERNEL); - - if (ret) - goto out_free_cdb; - - bio = rq->bio; - req->retries = 0; - - start_time = jiffies; - - blk_execute_rq(bd_disk, rq, at_head); - - hdr->duration = jiffies_to_msecs(jiffies - start_time); - - ret = blk_complete_sghdr_rq(rq, hdr, bio); - -out_free_cdb: - scsi_req_free_cmd(req); -out_put_request: - blk_put_request(rq); - return ret; -} - -/** - * sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl - * @q: request queue to send scsi commands down - * @disk: gendisk to operate on (option) - * @mode: mode used to open the file through which the ioctl has been - * submitted - * @sic: userspace structure describing the command to perform - * - * Send down the scsi command described by @sic to the device below - * the request queue @q. If @file is non-NULL it's used to perform - * fine-grained permission checks that allow users to send down - * non-destructive SCSI commands. If the caller has a struct gendisk - * available it should be passed in as @disk to allow the low level - * driver to use the information contained in it. A non-NULL @disk - * is only allowed if the caller knows that the low level driver doesn't - * need it (e.g. in the scsi subsystem). - * - * Notes: - * - This interface is deprecated - users should use the SG_IO - * interface instead, as this is a more flexible approach to - * performing SCSI commands on a device. - * - The SCSI command length is determined by examining the 1st byte - * of the given command. There is no way to override this. - * - Data transfers are limited to PAGE_SIZE - * - The length (x + y) must be at least OMAX_SB_LEN bytes long to - * accommodate the sense buffer when an error occurs. - * The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that - * old code will not be surprised. - * - If a Unix error occurs (e.g. ENOMEM) then the user will receive - * a negative return and the Unix error code in 'errno'. - * If the SCSI command succeeds then 0 is returned. - * Positive numbers returned are the compacted SCSI error codes (4 - * bytes in one int) where the lowest byte is the SCSI status. - */ -int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, - struct scsi_ioctl_command __user *sic) -{ - enum { OMAX_SB_LEN = 16 }; /* For backward compatibility */ - struct request *rq; - struct scsi_request *req; - int err; - unsigned int in_len, out_len, bytes, opcode, cmdlen; - char *buffer = NULL; - - if (!sic) - return -EINVAL; - - /* - * get in an out lengths, verify they don't exceed a page worth of data - */ - if (get_user(in_len, &sic->inlen)) - return -EFAULT; - if (get_user(out_len, &sic->outlen)) - return -EFAULT; - if (in_len > PAGE_SIZE || out_len > PAGE_SIZE) - return -EINVAL; - if (get_user(opcode, sic->data)) - return -EFAULT; - - bytes = max(in_len, out_len); - if (bytes) { - buffer = kzalloc(bytes, GFP_NOIO | GFP_USER | __GFP_NOWARN); - if (!buffer) - return -ENOMEM; - - } - - rq = blk_get_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); - if (IS_ERR(rq)) { - err = PTR_ERR(rq); - goto error_free_buffer; - } - req = scsi_req(rq); - - cmdlen = COMMAND_SIZE(opcode); - - /* - * get command and data to send to device, if any - */ - err = -EFAULT; - req->cmd_len = cmdlen; - if (copy_from_user(req->cmd, sic->data, cmdlen)) - goto error; - - if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) - goto error; - - err = -EPERM; - if (!scsi_cmd_allowed(req->cmd, mode)) - goto error; - - /* default. possible overriden later */ - req->retries = 5; - - switch (opcode) { - case SEND_DIAGNOSTIC: - case FORMAT_UNIT: - rq->timeout = FORMAT_UNIT_TIMEOUT; - req->retries = 1; - break; - case START_STOP: - rq->timeout = START_STOP_TIMEOUT; - break; - case MOVE_MEDIUM: - rq->timeout = MOVE_MEDIUM_TIMEOUT; - break; - case READ_ELEMENT_STATUS: - rq->timeout = READ_ELEMENT_STATUS_TIMEOUT; - break; - case READ_DEFECT_DATA: - rq->timeout = READ_DEFECT_DATA_TIMEOUT; - req->retries = 1; - break; - default: - rq->timeout = BLK_DEFAULT_SG_TIMEOUT; - break; - } - - if (bytes) { - err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO); - if (err) - goto error; - } - - blk_execute_rq(disk, rq, 0); - - err = req->result & 0xff; /* only 8 bit SCSI status */ - if (err) { - if (req->sense_len && req->sense) { - bytes = (OMAX_SB_LEN > req->sense_len) ? - req->sense_len : OMAX_SB_LEN; - if (copy_to_user(sic->data, req->sense, bytes)) - err = -EFAULT; - } - } else { - if (copy_to_user(sic->data, buffer, out_len)) - err = -EFAULT; - } - -error: - blk_put_request(rq); - -error_free_buffer: - kfree(buffer); - - return err; -} -EXPORT_SYMBOL_GPL(sg_scsi_ioctl); - -/* Send basic block requests */ -static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, - int cmd, int data) -{ - struct request *rq; - int err; - - rq = blk_get_request(q, REQ_OP_DRV_OUT, 0); - if (IS_ERR(rq)) - return PTR_ERR(rq); - rq->timeout = BLK_DEFAULT_SG_TIMEOUT; - scsi_req(rq)->cmd[0] = cmd; - scsi_req(rq)->cmd[4] = data; - scsi_req(rq)->cmd_len = 6; - blk_execute_rq(bd_disk, rq, 0); - err = scsi_req(rq)->result ? -EIO : 0; - blk_put_request(rq); - - return err; -} - -static inline int blk_send_start_stop(struct request_queue *q, - struct gendisk *bd_disk, int data) -{ - return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); -} - -int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp) -{ -#ifdef CONFIG_COMPAT - if (in_compat_syscall()) { - struct compat_sg_io_hdr hdr32 = { - .interface_id = hdr->interface_id, - .dxfer_direction = hdr->dxfer_direction, - .cmd_len = hdr->cmd_len, - .mx_sb_len = hdr->mx_sb_len, - .iovec_count = hdr->iovec_count, - .dxfer_len = hdr->dxfer_len, - .dxferp = (uintptr_t)hdr->dxferp, - .cmdp = (uintptr_t)hdr->cmdp, - .sbp = (uintptr_t)hdr->sbp, - .timeout = hdr->timeout, - .flags = hdr->flags, - .pack_id = hdr->pack_id, - .usr_ptr = (uintptr_t)hdr->usr_ptr, - .status = hdr->status, - .masked_status = hdr->masked_status, - .msg_status = hdr->msg_status, - .sb_len_wr = hdr->sb_len_wr, - .host_status = hdr->host_status, - .driver_status = hdr->driver_status, - .resid = hdr->resid, - .duration = hdr->duration, - .info = hdr->info, - }; - - if (copy_to_user(argp, &hdr32, sizeof(hdr32))) - return -EFAULT; - - return 0; - } -#endif - - if (copy_to_user(argp, hdr, sizeof(*hdr))) - return -EFAULT; - - return 0; -} -EXPORT_SYMBOL(put_sg_io_hdr); - -int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp) -{ -#ifdef CONFIG_COMPAT - struct compat_sg_io_hdr hdr32; - - if (in_compat_syscall()) { - if (copy_from_user(&hdr32, argp, sizeof(hdr32))) - return -EFAULT; - - *hdr = (struct sg_io_hdr) { - .interface_id = hdr32.interface_id, - .dxfer_direction = hdr32.dxfer_direction, - .cmd_len = hdr32.cmd_len, - .mx_sb_len = hdr32.mx_sb_len, - .iovec_count = hdr32.iovec_count, - .dxfer_len = hdr32.dxfer_len, - .dxferp = compat_ptr(hdr32.dxferp), - .cmdp = compat_ptr(hdr32.cmdp), - .sbp = compat_ptr(hdr32.sbp), - .timeout = hdr32.timeout, - .flags = hdr32.flags, - .pack_id = hdr32.pack_id, - .usr_ptr = compat_ptr(hdr32.usr_ptr), - .status = hdr32.status, - .masked_status = hdr32.masked_status, - .msg_status = hdr32.msg_status, - .sb_len_wr = hdr32.sb_len_wr, - .host_status = hdr32.host_status, - .driver_status = hdr32.driver_status, - .resid = hdr32.resid, - .duration = hdr32.duration, - .info = hdr32.info, - }; - - return 0; - } -#endif - - if (copy_from_user(hdr, argp, sizeof(*hdr))) - return -EFAULT; - - return 0; -} -EXPORT_SYMBOL(get_sg_io_hdr); - -#ifdef CONFIG_COMPAT -struct compat_cdrom_generic_command { - unsigned char cmd[CDROM_PACKET_SIZE]; - compat_caddr_t buffer; - compat_uint_t buflen; - compat_int_t stat; - compat_caddr_t sense; - unsigned char data_direction; - unsigned char pad[3]; - compat_int_t quiet; - compat_int_t timeout; - compat_caddr_t unused; -}; -#endif - -static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc, - const void __user *arg) -{ -#ifdef CONFIG_COMPAT - if (in_compat_syscall()) { - struct compat_cdrom_generic_command cgc32; - - if (copy_from_user(&cgc32, arg, sizeof(cgc32))) - return -EFAULT; - - *cgc = (struct cdrom_generic_command) { - .buffer = compat_ptr(cgc32.buffer), - .buflen = cgc32.buflen, - .stat = cgc32.stat, - .sense = compat_ptr(cgc32.sense), - .data_direction = cgc32.data_direction, - .quiet = cgc32.quiet, - .timeout = cgc32.timeout, - .unused = compat_ptr(cgc32.unused), - }; - memcpy(&cgc->cmd, &cgc32.cmd, CDROM_PACKET_SIZE); - return 0; - } -#endif - if (copy_from_user(cgc, arg, sizeof(*cgc))) - return -EFAULT; - - return 0; -} - -static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc, - void __user *arg) -{ -#ifdef CONFIG_COMPAT - if (in_compat_syscall()) { - struct compat_cdrom_generic_command cgc32 = { - .buffer = (uintptr_t)(cgc->buffer), - .buflen = cgc->buflen, - .stat = cgc->stat, - .sense = (uintptr_t)(cgc->sense), - .data_direction = cgc->data_direction, - .quiet = cgc->quiet, - .timeout = cgc->timeout, - .unused = (uintptr_t)(cgc->unused), - }; - memcpy(&cgc32.cmd, &cgc->cmd, CDROM_PACKET_SIZE); - - if (copy_to_user(arg, &cgc32, sizeof(cgc32))) - return -EFAULT; - - return 0; - } -#endif - if (copy_to_user(arg, cgc, sizeof(*cgc))) - return -EFAULT; - - return 0; -} - -static int scsi_cdrom_send_packet(struct request_queue *q, - struct gendisk *bd_disk, - fmode_t mode, void __user *arg) -{ - struct cdrom_generic_command cgc; - struct sg_io_hdr hdr; - int err; - - err = scsi_get_cdrom_generic_arg(&cgc, arg); - if (err) - return err; - - cgc.timeout = clock_t_to_jiffies(cgc.timeout); - memset(&hdr, 0, sizeof(hdr)); - hdr.interface_id = 'S'; - hdr.cmd_len = sizeof(cgc.cmd); - hdr.dxfer_len = cgc.buflen; - switch (cgc.data_direction) { - case CGC_DATA_UNKNOWN: - hdr.dxfer_direction = SG_DXFER_UNKNOWN; - break; - case CGC_DATA_WRITE: - hdr.dxfer_direction = SG_DXFER_TO_DEV; - break; - case CGC_DATA_READ: - hdr.dxfer_direction = SG_DXFER_FROM_DEV; - break; - case CGC_DATA_NONE: - hdr.dxfer_direction = SG_DXFER_NONE; - break; - default: - return -EINVAL; - } - - hdr.dxferp = cgc.buffer; - hdr.sbp = cgc.sense; - if (hdr.sbp) - hdr.mx_sb_len = sizeof(struct request_sense); - hdr.timeout = jiffies_to_msecs(cgc.timeout); - hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd; - hdr.cmd_len = sizeof(cgc.cmd); - - err = sg_io(q, bd_disk, &hdr, mode); - if (err == -EFAULT) - return -EFAULT; - - if (hdr.status) - return -EIO; - - cgc.stat = err; - cgc.buflen = hdr.resid; - if (scsi_put_cdrom_generic_arg(&cgc, arg)) - return -EFAULT; - - return err; -} - -int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mode, - unsigned int cmd, void __user *arg) -{ - int err; - - if (!q) - return -ENXIO; - - switch (cmd) { - /* - * new sgv3 interface - */ - case SG_GET_VERSION_NUM: - err = sg_get_version(arg); - break; - case SG_SET_TIMEOUT: - err = sg_set_timeout(q, arg); - break; - case SG_GET_TIMEOUT: - err = sg_get_timeout(q); - break; - case SG_GET_RESERVED_SIZE: - err = sg_get_reserved_size(q, arg); - break; - case SG_SET_RESERVED_SIZE: - err = sg_set_reserved_size(q, arg); - break; - case SG_EMULATED_HOST: - err = sg_emulated_host(q, arg); - break; - case SG_IO: { - struct sg_io_hdr hdr; - - err = get_sg_io_hdr(&hdr, arg); - if (err) - break; - err = sg_io(q, bd_disk, &hdr, mode); - if (err == -EFAULT) - break; - - if (put_sg_io_hdr(&hdr, arg)) - err = -EFAULT; - break; - } - case CDROM_SEND_PACKET: - err = scsi_cdrom_send_packet(q, bd_disk, mode, arg); - break; - - /* - * old junk scsi send command ioctl - */ - case SCSI_IOCTL_SEND_COMMAND: - printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm); - err = -EINVAL; - if (!arg) - break; - - err = sg_scsi_ioctl(q, bd_disk, mode, arg); - break; - case CDROMCLOSETRAY: - err = blk_send_start_stop(q, bd_disk, 0x03); - break; - case CDROMEJECT: - err = blk_send_start_stop(q, bd_disk, 0x02); - break; - default: - err = -ENOTTY; - } - - return err; -} -EXPORT_SYMBOL(scsi_cmd_ioctl); diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 7739575b5229..2c4cdd0fc26e 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -189,6 +190,706 @@ static int scsi_ioctl_get_pci(struct scsi_device *sdev, void __user *arg) ? -EFAULT: 0; } +static int sg_get_version(int __user *p) +{ + static const int sg_version_num = 30527; + return put_user(sg_version_num, p); +} + +static int sg_get_timeout(struct request_queue *q) +{ + return jiffies_to_clock_t(q->sg_timeout); +} + +static int sg_set_timeout(struct request_queue *q, int __user *p) +{ + int timeout, err = get_user(timeout, p); + + if (!err) + q->sg_timeout = clock_t_to_jiffies(timeout); + + return err; +} + +static int sg_get_reserved_size(struct request_queue *q, int __user *p) +{ + int val = min(q->sg_reserved_size, queue_max_bytes(q)); + + return put_user(val, p); +} + +static int sg_set_reserved_size(struct request_queue *q, int __user *p) +{ + int size, err = get_user(size, p); + + if (err) + return err; + + if (size < 0) + return -EINVAL; + + q->sg_reserved_size = min_t(unsigned int, size, queue_max_bytes(q)); + return 0; +} + +/* + * will always return that we are ATAPI even for a real SCSI drive, I'm not + * so sure this is worth doing anything about (why would you care??) + */ +static int sg_emulated_host(struct request_queue *q, int __user *p) +{ + return put_user(1, p); +} + +/* Send basic block requests */ +static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, + int cmd, int data) +{ + struct request *rq; + int err; + + rq = blk_get_request(q, REQ_OP_DRV_OUT, 0); + if (IS_ERR(rq)) + return PTR_ERR(rq); + rq->timeout = BLK_DEFAULT_SG_TIMEOUT; + scsi_req(rq)->cmd[0] = cmd; + scsi_req(rq)->cmd[4] = data; + scsi_req(rq)->cmd_len = 6; + blk_execute_rq(bd_disk, rq, 0); + err = scsi_req(rq)->result ? -EIO : 0; + blk_put_request(rq); + + return err; +} + +static inline int blk_send_start_stop(struct request_queue *q, + struct gendisk *bd_disk, int data) +{ + return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); +} + +/* + * Check if the given command is allowed. + * + * Only a subset of commands are allowed for unprivileged users. Commands used + * to format the media, update the firmware, etc. are not permitted. + */ +bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode) +{ + /* root can do any command. */ + if (capable(CAP_SYS_RAWIO)) + return true; + + /* Anybody who can open the device can do a read-safe command */ + switch (cmd[0]) { + /* Basic read-only commands */ + case TEST_UNIT_READY: + case REQUEST_SENSE: + case READ_6: + case READ_10: + case READ_12: + case READ_16: + case READ_BUFFER: + case READ_DEFECT_DATA: + case READ_CAPACITY: /* also GPCMD_READ_CDVD_CAPACITY */ + case READ_LONG: + case INQUIRY: + case MODE_SENSE: + case MODE_SENSE_10: + case LOG_SENSE: + case START_STOP: + case GPCMD_VERIFY_10: + case VERIFY_16: + case REPORT_LUNS: + case SERVICE_ACTION_IN_16: + case RECEIVE_DIAGNOSTIC: + case MAINTENANCE_IN: /* also GPCMD_SEND_KEY, which is a write command */ + case GPCMD_READ_BUFFER_CAPACITY: + /* Audio CD commands */ + case GPCMD_PLAY_CD: + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_MSF: + case GPCMD_PLAY_AUDIO_TI: + case GPCMD_PAUSE_RESUME: + /* CD/DVD data reading */ + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + case GPCMD_READ_DISC_INFO: + case GPCMD_READ_DVD_STRUCTURE: + case GPCMD_READ_HEADER: + case GPCMD_READ_TRACK_RZONE_INFO: + case GPCMD_READ_SUBCHANNEL: + case GPCMD_READ_TOC_PMA_ATIP: + case GPCMD_REPORT_KEY: + case GPCMD_SCAN: + case GPCMD_GET_CONFIGURATION: + case GPCMD_READ_FORMAT_CAPACITIES: + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + case GPCMD_GET_PERFORMANCE: + case GPCMD_SEEK: + case GPCMD_STOP_PLAY_SCAN: + /* ZBC */ + case ZBC_IN: + return true; + /* Basic writing commands */ + case WRITE_6: + case WRITE_10: + case WRITE_VERIFY: + case WRITE_12: + case WRITE_VERIFY_12: + case WRITE_16: + case WRITE_LONG: + case WRITE_LONG_2: + case WRITE_SAME: + case WRITE_SAME_16: + case WRITE_SAME_32: + case ERASE: + case GPCMD_MODE_SELECT_10: + case MODE_SELECT: + case LOG_SELECT: + case GPCMD_BLANK: + case GPCMD_CLOSE_TRACK: + case GPCMD_FLUSH_CACHE: + case GPCMD_FORMAT_UNIT: + case GPCMD_REPAIR_RZONE_TRACK: + case GPCMD_RESERVE_RZONE_TRACK: + case GPCMD_SEND_DVD_STRUCTURE: + case GPCMD_SEND_EVENT: + case GPCMD_SEND_OPC: + case GPCMD_SEND_CUE_SHEET: + case GPCMD_SET_SPEED: + case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: + case GPCMD_LOAD_UNLOAD: + case GPCMD_SET_STREAMING: + case GPCMD_SET_READ_AHEAD: + /* ZBC */ + case ZBC_OUT: + return (mode & FMODE_WRITE); + default: + return false; + } +} +EXPORT_SYMBOL(scsi_cmd_allowed); + +static int scsi_fill_sghdr_rq(struct request_queue *q, struct request *rq, + struct sg_io_hdr *hdr, fmode_t mode) +{ + struct scsi_request *req = scsi_req(rq); + + if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) + return -EFAULT; + if (!scsi_cmd_allowed(req->cmd, mode)) + return -EPERM; + + /* + * fill in request structure + */ + req->cmd_len = hdr->cmd_len; + + rq->timeout = msecs_to_jiffies(hdr->timeout); + if (!rq->timeout) + rq->timeout = q->sg_timeout; + if (!rq->timeout) + rq->timeout = BLK_DEFAULT_SG_TIMEOUT; + if (rq->timeout < BLK_MIN_SG_TIMEOUT) + rq->timeout = BLK_MIN_SG_TIMEOUT; + + return 0; +} + +static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, + struct bio *bio) +{ + struct scsi_request *req = scsi_req(rq); + int r, ret = 0; + + /* + * fill in all the output members + */ + hdr->status = req->result & 0xff; + hdr->masked_status = status_byte(req->result); + hdr->msg_status = COMMAND_COMPLETE; + hdr->host_status = host_byte(req->result); + hdr->driver_status = 0; + if (scsi_status_is_check_condition(hdr->status)) + hdr->driver_status = DRIVER_SENSE; + hdr->info = 0; + if (hdr->masked_status || hdr->host_status || hdr->driver_status) + hdr->info |= SG_INFO_CHECK; + hdr->resid = req->resid_len; + hdr->sb_len_wr = 0; + + if (req->sense_len && hdr->sbp) { + int len = min((unsigned int) hdr->mx_sb_len, req->sense_len); + + if (!copy_to_user(hdr->sbp, req->sense, len)) + hdr->sb_len_wr = len; + else + ret = -EFAULT; + } + + r = blk_rq_unmap_user(bio); + if (!ret) + ret = r; + + return ret; +} + +static int sg_io(struct request_queue *q, struct gendisk *bd_disk, + struct sg_io_hdr *hdr, fmode_t mode) +{ + unsigned long start_time; + ssize_t ret = 0; + int writing = 0; + int at_head = 0; + struct request *rq; + struct scsi_request *req; + struct bio *bio; + + if (hdr->interface_id != 'S') + return -EINVAL; + + if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) + return -EIO; + + if (hdr->dxfer_len) + switch (hdr->dxfer_direction) { + default: + return -EINVAL; + case SG_DXFER_TO_DEV: + writing = 1; + break; + case SG_DXFER_TO_FROM_DEV: + case SG_DXFER_FROM_DEV: + break; + } + if (hdr->flags & SG_FLAG_Q_AT_HEAD) + at_head = 1; + + ret = -ENOMEM; + rq = blk_get_request(q, writing ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + if (IS_ERR(rq)) + return PTR_ERR(rq); + req = scsi_req(rq); + + if (hdr->cmd_len > BLK_MAX_CDB) { + req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL); + if (!req->cmd) + goto out_put_request; + } + + ret = scsi_fill_sghdr_rq(q, rq, hdr, mode); + if (ret < 0) + goto out_free_cdb; + + ret = 0; + if (hdr->iovec_count) { + struct iov_iter i; + struct iovec *iov = NULL; + + ret = import_iovec(rq_data_dir(rq), hdr->dxferp, + hdr->iovec_count, 0, &iov, &i); + if (ret < 0) + goto out_free_cdb; + + /* SG_IO howto says that the shorter of the two wins */ + iov_iter_truncate(&i, hdr->dxfer_len); + + ret = blk_rq_map_user_iov(q, rq, NULL, &i, GFP_KERNEL); + kfree(iov); + } else if (hdr->dxfer_len) + ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, + GFP_KERNEL); + + if (ret) + goto out_free_cdb; + + bio = rq->bio; + req->retries = 0; + + start_time = jiffies; + + blk_execute_rq(bd_disk, rq, at_head); + + hdr->duration = jiffies_to_msecs(jiffies - start_time); + + ret = scsi_complete_sghdr_rq(rq, hdr, bio); + +out_free_cdb: + scsi_req_free_cmd(req); +out_put_request: + blk_put_request(rq); + return ret; +} + +/** + * sg_scsi_ioctl -- handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl + * @q: request queue to send scsi commands down + * @disk: gendisk to operate on (option) + * @mode: mode used to open the file through which the ioctl has been + * submitted + * @sic: userspace structure describing the command to perform + * + * Send down the scsi command described by @sic to the device below + * the request queue @q. If @file is non-NULL it's used to perform + * fine-grained permission checks that allow users to send down + * non-destructive SCSI commands. If the caller has a struct gendisk + * available it should be passed in as @disk to allow the low level + * driver to use the information contained in it. A non-NULL @disk + * is only allowed if the caller knows that the low level driver doesn't + * need it (e.g. in the scsi subsystem). + * + * Notes: + * - This interface is deprecated - users should use the SG_IO + * interface instead, as this is a more flexible approach to + * performing SCSI commands on a device. + * - The SCSI command length is determined by examining the 1st byte + * of the given command. There is no way to override this. + * - Data transfers are limited to PAGE_SIZE + * - The length (x + y) must be at least OMAX_SB_LEN bytes long to + * accommodate the sense buffer when an error occurs. + * The sense buffer is truncated to OMAX_SB_LEN (16) bytes so that + * old code will not be surprised. + * - If a Unix error occurs (e.g. ENOMEM) then the user will receive + * a negative return and the Unix error code in 'errno'. + * If the SCSI command succeeds then 0 is returned. + * Positive numbers returned are the compacted SCSI error codes (4 + * bytes in one int) where the lowest byte is the SCSI status. + */ +int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, + struct scsi_ioctl_command __user *sic) +{ + enum { OMAX_SB_LEN = 16 }; /* For backward compatibility */ + struct request *rq; + struct scsi_request *req; + int err; + unsigned int in_len, out_len, bytes, opcode, cmdlen; + char *buffer = NULL; + + if (!sic) + return -EINVAL; + + /* + * get in an out lengths, verify they don't exceed a page worth of data + */ + if (get_user(in_len, &sic->inlen)) + return -EFAULT; + if (get_user(out_len, &sic->outlen)) + return -EFAULT; + if (in_len > PAGE_SIZE || out_len > PAGE_SIZE) + return -EINVAL; + if (get_user(opcode, sic->data)) + return -EFAULT; + + bytes = max(in_len, out_len); + if (bytes) { + buffer = kzalloc(bytes, GFP_NOIO | GFP_USER | __GFP_NOWARN); + if (!buffer) + return -ENOMEM; + + } + + rq = blk_get_request(q, in_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto error_free_buffer; + } + req = scsi_req(rq); + + cmdlen = COMMAND_SIZE(opcode); + + /* + * get command and data to send to device, if any + */ + err = -EFAULT; + req->cmd_len = cmdlen; + if (copy_from_user(req->cmd, sic->data, cmdlen)) + goto error; + + if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len)) + goto error; + + err = -EPERM; + if (!scsi_cmd_allowed(req->cmd, mode)) + goto error; + + /* default. possible overridden later */ + req->retries = 5; + + switch (opcode) { + case SEND_DIAGNOSTIC: + case FORMAT_UNIT: + rq->timeout = FORMAT_UNIT_TIMEOUT; + req->retries = 1; + break; + case START_STOP: + rq->timeout = START_STOP_TIMEOUT; + break; + case MOVE_MEDIUM: + rq->timeout = MOVE_MEDIUM_TIMEOUT; + break; + case READ_ELEMENT_STATUS: + rq->timeout = READ_ELEMENT_STATUS_TIMEOUT; + break; + case READ_DEFECT_DATA: + rq->timeout = READ_DEFECT_DATA_TIMEOUT; + req->retries = 1; + break; + default: + rq->timeout = BLK_DEFAULT_SG_TIMEOUT; + break; + } + + if (bytes) { + err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO); + if (err) + goto error; + } + + blk_execute_rq(disk, rq, 0); + + err = req->result & 0xff; /* only 8 bit SCSI status */ + if (err) { + if (req->sense_len && req->sense) { + bytes = (OMAX_SB_LEN > req->sense_len) ? + req->sense_len : OMAX_SB_LEN; + if (copy_to_user(sic->data, req->sense, bytes)) + err = -EFAULT; + } + } else { + if (copy_to_user(sic->data, buffer, out_len)) + err = -EFAULT; + } + +error: + blk_put_request(rq); + +error_free_buffer: + kfree(buffer); + + return err; +} +EXPORT_SYMBOL_GPL(sg_scsi_ioctl); + +int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp) +{ +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) { + struct compat_sg_io_hdr hdr32 = { + .interface_id = hdr->interface_id, + .dxfer_direction = hdr->dxfer_direction, + .cmd_len = hdr->cmd_len, + .mx_sb_len = hdr->mx_sb_len, + .iovec_count = hdr->iovec_count, + .dxfer_len = hdr->dxfer_len, + .dxferp = (uintptr_t)hdr->dxferp, + .cmdp = (uintptr_t)hdr->cmdp, + .sbp = (uintptr_t)hdr->sbp, + .timeout = hdr->timeout, + .flags = hdr->flags, + .pack_id = hdr->pack_id, + .usr_ptr = (uintptr_t)hdr->usr_ptr, + .status = hdr->status, + .masked_status = hdr->masked_status, + .msg_status = hdr->msg_status, + .sb_len_wr = hdr->sb_len_wr, + .host_status = hdr->host_status, + .driver_status = hdr->driver_status, + .resid = hdr->resid, + .duration = hdr->duration, + .info = hdr->info, + }; + + if (copy_to_user(argp, &hdr32, sizeof(hdr32))) + return -EFAULT; + + return 0; + } +#endif + + if (copy_to_user(argp, hdr, sizeof(*hdr))) + return -EFAULT; + + return 0; +} +EXPORT_SYMBOL(put_sg_io_hdr); + +int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp) +{ +#ifdef CONFIG_COMPAT + struct compat_sg_io_hdr hdr32; + + if (in_compat_syscall()) { + if (copy_from_user(&hdr32, argp, sizeof(hdr32))) + return -EFAULT; + + *hdr = (struct sg_io_hdr) { + .interface_id = hdr32.interface_id, + .dxfer_direction = hdr32.dxfer_direction, + .cmd_len = hdr32.cmd_len, + .mx_sb_len = hdr32.mx_sb_len, + .iovec_count = hdr32.iovec_count, + .dxfer_len = hdr32.dxfer_len, + .dxferp = compat_ptr(hdr32.dxferp), + .cmdp = compat_ptr(hdr32.cmdp), + .sbp = compat_ptr(hdr32.sbp), + .timeout = hdr32.timeout, + .flags = hdr32.flags, + .pack_id = hdr32.pack_id, + .usr_ptr = compat_ptr(hdr32.usr_ptr), + .status = hdr32.status, + .masked_status = hdr32.masked_status, + .msg_status = hdr32.msg_status, + .sb_len_wr = hdr32.sb_len_wr, + .host_status = hdr32.host_status, + .driver_status = hdr32.driver_status, + .resid = hdr32.resid, + .duration = hdr32.duration, + .info = hdr32.info, + }; + + return 0; + } +#endif + + if (copy_from_user(hdr, argp, sizeof(*hdr))) + return -EFAULT; + + return 0; +} +EXPORT_SYMBOL(get_sg_io_hdr); + +#ifdef CONFIG_COMPAT +struct compat_cdrom_generic_command { + unsigned char cmd[CDROM_PACKET_SIZE]; + compat_caddr_t buffer; + compat_uint_t buflen; + compat_int_t stat; + compat_caddr_t sense; + unsigned char data_direction; + unsigned char pad[3]; + compat_int_t quiet; + compat_int_t timeout; + compat_caddr_t unused; +}; +#endif + +static int scsi_get_cdrom_generic_arg(struct cdrom_generic_command *cgc, + const void __user *arg) +{ +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) { + struct compat_cdrom_generic_command cgc32; + + if (copy_from_user(&cgc32, arg, sizeof(cgc32))) + return -EFAULT; + + *cgc = (struct cdrom_generic_command) { + .buffer = compat_ptr(cgc32.buffer), + .buflen = cgc32.buflen, + .stat = cgc32.stat, + .sense = compat_ptr(cgc32.sense), + .data_direction = cgc32.data_direction, + .quiet = cgc32.quiet, + .timeout = cgc32.timeout, + .unused = compat_ptr(cgc32.unused), + }; + memcpy(&cgc->cmd, &cgc32.cmd, CDROM_PACKET_SIZE); + return 0; + } +#endif + if (copy_from_user(cgc, arg, sizeof(*cgc))) + return -EFAULT; + + return 0; +} + +static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc, + void __user *arg) +{ +#ifdef CONFIG_COMPAT + if (in_compat_syscall()) { + struct compat_cdrom_generic_command cgc32 = { + .buffer = (uintptr_t)(cgc->buffer), + .buflen = cgc->buflen, + .stat = cgc->stat, + .sense = (uintptr_t)(cgc->sense), + .data_direction = cgc->data_direction, + .quiet = cgc->quiet, + .timeout = cgc->timeout, + .unused = (uintptr_t)(cgc->unused), + }; + memcpy(&cgc32.cmd, &cgc->cmd, CDROM_PACKET_SIZE); + + if (copy_to_user(arg, &cgc32, sizeof(cgc32))) + return -EFAULT; + + return 0; + } +#endif + if (copy_to_user(arg, cgc, sizeof(*cgc))) + return -EFAULT; + + return 0; +} + +static int scsi_cdrom_send_packet(struct request_queue *q, + struct gendisk *bd_disk, + fmode_t mode, void __user *arg) +{ + struct cdrom_generic_command cgc; + struct sg_io_hdr hdr; + int err; + + err = scsi_get_cdrom_generic_arg(&cgc, arg); + if (err) + return err; + + cgc.timeout = clock_t_to_jiffies(cgc.timeout); + memset(&hdr, 0, sizeof(hdr)); + hdr.interface_id = 'S'; + hdr.cmd_len = sizeof(cgc.cmd); + hdr.dxfer_len = cgc.buflen; + switch (cgc.data_direction) { + case CGC_DATA_UNKNOWN: + hdr.dxfer_direction = SG_DXFER_UNKNOWN; + break; + case CGC_DATA_WRITE: + hdr.dxfer_direction = SG_DXFER_TO_DEV; + break; + case CGC_DATA_READ: + hdr.dxfer_direction = SG_DXFER_FROM_DEV; + break; + case CGC_DATA_NONE: + hdr.dxfer_direction = SG_DXFER_NONE; + break; + default: + return -EINVAL; + } + + hdr.dxferp = cgc.buffer; + hdr.sbp = cgc.sense; + if (hdr.sbp) + hdr.mx_sb_len = sizeof(struct request_sense); + hdr.timeout = jiffies_to_msecs(cgc.timeout); + hdr.cmdp = ((struct cdrom_generic_command __user *) arg)->cmd; + hdr.cmd_len = sizeof(cgc.cmd); + + err = sg_io(q, bd_disk, &hdr, mode); + if (err == -EFAULT) + return -EFAULT; + + if (hdr.status) + return -EIO; + + cgc.stat = err; + cgc.buflen = hdr.resid; + if (scsi_put_cdrom_generic_arg(&cgc, arg)) + return -EFAULT; + + return err; +} + /** * scsi_ioctl - Dispatch ioctl to scsi device * @sdev: scsi device receiving ioctl @@ -225,13 +926,42 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, break; } - if (cmd != SCSI_IOCTL_GET_IDLUN && cmd != SCSI_IOCTL_GET_BUS_NUMBER) { - error = scsi_cmd_ioctl(q, disk, mode, cmd, arg); - if (error != -ENOTTY) + switch (cmd) { + case SG_GET_VERSION_NUM: + return sg_get_version(arg); + case SG_SET_TIMEOUT: + return sg_set_timeout(q, arg); + case SG_GET_TIMEOUT: + return sg_get_timeout(q); + case SG_GET_RESERVED_SIZE: + return sg_get_reserved_size(q, arg); + case SG_SET_RESERVED_SIZE: + return sg_set_reserved_size(q, arg); + case SG_EMULATED_HOST: + return sg_emulated_host(q, arg); + case SG_IO: { + struct sg_io_hdr hdr; + + error = get_sg_io_hdr(&hdr, arg); + if (error) return error; - } - switch (cmd) { + error = sg_io(q, disk, &hdr, mode); + if (error == -EFAULT) + return error; + + if (put_sg_io_hdr(&hdr, arg)) + return -EFAULT; + return 0; + } + case SCSI_IOCTL_SEND_COMMAND: + return sg_scsi_ioctl(q, disk, mode, arg); + case CDROM_SEND_PACKET: + return scsi_cdrom_send_packet(q, disk, mode, arg); + case CDROMCLOSETRAY: + return blk_send_start_stop(q, disk, 0x03); + case CDROMEJECT: + return blk_send_start_stop(q, disk, 0x02); case SCSI_IOCTL_GET_IDLUN: { struct scsi_idlun v = { .dev_id = (sdev->id & 0xff) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e28679e63373..8c617a5a5d61 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -28,8 +28,6 @@ #include struct module; -struct scsi_ioctl_command; - struct request_queue; struct elevator_queue; struct blk_trace; @@ -888,13 +886,6 @@ extern blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request *rq); int blk_rq_append_bio(struct request *rq, struct bio *bio); extern void blk_queue_split(struct bio **); -extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, - unsigned int, void __user *); -extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, - struct scsi_ioctl_command __user *); -extern int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp); -extern int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp); - extern int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags); extern void blk_queue_exit(struct request_queue *q); extern void blk_sync_queue(struct request_queue *q); @@ -1343,8 +1334,6 @@ static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, gfp_mask, 0); } -bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode); - static inline bool bdev_is_partition(struct block_device *bdev) { return bdev->bd_partno; diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index defbe8084eb8..b3918fded464 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -20,6 +20,7 @@ struct gendisk; struct scsi_device; +struct sg_io_hdr; /* * Structures used for scsi_ioctl et al. @@ -46,6 +47,11 @@ int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, int cmd, void __user *arg); +int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, + struct scsi_ioctl_command __user *argp); +int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp); +int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp); +bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ -- cgit v1.2.3-70-g09d2 From 33ff4ce45b124e0356a396a381f374751b9ec7ba Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:28 +0200 Subject: scsi: core: Rename CONFIG_BLK_SCSI_REQUEST to CONFIG_SCSI_COMMON CONFIG_BLK_SCSI_REQUEST is rather misnamed as it enables building a small amount of code shared by the SCSI initiator, target, and consumers of the scsi_request passthrough API. Rename it and also allow building it as a module. [mkp: add module license] Link: https://lore.kernel.org/r/20210724072033.1284840-20-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/Kconfig | 3 --- drivers/block/Kconfig | 2 +- drivers/scsi/Kconfig | 5 ++++- drivers/scsi/Makefile | 2 +- drivers/scsi/scsi_common.c | 3 +++ drivers/target/Kconfig | 2 +- fs/nfsd/Kconfig | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/block/Kconfig b/block/Kconfig index 88aa88241795..97c1d999b920 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -29,9 +29,6 @@ if BLOCK config BLK_RQ_ALLOC_TIME bool -config BLK_SCSI_REQUEST - bool - config BLK_CGROUP_RWSTAT bool diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 4652bcdb9efb..90ed1642304a 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -305,7 +305,7 @@ config CDROM_PKTCDVD tristate "Packet writing on CD/DVD media (DEPRECATED)" depends on !UML select CDROM - select BLK_SCSI_REQUEST + select SCSI_COMMON help Note: This driver is deprecated and will be removed from the kernel in the near future! diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 86ecab196dfd..6e3a04107bb6 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -14,12 +14,15 @@ config RAID_ATTRS help Provides RAID +config SCSI_COMMON + tristate + config SCSI tristate "SCSI device support" depends on BLOCK select SCSI_DMA if HAS_DMA select SG_POOL - select BLK_SCSI_REQUEST + select SCSI_COMMON select BLK_DEV_BSG_COMMON if BLK_DEV_BSG help If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 240b831b5a11..f086eca2bcd7 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -20,7 +20,7 @@ CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF obj-$(CONFIG_PCMCIA) += pcmcia/ obj-$(CONFIG_SCSI) += scsi_mod.o -obj-$(CONFIG_BLK_SCSI_REQUEST) += scsi_common.o +obj-$(CONFIG_SCSI_COMMON) += scsi_common.o obj-$(CONFIG_RAID_ATTRS) += raid_class.o diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index 8aac4e5e8c4c..6e50e81a8216 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -7,9 +7,12 @@ #include #include #include +#include #include #include +MODULE_LICENSE("GPL v2"); + /* Command group 3 is reserved and should never be used. */ const unsigned char scsi_command_size_tbl[8] = { 6, 10, 10, 12, 16, 12, 10, 10 diff --git a/drivers/target/Kconfig b/drivers/target/Kconfig index c163b14774d7..72171ea3dd53 100644 --- a/drivers/target/Kconfig +++ b/drivers/target/Kconfig @@ -5,7 +5,7 @@ menuconfig TARGET_CORE depends on BLOCK select CONFIGFS_FS select CRC_T10DIF - select BLK_SCSI_REQUEST + select SCSI_COMMON select SGL_ALLOC default n help diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index f229172652be..6e9ea4ee0f73 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -109,7 +109,7 @@ config NFSD_SCSILAYOUT depends on NFSD_V4 && BLOCK select NFSD_PNFS select EXPORTFS_BLOCK_OPS - select BLK_SCSI_REQUEST + select SCSI_COMMON help This option enables support for the exporting pNFS SCSI layouts in the kernel's NFS server. The pNFS SCSI layout enables NFS -- cgit v1.2.3-70-g09d2 From a9705477f552c1c9a2da8e94bb9914086f7798bf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:29 +0200 Subject: scsi: scsi_ioctl: Remove a very misleading comment Remove the comment above ioctl_internal_command() which doesn't document this function at all. Link: https://lore.kernel.org/r/20210724072033.1284840-21-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_ioctl.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 2c4cdd0fc26e..0b5ceca776dd 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -64,29 +64,6 @@ static int ioctl_probe(struct Scsi_Host *host, void __user *buffer) return 1; } -/* - - * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host. - * The IOCTL_NORMAL_TIMEOUT and NORMAL_RETRIES variables are used. - * - * dev is the SCSI device struct ptr, *(int *) arg is the length of the - * input data, if any, not including the command string & counts, - * *((int *)arg + 1) is the output buffer size in bytes. - * - * *(char *) ((int *) arg)[2] the actual command byte. - * - * Note that if more than MAX_BUF bytes are requested to be transferred, - * the ioctl will fail with error EINVAL. - * - * This size *does not* include the initial lengths that were passed. - * - * The SCSI command is read from the memory location immediately after the - * length words, and the input data is right after the command. The SCSI - * routines know the command size based on the opcode decode. - * - * The output area is then filled in starting from the command byte. - */ - static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, int timeout, int retries) { -- cgit v1.2.3-70-g09d2 From 514761874350b2804ce5027606efc412f0bc78f3 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:30 +0200 Subject: scsi: scsi_ioctl: Consolidate the START STOP UNIT handling Factor out a helper for the various flavors of START STOP UNIT command ioctls. Link: https://lore.kernel.org/r/20210724072033.1284840-22-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_ioctl.c | 48 ++++++++++------------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 0b5ceca776dd..21f7a3cb9af3 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -218,31 +218,14 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } -/* Send basic block requests */ -static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, - int cmd, int data) +static int scsi_send_start_stop(struct scsi_device *sdev, int data) { - struct request *rq; - int err; - - rq = blk_get_request(q, REQ_OP_DRV_OUT, 0); - if (IS_ERR(rq)) - return PTR_ERR(rq); - rq->timeout = BLK_DEFAULT_SG_TIMEOUT; - scsi_req(rq)->cmd[0] = cmd; - scsi_req(rq)->cmd[4] = data; - scsi_req(rq)->cmd_len = 6; - blk_execute_rq(bd_disk, rq, 0); - err = scsi_req(rq)->result ? -EIO : 0; - blk_put_request(rq); + u8 cdb[MAX_COMMAND_SIZE] = { }; - return err; -} - -static inline int blk_send_start_stop(struct request_queue *q, - struct gendisk *bd_disk, int data) -{ - return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data); + cdb[0] = START_STOP; + cdb[4] = data; + return ioctl_internal_command(sdev, cdb, START_STOP_TIMEOUT, + NORMAL_RETRIES); } /* @@ -883,7 +866,6 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, int cmd, void __user *arg) { struct request_queue *q = sdev->request_queue; - char scsi_cmd[MAX_COMMAND_SIZE]; struct scsi_sense_hdr sense_hdr; int error; @@ -936,9 +918,9 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, case CDROM_SEND_PACKET: return scsi_cdrom_send_packet(q, disk, mode, arg); case CDROMCLOSETRAY: - return blk_send_start_stop(q, disk, 0x03); + return scsi_send_start_stop(sdev, 3); case CDROMEJECT: - return blk_send_start_stop(q, disk, 0x02); + return scsi_send_start_stop(sdev, 2); case SCSI_IOCTL_GET_IDLUN: { struct scsi_idlun v = { .dev_id = (sdev->id & 0xff) @@ -963,19 +945,9 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, return scsi_test_unit_ready(sdev, IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES, &sense_hdr); case SCSI_IOCTL_START_UNIT: - scsi_cmd[0] = START_STOP; - scsi_cmd[1] = 0; - scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0; - scsi_cmd[4] = 1; - return ioctl_internal_command(sdev, scsi_cmd, - START_STOP_TIMEOUT, NORMAL_RETRIES); + return scsi_send_start_stop(sdev, 1); case SCSI_IOCTL_STOP_UNIT: - scsi_cmd[0] = START_STOP; - scsi_cmd[1] = 0; - scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0; - scsi_cmd[4] = 0; - return ioctl_internal_command(sdev, scsi_cmd, - START_STOP_TIMEOUT, NORMAL_RETRIES); + return scsi_send_start_stop(sdev, 0); case SCSI_IOCTL_GET_PCI: return scsi_ioctl_get_pci(sdev, arg); case SG_SCSI_RESET: -- cgit v1.2.3-70-g09d2 From 2102a5cc1233ff84a0ebf95bbc4d346eb4927c8f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:31 +0200 Subject: scsi: scsi_ioctl: Factor SCSI_IOCTL_GET_IDLUN handling into a helper Split the SCSI_IOCTL_GET_IDLUN handler from the main scsi_ioctl() routine. Link: https://lore.kernel.org/r/20210724072033.1284840-23-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_ioctl.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 21f7a3cb9af3..498e6a6e4b2b 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -218,6 +218,20 @@ static int sg_emulated_host(struct request_queue *q, int __user *p) return put_user(1, p); } +static int scsi_get_idlun(struct scsi_device *sdev, void __user *argp) +{ + struct scsi_idlun v = { + .dev_id = (sdev->id & 0xff) + + ((sdev->lun & 0xff) << 8) + + ((sdev->channel & 0xff) << 16) + + ((sdev->host->host_no & 0xff) << 24), + .host_unique_id = sdev->host->unique_id + }; + if (copy_to_user(argp, &v, sizeof(struct scsi_idlun))) + return -EFAULT; + return 0; +} + static int scsi_send_start_stop(struct scsi_device *sdev, int data) { u8 cdb[MAX_COMMAND_SIZE] = { }; @@ -921,18 +935,8 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, return scsi_send_start_stop(sdev, 3); case CDROMEJECT: return scsi_send_start_stop(sdev, 2); - case SCSI_IOCTL_GET_IDLUN: { - struct scsi_idlun v = { - .dev_id = (sdev->id & 0xff) - + ((sdev->lun & 0xff) << 8) - + ((sdev->channel & 0xff) << 16) - + ((sdev->host->host_no & 0xff) << 24), - .host_unique_id = sdev->host->unique_id - }; - if (copy_to_user(arg, &v, sizeof(struct scsi_idlun))) - return -EFAULT; - return 0; - } + case SCSI_IOCTL_GET_IDLUN: + return scsi_get_idlun(sdev, arg); case SCSI_IOCTL_GET_BUS_NUMBER: return put_user(sdev->host->host_no, (int __user *)arg); case SCSI_IOCTL_PROBE_HOST: -- cgit v1.2.3-70-g09d2 From b2123d3b0987a2164e5bef116cafe19ac2281e34 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:32 +0200 Subject: scsi: scsi_ioctl: Factor SG_IO handling into a helper Split the SG_IO handler from the main scsi_ioctl() routine. Link: https://lore.kernel.org/r/20210724072033.1284840-24-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_ioctl.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 498e6a6e4b2b..738794148692 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -864,6 +864,23 @@ static int scsi_cdrom_send_packet(struct request_queue *q, return err; } +static int scsi_ioctl_sg_io(struct request_queue *q, struct gendisk *disk, + fmode_t mode, void __user *argp) +{ + struct sg_io_hdr hdr; + int error; + + error = get_sg_io_hdr(&hdr, argp); + if (error) + return error; + error = sg_io(q, disk, &hdr, mode); + if (error == -EFAULT) + return error; + if (put_sg_io_hdr(&hdr, argp)) + return -EFAULT; + return 0; +} + /** * scsi_ioctl - Dispatch ioctl to scsi device * @sdev: scsi device receiving ioctl @@ -881,7 +898,6 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, { struct request_queue *q = sdev->request_queue; struct scsi_sense_hdr sense_hdr; - int error; /* Check for deprecated ioctls ... all the ioctls which don't * follow the new unique numbering scheme are deprecated */ @@ -912,21 +928,8 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, return sg_set_reserved_size(q, arg); case SG_EMULATED_HOST: return sg_emulated_host(q, arg); - case SG_IO: { - struct sg_io_hdr hdr; - - error = get_sg_io_hdr(&hdr, arg); - if (error) - return error; - - error = sg_io(q, disk, &hdr, mode); - if (error == -EFAULT) - return error; - - if (put_sg_io_hdr(&hdr, arg)) - return -EFAULT; - return 0; - } + case SG_IO: + return scsi_ioctl_sg_io(q, disk, mode, arg); case SCSI_IOCTL_SEND_COMMAND: return sg_scsi_ioctl(q, disk, mode, arg); case CDROM_SEND_PACKET: -- cgit v1.2.3-70-g09d2 From 08dc2f9b53afbbc897bc895aa41906194f5af1cf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 24 Jul 2021 09:20:33 +0200 Subject: scsi: scsi_ioctl: Unexport sg_scsi_ioctl() Just call scsi_ioctl() in sg as that has the same effect. Link: https://lore.kernel.org/r/20210724072033.1284840-25-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_ioctl.c | 5 ++--- drivers/scsi/sg.c | 2 +- include/scsi/scsi_ioctl.h | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 738794148692..633f016c2bfe 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -530,8 +530,8 @@ out_put_request: * Positive numbers returned are the compacted SCSI error codes (4 * bytes in one int) where the lowest byte is the SCSI status. */ -int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, - struct scsi_ioctl_command __user *sic) +static int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, + fmode_t mode, struct scsi_ioctl_command __user *sic) { enum { OMAX_SB_LEN = 16 }; /* For backward compatibility */ struct request *rq; @@ -643,7 +643,6 @@ error_free_buffer: return err; } -EXPORT_SYMBOL_GPL(sg_scsi_ioctl); int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp) { diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index c86fa4476334..9be76deea242 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1109,7 +1109,7 @@ sg_ioctl_common(struct file *filp, Sg_device *sdp, Sg_fd *sfp, case SCSI_IOCTL_SEND_COMMAND: if (atomic_read(&sdp->detaching)) return -ENODEV; - return sg_scsi_ioctl(sdp->device->request_queue, NULL, filp->f_mode, p); + return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p); case SG_SET_DEBUG: result = get_user(val, ip); if (result) diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h index b3918fded464..d2cb9aeaf1f1 100644 --- a/include/scsi/scsi_ioctl.h +++ b/include/scsi/scsi_ioctl.h @@ -47,8 +47,6 @@ int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev, int cmd, bool ndelay); int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, int cmd, void __user *arg); -int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, - struct scsi_ioctl_command __user *argp); int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp); int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp); bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode); -- cgit v1.2.3-70-g09d2 From b60bb6e2bfc192091b8f792781b83b5e0f9324f6 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Thu, 22 Jul 2021 13:10:51 -0700 Subject: dmaengine: idxd: fix abort status check Coverity static analysis of linux-next found issue. The check (status == IDXD_COMP_DESC_ABORT) is always false since status was previously masked with 0x7f and IDXD_COMP_DESC_ABORT is 0xff. Fixes: 6b4b87f2c31a ("dmaengine: idxd: fix submission race window") Reported-by: Colin Ian King Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162698465160.3560828.18173186265683415384.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/irq.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index e018459b534f..65dc7bbb0a13 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -194,7 +194,11 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; if (status) { - if (unlikely(status == IDXD_COMP_DESC_ABORT)) { + /* + * Check against the original status as ABORT is software defined + * and 0xff, which DSA_COMP_STATUS_MASK can mask out. + */ + if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { complete_desc(desc, IDXD_COMPLETE_ABORT); (*processed)++; continue; @@ -250,7 +254,11 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, list_for_each_entry(desc, &flist, list) { u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; - if (unlikely(status == IDXD_COMP_DESC_ABORT)) { + /* + * Check against the original status as ABORT is software defined + * and 0xff, which DSA_COMP_STATUS_MASK can mask out. + */ + if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { complete_desc(desc, IDXD_COMPLETE_ABORT); continue; } -- cgit v1.2.3-70-g09d2 From 6fffe52fb336ec2063270a7305652a93ea677ca1 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Wed, 28 Jul 2021 14:00:28 -0400 Subject: clk: rockchip: drop GRF dependency for rk3328/rk3036 pll types The rk3036/rk3328 pll types were converted to checking the lock status via the internal register in january 2020, so don't need the grf reference since then. But it was forgotten to remove grf check when deciding between the pll rate ops (read-only vs. read-write), so a clock driver without the needed grf reference might've been put into the read-only mode just because the grf reference was missing. This affected the rk356x that needs to reclock certain plls at boot. Fix this by removing the check for the grf for selecting the utilized operations. Suggested-by: Heiko Stuebner Fixes: 7f6ffbb885d1 ("clk: rockchip: convert rk3036 pll type to use internal lock status") Signed-off-by: Peter Geis [adjusted the commit message, adjusted the fixes tag] Link: https://lore.kernel.org/r/20210728180034.717953-3-pgwipeout@gmail.com Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index fe937bcdb487..f7827b3b7fc1 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -940,7 +940,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, switch (pll_type) { case pll_rk3036: case pll_rk3328: - if (!pll->rate_table || IS_ERR(ctx->grf)) + if (!pll->rate_table) init.ops = &rockchip_rk3036_pll_clk_norate_ops; else init.ops = &rockchip_rk3036_pll_clk_ops; -- cgit v1.2.3-70-g09d2 From a86aadeff2fe9203d9575f1c157d09b3c557d1ce Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 28 Jul 2021 11:26:12 +0100 Subject: MIPS: Alchemy: Fix spelling contraction "cant" -> "can't" There is a spelling mistake in a pr_warn message. Fix it. Signed-off-by: Colin Ian King Signed-off-by: Thomas Bogendoerfer --- arch/mips/alchemy/devboards/db1200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 421d651433b6..1864eb935ca5 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c @@ -835,7 +835,7 @@ int __init db1200_dev_setup(void) if (!IS_ERR(c)) { pfc = clk_round_rate(c, 50000000); if ((pfc < 1) || (abs(50000000 - pfc) > 2500000)) - pr_warn("DB1200: cant get I2C close to 50MHz\n"); + pr_warn("DB1200: can't get I2C close to 50MHz\n"); else clk_set_rate(c, pfc); clk_prepare_enable(c); -- cgit v1.2.3-70-g09d2 From c0c81245dac7caaef4db627fb7043495d1afe662 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Wed, 21 Jul 2021 20:48:16 +0800 Subject: clk: rockchip: make rk3308 ddrphy4x clock critical Currently, no driver support for DDR memory controller (DMC) is present, as a result, no driver is explicitly consuming the ddrphy clock. This means that VPLL1 (parent of ddr clock) will be shutdown if we enable and then disable any child clock of VPLL1 (e.g. SCLK_I2S0_8CH_TX). If VPLL1 is disabled, the whole system will freeze, because the DDR controller will lose its clock. So, it's necessary to prevent VPLL1 from shutting down, by marking the ddrphy4x CLK_IS_CRITICAL. This bug was discovered when I was porting rockchip_i2s_tdm driver to mainline kernel from Rockchip 4.4 kernel. I guess that other Rockchip SoCs without DMC driver may need the same patch. If this applies to other devices, please let us know. Signed-off-by: Yunhao Tian Link: https://lore.kernel.org/r/BYAPR20MB24886765F888A9705CBEB70789E39@BYAPR20MB2488.namprd20.prod.outlook.com [adapted subject, changed to add the clock to the critical list] Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3308.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/rockchip/clk-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c index 2c3bd0c749f2..db3396c3e6e9 100644 --- a/drivers/clk/rockchip/clk-rk3308.c +++ b/drivers/clk/rockchip/clk-rk3308.c @@ -911,6 +911,7 @@ static const char *const rk3308_critical_clocks[] __initconst = { "hclk_audio", "pclk_audio", "sclk_ddrc", + "clk_ddrphy4x", }; static void __init rk3308_clk_init(struct device_node *np) -- cgit v1.2.3-70-g09d2 From 4e804c39f1be4498d80f379e5b7bc6d4f80f813c Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Wed, 28 Jul 2021 06:12:51 +0200 Subject: gpiolib: convert 'devprop_gpiochip_set_names' to support multiple gpiochip banks per device The default gpiolib-of implementation does not work with the multiple gpiochip banks per device structure used for example by the gpio-mt7621 and gpio-brcmstb drivers. To fix these kind of situations driver code is forced to fill the names to avoid the gpiolib code to set names repeated along the banks. Instead of continue with that antipattern fix the gpiolib core function to get expected behaviour for every single situation adding a field 'offset' in the gpiochip structure. Doing in this way, we can assume this offset will be zero for normal driver code where only one gpiochip bank per device is used but can be set explicitly in those drivers that really need more than one gpiochip. Reviewed-by: Andy Shevchenko Reviewed-by: Gregory Fong Signed-off-by: Sergio Paracuellos Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 32 +++++++++++++++++++++++++++----- include/linux/gpio/driver.h | 4 ++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 27c07108496d..d1b9b721218f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -382,10 +382,18 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip) if (count < 0) return 0; - if (count > gdev->ngpio) { - dev_warn(&gdev->dev, "gpio-line-names is length %d but should be at most length %d", - count, gdev->ngpio); - count = gdev->ngpio; + /* + * When offset is set in the driver side we assume the driver internally + * is using more than one gpiochip per the same device. We have to stop + * setting friendly names if the specified ones with 'gpio-line-names' + * are less than the offset in the device itself. This means all the + * lines are not present for every single pin within all the internal + * gpiochips. + */ + if (count <= chip->offset) { + dev_warn(&gdev->dev, "gpio-line-names too short (length %d), cannot map names for the gpiochip at offset %u\n", + count, chip->offset); + return 0; } names = kcalloc(count, sizeof(*names), GFP_KERNEL); @@ -400,8 +408,22 @@ static int devprop_gpiochip_set_names(struct gpio_chip *chip) return ret; } + /* + * When more that one gpiochip per device is used, 'count' can + * contain at most number gpiochips x chip->ngpio. We have to + * correctly distribute all defined lines taking into account + * chip->offset as starting point from where we will assign + * the names to pins from the 'names' array. Since property + * 'gpio-line-names' cannot contains gaps, we have to be sure + * we only assign those pins that really exists since chip->ngpio + * can be different of the chip->offset. + */ + count = (count > chip->offset) ? count - chip->offset : count; + if (count > chip->ngpio) + count = chip->ngpio; + for (i = 0; i < count; i++) - gdev->descs[i].name = names[i]; + gdev->descs[i].name = names[chip->offset + i]; kfree(names); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 3a268781fcec..a0f9901dcae6 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -312,6 +312,9 @@ struct gpio_irq_chip { * get rid of the static GPIO number space in the long run. * @ngpio: the number of GPIOs handled by this controller; the last GPIO * handled is (base + ngpio - 1). + * @offset: when multiple gpio chips belong to the same device this + * can be used as offset within the device so friendly names can + * be properly assigned. * @names: if set, must be an array of strings to use as alternative * names for the GPIOs in this chip. Any entry in the array * may be NULL if there is no alias for the GPIO, however the @@ -398,6 +401,7 @@ struct gpio_chip { int base; u16 ngpio; + u16 offset; const char *const *names; bool can_sleep; -- cgit v1.2.3-70-g09d2 From 0fb903914914a10b04dc8e5e5b09c8dca452ca91 Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Wed, 28 Jul 2021 06:12:52 +0200 Subject: gpio: mt7621: support gpio-line-names property This driver uses multiple gpiochip banks per device. To support 'gpio-line-names' along the banks 'offset' for each bank must be set explicitly. Reviewed-by: Andy Shevchenko Signed-off-by: Sergio Paracuellos Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mt7621.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c index 82fb20dca53a..5854a9343491 100644 --- a/drivers/gpio/gpio-mt7621.c +++ b/drivers/gpio/gpio-mt7621.c @@ -241,6 +241,7 @@ mediatek_gpio_bank_probe(struct device *dev, if (!rg->chip.label) return -ENOMEM; + rg->chip.offset = bank * MTK_BANK_WIDTH; rg->irq_chip.name = dev_name(dev); rg->irq_chip.parent_device = dev; rg->irq_chip.irq_unmask = mediatek_gpio_irq_unmask; -- cgit v1.2.3-70-g09d2 From e5de9d283a36a2923f7f309050b8c51b14753c3a Mon Sep 17 00:00:00 2001 From: Sergio Paracuellos Date: Wed, 28 Jul 2021 06:12:53 +0200 Subject: gpio: brcmstb: remove custom 'brcmstb_gpio_set_names' Gpiolib core code has been updated to support setting friendly names through properly 'gpio-line-names'. Instead of redefine behaviour here to skip the core to be executed, just properly assign the desired offset per bank to get in the core the expected behaviour. Reviewed-by: Andy Shevchenko Acked-by: Gregory Fong Signed-off-by: Sergio Paracuellos Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-brcmstb.c | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index fcfc1a1f1a5c..a7275159052e 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -603,49 +603,6 @@ static const struct dev_pm_ops brcmstb_gpio_pm_ops = { .resume_noirq = brcmstb_gpio_resume, }; -static void brcmstb_gpio_set_names(struct device *dev, - struct brcmstb_gpio_bank *bank) -{ - struct device_node *np = dev->of_node; - const char **names; - int nstrings, base; - unsigned int i; - - base = bank->id * MAX_GPIO_PER_BANK; - - nstrings = of_property_count_strings(np, "gpio-line-names"); - if (nstrings <= base) - /* Line names not present */ - return; - - names = devm_kcalloc(dev, MAX_GPIO_PER_BANK, sizeof(*names), - GFP_KERNEL); - if (!names) - return; - - /* - * Make sure to not index beyond the end of the number of descriptors - * of the GPIO device. - */ - for (i = 0; i < bank->width; i++) { - const char *name; - int ret; - - ret = of_property_read_string_index(np, "gpio-line-names", - base + i, &name); - if (ret) { - if (ret != -ENODATA) - dev_err(dev, "unable to name line %d: %d\n", - base + i, ret); - break; - } - if (*name) - names[i] = name; - } - - bank->gc.names = names; -} - static int brcmstb_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -759,6 +716,7 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) gc->of_xlate = brcmstb_gpio_of_xlate; /* not all ngpio lines are valid, will use bank width later */ gc->ngpio = MAX_GPIO_PER_BANK; + gc->offset = bank->id * MAX_GPIO_PER_BANK; if (priv->parent_irq > 0) gc->to_irq = brcmstb_gpio_to_irq; @@ -769,7 +727,6 @@ static int brcmstb_gpio_probe(struct platform_device *pdev) need_wakeup_event |= !!__brcmstb_gpio_get_active_irqs(bank); gc->write_reg(reg_base + GIO_MASK(bank->id), 0); - brcmstb_gpio_set_names(dev, bank); err = gpiochip_add_data(gc, bank); if (err) { dev_err(dev, "Could not add gpiochip for bank %d\n", -- cgit v1.2.3-70-g09d2 From ff128cdb7f3ddf237989c4ff925b42c9def33f7e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 13 Jul 2021 09:25:12 -0300 Subject: pinctrl: imx8mn: Constify imx_pinctrl_soc_info The imx_pinctrl_soc_info structure content is never changed, so it can be declared as 'const', like it is done on all other i.MX pinctrl drivers. Make it 'const' in this driver too. Signed-off-by: Fabio Estevam Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20210713122513.3112941-1-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx8mn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/pinctrl-imx8mn.c b/drivers/pinctrl/freescale/pinctrl-imx8mn.c index 448a79eb4568..dbf89cfba477 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8mn.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8mn.c @@ -317,7 +317,7 @@ static const struct pinctrl_pin_desc imx8mn_pinctrl_pads[] = { IMX_PINCTRL_PIN(MX8MN_IOMUXC_UART4_TXD), }; -static struct imx_pinctrl_soc_info imx8mn_pinctrl_info = { +static const struct imx_pinctrl_soc_info imx8mn_pinctrl_info = { .pins = imx8mn_pinctrl_pads, .npins = ARRAY_SIZE(imx8mn_pinctrl_pads), .gpr_compatible = "fsl,imx8mn-iomuxc-gpr", -- cgit v1.2.3-70-g09d2 From b013dc8a02d9a604767d589feb6549e2da6a9133 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 13 Jul 2021 09:25:13 -0300 Subject: pinctrl: imx8qxp: Constify imx_pinctrl_soc_info The imx_pinctrl_soc_info structure content is never changed, so it can be declared as 'const', like it is done on all other i.MX pinctrl drivers. Make it 'const' in this driver too. Signed-off-by: Fabio Estevam Reviewed-by: Dong Aisheng Link: https://lore.kernel.org/r/20210713122513.3112941-2-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx8qxp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c index 4f97813ba8b7..0a0acc0038d0 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8qxp.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8qxp.c @@ -194,7 +194,7 @@ static const struct pinctrl_pin_desc imx8qxp_pinctrl_pads[] = { IMX_PINCTRL_PIN(IMX8QXP_COMP_CTL_GPIO_1V8_3V3_QSPI0B), }; -static struct imx_pinctrl_soc_info imx8qxp_pinctrl_info = { +static const struct imx_pinctrl_soc_info imx8qxp_pinctrl_info = { .pins = imx8qxp_pinctrl_pads, .npins = ARRAY_SIZE(imx8qxp_pinctrl_pads), .flags = IMX_USE_SCU, -- cgit v1.2.3-70-g09d2 From 2fefcf2400659f3f2d2c5ed87a4ceebde3dad7a8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 16 Jul 2021 10:13:41 -0300 Subject: pinctrl: imx8dxl: Constify imx_pinctrl_soc_info The imx_pinctrl_soc_info structure content is never changed, so it can be declared as 'const', like it is done on all other i.MX pinctrl drivers. Make it 'const' in this driver too. Reported-by: Dong Aisheng Signed-off-by: Fabio Estevam Link: https://lore.kernel.org/r/20210716131341.3370620-1-festevam@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx8dxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c index 041455c13d0d..f947b1d0d1aa 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx8dxl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx8dxl.c @@ -155,7 +155,7 @@ static const struct pinctrl_pin_desc imx8dxl_pinctrl_pads[] = { }; -static struct imx_pinctrl_soc_info imx8dxl_pinctrl_info = { +static const struct imx_pinctrl_soc_info imx8dxl_pinctrl_info = { .pins = imx8dxl_pinctrl_pads, .npins = ARRAY_SIZE(imx8dxl_pinctrl_pads), .flags = IMX_USE_SCU, -- cgit v1.2.3-70-g09d2 From e9901043b25000ed21c7073373a7d9fd64f3d1e3 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Thu, 15 Jul 2021 12:04:40 -0400 Subject: IB/hfi1: Indicate DMA wait when txq is queued for wakeup There is no counter for dmawait in AIP, which hampers debugging performance issues. Add the counter increment when the txq is queued. Fixes: d99dc602e2a5 ("IB/hfi1: Add functions to transmit datagram ipoib packets") Link: https://lore.kernel.org/r/20210715160440.142451.8278.stgit@awfm-01.cornelisnetworks.com Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hfi1/ipoib_tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/hw/hfi1/ipoib_tx.c b/drivers/infiniband/hw/hfi1/ipoib_tx.c index 993f9838b6c8..e74ddbe46589 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_tx.c +++ b/drivers/infiniband/hw/hfi1/ipoib_tx.c @@ -644,10 +644,13 @@ static int hfi1_ipoib_sdma_sleep(struct sdma_engine *sde, /* came from non-list submit */ list_add_tail(&txreq->list, &txq->tx_list); if (list_empty(&txq->wait.list)) { + struct hfi1_ibport *ibp = &sde->ppd->ibport_data; + if (!atomic_xchg(&txq->no_desc, 1)) { trace_hfi1_txq_queued(txq); hfi1_ipoib_stop_txq(txq); } + ibp->rvp.n_dmawait++; iowait_queue(pkts_sent, wait->iow, &sde->dmawait); } -- cgit v1.2.3-70-g09d2 From 62004871e1fa7f9a60797595c03477af5b5ec36f Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Thu, 15 Jul 2021 12:04:45 -0400 Subject: IB/hfi1: Adjust pkey entry in index 0 It is possible for the primary IPoIB network device associated with any RDMA device to fail to join certain multicast groups preventing IPv6 neighbor discovery and possibly other network ULPs from working correctly. The IPv4 broadcast group is not affected as the IPoIB network device handles joining that multicast group directly. This is because the primary IPoIB network device uses the pkey at ndex 0 in the associated RDMA device's pkey table. Anytime the pkey value of index 0 changes, the primary IPoIB network device automatically modifies it's broadcast address (i.e. /sys/class/net/[ib0]/broadcast), since the broadcast address includes the pkey value, and then bounces carrier. This includes initial pkey assignment, such as when the pkey at index 0 transitions from the opa default of invalid (0x0000) to some value such as the OPA default pkey for Virtual Fabric 0: 0x8001 or when the fabric manager is restarted with a configuration change causing the pkey at index 0 to change. Many network ULPs are not sensitive to the carrier bounce and are not expecting the broadcast address to change including the linux IPv6 stack. This problem does not affect IPoIB child network devices as their pkey value is constant for all time. To mitigate this issue, change the default pkey in at index 0 to 0x8001 to cover the predominant case and avoid issues as ipoib comes up and the FM sweeps. At some point, ipoib multicast support should automatically fix non-broadcast addresses as it does with the primary broadcast address. Fixes: 7724105686e7 ("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20210715160445.142451.47651.stgit@awfm-01.cornelisnetworks.com Suggested-by: Josh Collier Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hfi1/init.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 0986aa065418..34106e5be679 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -650,12 +650,7 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY; ppd->part_enforce |= HFI1_PART_ENFORCE_IN; - - if (loopback) { - dd_dev_err(dd, "Faking data partition 0x8001 in idx %u\n", - !default_pkey_idx); - ppd->pkeys[!default_pkey_idx] = 0x8001; - } + ppd->pkeys[0] = 0x8001; INIT_WORK(&ppd->link_vc_work, handle_verify_cap); INIT_WORK(&ppd->link_up_work, handle_link_up); -- cgit v1.2.3-70-g09d2 From a0293eb24936ff30e5a23f9438fd4ad1c4009dbf Mon Sep 17 00:00:00 2001 From: Xiyu Yang Date: Mon, 19 Jul 2021 14:00:53 +0800 Subject: RDMA/hfi1: Convert from atomic_t to refcount_t on hfi1_devdata->user_refcount refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations. Link: https://lore.kernel.org/r/1626674454-56075-1-git-send-email-xiyuyang19@fudan.edu.cn Signed-off-by: Xiyu Yang Signed-off-by: Xin Tan Tested-by: Josh Fisher Acked-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hfi1/chip.c | 2 +- drivers/infiniband/hw/hfi1/file_ops.c | 6 +++--- drivers/infiniband/hw/hfi1/hfi.h | 3 ++- drivers/infiniband/hw/hfi1/init.c | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index c97544638367..50ffb8244625 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -15336,7 +15336,7 @@ int hfi1_init_dd(struct hfi1_devdata *dd) init_completion(&dd->user_comp); /* The user refcount starts with one to inidicate an active device */ - atomic_set(&dd->user_refcount, 1); + refcount_set(&dd->user_refcount, 1); goto bail; diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 955c3637980e..6dbfb794c255 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -194,7 +194,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) if (!((dd->flags & HFI1_PRESENT) && dd->kregbase1)) return -EINVAL; - if (!atomic_inc_not_zero(&dd->user_refcount)) + if (!refcount_inc_not_zero(&dd->user_refcount)) return -ENXIO; /* The real work is performed later in assign_ctxt() */ @@ -213,7 +213,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) nomem: kfree(fd); fp->private_data = NULL; - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); return -ENOMEM; } @@ -711,7 +711,7 @@ static int hfi1_file_close(struct inode *inode, struct file *fp) deallocate_ctxt(uctxt); done: - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); cleanup_srcu_struct(&fdata->pq_srcu); diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 31664f43c27f..6cf03d16a495 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h @@ -48,6 +48,7 @@ * */ +#include #include #include #include @@ -1384,7 +1385,7 @@ struct hfi1_devdata { /* Number of verbs contexts which have disabled ASPM */ atomic_t aspm_disabled_cnt; /* Keeps track of user space clients */ - atomic_t user_refcount; + refcount_t user_refcount; /* Used to wait for outstanding user space clients before dev removal */ struct completion user_comp; diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index 34106e5be679..f37b157dbdb2 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -1747,7 +1747,7 @@ static void wait_for_clients(struct hfi1_devdata *dd) * Remove the device init value and complete the device if there is * no clients or wait for active clients to finish. */ - if (atomic_dec_and_test(&dd->user_refcount)) + if (refcount_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); wait_for_completion(&dd->user_comp); -- cgit v1.2.3-70-g09d2 From 6ceb3c64063cd7b7155709f5ff67b85aa8a0e20b Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 21 Jul 2021 11:01:31 +0800 Subject: pinctrl: pistachio: Make it as an option So it will be avilable for generic MIPS kernel. -- Signed-off-by: Jiaxun Yang v3: Depend on OF as well Link: https://lore.kernel.org/r/20210721030134.10562-7-jiaxun.yang@flygoat.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index f38f12801f18..eb981713b40d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -248,12 +248,15 @@ config PINCTRL_SX150X - 16 bits: sx1509q, sx1506q config PINCTRL_PISTACHIO - def_bool y if MACH_PISTACHIO + bool "IMG Pistachio SoC pinctrl driver" + depends on OF && (MIPS || COMPILE_TEST) depends on GPIOLIB select PINMUX select GENERIC_PINCONF select GPIOLIB_IRQCHIP select OF_GPIO + help + This support pinctrl and gpio driver for IMG Pistachio SoC. config PINCTRL_ST bool -- cgit v1.2.3-70-g09d2 From 153df45acda08afec4bd13dd9145464111ef7ba7 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Wed, 21 Jul 2021 17:22:30 +0530 Subject: dt-bindings: pinctrl: pinctrl-zynq: Convert to yaml Convert the Zynq pinctrl binding file to yaml. Signed-off-by: Sai Krishna Potthuri Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1626868353-96475-2-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/xlnx,zynq-pinctrl.txt | 105 ---------- .../bindings/pinctrl/xlnx,zynq-pinctrl.yaml | 216 +++++++++++++++++++++ 2 files changed, 216 insertions(+), 105 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.txt deleted file mode 100644 index f488b0f77406..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.txt +++ /dev/null @@ -1,105 +0,0 @@ - Binding for Xilinx Zynq Pinctrl - -Required properties: -- compatible: "xlnx,zynq-pinctrl" -- syscon: phandle to SLCR -- reg: Offset and length of pinctrl space in SLCR - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -Zynq's pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those pin(s)/group(s), and various pin configuration -parameters, such as pull-up, slew rate, etc. - -Each configuration node can consist of multiple nodes describing the pinmux and -pinconf options. Those nodes can be pinmux nodes or pinconf nodes. - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Required properties for pinmux nodes are: - - groups: A list of pinmux groups. - - function: The name of a pinmux function to activate for the specified set - of groups. - -Required properties for configuration nodes: -One of: - - pins: a list of pin names - - groups: A list of pinmux groups. - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pinmux subnode: - groups, function - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pinconf subnode: - groups, pins, bias-disable, bias-high-impedance, bias-pull-up, slew-rate, - low-power-disable, low-power-enable - - Valid arguments for 'slew-rate' are '0' and '1' to select between slow and fast - respectively. - - Valid values for groups are: - ethernet0_0_grp, ethernet1_0_grp, mdio0_0_grp, mdio1_0_grp, - qspi0_0_grp, qspi1_0_grp, qspi_fbclk, qspi_cs1_grp, spi0_0_grp - spi0_2_grp, - spi0_X_ssY (X=0..2, Y=0..2), spi1_0_grp - spi1_3_grp, - spi1_X_ssY (X=0..3, Y=0..2), sdio0_0_grp - sdio0_2_grp, - sdio1_0_grp - sdio1_3_grp, sdio0_emio_wp, sdio0_emio_cd, sdio1_emio_wp, - sdio1_emio_cd, smc0_nor, smc0_nor_cs1_grp, smc0_nor_addr25_grp, smc0_nand, - can0_0_grp - can0_10_grp, can1_0_grp - can1_11_grp, uart0_0_grp - uart0_10_grp, - uart1_0_grp - uart1_11_grp, i2c0_0_grp - i2c0_10_grp, i2c1_0_grp - i2c1_10_grp, - ttc0_0_grp - ttc0_2_grp, ttc1_0_grp - ttc1_2_grp, swdt0_0_grp - swdt0_4_grp, - gpio0_0_grp - gpio0_53_grp, usb0_0_grp, usb1_0_grp - - Valid values for pins are: - MIO0 - MIO53 - - Valid values for function are: - ethernet0, ethernet1, mdio0, mdio1, qspi0, qspi1, qspi_fbclk, qspi_cs1, - spi0, spi0_ss, spi1, spi1_ss, sdio0, sdio0_pc, sdio0_cd, sdio0_wp, - sdio1, sdio1_pc, sdio1_cd, sdio1_wp, - smc0_nor, smc0_nor_cs1, smc0_nor_addr25, smc0_nand, can0, can1, uart0, uart1, - i2c0, i2c1, ttc0, ttc1, swdt0, gpio0, usb0, usb1 - -The following driver-specific properties as defined here are valid to specify in -a pin configuration subnode: - - io-standard: Configure the pin to use the selected IO standard according to - this mapping: - 1: LVCMOS18 - 2: LVCMOS25 - 3: LVCMOS33 - 4: HSTL - -Example: - pinctrl0: pinctrl@700 { - compatible = "xlnx,pinctrl-zynq"; - reg = <0x700 0x200>; - syscon = <&slcr>; - - pinctrl_uart1_default: uart1-default { - mux { - groups = "uart1_10_grp"; - function = "uart1"; - }; - - conf { - groups = "uart1_10_grp"; - slew-rate = <0>; - io-standard = <1>; - }; - - conf-rx { - pins = "MIO49"; - bias-high-impedance; - }; - - conf-tx { - pins = "MIO48"; - bias-disable; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml new file mode 100644 index 000000000000..2da1969e02ec --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml @@ -0,0 +1,216 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/xlnx,zynq-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Xilinx Zynq Pinctrl + +maintainers: + - Sai Krishna Potthuri + +description: | + Please refer to pinctrl-bindings.txt in this directory for details of the + common pinctrl bindings used by client devices, including the meaning of the + phrase "pin configuration node". + + Zynq's pin configuration nodes act as a container for an arbitrary number of + subnodes. Each of these subnodes represents some desired configuration for a + pin, a group, or a list of pins or groups. This configuration can include the + mux function to select on those pin(s)/group(s), and various pin configuration + parameters, such as pull-up, slew rate, etc. + + Each configuration node can consist of multiple nodes describing the pinmux and + pinconf options. Those nodes can be pinmux nodes or pinconf nodes. + + The name of each subnode is not important; all subnodes should be enumerated + and processed purely based on their content. + +properties: + compatible: + const: xlnx,zynq-pinctrl + + reg: + description: Specifies the base address and size of the SLCR space. + maxItems: 1 + + syscon: + description: + phandle to the SLCR. + +patternProperties: + '^(.*-)?(default|gpio)$': + type: object + patternProperties: + '^mux': + type: object + description: + Pinctrl node's client devices use subnodes for pin muxes, + which in turn use below standard properties. + $ref: pinmux-node.yaml# + + properties: + groups: + description: + List of groups to select (either this or "pins" must be + specified), available groups for this subnode. + items: + enum: [ethernet0_0_grp, ethernet1_0_grp, mdio0_0_grp, + mdio1_0_grp, qspi0_0_grp, qspi1_0_grp, qspi_fbclk, + qspi_cs1_grp, spi0_0_grp, spi0_1_grp, spi0_2_grp, + spi0_0_ss0, spi0_0_ss1, spi0_0_ss2, spi0_1_ss0, + spi0_1_ss1, spi0_1_ss2, spi0_2_ss0, spi0_2_ss1, + spi0_2_ss2, spi1_0_grp, spi1_1_grp, spi1_2_grp, + spi1_3_grp, spi1_0_ss0, spi1_0_ss1, spi1_0_ss2, + spi1_1_ss0, spi1_1_ss1, spi1_1_ss2, spi1_2_ss0, + spi1_2_ss1, spi1_2_ss2, spi1_3_ss0, spi1_3_ss1, + spi1_3_ss2, sdio0_0_grp, sdio0_1_grp, sdio0_2_grp, + sdio1_0_grp, sdio1_1_grp, sdio1_2_grp, sdio1_3_grp, + sdio0_emio_wp, sdio0_emio_cd, sdio1_emio_wp, + sdio1_emio_cd, smc0_nor, smc0_nor_cs1_grp, + smc0_nor_addr25_grp, smc0_nand, can0_0_grp, can0_1_grp, + can0_2_grp, can0_3_grp, can0_4_grp, can0_5_grp, + can0_6_grp, can0_7_grp, can0_8_grp, can0_9_grp, + can0_10_grp, can1_0_grp, can1_1_grp, can1_2_grp, + can1_3_grp, can1_4_grp, can1_5_grp, can1_6_grp, + can1_7_grp, can1_8_grp, can1_9_grp, can1_10_grp, + can1_11_grp, uart0_0_grp, uart0_1_grp, uart0_2_grp, + uart0_3_grp, uart0_4_grp, uart0_5_grp, uart0_6_grp, + uart0_7_grp, uart0_8_grp, uart0_9_grp, uart0_10_grp, + uart1_0_grp, uart1_1_grp, uart1_2_grp, uart1_3_grp, + uart1_4_grp, uart1_5_grp, uart1_6_grp, uart1_7_grp, + uart1_8_grp, uart1_9_grp, uart1_10_grp, uart1_11_grp, + i2c0_0_grp, i2c0_1_grp, i2c0_2_grp, i2c0_3_grp, + i2c0_4_grp, i2c0_5_grp, i2c0_6_grp, i2c0_7_grp, + i2c0_8_grp, i2c0_9_grp, i2c0_10_grp, i2c1_0_grp, + i2c1_1_grp, i2c1_2_grp, i2c1_3_grp, i2c1_4_grp, + i2c1_5_grp, i2c1_6_grp, i2c1_7_grp, i2c1_8_grp, + i2c1_9_grp, i2c1_10_grp, ttc0_0_grp, ttc0_1_grp, + ttc0_2_grp, ttc1_0_grp, ttc1_1_grp, ttc1_2_grp, + swdt0_0_grp, swdt0_1_grp, swdt0_2_grp, swdt0_3_grp, + swdt0_4_grp, gpio0_0_grp, gpio0_1_grp, gpio0_2_grp, + gpio0_3_grp, gpio0_4_grp, gpio0_5_grp, gpio0_6_grp, + gpio0_7_grp, gpio0_8_grp, gpio0_9_grp, gpio0_10_grp, + gpio0_11_grp, gpio0_12_grp, gpio0_13_grp, gpio0_14_grp, + gpio0_15_grp, gpio0_16_grp, gpio0_17_grp, gpio0_18_grp, + gpio0_19_grp, gpio0_20_grp, gpio0_21_grp, gpio0_22_grp, + gpio0_23_grp, gpio0_24_grp, gpio0_25_grp, gpio0_26_grp, + gpio0_27_grp, gpio0_28_grp, gpio0_29_grp, gpio0_30_grp, + gpio0_31_grp, gpio0_32_grp, gpio0_33_grp, gpio0_34_grp, + gpio0_35_grp, gpio0_36_grp, gpio0_37_grp, gpio0_38_grp, + gpio0_39_grp, gpio0_40_grp, gpio0_41_grp, gpio0_42_grp, + gpio0_43_grp, gpio0_44_grp, gpio0_45_grp, gpio0_46_grp, + gpio0_47_grp, gpio0_48_grp, gpio0_49_grp, gpio0_50_grp, + gpio0_51_grp, gpio0_52_grp, gpio0_53_grp, usb0_0_grp, + usb1_0_grp] + maxItems: 54 + + function: + description: + Specify the alternative function to be configured for the + given pin groups. + enum: [ethernet0, ethernet1, mdio0, mdio1, qspi0, qspi1, qspi_fbclk, + qspi_cs1, spi0, spi0_ss, spi1, spi1_ss, sdio0, sdio0_pc, + sdio0_cd, sdio0_wp, sdio1, sdio1_pc, sdio1_cd, sdio1_wp, + smc0_nor, smc0_nor_cs1, smc0_nor_addr25, smc0_nand, can0, + can1, uart0, uart1, i2c0, i2c1, ttc0, ttc1, swdt0, gpio0, + usb0, usb1] + + required: + - groups + - function + + additionalProperties: false + + '^conf': + type: object + description: + Pinctrl node's client devices use subnodes for pin configurations, + which in turn use the standard properties below. + $ref: pincfg-node.yaml# + + properties: + groups: + description: + List of pin groups as mentioned above. + + pins: + description: + List of pin names to select in this subnode. + items: + pattern: '^MIO([0-9]|[1-4][0-9]|5[0-3])$' + maxItems: 54 + + bias-pull-up: true + + bias-pull-down: true + + bias-disable: true + + bias-high-impedance: true + + low-power-enable: true + + low-power-disable: true + + slew-rate: + enum: [0, 1] + + io-standard: + description: + Selects the IO standard for MIO pins, this is driver specific. + $ref: "/schemas/types.yaml#/definitions/uint32" + enum: [1, 2, 3, 4] + + oneOf: + - required: [ groups ] + - required: [ pins ] + + additionalProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - syscon + +additionalProperties: false + +examples: + - | + pinctrl0: pinctrl@700 { + compatible = "xlnx,zynq-pinctrl"; + reg = <0x700 0x200>; + syscon = <&slcr>; + + pinctrl_uart1_default: uart1-default { + mux { + groups = "uart1_10_grp"; + function = "uart1"; + }; + + conf { + groups = "uart1_10_grp"; + slew-rate = <0>; + io-standard = <1>; + }; + + conf-rx { + pins = "MIO49"; + bias-high-impedance; + }; + + conf-tx { + pins = "MIO48"; + bias-disable; + }; + }; + }; + + uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; + }; + +... -- cgit v1.2.3-70-g09d2 From ef641c449e8083c4314c125d8e32b37644ddd852 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Wed, 21 Jul 2021 17:22:31 +0530 Subject: dt-bindings: pinctrl-zynq: Replace 'io-standard' with 'power-source' Replace custom pin configuration option 'io-standard' with generic property 'power-source' for Zynq pinctrl also add dt-binding file contains pin configuration defines for Zynq pinctrl. Signed-off-by: Sai Krishna Potthuri Link: https://lore.kernel.org/r/1626868353-96475-3-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml | 8 +++----- include/dt-bindings/pinctrl/pinctrl-zynq.h | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 include/dt-bindings/pinctrl/pinctrl-zynq.h diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml index 2da1969e02ec..ac97dbf6998e 100644 --- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynq-pinctrl.yaml @@ -156,10 +156,7 @@ patternProperties: slew-rate: enum: [0, 1] - io-standard: - description: - Selects the IO standard for MIO pins, this is driver specific. - $ref: "/schemas/types.yaml#/definitions/uint32" + power-source: enum: [1, 2, 3, 4] oneOf: @@ -179,6 +176,7 @@ additionalProperties: false examples: - | + #include pinctrl0: pinctrl@700 { compatible = "xlnx,zynq-pinctrl"; reg = <0x700 0x200>; @@ -193,7 +191,7 @@ examples: conf { groups = "uart1_10_grp"; slew-rate = <0>; - io-standard = <1>; + power-source = ; }; conf-rx { diff --git a/include/dt-bindings/pinctrl/pinctrl-zynq.h b/include/dt-bindings/pinctrl/pinctrl-zynq.h new file mode 100644 index 000000000000..bbfc345f017d --- /dev/null +++ b/include/dt-bindings/pinctrl/pinctrl-zynq.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * MIO pin configuration defines for Xilinx Zynq + * + * Copyright (C) 2021 Xilinx, Inc. + */ + +#ifndef _DT_BINDINGS_PINCTRL_ZYNQ_H +#define _DT_BINDINGS_PINCTRL_ZYNQ_H + +/* Configuration options for different power supplies */ +#define IO_STANDARD_LVCMOS18 1 +#define IO_STANDARD_LVCMOS25 2 +#define IO_STANDARD_LVCMOS33 3 +#define IO_STANDARD_HSTL 4 + +#endif /* _DT_BINDINGS_PINCTRL_ZYNQ_H */ -- cgit v1.2.3-70-g09d2 From cdd57325548af9803f0602914de16a8ddcb5bec0 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Wed, 21 Jul 2021 17:22:32 +0530 Subject: pinctrl: pinctrl-zynq: Add support for 'power-source' parameter Add support for generic pin parameter 'power-source'. To maintain the backward compatibility, 'io-standard' parameter is still supported in the driver. Signed-off-by: Sai Krishna Potthuri Link: https://lore.kernel.org/r/1626868353-96475-4-git-send-email-lakshmi.sai.krishna.potthuri@xilinx.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-zynq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c index 5fb924a2eedd..a96af8a76a7a 100644 --- a/drivers/pinctrl/pinctrl-zynq.c +++ b/drivers/pinctrl/pinctrl-zynq.c @@ -1028,6 +1028,7 @@ static int zynq_pinconf_cfg_get(struct pinctrl_dev *pctldev, break; } case PIN_CONFIG_IOSTANDARD: + case PIN_CONFIG_POWER_SOURCE: arg = zynq_pinconf_iostd_get(reg); break; default: @@ -1078,6 +1079,7 @@ static int zynq_pinconf_cfg_set(struct pinctrl_dev *pctldev, break; case PIN_CONFIG_IOSTANDARD: + case PIN_CONFIG_POWER_SOURCE: if (arg <= zynq_iostd_min || arg >= zynq_iostd_max) { dev_warn(pctldev->dev, "unsupported IO standard '%u'\n", -- cgit v1.2.3-70-g09d2 From e677b72a0647249370f2635862bf0241c86f66ad Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 17:08:55 +0300 Subject: RDMA/iwcm: Release resources if iw_cm module initialization fails The failure during iw_cm module initialization partially left the system with unreleased memory and other resources. Rewrite the module init/exit routines in such way that netlink commands will be opened only after successful initialization. Fixes: b493d91d333e ("iwcm: common code for port mapper") Link: https://lore.kernel.org/r/b01239f99cb1a3e6d2b0694c242d89e6410bcd93.1627048781.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/iwcm.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 42261152b489..2b47073c61a6 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -1186,29 +1186,34 @@ static int __init iw_cm_init(void) ret = iwpm_init(RDMA_NL_IWCM); if (ret) - pr_err("iw_cm: couldn't init iwpm\n"); - else - rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); + return ret; + iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0); if (!iwcm_wq) - return -ENOMEM; + goto err_alloc; iwcm_ctl_table_hdr = register_net_sysctl(&init_net, "net/iw_cm", iwcm_ctl_table); if (!iwcm_ctl_table_hdr) { pr_err("iw_cm: couldn't register sysctl paths\n"); - destroy_workqueue(iwcm_wq); - return -ENOMEM; + goto err_sysctl; } + rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); return 0; + +err_sysctl: + destroy_workqueue(iwcm_wq); +err_alloc: + iwpm_exit(RDMA_NL_IWCM); + return -ENOMEM; } static void __exit iw_cm_cleanup(void) { + rdma_nl_unregister(RDMA_NL_IWCM); unregister_net_sysctl_table(iwcm_ctl_table_hdr); destroy_workqueue(iwcm_wq); - rdma_nl_unregister(RDMA_NL_IWCM); iwpm_exit(RDMA_NL_IWCM); } -- cgit v1.2.3-70-g09d2 From bdb0e4e3ff19b6699ab82828412f2fd9ad811b1d Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 17:08:56 +0300 Subject: RDMA/iwpm: Remove not-needed reference counting iwpm_init() and iwpm_exit() are called only once during iw_cm module load. This makes whole reference count implementation not needed at all. Link: https://lore.kernel.org/r/1778ded873ba58c9fadc5bb25038de1cec843bec.1627048781.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/iwpm_util.c | 62 ++++++++++--------------------------- drivers/infiniband/core/iwpm_util.h | 1 - 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 3f8c019c7260..45e9aa503a44 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -48,7 +48,6 @@ static DEFINE_SPINLOCK(iwpm_mapinfo_lock); static struct hlist_head *iwpm_reminfo_bucket; static DEFINE_SPINLOCK(iwpm_reminfo_lock); -static DEFINE_MUTEX(iwpm_admin_lock); static struct iwpm_admin_data iwpm_admin; /** @@ -59,39 +58,22 @@ static struct iwpm_admin_data iwpm_admin; */ int iwpm_init(u8 nl_client) { - int ret = 0; - mutex_lock(&iwpm_admin_lock); - if (!refcount_read(&iwpm_admin.refcount)) { - iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE, - sizeof(struct hlist_head), - GFP_KERNEL); - if (!iwpm_hash_bucket) { - ret = -ENOMEM; - goto init_exit; - } - iwpm_reminfo_bucket = kcalloc(IWPM_REMINFO_HASH_SIZE, - sizeof(struct hlist_head), - GFP_KERNEL); - if (!iwpm_reminfo_bucket) { - kfree(iwpm_hash_bucket); - ret = -ENOMEM; - goto init_exit; - } + iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE, + sizeof(struct hlist_head), GFP_KERNEL); + if (!iwpm_hash_bucket) + return -ENOMEM; - refcount_set(&iwpm_admin.refcount, 1); - } else { - refcount_inc(&iwpm_admin.refcount); + iwpm_reminfo_bucket = kcalloc(IWPM_REMINFO_HASH_SIZE, + sizeof(struct hlist_head), GFP_KERNEL); + if (!iwpm_reminfo_bucket) { + kfree(iwpm_hash_bucket); + return -ENOMEM; } -init_exit: - mutex_unlock(&iwpm_admin_lock); - if (!ret) { - iwpm_set_valid(nl_client, 1); - iwpm_set_registration(nl_client, IWPM_REG_UNDEF); - pr_debug("%s: Mapinfo and reminfo tables are created\n", - __func__); - } - return ret; + iwpm_set_valid(nl_client, 1); + iwpm_set_registration(nl_client, IWPM_REG_UNDEF); + pr_debug("%s: Mapinfo and reminfo tables are created\n", __func__); + return 0; } static void free_hash_bucket(void); @@ -105,21 +87,9 @@ static void free_reminfo_bucket(void); */ int iwpm_exit(u8 nl_client) { - - if (!iwpm_valid_client(nl_client)) - return -EINVAL; - mutex_lock(&iwpm_admin_lock); - if (!refcount_read(&iwpm_admin.refcount)) { - mutex_unlock(&iwpm_admin_lock); - pr_err("%s Incorrect usage - negative refcount\n", __func__); - return -EINVAL; - } - if (refcount_dec_and_test(&iwpm_admin.refcount)) { - free_hash_bucket(); - free_reminfo_bucket(); - pr_debug("%s: Resources are destroyed\n", __func__); - } - mutex_unlock(&iwpm_admin_lock); + free_hash_bucket(); + free_reminfo_bucket(); + pr_debug("%s: Resources are destroyed\n", __func__); iwpm_set_valid(nl_client, 0); iwpm_set_registration(nl_client, IWPM_REG_UNDEF); return 0; diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index e201835de733..e2eacc017078 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h @@ -90,7 +90,6 @@ struct iwpm_remote_info { }; struct iwpm_admin_data { - refcount_t refcount; atomic_t nlmsg_seq; int client_list[RDMA_NL_NUM_CLIENTS]; u32 reg_list[RDMA_NL_NUM_CLIENTS]; -- cgit v1.2.3-70-g09d2 From bbafcbc2b1c9a9b01ecd97020cf5057a22cb20b2 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 17:08:57 +0300 Subject: RDMA/iwpm: Rely on the rdma_nl_[un]register() to ensure that requests are valid The core netlink code alread guarentees that no netlink callback can be running outside the rdma_nl_register/unregister() region and this registration happens during module init/exit. Thus it is already prevented that iwpm_valid_client() can ever fail. Remove it. Link: https://lore.kernel.org/r/a9f05a78f9996bf6ea47099b5e02671bf742f5ab.1627048781.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/iwpm_msg.c | 34 +--------------------------------- drivers/infiniband/core/iwpm_util.c | 18 ------------------ drivers/infiniband/core/iwpm_util.h | 17 ----------------- 3 files changed, 1 insertion(+), 68 deletions(-) diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index 12a9816fc0e2..3c9a9869212b 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -69,10 +69,6 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) const char *err_str = ""; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) { - err_str = "Invalid port mapper client"; - goto pid_query_error; - } if (iwpm_check_registration(nl_client, IWPM_REG_VALID) || iwpm_user_pid == IWPM_PID_UNAVAILABLE) return 0; @@ -153,10 +149,6 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) const char *err_str = ""; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) { - err_str = "Invalid port mapper client"; - goto add_mapping_error; - } if (!iwpm_valid_pid()) return 0; if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { @@ -240,10 +232,6 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) const char *err_str = ""; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) { - err_str = "Invalid port mapper client"; - goto query_mapping_error; - } if (!iwpm_valid_pid()) return 0; if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) { @@ -331,10 +319,6 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) const char *err_str = ""; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) { - err_str = "Invalid port mapper client"; - goto remove_mapping_error; - } if (!iwpm_valid_pid()) return 0; if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) { @@ -444,8 +428,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", __func__, iwpm_user_pid); - if (iwpm_valid_client(nl_client)) - iwpm_set_registration(nl_client, IWPM_REG_VALID); + iwpm_set_registration(nl_client, IWPM_REG_VALID); register_pid_response_exit: nlmsg_request->request_done = 1; /* always for found nlmsg_request */ @@ -649,11 +632,6 @@ int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) return ret; nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); - if (!iwpm_valid_client(nl_client)) { - pr_info("%s: Invalid port mapper client = %u\n", - __func__, nl_client); - return ret; - } atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); local_sockaddr = (struct sockaddr_storage *) @@ -736,11 +714,6 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) return ret; } nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); - if (!iwpm_valid_client(nl_client)) { - pr_info("%s: Invalid port mapper client = %u\n", - __func__, nl_client); - return ret; - } iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); iwpm_user_pid = cb->nlh->nlmsg_pid; @@ -863,11 +836,6 @@ int iwpm_hello_cb(struct sk_buff *skb, struct netlink_callback *cb) } abi_version = nla_get_u16(nltb[IWPM_NLA_HELLO_ABI_VERSION]); nl_client = RDMA_NL_GET_CLIENT(cb->nlh->nlmsg_type); - if (!iwpm_valid_client(nl_client)) { - pr_info("%s: Invalid port mapper client = %u\n", - __func__, nl_client); - return ret; - } iwpm_set_registration(nl_client, IWPM_REG_INCOMPL); atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); iwpm_ulib_version = min_t(u16, IWPM_UABI_VERSION, abi_version); diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index 45e9aa503a44..54f4feb604d8 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -70,7 +70,6 @@ int iwpm_init(u8 nl_client) return -ENOMEM; } - iwpm_set_valid(nl_client, 1); iwpm_set_registration(nl_client, IWPM_REG_UNDEF); pr_debug("%s: Mapinfo and reminfo tables are created\n", __func__); return 0; @@ -90,7 +89,6 @@ int iwpm_exit(u8 nl_client) free_hash_bucket(); free_reminfo_bucket(); pr_debug("%s: Resources are destroyed\n", __func__); - iwpm_set_valid(nl_client, 0); iwpm_set_registration(nl_client, IWPM_REG_UNDEF); return 0; } @@ -115,8 +113,6 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, unsigned long flags; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) - return ret; map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); if (!map_info) return -ENOMEM; @@ -276,10 +272,6 @@ int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr, unsigned long flags; int ret = -EINVAL; - if (!iwpm_valid_client(nl_client)) { - pr_info("%s: Invalid client = %u\n", __func__, nl_client); - return ret; - } spin_lock_irqsave(&iwpm_reminfo_lock, flags); if (iwpm_reminfo_bucket) { hash_bucket_head = get_reminfo_hash_bucket( @@ -394,16 +386,6 @@ int iwpm_get_nlmsg_seq(void) return atomic_inc_return(&iwpm_admin.nlmsg_seq); } -int iwpm_valid_client(u8 nl_client) -{ - return iwpm_admin.client_list[nl_client]; -} - -void iwpm_set_valid(u8 nl_client, int valid) -{ - iwpm_admin.client_list[nl_client] = valid; -} - /* valid client */ u32 iwpm_get_registration(u8 nl_client) { diff --git a/drivers/infiniband/core/iwpm_util.h b/drivers/infiniband/core/iwpm_util.h index e2eacc017078..3a42ad43056e 100644 --- a/drivers/infiniband/core/iwpm_util.h +++ b/drivers/infiniband/core/iwpm_util.h @@ -91,7 +91,6 @@ struct iwpm_remote_info { struct iwpm_admin_data { atomic_t nlmsg_seq; - int client_list[RDMA_NL_NUM_CLIENTS]; u32 reg_list[RDMA_NL_NUM_CLIENTS]; }; @@ -146,22 +145,6 @@ int iwpm_get_nlmsg_seq(void); */ void iwpm_add_remote_info(struct iwpm_remote_info *reminfo); -/** - * iwpm_valid_client - Check if the port mapper client is valid - * @nl_client: The index of the netlink client - * - * Valid clients need to call iwpm_init() before using - * the port mapper - */ -int iwpm_valid_client(u8 nl_client); - -/** - * iwpm_set_valid - Set the port mapper client to valid or not - * @nl_client: The index of the netlink client - * @valid: 1 if valid or 0 if invalid - */ -void iwpm_set_valid(u8 nl_client, int valid); - /** * iwpm_check_registration - Check if the client registration * matches the given one -- cgit v1.2.3-70-g09d2 From 8d7e415d55610d503fdb8815344846b72d194a40 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Wed, 28 Jul 2021 16:04:12 +0300 Subject: docs: Fix infiniband uverbs minor number Starting from the beginning of infiniband subsystem, the uverbs char devices start from 192 as a minor number, see commit bc38a6abdd5a ("[PATCH] IB uverbs: core implementation"). This patch updates the admin guide documentation to reflect it. Fixes: 9d85025b0418 ("docs-rst: create an user's manual book") Link: https://lore.kernel.org/r/bad03e6bcde45550c01e12908a6fe7dfa4770703.1627477347.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- Documentation/admin-guide/devices.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 9c2be821c225..922c23bb4372 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -2993,10 +2993,10 @@ 65 = /dev/infiniband/issm1 Second InfiniBand IsSM device ... 127 = /dev/infiniband/issm63 63rd InfiniBand IsSM device - 128 = /dev/infiniband/uverbs0 First InfiniBand verbs device - 129 = /dev/infiniband/uverbs1 Second InfiniBand verbs device + 192 = /dev/infiniband/uverbs0 First InfiniBand verbs device + 193 = /dev/infiniband/uverbs1 Second InfiniBand verbs device ... - 159 = /dev/infiniband/uverbs31 31st InfiniBand verbs device + 223 = /dev/infiniband/uverbs31 31st InfiniBand verbs device 232 char Biometric Devices 0 = /dev/biometric/sensor0/fingerprint first fingerprint sensor on first device -- cgit v1.2.3-70-g09d2 From 991c4274dc17b58b642894a48ccae85c9e53aad6 Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Thu, 29 Jul 2021 16:23:46 +0800 Subject: RDMA/hfi1: Fix typo in comments Remove the repeated word 'the' from comments Link: https://lore.kernel.org/r/20210729082346.1882-1-caihuoqing@baidu.com Signed-off-by: Cai Huoqing Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hfi1/chip.c | 4 ++-- drivers/infiniband/hw/hfi1/hfi.h | 2 +- drivers/infiniband/hw/hfi1/ruc.c | 2 +- drivers/infiniband/hw/hfi1/sdma.c | 2 +- drivers/infiniband/hw/hfi1/tid_rdma.c | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 50ffb8244625..b77938639c4b 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -14414,7 +14414,7 @@ static void init_qos(struct hfi1_devdata *dd, struct rsm_map_table *rmt) if (rmt->used + rmt_entries >= NUM_MAP_ENTRIES) goto bail; - /* add qos entries to the the RSM map table */ + /* add qos entries to the RSM map table */ for (i = 0, ctxt = FIRST_KERNEL_KCTXT; i < num_vls; i++) { unsigned tctxt; @@ -14893,7 +14893,7 @@ int hfi1_clear_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt) } /* - * Start doing the clean up the the chip. Our clean up happens in multiple + * Start doing the clean up the chip. Our clean up happens in multiple * stages and this is just the first. */ void hfi1_start_cleanup(struct hfi1_devdata *dd) diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 6cf03d16a495..9fbf4bb48161 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h @@ -2602,7 +2602,7 @@ static inline bool hfi1_get_hdr_type(u32 lid, struct rdma_ah_attr *attr) HFI1_PKT_TYPE_16B : HFI1_PKT_TYPE_9B; /* - * Return a 16B header type if either the the destination + * Return a 16B header type if either the destination * or source lid is extended. */ if (hfi1_get_packet_type(rdma_ah_get_dlid(attr)) == HFI1_PKT_TYPE_16B) diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c index c3fa1814c6a8..8cc65a7182f3 100644 --- a/drivers/infiniband/hw/hfi1/ruc.c +++ b/drivers/infiniband/hw/hfi1/ruc.c @@ -459,7 +459,7 @@ void hfi1_make_ruc_header(struct rvt_qp *qp, struct ib_other_headers *ohdr, * send engine * @qp: a pointer to QP * @ps: a pointer to a structure with commonly lookup values for - * the the send engine progress + * the send engine progress * @tid: true if it is the tid leg * * This routine checks if the time slice for the QP has expired diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index eb15c310d63d..f5bd40152cb7 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1860,7 +1860,7 @@ retry: /* * The SDMA idle interrupt is not guaranteed to be ordered with respect - * to updates to the the dma_head location in host memory. The head + * to updates to the dma_head location in host memory. The head * value read might not be fully up to date. If there are pending * descriptors and the SDMA idle interrupt fired then read from the * CSR SDMA head instead to get the latest value from the hardware. diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c index 233ea48b72c8..2a7abf7a1f7f 100644 --- a/drivers/infiniband/hw/hfi1/tid_rdma.c +++ b/drivers/infiniband/hw/hfi1/tid_rdma.c @@ -605,7 +605,7 @@ static void __trigger_tid_waiter(struct rvt_qp *qp) * to this call via first_qp(). * * If the qp trigger was already scheduled (!rval) - * the the reference is dropped, otherwise the resume + * the reference is dropped, otherwise the resume * or the destroy cancel will dispatch the reference. */ static void tid_rdma_schedule_tid_wakeup(struct rvt_qp *qp) @@ -5174,7 +5174,7 @@ bail_no_tx: priv->s_flags &= ~RVT_S_BUSY; /* * If we didn't get a txreq, the QP will be woken up later to try - * again, set the flags to the the wake up which work item to wake + * again, set the flags to the wake up which work item to wake * up. * (A better algorithm should be found to do this and generalize the * sleep/wakeup flags.) -- cgit v1.2.3-70-g09d2 From 090473004b026747a2795244ecd67bd51a24c923 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 29 Jul 2021 18:17:31 +0300 Subject: RDMA/qed: Use accurate error num in qed_cxt_dynamic_ilt_alloc To have more accurate error return type use -EOPNOTSUPP instead of -EINVAL. Link: https://lore.kernel.org/r/20210729151732.30995-1-pkushwaha@marvell.com Signed-off-by: Shai Malin Signed-off-by: Ariel Elior Signed-off-by: Prabhakar Kushwaha Signed-off-by: Jason Gunthorpe --- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index 5a0a3cbcc1c1..cb0f2a3a1ac9 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c @@ -2226,8 +2226,8 @@ qed_cxt_dynamic_ilt_alloc(struct qed_hwfn *p_hwfn, p_blk = &p_cli->pf_blks[CDUT_SEG_BLK(QED_CXT_ROCE_TID_SEG)]; break; default: - DP_NOTICE(p_hwfn, "-EINVALID elem type = %d", elem_type); - return -EINVAL; + DP_NOTICE(p_hwfn, "-EOPNOTSUPP elem type = %d", elem_type); + return -EOPNOTSUPP; } /* Calculate line in ilt */ -- cgit v1.2.3-70-g09d2 From 0050a57638ca4d681ff92bee55246bf64a6afe54 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Thu, 29 Jul 2021 18:17:32 +0300 Subject: RDMA/qedr: Improve error logs for rdma_alloc_tid error return Use -EINVAL return type to identify whether error is returned because of "Out of MR resources" or any other error types. Link: https://lore.kernel.org/r/20210729151732.30995-2-pkushwaha@marvell.com Signed-off-by: Shai Malin Signed-off-by: Ariel Elior Signed-off-by: Prabhakar Kushwaha Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/qedr/verbs.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index fdc47ef7d861..b72ef24db657 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -2996,7 +2996,11 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, rc = dev->ops->rdma_alloc_tid(dev->rdma_ctx, &mr->hw_mr.itid); if (rc) { - DP_ERR(dev, "roce alloc tid returned an error %d\n", rc); + if (rc == -EINVAL) + DP_ERR(dev, "Out of MR resources\n"); + else + DP_ERR(dev, "roce alloc tid returned error %d\n", rc); + goto err1; } @@ -3091,7 +3095,11 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, rc = dev->ops->rdma_alloc_tid(dev->rdma_ctx, &mr->hw_mr.itid); if (rc) { - DP_ERR(dev, "roce alloc tid returned an error %d\n", rc); + if (rc == -EINVAL) + DP_ERR(dev, "Out of MR resources\n"); + else + DP_ERR(dev, "roce alloc tid returned error %d\n", rc); + goto err0; } @@ -3221,7 +3229,11 @@ struct ib_mr *qedr_get_dma_mr(struct ib_pd *ibpd, int acc) rc = dev->ops->rdma_alloc_tid(dev->rdma_ctx, &mr->hw_mr.itid); if (rc) { - DP_ERR(dev, "roce alloc tid returned an error %d\n", rc); + if (rc == -EINVAL) + DP_ERR(dev, "Out of MR resources\n"); + else + DP_ERR(dev, "roce alloc tid returned error %d\n", rc); + goto err1; } -- cgit v1.2.3-70-g09d2 From a311936b5bcb93de64f930431e754aa9172b32ba Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 2 Jul 2021 15:43:48 +0200 Subject: USB: serial: io_edgeport: drop unused descriptor helper Drop the unused (and not even compiled) string descriptor helper. Signed-off-by: Johan Hovold --- drivers/usb/serial/io_edgeport.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index ea4edf5eed27..bdee78cc4a07 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -389,39 +389,6 @@ static void update_edgeport_E2PROM(struct edgeport_serial *edge_serial) release_firmware(fw); } -#if 0 -/************************************************************************ - * - * Get string descriptor from device - * - ************************************************************************/ -static int get_string_desc(struct usb_device *dev, int Id, - struct usb_string_descriptor **pRetDesc) -{ - struct usb_string_descriptor StringDesc; - struct usb_string_descriptor *pStringDesc; - - dev_dbg(&dev->dev, "%s - USB String ID = %d\n", __func__, Id); - - if (!usb_get_descriptor(dev, USB_DT_STRING, Id, &StringDesc, - sizeof(StringDesc))) - return 0; - - pStringDesc = kmalloc(StringDesc.bLength, GFP_KERNEL); - if (!pStringDesc) - return -1; - - if (!usb_get_descriptor(dev, USB_DT_STRING, Id, pStringDesc, - StringDesc.bLength)) { - kfree(pStringDesc); - return -1; - } - - *pRetDesc = pStringDesc; - return 0; -} -#endif - static void dump_product_info(struct edgeport_serial *edge_serial, struct edgeport_product_info *product_info) { -- cgit v1.2.3-70-g09d2 From 2d9a00705910ccea2dc5d9cba5469ff2de72fc87 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:10 +0200 Subject: USB: serial: cp210x: fix control-characters error handling In the unlikely event that setting the software flow-control characters fails the other flow-control settings should still be updated (just like all other terminal settings). Move out the error message printed by the set_chars() helper to make it more obvious that this is intentional. Fixes: 7748feffcd80 ("USB: serial: cp210x: add support for software flow control") Cc: stable@vger.kernel.org # 5.11 Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 3c80bfbf3bec..ad6aeb44f3e6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1164,10 +1164,8 @@ static int cp210x_set_chars(struct usb_serial_port *port, kfree(dmabuf); - if (result < 0) { - dev_err(&port->dev, "failed to set special chars: %d\n", result); + if (result < 0) return result; - } return 0; } @@ -1219,8 +1217,10 @@ static void cp210x_set_flow_control(struct tty_struct *tty, chars.bXoffChar = STOP_CHAR(tty); ret = cp210x_set_chars(port, &chars); - if (ret) - return; + if (ret) { + dev_err(&port->dev, "failed to set special chars: %d\n", + ret); + } } mutex_lock(&port_priv->mutex); -- cgit v1.2.3-70-g09d2 From ba4bbdabecd11530dca78dbae3ee7e51ffdc0a06 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:11 +0200 Subject: USB: serial: cp210x: fix flow-control error handling Make sure that the driver crtscts state is not updated in the unlikely event that the flow-control request fails. Not doing so could break RTS control. Fixes: 5951b8508855 ("USB: serial: cp210x: suppress modem-control errors") Cc: stable@vger.kernel.org # 5.11 Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index ad6aeb44f3e6..d48bed5782a5 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1190,6 +1190,7 @@ static void cp210x_set_flow_control(struct tty_struct *tty, struct cp210x_flow_ctl flow_ctl; u32 flow_repl; u32 ctl_hs; + bool crtscts; int ret; /* @@ -1249,14 +1250,14 @@ static void cp210x_set_flow_control(struct tty_struct *tty, flow_repl |= CP210X_SERIAL_RTS_FLOW_CTL; else flow_repl |= CP210X_SERIAL_RTS_INACTIVE; - port_priv->crtscts = true; + crtscts = true; } else { ctl_hs &= ~CP210X_SERIAL_CTS_HANDSHAKE; if (port_priv->rts) flow_repl |= CP210X_SERIAL_RTS_ACTIVE; else flow_repl |= CP210X_SERIAL_RTS_INACTIVE; - port_priv->crtscts = false; + crtscts = false; } if (I_IXOFF(tty)) { @@ -1279,8 +1280,12 @@ static void cp210x_set_flow_control(struct tty_struct *tty, flow_ctl.ulControlHandshake = cpu_to_le32(ctl_hs); flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); - cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl, + ret = cp210x_write_reg_block(port, CP210X_SET_FLOW, &flow_ctl, sizeof(flow_ctl)); + if (ret) + goto out_unlock; + + port_priv->crtscts = crtscts; out_unlock: mutex_unlock(&port_priv->mutex); } -- cgit v1.2.3-70-g09d2 From befc28a720362cb2b14601b5ba3d1f4c600ffaec Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:12 +0200 Subject: USB: serial: cp210x: clean up control-request timeout For consistency use the USB_CTRL_GET_TIMEOUT define for the read-register request timeout (same value as USB_CTRL_SET_TIMEOUT). Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index d48bed5782a5..779a94a83485 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -638,7 +638,7 @@ static int cp210x_read_reg_block(struct usb_serial_port *port, u8 req, result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), req, REQTYPE_INTERFACE_TO_HOST, 0, port_priv->bInterfaceNumber, dmabuf, bufsize, - USB_CTRL_SET_TIMEOUT); + USB_CTRL_GET_TIMEOUT); if (result == bufsize) { memcpy(buf, dmabuf, bufsize); result = 0; -- cgit v1.2.3-70-g09d2 From 33a61d2cc731d1c8a763f147528fc5e46978599f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:13 +0200 Subject: USB: serial: cp210x: clean up set-chars request Use the generic control request helper to implement the SET_CHARS request. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 779a94a83485..c19073ae3891 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1145,31 +1145,6 @@ static void cp210x_disable_event_mode(struct usb_serial_port *port) port_priv->event_mode = false; } -static int cp210x_set_chars(struct usb_serial_port *port, - struct cp210x_special_chars *chars) -{ - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - void *dmabuf; - int result; - - dmabuf = kmemdup(chars, sizeof(*chars), GFP_KERNEL); - if (!dmabuf) - return -ENOMEM; - - result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - CP210X_SET_CHARS, REQTYPE_HOST_TO_INTERFACE, 0, - port_priv->bInterfaceNumber, - dmabuf, sizeof(*chars), USB_CTRL_SET_TIMEOUT); - - kfree(dmabuf); - - if (result < 0) - return result; - - return 0; -} - static bool cp210x_termios_change(const struct ktermios *a, const struct ktermios *b) { bool iflag_change, cc_change; @@ -1217,7 +1192,8 @@ static void cp210x_set_flow_control(struct tty_struct *tty, chars.bXonChar = START_CHAR(tty); chars.bXoffChar = STOP_CHAR(tty); - ret = cp210x_set_chars(port, &chars); + ret = cp210x_write_reg_block(port, CP210X_SET_CHARS, &chars, + sizeof(chars)); if (ret) { dev_err(&port->dev, "failed to set special chars: %d\n", ret); -- cgit v1.2.3-70-g09d2 From 33fb934a0992440e3d645d3965e71217c185fd6d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:14 +0200 Subject: USB: serial: cp210x: clean up type detection Clean up attach somewhat by moving type detection into the quirk helper and giving it a more generic name. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index c19073ae3891..a120646b0926 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -2092,11 +2092,21 @@ static int cp210x_get_fw_version(struct usb_serial *serial, u16 value) return 0; } -static void cp210x_determine_quirks(struct usb_serial *serial) +static void cp210x_determine_type(struct usb_serial *serial) { struct cp210x_serial_private *priv = usb_get_serial_data(serial); int ret; + ret = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, + CP210X_GET_PARTNUM, &priv->partnum, + sizeof(priv->partnum)); + if (ret < 0) { + dev_warn(&serial->interface->dev, + "querying part number failed\n"); + priv->partnum = CP210X_PARTNUM_UNKNOWN; + return; + } + switch (priv->partnum) { case CP210X_PARTNUM_CP2102N_QFN28: case CP210X_PARTNUM_CP2102N_QFN24: @@ -2121,18 +2131,9 @@ static int cp210x_attach(struct usb_serial *serial) if (!priv) return -ENOMEM; - result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, - CP210X_GET_PARTNUM, &priv->partnum, - sizeof(priv->partnum)); - if (result < 0) { - dev_warn(&serial->interface->dev, - "querying part number failed\n"); - priv->partnum = CP210X_PARTNUM_UNKNOWN; - } - usb_set_serial_data(serial, priv); - cp210x_determine_quirks(serial); + cp210x_determine_type(serial); cp210x_init_max_speed(serial); result = cp210x_gpio_init(serial); -- cgit v1.2.3-70-g09d2 From 4e9340bb551a5ad664196465ba7620009d835dbc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 5 Jul 2021 10:20:15 +0200 Subject: USB: serial: cp210x: determine fw version for CP2105 and CP2108 CP2105, CP2108 and CP2102N have vendor requests that can be used to retrieve the firmware version. Having this information available is essential when trying to work around buggy firmware as a recent CP2102N regression showed. Determine and log the firmware version also for CP2105 and CP2108 during type detection at probe. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index a120646b0926..66a6ac50a4cd 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -400,6 +400,7 @@ struct cp210x_special_chars { }; /* CP210X_VENDOR_SPECIFIC values */ +#define CP210X_GET_FW_VER 0x000E #define CP210X_READ_2NCONFIG 0x000E #define CP210X_GET_FW_VER_2N 0x0010 #define CP210X_READ_LATCH 0x00C2 @@ -2108,6 +2109,10 @@ static void cp210x_determine_type(struct usb_serial *serial) } switch (priv->partnum) { + case CP210X_PARTNUM_CP2105: + case CP210X_PARTNUM_CP2108: + cp210x_get_fw_version(serial, CP210X_GET_FW_VER); + break; case CP210X_PARTNUM_CP2102N_QFN28: case CP210X_PARTNUM_CP2102N_QFN24: case CP210X_PARTNUM_CP2102N_QFN20: -- cgit v1.2.3-70-g09d2 From e2cdd86b561719da9ac928635f2a55b370dbb5b1 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 15 Jul 2021 16:59:55 -0500 Subject: PCI/VPD: Correct diagnostic for VPD read failure Previously, when a VPD read failed, we warned about an "invalid large VPD tag". Warn about the VPD read failure instead. Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 26bf7c877de5..8c4fad7e3b6a 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -92,8 +92,8 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) (tag == PCI_VPD_LTIN_RW_DATA)) { if (pci_read_vpd(dev, off+1, 2, &header[1]) != 2) { - pci_warn(dev, "invalid large VPD tag %02x size at offset %zu", - tag, off + 1); + pci_warn(dev, "failed VPD read at offset %zu\n", + off + 1); return 0; } off += PCI_VPD_LRDT_TAG_SIZE + -- cgit v1.2.3-70-g09d2 From 70730db0f611a721fe652cfe92c7f94ccf687454 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 15 Jul 2021 16:59:56 -0500 Subject: PCI/VPD: Check Resource Item Names against those valid for type Previously, we checked for PCI_VPD_STIN_END, PCI_VPD_LTIN_ID_STRING, etc., outside the Large and Small Resource cases, so we checked Large Resource Item Names against a Small Resource name and vice versa. Move these tests into the Large and Small Resource cases, so we only check PCI_VPD_STIN_END for Small Resources and PCI_VPD_LTIN_* for Large Resources. Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 8c4fad7e3b6a..28052d4d1990 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -98,24 +98,18 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) } off += PCI_VPD_LRDT_TAG_SIZE + pci_vpd_lrdt_size(header); + } else { + pci_warn(dev, "invalid large VPD tag %02x at offset %zu\n", + tag, off); + return 0; } } else { /* Short Resource Data Type Tag */ off += PCI_VPD_SRDT_TAG_SIZE + pci_vpd_srdt_size(header); tag = pci_vpd_srdt_tag(header); - } - - if (tag == PCI_VPD_STIN_END) /* End tag descriptor */ - return off; - - if ((tag != PCI_VPD_LTIN_ID_STRING) && - (tag != PCI_VPD_LTIN_RO_DATA) && - (tag != PCI_VPD_LTIN_RW_DATA)) { - pci_warn(dev, "invalid %s VPD tag %02x at offset %zu", - (header[0] & PCI_VPD_LRDT) ? "large" : "short", - tag, off); - return 0; + if (tag == PCI_VPD_STIN_END) /* End tag descriptor */ + return off; } } return 0; -- cgit v1.2.3-70-g09d2 From 4e0d77f8e831fcbe86a02dd0ead12d9c8c057700 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 29 Jul 2021 12:22:25 -0500 Subject: PCI/VPD: Treat initial 0xff as missing EEPROM Previously we assumed that the first tag being 0x00 meant an EEPROM was missing. The first tag being 0xff means the same thing; check for that also. [bhelgaas: rework error mesage] Signed-off-by: Heiner Kallweit Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 28052d4d1990..05e4df0a84d3 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -78,10 +78,8 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) while (off < old_size && pci_read_vpd(dev, off, 1, header) == 1) { unsigned char tag; - if (!header[0] && !off) { - pci_info(dev, "Invalid VPD tag 00, assume missing optional VPD EPROM\n"); - return 0; - } + if (off == 0 && (header[0] == 0x00 || header[0] == 0xff)) + goto error; if (header[0] & PCI_VPD_LRDT) { /* Large Resource Data Type Tag */ @@ -113,6 +111,12 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) } } return 0; + +error: + pci_info(dev, "invalid VPD tag %#04x at offset %zu%s\n", + header[0], off, off == 0 ? + "; assume missing optional EEPROM" : ""); + return 0; } /* -- cgit v1.2.3-70-g09d2 From 76f1fc266b897de07ad585667b574e03fd2e9d01 Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Thu, 29 Jul 2021 23:56:25 +0800 Subject: docs: add traditional Chinese translation for kernel Documentation Add traditional Chinese translation (zh_TW) for the Linux Kernel documentation with a series of translated files. Signed-off-by: Hu Haowen Reviewed-by: Pan Yunwang Link: https://lore.kernel.org/r/20210729155627.41744-1-src.res@email.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/index.rst | 1 + Documentation/translations/zh_TW/IRQ.txt | 41 + .../translations/zh_TW/admin-guide/README.rst | 351 +++++ .../translations/zh_TW/admin-guide/bug-bisect.rst | 85 ++ .../translations/zh_TW/admin-guide/bug-hunting.rst | 344 +++++ .../zh_TW/admin-guide/clearing-warn-once.rst | 16 + .../translations/zh_TW/admin-guide/cpu-load.rst | 112 ++ .../translations/zh_TW/admin-guide/index.rst | 135 ++ .../translations/zh_TW/admin-guide/init.rst | 58 + .../zh_TW/admin-guide/reporting-issues.rst | 1337 ++++++++++++++++++++ .../zh_TW/admin-guide/security-bugs.rst | 78 ++ .../zh_TW/admin-guide/tainted-kernels.rst | 161 +++ .../translations/zh_TW/admin-guide/unicode.rst | 174 +++ .../translations/zh_TW/disclaimer-zh_TW.rst | 11 + Documentation/translations/zh_TW/gpio.txt | 651 ++++++++++ Documentation/translations/zh_TW/index.rst | 162 +++ Documentation/translations/zh_TW/io_ordering.txt | 68 + Documentation/translations/zh_TW/oops-tracing.txt | 212 ++++ Documentation/translations/zh_TW/sparse.txt | 91 ++ 19 files changed, 4088 insertions(+) create mode 100644 Documentation/translations/zh_TW/IRQ.txt create mode 100644 Documentation/translations/zh_TW/admin-guide/README.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/bug-bisect.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/bug-hunting.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/cpu-load.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/index.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/init.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/reporting-issues.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/security-bugs.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst create mode 100644 Documentation/translations/zh_TW/admin-guide/unicode.rst create mode 100644 Documentation/translations/zh_TW/disclaimer-zh_TW.rst create mode 100644 Documentation/translations/zh_TW/gpio.txt create mode 100644 Documentation/translations/zh_TW/index.rst create mode 100644 Documentation/translations/zh_TW/io_ordering.txt create mode 100644 Documentation/translations/zh_TW/oops-tracing.txt create mode 100644 Documentation/translations/zh_TW/sparse.txt diff --git a/Documentation/translations/index.rst b/Documentation/translations/index.rst index 556b050884fc..1175a47d07f0 100644 --- a/Documentation/translations/index.rst +++ b/Documentation/translations/index.rst @@ -8,6 +8,7 @@ Translations :maxdepth: 1 zh_CN/index + zh_TW/index it_IT/index ko_KR/index ja_JP/index diff --git a/Documentation/translations/zh_TW/IRQ.txt b/Documentation/translations/zh_TW/IRQ.txt new file mode 100644 index 000000000000..73d435a0d1e7 --- /dev/null +++ b/Documentation/translations/zh_TW/IRQ.txt @@ -0,0 +1,41 @@ +Chinese translated version of Documentation/core-api/irq/index.rst + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Maintainer: Eric W. Biederman +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/core-api/irq/index.rst 的繁體中文翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +英文版維護者: Eric W. Biederman +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen +繁體中文版校譯者: 胡皓文 Hu Haowen + + +以下爲正文 +--------------------------------------------------------------------- +何爲 IRQ? + +一個 IRQ 是來自某個設備的一個中斷請求。目前,它們可以來自一個硬體引腳, +或來自一個數據包。多個設備可能連接到同個硬體引腳,從而共享一個 IRQ。 + +一個 IRQ 編號是用於告知硬體中斷源的內核標識。通常情況下,這是一個 +全局 irq_desc 數組的索引,但是除了在 linux/interrupt.h 中的實現, +具體的細節是體系結構特定的。 + +一個 IRQ 編號是設備上某個可能的中斷源的枚舉。通常情況下,枚舉的編號是 +該引腳在系統內中斷控制器的所有輸入引腳中的編號。對於 ISA 總線中的情況, +枚舉的是在兩個 i8259 中斷控制器中 16 個輸入引腳。 + +架構可以對 IRQ 編號指定額外的含義,在硬體涉及任何手工配置的情況下, +是被提倡的。ISA 的 IRQ 是一個分配這類額外含義的典型例子。 + diff --git a/Documentation/translations/zh_TW/admin-guide/README.rst b/Documentation/translations/zh_TW/admin-guide/README.rst new file mode 100644 index 000000000000..b752e50359e6 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/README.rst @@ -0,0 +1,351 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: Documentation/admin-guide/README.rst + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +Linux內核5.x版本 +========================================= + +以下是Linux版本5的發行註記。仔細閱讀它們, +它們會告訴你這些都是什麼,解釋如何安裝內核,以及遇到問題時該如何做。 + +什麼是Linux? +--------------- + + Linux是Unix作業系統的克隆版本,由Linus Torvalds在一個鬆散的網絡黑客 + (Hacker,無貶義)團隊的幫助下從頭開始編寫。它旨在實現兼容POSIX和 + 單一UNIX規範。 + + 它具有在現代成熟的Unix中應當具有的所有功能,包括真正的多任務處理、虛擬內存、 + 共享庫、按需加載、共享的寫時拷貝(COW)可執行文件、恰當的內存管理以及包括 + IPv4和IPv6在內的複合網絡棧。 + + Linux在GNU通用公共許可證,版本2(GNU GPLv2)下分發,詳見隨附的COPYING文件。 + +它能在什麼樣的硬體上運行? +----------------------------- + + 雖然Linux最初是爲32位的x86 PC機(386或更高版本)開發的,但今天它也能運行在 + (至少)Compaq Alpha AXP、Sun SPARC與UltraSPARC、Motorola 68000、PowerPC、 + PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、HP PA-RISC、Intel + IA-64、DEC VAX、AMD x86-64 Xtensa和ARC架構上。 + + Linux很容易移植到大多數通用的32位或64位體系架構,只要它們有一個分頁內存管理 + 單元(PMMU)和一個移植的GNU C編譯器(gcc;GNU Compiler Collection,GCC的一 + 部分)。Linux也被移植到許多沒有PMMU的體系架構中,儘管功能顯然受到了一定的 + 限制。 + Linux也被移植到了其自己上。現在可以將內核作爲用戶空間應用程式運行——這被 + 稱爲用戶模式Linux(UML)。 + +文檔 +----- +網際網路上和書籍上都有大量的電子文檔,既有Linux專屬文檔,也有與一般UNIX問題相關 +的文檔。我建議在任何Linux FTP站點上查找LDP(Linux文檔項目)書籍的文檔子目錄。 +本自述文件並不是關於系統的文檔:有更好的可用資源。 + + - 網際網路上和書籍上都有大量的(電子)文檔,既有Linux專屬文檔,也有與普通 + UNIX問題相關的文檔。我建議在任何有LDP(Linux文檔項目)書籍的Linux FTP + 站點上查找文檔子目錄。本自述文件並不是關於系統的文檔:有更好的可用資源。 + + - 文檔/子目錄中有各種自述文件:例如,這些文件通常包含一些特定驅動程序的 + 內核安裝說明。請閱讀 + :ref:`Documentation/process/changes.rst ` 文件,它包含了升級內核 + 可能會導致的問題的相關信息。 + +安裝內核原始碼 +--------------- + + - 如果您要安裝完整的原始碼,請把內核tar檔案包放在您有權限的目錄中(例如您 + 的主目錄)並將其解包:: + + xz -cd linux-5.x.tar.xz | tar xvf - + + 將「X」替換成最新內核的版本號。 + + 【不要】使用 /usr/src/linux 目錄!這裡有一組庫頭文件使用的內核頭文件 + (通常是不完整的)。它們應該與庫匹配,而不是被內核的變化搞得一團糟。 + + - 您還可以通過打補丁在5.x版本之間升級。補丁以xz格式分發。要通過打補丁進行 + 安裝,請獲取所有較新的補丁文件,進入內核原始碼(linux-5.x)的目錄並 + 執行:: + + xz -cd ../patch-5.x.xz | patch -p1 + + 請【按順序】替換所有大於當前原始碼樹版本的「x」,這樣就可以了。您可能想要 + 刪除備份文件(文件名類似xxx~ 或 xxx.orig),並確保沒有失敗的補丁(文件名 + 類似xxx# 或 xxx.rej)。如果有,不是你就是我犯了錯誤。 + + 與5.x內核的補丁不同,5.x.y內核(也稱爲穩定版內核)的補丁不是增量的,而是 + 直接應用於基本的5.x內核。例如,如果您的基本內核是5.0,並且希望應用5.0.3 + 補丁,則不應先應用5.0.1和5.0.2的補丁。類似地,如果您運行的是5.0.2內核, + 並且希望跳轉到5.0.3,那麼在應用5.0.3補丁之前,必須首先撤銷5.0.2補丁 + (即patch -R)。更多關於這方面的內容,請閱讀 + :ref:`Documentation/process/applying-patches.rst ` 。 + + 或者,腳本 patch-kernel 可以用來自動化這個過程。它能確定當前內核版本並 + 應用找到的所有補丁:: + + linux/scripts/patch-kernel linux + + 上面命令中的第一個參數是內核原始碼的位置。補丁是在當前目錄應用的,但是 + 可以將另一個目錄指定爲第二個參數。 + + - 確保沒有過時的 .o 文件和依賴項:: + + cd linux + make mrproper + + 現在您應該已經正確安裝了原始碼。 + +軟體要求 +--------- + + 編譯和運行5.x內核需要各種軟體包的最新版本。請參考 + :ref:`Documentation/process/changes.rst ` + 來了解最低版本要求以及如何升級軟體包。請注意,使用過舊版本的這些包可能會 + 導致很難追蹤的間接錯誤,因此不要以爲在生成或操作過程中出現明顯問題時可以 + 只更新包。 + +爲內核建立目錄 +--------------- + + 編譯內核時,默認情況下所有輸出文件都將與內核原始碼放在一起。使用 + ``make O=output/dir`` 選項可以爲輸出文件(包括 .config)指定備用位置。 + 例如:: + + kernel source code: /usr/src/linux-5.x + build directory: /home/name/build/kernel + + 要配置和構建內核,請使用:: + + cd /usr/src/linux-5.x + make O=/home/name/build/kernel menuconfig + make O=/home/name/build/kernel + sudo make O=/home/name/build/kernel modules_install install + + 請注意:如果使用了 ``O=output/dir`` 選項,那麼它必須用於make的所有調用。 + +配置內核 +--------- + + 即使只升級一個小版本,也不要跳過此步驟。每個版本中都會添加新的配置選項, + 如果配置文件沒有按預定設置,就會出現奇怪的問題。如果您想以最少的工作量 + 將現有配置升級到新版本,請使用 ``makeoldconfig`` ,它只會詢問您新配置 + 選項的答案。 + + - 其他配置命令包括:: + + "make config" 純文本界面。 + + "make menuconfig" 基於文本的彩色菜單、選項列表和對話框。 + + "make nconfig" 增強的基於文本的彩色菜單。 + + "make xconfig" 基於Qt的配置工具。 + + "make gconfig" 基於GTK+的配置工具。 + + "make oldconfig" 基於現有的 ./.config 文件選擇所有選項,並詢問 + 新配置選項。 + + "make olddefconfig" + 類似上一個,但不詢問直接將新選項設置爲默認值。 + + "make defconfig" 根據體系架構,使用arch/$arch/defconfig或 + arch/$arch/configs/${PLATFORM}_defconfig中的 + 默認選項值創建./.config文件。 + + "make ${PLATFORM}_defconfig" + 使用arch/$arch/configs/${PLATFORM}_defconfig中 + 的默認選項值創建一個./.config文件。 + 用「makehelp」來獲取您體系架構中所有可用平台的列表。 + + "make allyesconfig" + 通過儘可能將選項值設置爲「y」,創建一個 + ./.config文件。 + + "make allmodconfig" + 通過儘可能將選項值設置爲「m」,創建一個 + ./.config文件。 + + "make allnoconfig" 通過儘可能將選項值設置爲「n」,創建一個 + ./.config文件。 + + "make randconfig" 通過隨機設置選項值來創建./.config文件。 + + "make localmodconfig" 基於當前配置和加載的模塊(lsmod)創建配置。禁用 + 已加載的模塊不需要的任何模塊選項。 + + 要爲另一台計算機創建localmodconfig,請將該計算機 + 的lsmod存儲到一個文件中,並將其作爲lsmod參數傳入。 + + 此外,通過在參數LMC_KEEP中指定模塊的路徑,可以將 + 模塊保留在某些文件夾或kconfig文件中。 + + target$ lsmod > /tmp/mylsmod + target$ scp /tmp/mylsmod host:/tmp + + host$ make LSMOD=/tmp/mylsmod \ + LMC_KEEP="drivers/usb:drivers/gpu:fs" \ + localmodconfig + + 上述方法在交叉編譯時也適用。 + + "make localyesconfig" 與localmodconfig類似,只是它會將所有模塊選項轉換 + 爲內置(=y)。你可以同時通過LMC_KEEP保留模塊。 + + "make kvmconfig" 爲kvm客體內核支持啓用其他選項。 + + "make xenconfig" 爲xen dom0客體內核支持啓用其他選項。 + + "make tinyconfig" 配置儘可能小的內核。 + + 更多關於使用Linux內核配置工具的信息,見文檔 + Documentation/kbuild/kconfig.rst。 + + - ``make config`` 注意事項: + + - 包含不必要的驅動程序會使內核變大,並且在某些情況下會導致問題: + 探測不存在的控制器卡可能會混淆其他控制器。 + + - 如果存在協處理器,則編譯了數學仿真的內核仍將使用協處理器:在 + 這種情況下,數學仿真永遠不會被使用。內核會稍微大一點,但不管 + 是否有數學協處理器,都可以在不同的機器上工作。 + + - 「kernel hacking」配置細節通常會導致更大或更慢的內核(或兩者 + 兼而有之),甚至可以通過配置一些例程來主動嘗試破壞壞代碼以發現 + 內核問題,從而降低內核的穩定性(kmalloc())。因此,您可能應該 + 用於研究「開發」、「實驗」或「調試」特性相關問題。 + +編譯內核 +--------- + + - 確保您至少有gcc 4.9可用。 + 有關更多信息,請參閱 :ref:`Documentation/process/changes.rst ` 。 + + 請注意,您仍然可以使用此內核運行a.out用戶程序。 + + - 執行 ``make`` 來創建壓縮內核映像。如果您安裝了lilo以適配內核makefile, + 那麼也可以進行 ``makeinstall`` ,但是您可能需要先檢查特定的lilo設置。 + + 實際安裝必須以root身份執行,但任何正常構建都不需要。 + 無須徒然使用root身份。 + + - 如果您將內核的任何部分配置爲模塊,那麼還必須執行 ``make modules_install`` 。 + + - 詳細的內核編譯/生成輸出: + + 通常,內核構建系統在相當安靜的模式下運行(但不是完全安靜)。但是有時您或 + 其他內核開發人員需要看到編譯、連結或其他命令的執行過程。爲此,可使用 + 「verbose(詳細)」構建模式。 + 向 ``make`` 命令傳遞 ``V=1`` 來實現,例如:: + + make V=1 all + + 如需構建系統也給出內個目標重建的願意,請使用 ``V=2`` 。默認爲 ``V=0`` 。 + + - 準備一個備份內核以防出錯。對於開發版本尤其如此,因爲每個新版本都包含 + 尚未調試的新代碼。也要確保保留與該內核對應的模塊的備份。如果要安裝 + 與工作內核版本號相同的新內核,請在進行 ``make modules_install`` 安裝 + 之前備份modules目錄。 + + 或者,在編譯之前,使用內核配置選項「LOCALVERSION」向常規內核版本附加 + 一個唯一的後綴。LOCALVERSION可以在「General Setup」菜單中設置。 + + - 爲了引導新內核,您需要將內核映像(例如編譯後的 + .../linux/arch/x86/boot/bzImage)複製到常規可引導內核的位置。 + + - 不再支持在沒有LILO等啓動裝載程序幫助的情況下直接從軟盤引導內核。 + + 如果從硬碟引導Linux,很可能使用LILO,它使用/etc/lilo.conf文件中 + 指定的內核映像文件。內核映像文件通常是/vmlinuz、/boot/vmlinuz、 + /bzImage或/boot/bzImage。使用新內核前,請保存舊映像的副本,並複製 + 新映像覆蓋舊映像。然後您【必須重新運行LILO】來更新加載映射!否則, + 將無法啓動新的內核映像。 + + 重新安裝LILO通常需要運行/sbin/LILO。您可能希望編輯/etc/lilo.conf + 文件爲舊內核映像指定一個條目(例如/vmlinux.old)防止新的不能正常 + 工作。有關更多信息,請參閱LILO文檔。 + + 重新安裝LILO之後,您應該就已經準備好了。關閉系統,重新啓動,盡情 + 享受吧! + + 如果需要更改內核映像中的默認根設備、視頻模式等,請在適當的地方使用 + 啓動裝載程序的引導選項。無需重新編譯內核即可更改這些參數。 + + - 使用新內核重新啓動並享受它吧。 + +若遇到問題 +----------- + + - 如果您發現了一些可能由於內核缺陷所導致的問題,請檢查MAINTAINERS(維護者) + 文件看看是否有人與令您遇到麻煩的內核部分相關。如果無人在此列出,那麼第二 + 個最好的方案就是把它們發給我(torvalds@linux-foundation.org),也可能發送 + 到任何其他相關的郵件列表或新聞組。 + + - 在所有的缺陷報告中,【請】告訴我們您在說什麼內核,如何復現問題,以及您的 + 設置是什麼的(使用您的常識)。如果問題是新的,請告訴我;如果問題是舊的, + 請嘗試告訴我您什麼時候首次注意到它。 + + - 如果缺陷導致如下消息:: + + unable to handle kernel paging request at address C0000010 + Oops: 0002 + EIP: 0010:XXXXXXXX + eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx + esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx + ds: xxxx es: xxxx fs: xxxx gs: xxxx + Pid: xx, process nr: xx + xx xx xx xx xx xx xx xx xx xx + + 或者類似的內核調試信息顯示在屏幕上或在系統日誌里,請【如實】複製它。 + 可能對你來說轉儲(dump)看起來不可理解,但它確實包含可能有助於調試問題的 + 信息。轉儲上方的文本也很重要:它說明了內核轉儲代碼的原因(在上面的示例中, + 是由於內核指針錯誤)。更多關於如何理解轉儲的信息,請參見 + Documentation/admin-guide/bug-hunting.rst。 + + - 如果使用 CONFIG_KALLSYMS 編譯內核,則可以按原樣發送轉儲,否則必須使用 + ``ksymoops`` 程序來理解轉儲(但通常首選使用CONFIG_KALLSYMS編譯)。 + 此實用程序可從 + https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下載。 + 或者,您可以手動執行轉儲查找: + + - 在調試像上面這樣的轉儲時,如果您可以查找EIP值的含義,這將非常有幫助。 + 十六進位值本身對我或其他任何人都沒有太大幫助:它會取決於特定的內核設置。 + 您應該做的是從EIP行獲取十六進位值(忽略 ``0010:`` ),然後在內核名字列表 + 中查找它,以查看哪個內核函數包含有問題的地址。 + + 要找到內核函數名,您需要找到與顯示症狀的內核相關聯的系統二進位文件。就是 + 文件「linux/vmlinux」。要提取名字列表並將其與內核崩潰中的EIP進行匹配, + 請執行:: + + nm vmlinux | sort | less + + 這將爲您提供一個按升序排序的內核地址列表,從中很容易找到包含有問題的地址 + 的函數。請注意,內核調試消息提供的地址不一定與函數地址完全匹配(事實上, + 這是不可能的),因此您不能只「grep」列表:不過列表將爲您提供每個內核函數 + 的起點,因此通過查找起始地址低於你正在搜索的地址,但後一個函數的高於的 + 函數,你會找到您想要的。實際上,在您的問題報告中加入一些「上下文」可能是 + 一個好主意,給出相關的上下幾行。 + + 如果您由於某些原因無法完成上述操作(如您使用預編譯的內核映像或類似的映像), + 請儘可能多地告訴我您的相關設置信息,這會有所幫助。有關詳細信息請閱讀 + 『Documentation/admin-guide/reporting-issues.rst』。 + + - 或者,您可以在正在運行的內核上使用gdb(只讀的;即不能更改值或設置斷點)。 + 爲此,請首先使用-g編譯內核;適當地編輯arch/x86/Makefile,然後執行 ``make + clean`` 。您還需要啓用CONFIG_PROC_FS(通過 ``make config`` )。 + + 使用新內核重新啓動後,執行 ``gdb vmlinux /proc/kcore`` 。現在可以使用所有 + 普通的gdb命令。查找系統崩潰點的命令是 ``l *0xXXXXXXXX`` (將xxx替換爲EIP + 值)。 + + 用gdb無法調試一個當前未運行的內核是由於gdb(錯誤地)忽略了編譯內核的起始 + 偏移量。 + diff --git a/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst new file mode 100644 index 000000000000..41a39aebb8d6 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/bug-bisect.rst @@ -0,0 +1,85 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/bug-bisect` + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +二分(bisect)缺陷 ++++++++++++++++++++ + +(英文版)最後更新:2016年10月28日 + +引言 +===== + +始終嘗試由來自kernel.org的原始碼構建的最新內核。如果您沒有信心這樣做,請將 +錯誤報告給您的發行版供應商,而不是內核開發人員。 + +找到缺陷(bug)並不總是那麼容易,不過仍然得去找。如果你找不到它,不要放棄。 +儘可能多的向相關維護人員報告您發現的信息。請參閱MAINTAINERS文件以了解您所 +關注的子系統的維護人員。 + +在提交錯誤報告之前,請閱讀「Documentation/admin-guide/reporting-issues.rst」。 + +設備未出現(Devices not appearing) +==================================== + +這通常是由udev/systemd引起的。在將其歸咎於內核之前先檢查一下。 + +查找導致缺陷的補丁 +=================== + +使用 ``git`` 提供的工具可以很容易地找到缺陷,只要缺陷是可復現的。 + +操作步驟: + +- 從git原始碼構建內核 +- 以此開始二分 [#f1]_:: + + $ git bisect start + +- 標記損壞的變更集:: + + $ git bisect bad [commit] + +- 標記正常工作的變更集:: + + $ git bisect good [commit] + +- 重新構建內核並測試 +- 使用以下任一與git bisect進行交互:: + + $ git bisect good + + 或:: + + $ git bisect bad + + 這取決於您測試的變更集上是否有缺陷 +- 在一些交互之後,git bisect將給出可能導致缺陷的變更集。 + +- 例如,如果您知道當前版本有問題,而4.8版本是正常的,則可以執行以下操作:: + + $ git bisect start + $ git bisect bad # Current version is bad + $ git bisect good v4.8 + + +.. [#f1] 您可以(可選地)在開始git bisect的時候提供good或bad參數 + ``git bisect start [BAD] [GOOD]`` + +如需進一步參考,請閱讀: + +- ``git-bisect`` 的手冊頁 +- `Fighting regressions with git bisect(用git bisect解決回歸) + `_ +- `Fully automated bisecting with "git bisect run"(使用git bisect run + 來全自動二分) `_ +- `Using Git bisect to figure out when brokenness was introduced + (使用Git二分來找出何時引入了錯誤) `_ + diff --git a/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst new file mode 100644 index 000000000000..4d813aec77d2 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/bug-hunting.rst @@ -0,0 +1,344 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/bug-hunting` + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +追蹤缺陷 +========= + +內核錯誤報告通常附帶如下堆棧轉儲:: + + ------------[ cut here ]------------ + WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70 + Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core] + CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1 #1 + Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009 + 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6 + c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10 + f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617 + Call Trace: + [] ? dump_stack+0x44/0x64 + [] ? __warn+0xfa/0x120 + [] ? module_put+0x57/0x70 + [] ? module_put+0x57/0x70 + [] ? warn_slowpath_null+0x23/0x30 + [] ? module_put+0x57/0x70 + [] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk] + [] ? symbol_put_addr+0x27/0x50 + [] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] + [] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb] + [] ? usb_disable_endpoint+0x7c/0xb0 + [] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb] + [] ? usb_unbind_interface+0x62/0x250 + [] ? __pm_runtime_idle+0x44/0x70 + [] ? __device_release_driver+0x78/0x120 + [] ? driver_detach+0x87/0x90 + [] ? bus_remove_driver+0x38/0x90 + [] ? usb_deregister+0x58/0xb0 + [] ? SyS_delete_module+0x130/0x1f0 + [] ? task_work_run+0x64/0x80 + [] ? exit_to_usermode_loop+0x85/0x90 + [] ? do_fast_syscall_32+0x80/0x130 + [] ? sysenter_past_esp+0x40/0x6a + ---[ end trace 6ebc60ef3981792f ]--- + +這樣的堆棧跟蹤提供了足夠的信息來識別內核原始碼中發生錯誤的那一行。根據問題的 +嚴重性,它還可能包含 **「Oops」** 一詞,比如:: + + BUG: unable to handle kernel NULL pointer dereference at (null) + IP: [] iret_exc+0x7d0/0xa59 + *pdpt = 000000002258a001 *pde = 0000000000000000 + Oops: 0002 [#1] PREEMPT SMP + ... + +儘管有 **Oops** 或其他類型的堆棧跟蹤,但通常需要找到出問題的行來識別和處理缺 +陷。在本章中,我們將參考「Oops」來了解需要分析的各種堆棧跟蹤。 + +如果內核是用 ``CONFIG_DEBUG_INFO`` 編譯的,那麼可以使用文件: +`scripts/decode_stacktrace.sh` 。 + +連結的模塊 +----------- + +受到汙染或正在加載/卸載的模塊用「(…)」標記,汙染標誌在 +`Documentation/admin-guide/tainted-kernels.rst` 文件中進行了描述,「正在被加 +載」用「+」標註,「正在被卸載」用「-」標註。 + + +Oops消息在哪? +--------------- + +通常,Oops文本由klogd從內核緩衝區讀取,然後交給 ``syslogd`` ,後者將其寫入 +syslog文件,通常是 ``/var/log/messages`` (取決於 ``/etc/syslog.conf`` )。 +在使用systemd的系統上,它也可以由 ``journald`` 守護進程存儲,並通過運行 +``journalctl`` 命令進行訪問。 + +有時 ``klogd`` 會掛掉,這種情況下您可以運行 ``dmesg > file`` 從內核緩衝區 +讀取數據並保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必須適時 +中斷以停止傳輸,因爲 ``kmsg`` 是一個「永無止境的文件」。 + +如果機器嚴重崩潰,無法輸入命令或磁碟不可用,那還有三個選項: + +(1) 手動複製屏幕上的文本,並在機器重新啓動後輸入。很難受,但這是突然崩潰下 + 唯一的選擇。或者你可以用數位相機拍下屏幕——雖然不那麼好,但總比什麼都沒 + 有好。如果消息滾動超出控制台頂部,使用更高解析度(例如 ``vga=791`` ) + 引導啓動將允許您閱讀更多文本。(警告:這需要 ``vesafb`` ,因此對「早期」 + 的Oppses沒有幫助) + +(2) 從串口終端啓動(參見 + :ref:`Documentation/admin-guide/serial-console.rst ` ), + 在另一台機器上運行數據機然後用你喜歡的通信程序捕獲輸出。 + Minicom運行良好。 + +(3) 使用Kdump(參閱 Documentation/admin-guide/kdump/kdump.rst ),使用 + Documentation/admin-guide/kdump/gdbmacros.txt 中的dmesg gdbmacro從舊內存 + 中提取內核環形緩衝區。 + +找到缺陷位置 +------------- + +如果你能指出缺陷在內核原始碼中的位置,則報告缺陷的效果會非常好。這有兩種方法。 +通常來說使用 ``gdb`` 會比較容易,不過內核需要用調試信息來預編譯。 + +gdb +^^^^ + +GNU 調試器(GNU debugger, ``gdb`` )是從 ``vmlinux`` 文件中找出OOPS的確切 +文件和行號的最佳方法。 + +在使用 ``CONFIG_DEBUG_INFO`` 編譯的內核上使用gdb效果最好。可通過運行以下命令 +進行設置:: + + $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO + +在用 ``CONFIG_DEBUG_INFO`` 編譯的內核上,你可以直接從OOPS複製EIP值:: + + EIP: 0060:[] Not tainted VLI + +並使用GDB來將其翻譯成可讀形式:: + + $ gdb vmlinux + (gdb) l *0xc021e50e + +如果沒有啓用 ``CONFIG_DEBUG_INFO`` ,則使用OOPS的函數偏移:: + + EIP is at vt_ioctl+0xda8/0x1482 + +並在啓用 ``CONFIG_DEBUG_INFO`` 的情況下重新編譯內核:: + + $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO + $ make vmlinux + $ gdb vmlinux + (gdb) l *vt_ioctl+0xda8 + 0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293). + 288 { + 289 struct vc_data *vc = NULL; + 290 int ret = 0; + 291 + 292 console_lock(); + 293 if (VT_BUSY(vc_num)) + 294 ret = -EBUSY; + 295 else if (vc_num) + 296 vc = vc_deallocate(vc_num); + 297 console_unlock(); + +或者若您想要更詳細的顯示:: + + (gdb) p vt_ioctl + $1 = {int (struct tty_struct *, unsigned int, unsigned long)} 0xae0 + (gdb) l *0xae0+0xda8 + +您也可以使用對象文件作爲替代:: + + $ make drivers/tty/ + $ gdb drivers/tty/vt/vt_ioctl.o + (gdb) l *vt_ioctl+0xda8 + +如果你有調用跟蹤,類似:: + + Call Trace: + [] :jbd:log_wait_commit+0xa3/0xf5 + [] autoremove_wake_function+0x0/0x2e + [] :jbd:journal_stop+0x1be/0x1ee + ... + +這表明問題可能在 :jbd: 模塊中。您可以在gdb中加載該模塊並列出相關代碼:: + + $ gdb fs/jbd/jbd.ko + (gdb) l *log_wait_commit+0xa3 + +.. note:: + + 您還可以對堆棧跟蹤處的任何函數調用執行相同的操作,例如:: + + [] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] + + 上述調用發生的位置可以通過以下方式看到:: + + $ gdb drivers/media/usb/dvb-usb/dvb-usb.o + (gdb) l *dvb_usb_adapter_frontend_exit+0x3a + +objdump +^^^^^^^^ + +要調試內核,請使用objdump並從崩潰輸出中查找十六進位偏移,以找到有效的代碼/匯 +編行。如果沒有調試符號,您將看到所示例程的彙編程序代碼,但是如果內核有調試 +符號,C代碼也將可見(調試符號可以在內核配置菜單的hacking項中啓用)。例如:: + + $ objdump -r -S -l --disassemble net/dccp/ipv4.o + +.. note:: + + 您需要處於內核樹的頂層以便此獲得您的C文件。 + +如果您無法訪問原始碼,仍然可以使用以下方法調試一些崩潰轉儲(如Dave Miller的 +示例崩潰轉儲輸出所示):: + + EIP is at +0x14/0x4c0 + ... + Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00 + 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08 + <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85 + + Put the bytes into a "foo.s" file like this: + + .text + .globl foo + foo: + .byte .... /* bytes from Code: part of OOPS dump */ + + Compile it with "gcc -c -o foo.o foo.s" then look at the output of + "objdump --disassemble foo.o". + + Output: + + ip_queue_xmit: + push %ebp + push %edi + push %esi + push %ebx + sub $0xbc, %esp + mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb) + mov 0x8(%ebp), %ebx ! %ebx = skb->sk + mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt + +`scripts/decodecode` 文件可以用來自動完成大部分工作,這取決於正在調試的CPU +體系結構。 + +報告缺陷 +--------- + +一旦你通過定位缺陷找到了其發生的地方,你可以嘗試自己修復它或者向上游報告它。 + +爲了向上游報告,您應該找出用於開發受影響代碼的郵件列表。這可以使用 ``get_maintainer.pl`` 。 + + +例如,您在gspca的sonixj.c文件中發現一個缺陷,則可以通過以下方法找到它的維護者:: + + $ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c + Hans Verkuil (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%) + Mauro Carvalho Chehab (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%) + Tejun Heo (commit_signer:1/1=100%) + Bhaktipriya Shridhar (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%) + linux-media@vger.kernel.org (open list:GSPCA USB WEBCAM DRIVER) + linux-kernel@vger.kernel.org (open list) + +請注意它將指出: + +- 最後接觸原始碼的開發人員(如果這是在git樹中完成的)。在上面的例子中是Tejun + 和Bhaktipriya(在這個特定的案例中,沒有人真正參與這個文件的開發); +- 驅動維護人員(Hans Verkuil); +- 子系統維護人員(Mauro Carvalho Chehab); +- 驅動程序和/或子系統郵件列表(linux-media@vger.kernel.org); +- Linux內核郵件列表(linux-kernel@vger.kernel.org)。 + +通常,修復缺陷的最快方法是將它報告給用於開發相關代碼的郵件列表(linux-media +ML),抄送驅動程序維護者(Hans)。 + +如果你完全不知道該把報告寄給誰,且 ``get_maintainer.pl`` 也沒有提供任何有用 +的信息,請發送到linux-kernel@vger.kernel.org。 + +感謝您的幫助,這使Linux儘可能穩定:-) + +修復缺陷 +--------- + +如果你懂得編程,你不僅可以通過報告錯誤來幫助我們,還可以提供一個解決方案。 +畢竟,開源就是分享你的工作,你不想因爲你的天才而被認可嗎? + +如果你決定這樣做,請在制定解決方案後將其提交到上游。 + +請務必閱讀 +:ref:`Documentation/process/submitting-patches.rst ` , +以幫助您的代碼被接受。 + + +--------------------------------------------------------------------------- + +用 ``klogd`` 進行Oops跟蹤的注意事項 +------------------------------------ + +爲了幫助Linus和其他內核開發人員, ``klogd`` 對保護故障的處理提供了大量支持。 +爲了完整支持地址解析,至少應該使用 ``sysklogd`` 包的1.3-pl3版本。 + +當發生保護故障時, ``klogd`` 守護進程會自動將內核日誌消息中的重要地址轉換爲 +它們的等效符號。然後通過 ``klogd`` 使用的任何報告機制來轉發這個已翻譯的內核 +消息。保護錯誤消息可以直接從消息文件中剪切出來並轉發給內核開發人員。 + +``klogd`` 執行兩種類型的地址解析,靜態翻譯和動態翻譯。靜態翻譯使用System.map +文件。爲了進行靜態轉換, ``klogd`` 守護進程必須能夠在守護進程初始化時找到系 +統映射文件。有關 ``klogd`` 如何搜索映射文件的信息,請參見klogd手冊頁。 + +當使用內核可加載模塊時,動態地址轉換非常重要。由於內核模塊的內存是從內核的 +動態內存池中分配的,因此無論是模塊的開頭還是模塊中的函數和符號都沒有固定的 +位置。 + +內核支持系統調用,允許程序確定加載哪些模塊及其在內存中的位置。klogd守護進程 +使用這些系統調用構建了一個符號表,可用於調試可加載內核模塊中發生的保護錯誤。 + +klogd至少會提供產生保護故障的模塊的名稱。如果可加載模塊的開發人員選擇從模塊 +導出符號信息,則可能會有其他可用的符號信息。 + +由於內核模塊環境可以是動態的,因此當模塊環境發生變化時,必須有一種通知 +``klogd`` 守護進程的機制。有一些可用的命令行選項允許klogd向當前正在執行的守 +護進程發出信號示意應該刷新符號信息。有關更多信息,請參閱 ``klogd`` 手冊頁。 + +sysklogd發行版附帶了一個補丁,它修改了 ``modules-2.0.0`` 包,以便在加載或 +卸載模塊時自動向klogd發送信號。應用此補丁基本上可無縫支持調試內核可加載模塊 +發生的保護故障。 + +以下是 ``klogd`` 處理的可加載模塊中的保護故障示例:: + + Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc + Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 + Aug 29 09:51:01 blizard kernel: *pde = 00000000 + Aug 29 09:51:01 blizard kernel: Oops: 0002 + Aug 29 09:51:01 blizard kernel: CPU: 0 + Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] + Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 + Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c + Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c + Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 + Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) + Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 + Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 + Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 + Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] + Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 + +--------------------------------------------------------------------------- + +:: + + Dr. G.W. Wettstein Oncology Research Div. Computing Facility + Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com + 820 4th St. N. + Fargo, ND 58122 + Phone: 701-234-7556 + diff --git a/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst new file mode 100644 index 000000000000..bdc1a22046cf --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/clearing-warn-once.rst @@ -0,0 +1,16 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Translator: 胡皓文 Hu Haowen + +清除 WARN_ONCE +-------------- + +WARN_ONCE / WARN_ON_ONCE / printk_once 僅僅列印一次消息. + +echo 1 > /sys/kernel/debug/clear_warn_once + +可以清除這種狀態並且再次允許列印一次告警信息,這對於運行測試集後重現問題 +很有用。 + diff --git a/Documentation/translations/zh_TW/admin-guide/cpu-load.rst b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst new file mode 100644 index 000000000000..be087cef1967 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/cpu-load.rst @@ -0,0 +1,112 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Translator: 胡皓文 Hu Haowen + +======== +CPU 負載 +======== + +Linux通過``/proc/stat``和``/proc/uptime``導出各種信息,用戶空間工具 +如top(1)使用這些信息計算系統花費在某個特定狀態的平均時間。 +例如: + + $ iostat + Linux 2.6.18.3-exp (linmac) 02/20/2007 + + avg-cpu: %user %nice %system %iowait %steal %idle + 10.01 0.00 2.92 5.44 0.00 81.63 + + ... + +這裡系統認爲在默認採樣周期內有10.01%的時間工作在用戶空間,2.92%的時 +間用在系統空間,總體上有81.63%的時間是空閒的。 + +大多數情況下``/proc/stat``的信息幾乎真實反映了系統信息,然而,由於內 +核採集這些數據的方式/時間的特點,有時這些信息根本不可靠。 + +那麼這些信息是如何被搜集的呢?每當時間中斷觸發時,內核查看此刻運行的 +進程類型,並增加與此類型/狀態進程對應的計數器的值。這種方法的問題是 +在兩次時間中斷之間系統(進程)能夠在多種狀態之間切換多次,而計數器只 +增加最後一種狀態下的計數。 + +舉例 +--- + +假設系統有一個進程以如下方式周期性地占用cpu:: + + 兩個時鐘中斷之間的時間線 + |-----------------------| + ^ ^ + |_ 開始運行 | + |_ 開始睡眠 + (很快會被喚醒) + +在上面的情況下,根據``/proc/stat``的信息(由於當系統處於空閒狀態時, +時間中斷經常會發生)系統的負載將會是0 + +大家能夠想像內核的這種行爲會發生在許多情況下,這將導致``/proc/stat`` +中存在相當古怪的信息:: + + /* gcc -o hog smallhog.c */ + #include + #include + #include + #include + #define HIST 10 + + static volatile sig_atomic_t stop; + + static void sighandler (int signr) + { + (void) signr; + stop = 1; + } + static unsigned long hog (unsigned long niters) + { + stop = 0; + while (!stop && --niters); + return niters; + } + int main (void) + { + int i; + struct itimerval it = { .it_interval = { .tv_sec = 0, .tv_usec = 1 }, + .it_value = { .tv_sec = 0, .tv_usec = 1 } }; + sigset_t set; + unsigned long v[HIST]; + double tmp = 0.0; + unsigned long n; + signal (SIGALRM, &sighandler); + setitimer (ITIMER_REAL, &it, NULL); + + hog (ULONG_MAX); + for (i = 0; i < HIST; ++i) v[i] = ULONG_MAX - hog (ULONG_MAX); + for (i = 0; i < HIST; ++i) tmp += v[i]; + tmp /= HIST; + n = tmp - (tmp / 3.0); + + sigemptyset (&set); + sigaddset (&set, SIGALRM); + + for (;;) { + hog (n); + sigwait (&set, &i); + } + return 0; + } + + +參考 +--- + +- https://lore.kernel.org/r/loom.20070212T063225-663@post.gmane.org +- Documentation/filesystems/proc.rst (1.8) + + +謝謝 +--- + +Con Kolivas, Pavel Machek + diff --git a/Documentation/translations/zh_TW/admin-guide/index.rst b/Documentation/translations/zh_TW/admin-guide/index.rst new file mode 100644 index 000000000000..293c20245783 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/index.rst @@ -0,0 +1,135 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/index` +:Translator: 胡皓文 Hu Haowen + +Linux 內核用戶和管理員指南 +========================== + +下面是一組隨時間添加到內核中的面向用戶的文檔的集合。到目前爲止,還沒有一個 +整體的順序或組織 - 這些材料不是一個單一的,連貫的文件!幸運的話,情況會隨著 +時間的推移而迅速改善。 + +這個初始部分包含總體信息,包括描述內核的README, 關於內核參數的文檔等。 + +.. toctree:: + :maxdepth: 1 + + README + +Todolist: + + kernel-parameters + devices + sysctl/index + +本節介紹CPU漏洞及其緩解措施。 + +Todolist: + + hw-vuln/index + +下面的一組文檔,針對的是試圖跟蹤問題和bug的用戶。 + +.. toctree:: + :maxdepth: 1 + + reporting-issues + security-bugs + bug-hunting + bug-bisect + tainted-kernels + init + +Todolist: + + reporting-bugs + ramoops + dynamic-debug-howto + kdump/index + perf/index + +這是應用程式開發人員感興趣的章節的開始。可以在這裡找到涵蓋內核ABI各個 +方面的文檔。 + +Todolist: + + sysfs-rules + +本手冊的其餘部分包括各種指南,介紹如何根據您的喜好配置內核的特定行爲。 + + +.. toctree:: + :maxdepth: 1 + + clearing-warn-once + cpu-load + unicode + +Todolist: + + acpi/index + aoe/index + auxdisplay/index + bcache + binderfs + binfmt-misc + blockdev/index + bootconfig + braille-console + btmrvl + cgroup-v1/index + cgroup-v2 + cifs/index + cputopology + dell_rbu + device-mapper/index + edid + efi-stub + ext4 + nfs/index + gpio/index + highuid + hw_random + initrd + iostats + java + jfs + kernel-per-CPU-kthreads + laptops/index + lcd-panel-cgram + ldm + lockup-watchdogs + LSM/index + md + media/index + mm/index + module-signing + mono + namespaces/index + numastat + parport + perf-security + pm/index + pnp + rapidio + ras + rtc + serial-console + svga + sysrq + thunderbolt + ufs + vga-softcursor + video-output + xfs + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` + diff --git a/Documentation/translations/zh_TW/admin-guide/init.rst b/Documentation/translations/zh_TW/admin-guide/init.rst new file mode 100644 index 000000000000..32cdf134948f --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/init.rst @@ -0,0 +1,58 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/init` + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +解釋「No working init found.」啓動掛起消息 +========================================== + +:作者: + + Andreas Mohr + + Cristian Souza + +本文檔提供了加載初始化二進位(init binary)失敗的一些高層級原因(大致按執行 +順序列出)。 + +1) **無法掛載根文件系統Unable to mount root FS** :請設置「debug」內核參數(在 + 引導加載程序bootloader配置文件或CONFIG_CMDLINE)以獲取更詳細的內核消息。 + +2) **初始化二進位不存在於根文件系統上init binary doesn't exist on rootfs** : + 確保您的根文件系統類型正確(並且 ``root=`` 內核參數指向正確的分區);擁有 + 所需的驅動程序,例如SCSI或USB等存儲硬體;文件系統(ext3、jffs2等)是內建的 + (或者作爲模塊由initrd預加載)。 + +3) **控制台設備損壞Broken console device** : ``console= setup`` 中可能存在 + 衝突 --> 初始控制台不可用(initial console unavailable)。例如,由於串行 + IRQ問題(如缺少基於中斷的配置)導致的某些串行控制台不可靠。嘗試使用不同的 + ``console= device`` 或像 ``netconsole=`` 。 + +4) **二進位存在但依賴項不可用Binary exists but dependencies not available** : + 例如初始化二進位的必需庫依賴項,像 ``/lib/ld-linux.so.2`` 丟失或損壞。使用 + ``readelf -d |grep NEEDED`` 找出需要哪些庫。 + +5) **無法加載二進位Binary cannot be loaded** :請確保二進位的體系結構與您的 + 硬體匹配。例如i386不匹配x86_64,或者嘗試在ARM硬體上加載x86。如果您嘗試在 + 此處加載非二進位文件(shell腳本?),您應該確保腳本在其工作頭(shebang + header)行 ``#!/...`` 中指定能正常工作的解釋器(包括其庫依賴項)。在處理 + 腳本之前,最好先測試一個簡單的非腳本二進位文件,比如 ``/bin/sh`` ,並確認 + 它能成功執行。要了解更多信息,請將代碼添加到 ``init/main.c`` 以顯示 + kernel_execve()的返回值。 + +當您發現新的失敗原因時,請擴展本解釋(畢竟加載初始化二進位是一個 **關鍵** 且 +艱難的過渡步驟,需要儘可能無痛地進行),然後向LKML提交一個補丁。 + +待辦事項: + +- 通過一個可以存儲 ``kernel_execve()`` 結果值的結構體數組實現各種 + ``run_init_process()`` 調用,並在失敗時通過疊代 **所有** 結果來記錄一切 + (非常重要的可用性修復)。 +- 試著使實現本身在一般情況下更有幫助,例如在受影響的地方提供額外的錯誤消息。 + diff --git a/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst new file mode 100644 index 000000000000..27638e199f13 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/reporting-issues.rst @@ -0,0 +1,1337 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0) +.. + If you want to distribute this text under CC-BY-4.0 only, please use 'The + Linux kernel developers' for author attribution and link this as source: + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst +.. + Note: Only the content of this RST file as found in the Linux kernel sources + is available under CC-BY-4.0, as versions of this text that were processed + (for example by the kernel's build system) might contain content taken from + files which use a more restrictive license. + +.. include:: ../disclaimer-zh_TW.rst + +:Original: Documentation/admin-guide/reporting-issues.rst + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + + +報告問題 ++++++++++ + + +簡明指南(亦即 太長不看) +========================== + +您面臨的是否爲同系列穩定版或長期支持內核的普通內核的回歸?是否仍然受支持? +請搜索 `LKML內核郵件列表 `_ 和 +`Linux穩定版郵件列表 `_ 存檔中匹配的報告並 +加入討論。如果找不到匹配的報告,請安裝該系列的最新版本。如果它仍然出現問題, +報告給穩定版郵件列表(stable@vger.kernel.org)。 + +在所有其他情況下,請儘可能猜測是哪個內核部分導致了問題。查看MAINTAINERS文件, +了解開發人員希望如何得知問題,大多數情況下,報告問題都是通過電子郵件和抄送 +相關郵件列表進行的。檢查報告目的地的存檔中是否已有匹配的報告;也請搜索 +`LKML `_ 和網絡。如果找不到可加入的討論,請 +安裝 `最新的主線內核 `_ 。如果仍存在問題,請發送報告。 + +問題已經解決了,但是您希望看到它在一個仍然支持的穩定版或長期支持系列中得到 +解決?請安裝其最新版本。如果它出現了問題,那麼在主線中搜索修復它的更改,並 +檢查是否正在回傳(backporting)或者已放棄;如果兩者都沒有,那麼可詢問處理 +更改的人員。 + +**通用提醒** :當安裝和測試上述內核時,請確保它是普通的(即:沒有補丁,也沒 +有使用附加模塊)。還要確保它是在一個正常的環境中構建和運行,並且在問題發生 +之前沒有被汙染(tainted)。 + +在編寫報告時,要涵蓋與問題相關的所有信息,如使用的內核和發行版。在碰見回歸時, +嘗試給出引入它的更改的提交ID,二分可以找到它。如果您同時面臨Linux內核的多個 +問題,請分別報告每個問題。 + +一旦報告發出,請回答任何出現的問題,並儘可能地提供幫助。這包括通過不時重新 +測試新版本並發送狀態更新來推動進展。 + + +如何向內核維護人員報告問題的逐步指南 +===================================== + +上面的簡明指南概述了如何向Linux內核開發人員報告問題。對於已經熟悉向自由和開 +源軟體(FLOSS)項目報告問題的人來說,這可能是他們所需要的全部內容。對於其他 +人,本部分更爲詳細,並一步一步地描述。爲了便於閱讀,它仍然儘量簡潔,並省略 +了許多細節;這些在逐步指南後的參考章節中進行了描述,該章節更詳細地解釋了每 +個步驟。 + +注意:本節涉及的方面比簡明指南多,順序也稍有不同。這符合你的利益,以確保您 +儘早意識到看起來像Linux內核毛病的問題可能實際上是由其他原因引起的。這些步驟 +可以確保你最終不會覺得在這一過程中投入的時間是浪費: + + * 您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱讀 + 本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。尋找 + 和解決問題往往需要後者。 + + * 使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查 + `Linux內核郵件列表(LKML) `_ 的存檔。如果 + 找到匹配的報告,請加入討論而不是發送新報告。 + + * 看看你正在處理的問題是否爲回歸問題、安全問題或非常嚴重的問題:這些都是需 + 要在接下來的一些步驟中特別處理的「高優先級問題」。 + + * 確保不是內核環境導致了您面臨的問題。 + + * 創建一個新的備份,並將系統修復和恢復工具放在手邊。 + + * 確保您的系統不會通過動態構建額外的內核模塊來增強其內核,像DKMS這樣的解決 + 方案可能在您不知情的情況下就在本地進行了這樣的工作。 + + * 當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可能 + 會導致您面臨的問題。 + + * 粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫注 + 釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需要分 + 別報告給內核開發人員,除非它們嚴重糾纏在一起。 + + * 如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現 + 故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。 + + * 定位可能引起問題的驅動程序或內核子系統。找出其開發人員期望的報告的方式和 + 位置。注意:大多數情況下不會是 bugzilla.kernel.org,因爲問題通常需要通 + 過郵件發送給維護人員和公共郵件列表。 + + * 在缺陷追蹤器或問題相關郵件列表的存檔中徹底搜索可能與您的問題匹配的報告。 + 如果你發現了一些相關討論,請加入討論而不是發送新的報告。 + +在完成這些準備之後,你將進入主要部分: + + * 除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在某些 + 情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案;在 + 合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。無論 + 你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告被拒絕 + 或忽略的風險。 + + * 確保您剛剛安裝的內核在運行時不會「汙染」自己。 + + * 在您剛剛安裝的內核中復現這個問題。如果它沒有出現,請查看下方只發生在 + 穩定版和長期支持內核的問題的說明。 + + * 優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所有 + 重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到了一 + 些東西,請考慮再次搜索關於該問題的現有報告。 + + * 如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找觸 + 發錯誤的代碼行。 + + * 如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。 + + * 通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新內 + 核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內核 + 構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。包 + 含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci`` 的輸出 + 。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概述問題和 + 影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。現在給出一 + 個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的那樣發送或 + 提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面「高優先級問 + 題的特殊處理」所述特別關照。 + + * 等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請公 + 開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個新主 + 線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地提醒一 + 下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。 + + +報告穩定版和長期支持內核線的回歸 +---------------------------------- + +如果您發現了穩定版或長期支持內核版本線中的回歸問題並按上述流程跳到這裡,那麼 +請閱讀本小節。即例如您在從5.10.4更新到5.10.5時出現了問題(從5.9.15到5.10.5則 +不是)。開發人員希望儘快修復此類回歸,因此有一個簡化流程來報告它們: + + * 檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 `kernel.org 的首頁 + `_ ,確保此特定版本線的最新版沒有「[EOL]」標記。 + + * 檢查 `Linux穩定版郵件列表 `_ 中的現有報告。 + + * 從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍然 + 存在問題,因爲問題可能已經在那裡被修復了。如果您第一次發現供應商內核的問題, + 請檢查已知最新版本的普通構建是否可以正常運行。 + + * 向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。大致 + 描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常的版本。 + 然後等待進一步的指示。 + +下面的參考章節部分詳細解釋了這些步驟中的每一步。 + + +報告只發生在較舊內核版本線的問題 +---------------------------------- + +若您嘗試了上述的最新主線內核,但未能在那裡復現問題,那麼本小節適用於您;以下 +流程有助於使問題在仍然支持的穩定版或長期支持版本線,或者定期基於最新穩定版或 +長期支持內核的供應商內核中得到修復。如果是這種情況,請執行以下步驟: + + * 請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或太 + 冒險,無法移植到那裡。 + + * 執行前節「報告穩定版和長期支持內核線的回歸」中的前三個步驟。 + + * 在Linux內核版本控制系統中搜索修復主線問題的更改,因爲它的提交消息可能會 + 告訴你修復是否已經計劃好了支持。如果你沒有找到,搜索適當的郵件列表,尋找 + 討論此類問題或同行評議可能修復的帖子;然後檢查討論是否認爲修復不適合支持。 + 如果支持根本不被考慮,加入最新的討論,詢問是否有可能。 + + * 前面的步驟之一應該會給出一個解決方案。如果仍未能成功,請向可能引起問題的 + 子系統的維護人員詢問建議;抄送特定子系統的郵件列表以及穩定版郵件列表 + +下面的參考章節部分詳細解釋了這些步驟中的每一步。 + + +參考章節:向內核維護者報告問題 +=============================== + +上面的詳細指南簡要地列出了所有主要步驟,這對大多數人來說應該足夠了。但有時, +即使是有經驗的用戶也可能想知道如何實際執行這些步驟之一。這就是本節的目的, +因爲它將提供關於上述每個步驟的更多細節。請將此作爲參考文檔:可以從頭到尾 +閱讀它。但它主要是爲了瀏覽和查找如何實際執行這些步驟的詳細信息。 + +在深入挖掘細節之前,我想先給你一些一般性建議: + + * Linux內核開發人員很清楚這個過程很複雜,比其他的FLOSS項目要求更多。我們很 + 希望讓它更簡單。但這需要在不同的地方以及一些基礎設施上付諸努力,這些基礎 + 設施需要持續的維護;尚未有人站出來做這些工作,所以目前情況就是這樣。 + + * 與某些供應商簽訂的保證或支持合同並不能使您有權要求上游Linux內核社區的開 + 發人員進行修復:這樣的合同完全在Linux內核、其開發社區和本文檔的範圍之外。 + 這就是爲什麼在這種情況下,你不能要求任何契約保證,即使開發人員處理的問 + 題對供應商有效。如果您想主張您的權利,使用供應商的支持渠道代替。當這樣做 + 的時候,你可能想提出你希望看到這個問題在上游Linux內核中修復;可以這是確 + 保最終修復將被納入所有Linux發行版的唯一方法來鼓勵他們。 + + * 如果您從未向FLOSS項目報告過任何問題,那麼您應該考慮閱讀 `如何有效地報告 + 缺陷 `_ , `如何 + 以明智的方式提問 `_ , + 和 `如何提出好問題 `_ 。 + +解決這些問題之後,可以在下面找到如何正確地向Linux內核報告問題的詳細信息。 + + +確保您使用的是上游Linux內核 +---------------------------- + + *您是否面臨硬體或軟體供應商提供的Linux內核的問題?那麼基本上您最好停止閱 + 讀本文檔,轉而向您的供應商報告問題,除非您願意自己安裝最新的Linux版本。 + 尋找和解決問題往往需要後者。* + +與大多數程式設計師一樣,Linux內核開發人員不喜歡花時間處理他們維護的原始碼中根本 +不會發生的問題的報告。這只會浪費每個人的時間,尤其是你的時間。不幸的是,當 +涉及到內核時,這樣的情況很容易發生,並且常常導致雙方氣餒。這是因爲幾乎所有預 +裝在設備(台式機、筆記本電腦、智慧型手機、路由器等)上的Linux內核,以及大多數 +由Linux發行商提供的內核,都與由kernel.org發行的官方Linux內核相距甚遠:從Linux +開發的角度來看,這些供應商提供的內核通常是古老的或者經過了大量修改,通常兩點 +兼具。 + +大多數供應商內核都不適合用來向Linux內核開發人員報告問題:您在其中遇到的問題 +可能已經由Linux內核開發人員在數月或數年前修復;此外,供應商的修改和增強可能 +會導致您面臨的問題,即使它們看起來很小或者完全不相關。這就是爲什麼您應該向 +供應商報告這些內核的問題。它的開發者應該查看報告,如果它是一個上游問題,直接 +於上游修復或將報告轉發到那裡。在實踐中,這有時行不通。因此,您可能需要考慮 +通過自己安裝最新的Linux內核內核來繞過供應商。如果如果您選擇此方法,那麼本指 +南後面的步驟將解釋如何在排除了其他可能導致您的問題的原因後執行此操作。 + +注意前段使用的詞語是「大多數」,因爲有時候開發人員實際上願意處理供應商內核出現 +的問題報告。他們是否這麼做很大程度上取決於開發人員和相關問題。如果發行版只 +根據最近的Linux版本對內核進行了較小修改,那麼機會就比較大;例如對於Debian +GNU/Linux Sid或Fedora Rawhide所提供的主線內核。一些開發人員還將接受基於最新 +穩定內核的發行版內核問題報告,只要它改動不大;例如Arch Linux、常規Fedora版本 +和openSUSE Turboweed。但是請記住,您最好使用主線Linux,並避免在此流程中使用 +穩定版內核,如「安裝一個新的內核進行測試」一節中所詳述。 + +當然,您可以忽略所有這些建議,並向上游Linux開發人員報告舊的或經過大量修改的 +供應商內核的問題。但是注意,這樣的報告經常被拒絕或忽視,所以自行小心考慮一下。 +不過這還是比根本不報告問題要好:有時候這樣的報告會直接或間接地幫助解決之後的 +問題。 + + +搜索現有報告(第一部分) +------------------------- + + *使用您喜愛的網絡搜尋引擎對現有報告進行粗略搜索;此外,請檢查Linux內核 + 郵件列表(LKML)的存檔。如果找到匹配的報告,請加入討論而不是發送新報告。* + +報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告人的你。 +所以徹底檢查是否有人已經報告了這個問題,這對你自己是有利的。在流程中的這一步, +可以只執行一個粗略的搜索:一旦您知道您的問題需要報告到哪裡,稍後的步驟將告訴 +您如何詳細搜索。儘管如此,不要倉促完成這一步,它可以節省您的時間和減少麻煩。 + +只需先用你最喜歡的搜尋引擎在網際網路上搜索。然後再搜索Linux內核郵件列表(LKML) +存檔。 + +如果搜索結果實在太多,可以考慮讓你的搜尋引擎將搜索時間範圍限制在過去的一個 +月或一年。而且無論你在哪裡搜索,一定要用恰當的搜索關鍵詞;也要變化幾次關鍵 +詞。同時,試著從別人的角度看問題:這將幫助你想出其他的關鍵詞。另外,一定不 +要同時使用過多的關鍵詞。記住搜索時要同時嘗試包含和不包含內核驅動程序的名稱 +或受影響的硬體組件的名稱等信息。但其確切的品牌名稱(比如說「華碩紅魔 Radeon +RX 5700 XT Gaming OC」)往往幫助不大,因爲它太具體了。相反,嘗試搜索術語,如 +型號(Radeon 5700 或 Radeon 5000)和核心代號(「Navi」或「Navi10」),以及包含 +和不包含其製造商(「AMD」)。 + +如果你發現了關於你的問題的現有報告,請加入討論,因爲你可能會提供有價值的額 +外信息。這一點很重要,即使是在修復程序已經準備好或處於最後階段,因爲開發人 +員可能會尋找能夠提供額外信息或測試建議修復程序的人。跳到「發布報告後的責任」 +一節,了解有關如何正確參與的細節。 + +注意,搜索 `bugzilla.kernel.org `_ 網站可能 +也是一個好主意,因爲這可能會提供有價值的見解或找到匹配的報告。如果您發現後者, +請記住:大多數子系統都希望在不同的位置報告,如下面「你需要將問題報告到何處」 +一節中所述。因此本應處理這個問題的開發人員甚至可能不知道bugzilla的工單。所以 +請檢查工單中的問題是否已經按照本文檔所述得到報告,如果沒有,請考慮這樣做。 + +高優先級的問題? +----------------- + + *看看你正在處理的問題是否是回歸問題、安全問題或非常嚴重的問題:這些都是 + 需要在接下來的一些步驟中特別處理的「高優先級問題」。* + +Linus Torvalds和主要的Linux內核開發人員希望看到一些問題儘快得到解決,因此在 +報告過程中有一些「高優先級問題」的處理略有不同。有三種情況符合條件:回歸、安全 +問題和非常嚴重的問題。 + +如果在舊版本的Linux內核中工作的東西不能在新版本的Linux內核中工作,或者某種 +程度上在新版本的Linux內核中工作得更差,那麼你就需要處理「回歸」。因此,當一個 +在Linux 5.7中表現良好的WiFi驅動程序在5.8中表現不佳或根本不能工作時,這是一 +種回歸。如果應用程式在新的內核中出現不穩定的現象,這也是一種回歸,這可能是 +由於內核和用戶空間之間的接口(如procfs和sysfs)發生不兼容的更改造成的。顯著 +的性能降低或功耗增加也可以稱爲回歸。但是請記住:新內核需要使用與舊內核相似的 +配置來構建(參見下面如何實現這一點)。這是因爲內核開發人員在實現新特性時有 +時無法避免不兼容性;但是爲了避免回歸,這些特性必須在構建配置期間顯式地啓用。 + +什麼是安全問題留給您自己判斷。在繼續之前,請考慮閱讀 +「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」, +因爲它提供了如何最恰當地處理安全問題的額外細節。 + +當發生了完全無法接受的糟糕事情時,此問題就是一個「非常嚴重的問題」。例如, +Linux內核破壞了它處理的數據或損壞了它運行的硬體。當內核突然顯示錯誤消息 +(「kernel panic」)並停止工作,或者根本沒有任何停止信息時,您也在處理一個嚴重 +的問題。注意:不要混淆「panic」(內核停止自身的致命錯誤)和「Oops」(可恢復錯誤), +因爲顯示後者之後內核仍然在運行。 + + +確保環境健康 +-------------- + + *確保不是內核所處環境導致了你所面臨的問題。* + +看起來很像內核問題的問題有時是由構建或運行時環境引起的。很難完全排除這種問 +題,但你應該儘量減少這種問題: + + * 構建內核時,請使用經過驗證的工具,因爲編譯器或二進位文件中的錯誤可能會導 + 致內核出現錯誤行爲。 + + * 確保您的計算機組件在其設計規範內運行;這對處理器、內存和主板尤爲重要。因 + 此,當面臨潛在的內核問題時,停止低電壓或超頻。 + + * 儘量確保不是硬體故障導致了你的問題。例如,內存損壞會導致大量的問題,這些 + 問題會表現爲看起來像內核問題。 + + * 如果你正在處理一個文件系統問題,你可能需要用 ``fsck`` 檢查一下文件系統, + 因爲它可能會以某種方式被損壞,從而導致無法預期的內核行爲。 + + * 在處理回歸問題時,要確保沒有在更新內核的同時發生了其他變化。例如,這個問 + 題可能是由同時更新的其他軟體引起的。也有可能是在你第一次重啓進入新內核時, + 某個硬體巧合地壞了。更新系統 BIOS 或改變 BIOS 設置中的某些內容也會導致 + 一些看起來很像內核回歸的問題。 + + +爲緊急情況做好準備 +------------------- + + *創建一個全新的備份,並將系統修復和還原工具放在手邊* + +我得提醒您,您正在和計算機打交道,計算機有時會出現意想不到的事情,尤其是當 +您折騰其作業系統的內核等關鍵部件時。而這就是你在這個過程中要做的事情。因此, +一定要創建一個全新的備份;還要確保你手頭有修復或重裝作業系統的所有工具, +以及恢復備份所需的一切。 + + +確保你的內核不會被增強 +------------------------ + + *確保您的系統不會通過動態構建額外的內核模塊來增強其內核,像DKMS這樣的解 + 決方案可能在您不知情的情況下就在本地進行了這樣的工作。* + +如果內核以任何方式得到增強,那麼問題報告被忽略或拒絕的風險就會急劇增加。這就 +是爲什麼您應該刪除或禁用像akmods和DKMS這樣的機制:這些機制會自動構建額外內核 +模塊,例如當您安裝新的Linux內核或第一次引導它時。也要記得同時刪除他們可能安裝 +的任何模塊。然後重新啓動再繼續。 + +注意,你可能不知道你的系統正在使用這些解決方案之一:當你安裝 Nvidia 專有圖 +形驅動程序、VirtualBox 或其他需要 Linux 內核以外的模塊支持的軟體時,它們通 +常會靜默設置。這就是爲什麼你可能需要卸載這些軟體的軟體包,以擺脫任何第三方 +內核模塊。 + + +檢測「汙染」標誌 +---------------- + + *當問題發生時,檢查您的內核是否被「汙染」,因爲使內核設置這個標誌的事件可 + 能會導致您面臨的問題。* + +當某些可能會導致看起來完全不相關的後續錯誤的事情發生時,內核會用「汙染 +(taint)」標誌標記自己。如果您的內核受到汙染,那麼您面臨的可能是這樣的錯誤。 +因此在投入更多時間到這個過程中之前,儘早排除此情況可能對你有好處。這是這個 +步驟出現在這裡的唯一原因,因爲這個過程稍後會告訴您安裝最新的主線內核;然後 +您將需要再次檢查汙染標誌,因爲當它出問題的時候內核報告會關注它。 + +在正在運行的系統上檢查內核是否汙染非常容易:如果 ``cat /proc/sys/kernel/tainted`` +返回「0」,那麼內核沒有被汙染,一切正常。在某些情況下無法檢查該文件;這就是 +爲什麼當內核報告內部問題(「kernel bug」)、可恢復錯誤(「kernel Oops」)或停止 +操作前不可恢復的錯誤(「kernel panic」)時,它也會提到汙染狀態。當其中一個錯 +誤發生時,查看列印的錯誤消息的頂部,搜索以「CPU:」開頭的行。如果發現問題時內 +核未被汙染,那麼它應該以「Not infected」結束;如果你看到「Tainted:」且後跟一些 +空格和字母,那就被汙染了。 + +如果你的內核被汙染了,請閱讀「Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst」 +以找出原因。設法消除汙染因素。通常是由以下三種因素之一引起的: + + 1. 發生了一個可恢復的錯誤(「kernel Oops」),內核汙染了自己,因爲內核知道在 + 此之後它可能會出現奇怪的行爲錯亂。在這種情況下,檢查您的內核或系統日誌, + 並尋找以下列文字開頭的部分:: + + Oops: 0000 [#1] SMP + + 如方括號中的「#1」所示,這是自啓動以來的第一次Oops。每個Oops和此後發生的 + 任何其他問題都可能是首個Oops的後續問題,即使這兩個問題看起來完全不相關。 + 通過消除首個Oops的原因並在之後復現該問題,可以排除這種情況。有時僅僅 + 重新啓動就足夠了,有時更改配置後重新啓動可以消除Oops。但是在這個流程中 + 不要花費太多時間在這一點上,因爲引起Oops的原因可能已經在您稍後將按流程 + 安裝的新Linux內核版本中修復了。 + + 2. 您的系統使用的軟體安裝了自己的內核模塊,例如Nvidia的專有圖形驅動程序或 + VirtualBox。當內核從外部源(即使它們是開源的)加載此類模塊時,它會汙染 + 自己:它們有時會在不相關的內核區域導致錯誤,從而可能導致您面臨的問題。 + 因此,當您想要向Linux內核開發人員報告問題時,您必須阻止這些模塊加載。 + 大多數情況下最簡單的方法是:臨時卸載這些軟體,包括它們可能已經安裝的任 + 何模塊。之後重新啓動。 + + 3. 當內核加載駐留在Linux內核原始碼staging樹中的模塊時,它也會汙染自身。這 + 是一個特殊的區域,代碼(主要是驅動程序)還沒有達到正常Linux內核的質量 + 標準。當您報告此種模塊的問題時,內核受到汙染顯然是沒有問題的;只需確保 + 問題模塊是造成汙染的唯一原因。如果問題發生在一個不相關的區域,重新啓動 + 並通過指定 ``foo.blacklist=1`` 作爲內核參數臨時阻止該模塊被加載(用有 + 問題的模塊名替換「foo」)。 + + +記錄如何重現問題 +------------------ + + *粗略地寫下如何重現這個問題。如果您同時處理多個問題,請爲每個問題單獨寫 + 注釋,並確保它們在新啓動的系統上獨立出現。這是必要的,因爲每個問題都需 + 要分別報告給內核開發人員,除非它們嚴重糾纏在一起。* + +如果你同時處理多個問題,必須分別報告每個問題,因爲它們可能由不同的開發人員 +處理。在一份報告中描述多種問題,也會讓其他人難以將其分開。因此只有在問題嚴 +重糾纏的情況下,才能將問題合併在一份報告中。 + +此外,在報告過程中,你必須測試該問題是否發生在其他內核版本上。因此,如果您 +知道如何在一個新啓動的系統上快速重現問題,將使您的工作更加輕鬆。 + +注意:報告只發生過一次的問題往往是沒有結果的,因爲它們可能是由於宇宙輻射導 +致的位翻轉。所以你應該嘗試通過重現問題來排除這種情況,然後再繼續。如果你有 +足夠的經驗來區分由於硬體故障引起的一次性錯誤和難以重現的罕見內核問題,可以 +忽略這個建議。 + + +穩定版或長期支持內核的回歸? +----------------------------- + + *如果您正面臨穩定版或長期支持版本線的回歸(例如從5.10.4更新到5.10.5時出現 + 故障),請查看後文「報告穩定版和長期支持內核線的回歸」小節。* + +穩定版和長期支持內核版本線中的回歸是Linux開發人員非常希望解決的問題,這樣的 +問題甚至比主線開發分支中的回歸更不應出現,因爲它們會很快影響到很多人。開發人員 +希望儘快了解此類問題,因此有一個簡化流程來報告這些問題。注意,使用更新內核版 +本線的回歸(比如從5.9.15切換到5.10.5時出現故障)不符合條件。 + + +你需要將問題報告到何處 +------------------------ + + *定位可能引起問題的驅動程序或內核子系統。找出其開發人員期望的報告的方式 + 和位置。注意:大多數情況下不會是bugzilla.kernel.org,因爲問題通常需要通 + 過郵件發送給維護人員和公共郵件列表。* + +將報告發送給合適的人是至關重要的,因爲Linux內核是一個大項目,大多數開發人員 +只熟悉其中的一小部分。例如,相當多的程式設計師只關心一個驅動程序,比如一個WiFi +晶片驅動程序;它的開發人員可能對疏遠的或不相關的「子系統」(如TCP堆棧、 +PCIe/PCI子系統、內存管理或文件系統)的內部知識了解很少或完全不了解。 + +問題在於:Linux內核缺少一個,可以簡單地將問題歸檔並讓需要了解它的開發人員了 +解它的,中心化缺陷跟蹤器。這就是爲什麼你必須找到正確的途徑來自己報告問題。 +您可以在腳本的幫助下做到這一點(見下文),但它主要針對的是內核開發人員和專 +家。對於其他人來說,MAINTAINERS(維護人員)文件是更好的選擇。 + +如何閱讀MAINTAINERS維護者文件 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +爲了說明如何使用 :ref:`MAINTAINERS ` 文件,讓我們假設您的筆記 +本電腦中的WiFi在更新內核後突然出現了錯誤行爲。這種情況下可能是WiFi驅動的問 +題。顯然,它也可能由於驅動基於的某些代碼,但除非你懷疑有這樣的東西會附著在 +驅動程序上。如果真的是其他的問題,驅動程序的開發人員會讓合適的人參與進來。 + +遺憾的是,沒有通用且簡單的辦法來檢查哪個代碼驅動了特定硬體組件。 + +在WiFi驅動出現問題的情況下,你可能想查看 ``lspci -k`` 的輸出,因爲它列出了 +PCI/PCIe總線上的設備和驅動它的內核模塊:: + + [user@something ~]$ lspci -k + [...] + 3a:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32) + Subsystem: Bigfoot Networks, Inc. Device 1535 + Kernel driver in use: ath10k_pci + Kernel modules: ath10k_pci + [...] + +但如果你的WiFi晶片通過USB或其他內部總線連接,這種方法就行不通了。在這種情況 +下,您可能需要檢查您的WiFi管理器或 ``ip link`` 的輸出。尋找有問題的網絡接口 +的名稱,它可能類似於「wlp58s0」。此名稱可以用來找到驅動它的模塊:: + + [user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module + ath10k_pci + +如果這些技巧不能進一步幫助您,請嘗試在網上搜索如何縮小相關驅動程序或子系統 +的範圍。如果你不確定是哪一個:試著猜一下,即使你猜得不好,也會有人會幫助你 +的。 + +一旦您知道了相應的驅動程序或子系統,您就希望在MAINTAINERS文件中搜索它。如果 +是「ath10k_pci」,您不會找到任何東西,因爲名稱太具體了。有時你需要在網上尋找 +幫助;但在此之前,請嘗試使用一個稍短或修改過的名稱來搜索MAINTAINERS文件,因 +爲這樣你可能會發現類似這樣的東西:: + + QUALCOMM ATHEROS ATH10K WIRELESS DRIVER + Mail: A. Some Human + Mailing list: ath10k@lists.infradead.org + Status: Supported + Web-page: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k + SCM: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git + Files: drivers/net/wireless/ath/ath10k/ + +注意:如果您閱讀在Linux原始碼樹的根目錄中找到的原始維護者文件,則行描述將是 +縮寫。例如,「Mail:(郵件)」將是「M:」,「Mailing list:(郵件列表)」將是「L」, +「Status:(狀態)」將是「S:」。此文件頂部有一段解釋了這些和其他縮寫。 + +首先查看「Status」狀態行。理想情況下,它應該得到「Supported(支持)」或 +「Maintained(維護)」。如果狀態爲「Obsolete(過時的)」,那麼你在使用一些過時的 +方法,需要轉換到新的解決方案上。有時候,只有在感到有動力時,才會有人爲代碼 +提供「Odd Fixes」。如果碰見「Orphan」,你就完全不走運了,因爲再也沒有人關心代碼 +了,只剩下這些選項:準備好與問題共存,自己修復它,或者找一個願意修復它的程式設計師。 + +檢查狀態後,尋找以「bug:」開頭的一行:它將告訴你在哪裡可以找到子系統特定的缺 +陷跟蹤器來提交你的問題。上面的例子沒有此行。大多數部分都是這樣,因爲 Linux +內核的開發完全是由郵件驅動的。很少有子系統使用缺陷跟蹤器,且其中只有一部分 +依賴於 bugzilla.kernel.org。 + +在這種以及其他很多情況下,你必須尋找以「Mail:」開頭的行。這些行提到了特定代碼 +的維護者的名字和電子郵件地址。也可以查找以「Mailing list:」開頭的行,它告訴你 +開發代碼的公共郵件列表。你的報告之後需要通過郵件發到這些地址。另外,對於所有 +通過電子郵件發送的問題報告,一定要抄送 Linux Kernel Mailing List(LKML) +。在以後通過郵件發送問題報告時,不要遺漏任何 +一個郵件列表!維護者都是大忙人,可能會把一些工作留給子系統特定列表上的其他開 +發者;而 LKML 很重要,因爲需要一個可以找到所有問題報告的地方。 + + +藉助腳本找到維護者 +~~~~~~~~~~~~~~~~~~~~ + +對於手頭有Linux源碼的人來說,有第二個可以找到合適的報告地點的選擇:腳本 +「scripts/get_maintainer.pl」,它嘗試找到所有要聯繫的人。它會查詢MAINTAINERS +文件,並需要用相關原始碼的路徑來調用。對於編譯成模塊的驅動程序,經常可以用 +這樣的命令找到:: + + $ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!' + drivers/net/wireless/ath/ath10k/ath10k_pci.ko + +將其中的部分內容傳遞給腳本:: + + $ ./scripts/get_maintainer.pl -f drivers/net/wireless/ath/ath10k* + Some Human (supporter:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER) + Another S. Human (maintainer:NETWORKING DRIVERS) + ath10k@lists.infradead.org (open list:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER) + linux-wireless@vger.kernel.org (open list:NETWORKING DRIVERS (WIRELESS)) + netdev@vger.kernel.org (open list:NETWORKING DRIVERS) + linux-kernel@vger.kernel.org (open list) + +不要把你的報告發給所有的人。發送給維護者,腳本稱之爲「supporter:」;另外抄送 +代碼最相關的郵件列表,以及 Linux 內核郵件列表(LKML)。在此例中,你需要將報 +告發送給 「Some Human 」 ,並抄送 +「ath10k@lists.infradead.org」和「linux-kernel@vger.kernel.org」。 + +注意:如果你用 git 克隆了 Linux 原始碼,你可能需要用--git 再次調用 +get_maintainer.pl。腳本會查看提交歷史,以找到最近哪些人參與了相關代碼的編寫, +因爲他們可能會提供幫助。但要小心使用這些結果,因爲它很容易讓你誤入歧途。 +例如,這種情況常常會發生在很少被修改的地方(比如老舊的或未維護的驅動程序): +有時這樣的代碼會在樹級清理期間被根本不關心此驅動程序的開發者修改。 + + +搜索現有報告(第二部分) +-------------------------- + + *在缺陷追蹤器或問題相關郵件列表的存檔中徹底搜索可能與您的問題匹配的報告。 + 如果找到匹配的報告,請加入討論而不是發送新報告。* + +如前所述:報告一個別人已經提出的問題,對每個人來說都是浪費時間,尤其是作爲報告 +人的你。這就是爲什麼你應該再次搜索現有的報告。現在你已經知道問題需要報告到哪裡。 +如果是郵件列表,那麼一般在 `lore.kernel.org `_ 可以 +找到相應存檔。 + +但有些列表運行在其他地方。例如前面步驟中當例子的ath10k WiFi驅動程序就是這種 +情況。但是你通常可以在網上很容易地找到這些列表的檔案。例如搜索「archive +ath10k@lists.infradead.org」,將引導您到ath10k郵件列表的信息頁,該頁面頂部連結 +到其 `列表存檔 `_ 。遺憾的是, +這個列表和其他一些列表缺乏搜索其存檔的功能。在這種情況下可以使用常規的網際網路 +搜尋引擎,並添加類似「site:lists.infadead.org/pipermail/ath10k/」這 +樣的搜索條件,這會把結果限制在該連結中的檔案。 + +也請進一步搜索網絡、LKML和bugzilla.kernel.org網站。 + +有關如何搜索以及在找到匹配報告時如何操作的詳細信息,請參閱上面的「搜索現有報告 +(第一部分)」。 + +不要急著完成報告過程的這一步:花30到60分鐘甚至更多的時間可以爲你和其他人節省 / +減少相當多的時間和麻煩。 + + +安裝一個新的內核進行測試 +-------------------------- + + *除非您已經在運行最新的「主線」Linux內核,否則最好在報告流程前安裝它。在 + 某些情況下,使用最新的「穩定版」Linux進行測試和報告也是可以接受的替代方案; + 在合併窗口期間,這實際上可能是最好的方法,但在開發階段最好還是暫停幾天。 + 無論你選擇什麼版本,最好使用「普通」構建。忽略這些建議會大大增加您的報告 + 被拒絕或忽略的風險。* + +正如第一步的詳細解釋中所提到的:與大多數程式設計師一樣,與大多數程式設計師一樣,Linux +內核開發人員不喜歡花時間處理他們維護的原始碼中根本不會發生的問題的報告。這隻 +會浪費每個人的時間,尤其是你的時間。這就是爲什麼在報告問題之前,您必須先確認 +問題仍然存在於最新的上游代碼中,這符合每個人的利益。您可以忽略此建議,但如前 +所述:這樣做會極大地增加問題報告被拒絕或被忽略的風險。 + +內核「最新上游」的範圍通常指: + + * 安裝一個主線內核;最新的穩定版內核也可以是一個選擇,但大多數時候都最好避免。 + 長期支持內核(有時稱爲「LTS內核」)不適合此流程。下一小節將更詳細地解釋所有 + 這些。 + + * 下一小節描述獲取和安裝這樣一個內核的方法。它還指出了使用預編譯內核是可以的, + 但普通的內核更好,這意味著:它是直接使用從 `kernel.org `_ + 獲得的Linux原始碼構建並且沒有任何方式修改或增強。 + + +選擇適合測試的版本 +~~~~~~~~~~~~~~~~~~~~ + +前往 `kernel.org `_ 來決定使用哪個版本。忽略那個寫著 +「Latest release最新版本」的巨大黃色按鈕,往下看有一個表格。在表格的頂部,你會 +看到一行以「mainline」開頭的字樣,大多數情況下它會指向一個版本號類似「5.8-rc2」 +的預發布版本。如果是這樣的話,你將需要使用這個主線內核進行測試。不要讓「rc」 +嚇到你,這些「開發版內核」實際上非常可靠——而且你已經按照上面的指示做了備份, +不是嗎? + +大概每九到十周,「mainline」可能會給你指出一個版本號類似「5.7」的正式版本。如果 +碰見這種情況,請考慮暫停報告過程,直到下一個版本的第一個預發布(5.8-rc1)出 +現在 `kernel.org `_ 上。這是因爲 Linux 的開發周期正在 +兩周的「合併窗口」內。大部分的改動和所有干擾性的改動都會在這段時間內被合併到 +下一個版本中。在此期間使用主線是比較危險的。內核開發者通常也很忙,可能沒有 +多餘的時間來處理問題報告。這也是很有可能在合併窗口中應用了許多修改來修復你 +所面臨的問題;這就是爲什麼你很快就得用一個新的內核版本重新測試,就像下面「發 +布報告後的責任」一節中所述的那樣。 + +這就是爲什麼要等到合併窗口結束後才去做。但是如果你處理的是一些不應該等待的 +東西,則無需這樣做。在這種情況下,可以考慮通過 git 獲取最新的主線內核(見下 +文),或者使用 kernel.org 上提供的最新穩定版本。如果 mainline 因爲某些原因 +不無法正常工作,那麼使用它也是可以接受的。總的來說:用它來重現問題也比完全 +不報告問題要好。 + +最好避免在合併窗口外使用最新的穩定版內核,因爲所有修復都必須首先應用於主線。 +這就是爲什麼檢查最新的主線內核是如此重要:你希望看到在舊版本線修復的任何問題 +需要先在主線修復,然後才能得到回傳,這可能需要幾天或幾周。另一個原因是:您 +希望的修復對於回傳來說可能太難或太冒險;因此再次報告問題不太可能改變任何事情。 + +這些方面也部分表明了爲什麼長期支持內核(有時稱爲「LTS內核」)不適合報告流程: +它們與當前代碼的距離太遠。因此,先去測試主線,然後再按流程走:如果主線沒有 +出現問題,流程將指導您如何在舊版本線中修復它。 + +如何獲得新的 Linux 內核 +~~~~~~~~~~~~~~~~~~~~~~~~~ + +你可以使用預編譯或自編譯的內核進行測試;如果你選擇後者,可以使用 git 獲取源 +代碼,或者下載其 tar 存檔包。 + +**使用預編譯的內核** :這往往是最快速、最簡單、最安全的方法——尤其是在你不熟 +悉 Linux 內核的情況下。問題是:發行商或附加存儲庫提供的大多數版本都是從修改 +過的Linux原始碼構建的。因此它們不是普通的,通常不適合於測試和問題報告:這些 +更改可能會導致您面臨的問題或以某種方式影響問題。 + +但是如果您使用的是流行的Linux發行版,那麼您就很幸運了:對於大部分的發行版, +您可以在網上找到包含最新主線或穩定版本Linux內核包的存儲庫。使用這些是完全可 +以的,只要從存儲庫的描述中確認它們是普通的或者至少接近普通。此外,請確保軟體 +包包含kernel.org上提供的最新版本內核。如果這些軟體包的時間超過一周,那麼它們 +可能就不合適了,因爲新的主線和穩定版內核通常至少每周發布一次。 + +請注意,您以後可能需要手動構建自己的內核:有時這是調試或測試修復程序所必需的, +如後文所述。還要注意,預編譯的內核可能缺少在出現panic、Oops、warning或BUG時 +解碼內核列印的消息所需的調試符號;如果您計劃解碼這些消息,最好自己編譯內核 +(有關詳細信息,請參閱本小節結尾和「解碼失敗信息」小節)。 + +**使用git** :熟悉 git 的開發者和有經驗的 Linux 用戶通常最好直接從 +`kernel.org 上的官方開發倉庫 +`_ +中獲取最新的 Linux 內核原始碼。這些很可能比最新的主線預發布版本更新一些。不 +用擔心:它們和正式的預發布版本一樣可靠,除非內核的開發周期目前正處於合併窗 +口中。不過即便如此,它們也是相當可靠的。 + +**常規方法** :不熟悉 git 的人通常最好從 `kernel.org `_ +下載源碼的tar 存檔包。 + +如何實際構建一個內核並不在這裡描述,因爲許多網站已經解釋了必要的步驟。如果 +你是新手,可以考慮按照那些建議使用 ``make localmodconfig`` 來做,它將嘗試獲 +取你當前內核的配置,然後根據你的系統進行一些調整。這樣做並不能使編譯出來的 +內核更好,但可以更快地編譯。 + +注意:如果您正在處理來自內核的pannc、Oops、warning或BUG,請在配置內核時嘗試 +啓用 CONFIG_KALLSYMS 選項。此外,還可以啓用 CONFIG_DEBUG_KERNEL 和 +CONFIG_DEBUG_INFO;後者是相關選項,但只有啓用前者才能開啓。請注意, +CONFIG_DEBUG_INFO 會需要更多儲存空間來構建內核。但這是值得的,因爲這些選項將 +允許您稍後精確定位觸發問題的確切代碼行。下面的「解碼失敗信息」一節對此進行了更 +詳細的解釋。 + +但請記住:始終記錄遇到的問題,以防難以重現。發送未解碼的報告總比不報告要好。 + + +檢查「汙染」標誌 +---------------- + + *確保您剛剛安裝的內核在運行時不會「汙染」自己。* + +正如上面已經詳細介紹過的:當發生一些可能會導致一些看起來完全不相關的後續錯 +誤的事情時,內核會設置一個「汙染」標誌。這就是爲什麼你需要檢查你剛剛安裝的內 +核是否有設置此標誌。如果有的話,幾乎在任何情況下你都需要在報告問題之前先消 +除它。詳細的操作方法請看上面的章節。 + + +用新內核重現問題 +------------------ + + *在您剛剛安裝的內核中復現這個問題。如果它沒有出現,請查看下方只發生在 + 穩定版和長期支持內核的問題的說明。* + +檢查這個問題是否發生在你剛剛安裝的新 Linux 內核版本上。如果新內核已經修復了, +可以考慮使用此版本線,放棄報告問題。但是請記住,只要它沒有在 `kernel.org +`_ 的穩定版和長期版(以及由這些版本衍生出來的廠商內核) +中得到修復,其他用戶可能仍然會受到它的困擾。如果你喜歡使用其中的一個,或 +者只是想幫助它們的用戶,請前往下面的「報告只發生在較舊內核版本線的問題」一節。 + + +優化復現問題的描述 +-------------------- + + *優化你的筆記:試著找到並寫出最直接的復現問題的方法。確保最終結果包含所 + 有重要的細節,同時讓第一次聽說的人容易閱讀和理解。如果您在此過程中學到 + 了一些東西,請考慮再次搜索關於該問題的現有報告。* + +過於複雜的報告會讓別人很難理解。因此請儘量找到一個可以直接描述、易於以書面 +形式理解的再現方法。包含所有重要的細節,但同時也要儘量保持簡短。 + +在這在前面的步驟中,你很可能已經了解了一些關於你所面臨的問題的點。利用這些 +知識,再次搜索可以轉而加入的現有報告。 + + +解碼失敗信息 +------------- + + *如果失敗涉及「panic」、「Oops」、「warning」或「BUG」,請考慮解碼內核日誌以查找 + 觸發錯誤的代碼行。* + +當內核檢測到內部問題時,它會記錄一些有關已執行代碼的信息。這使得在原始碼中精 +確定位觸發問題的行並顯示如何調用它成爲可能。但只有在配置內核時啓用了 +CONFIG_DEBUG_INFO 和 CONFIG_KALLSYMS選項時,這種方法才起效。如果已啓用此選項, +請考慮解碼內核日誌中的信息。這將使我們更容易理解是什麼導致了「panic」、「Oops」、 +「warning」或「BUG」,從而增加了有人提供修復的機率。 + +解碼可以通過Linux原始碼樹中的腳本來完成。如果您運行的內核是之前自己編譯的, +這樣這樣調用它:: + + [user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh ./linux-5.10.5/vmlinux + /usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/ + +如果您運行的是打包好的普通內核,則可能需要安裝帶有調試符號的相應包。然後按以下 +方式調用腳本(如果發行版未打包,則可能需要從Linux原始碼獲取):: + + [user@something ~]$ sudo dmesg | ./linux-5.10.5/scripts/decode_stacktrace.sh \ + /usr/lib/debug/lib/modules/5.10.10-4.1.x86_64/vmlinux /usr/src/kernels/5.10.10-4.1.x86_64/ + +腳本將解碼如下的日誌行,這些日誌行顯示內核在發生錯誤時正在執行的代碼的地址:: + + [ 68.387301] RIP: 0010:test_module_init+0x5/0xffa [test_module] + +解碼之後,這些行將變成這樣:: + + [ 68.387301] RIP: 0010:test_module_init (/home/username/linux-5.10.5/test-module/test-module.c:16) test_module + +在本例中,執行的代碼是從文件「~/linux-5.10.5/test-module/test-module.c」構建的, +錯誤出現在第16行的指令中。 + +該腳本也會如此解碼以「Call trace」開頭的部分中提到的地址,該部分顯示出現問題的 +函數的路徑。此外,腳本還會顯示內核正在執行的代碼部分的彙編輸出。 + +注意,如果你沒法做到這一點,只需跳過這一步,並在報告中說明原因。如果你幸運的 +話,可能無需解碼。如果需要的話,也許有人會幫你做這件事情。還要注意,這只是解 +碼內核堆棧跟蹤的幾種方法之一。有時需要採取不同的步驟來檢索相關的詳細信息。 +別擔心,如果您碰到的情況需要這樣做,開發人員會告訴您該怎麼做。 + + +對回歸的特別關照 +----------------- + + *如果您的問題是回歸問題,請儘可能縮小引入問題時的範圍。* + +Linux 首席開發者 Linus Torvalds 認爲 Linux 內核永遠不應惡化,這就是爲什麼他 +認爲回歸是不可接受的,並希望看到它們被迅速修復。這就是爲什麼引入了回歸的改 +動導致的問題若無法通過其他方式快速解決,通常會被迅速撤銷。因此,報告回歸有 +點像「王炸」,會迅速得到修復。但要做到這一點,需要知道導致回歸的變化。通常情 +況下,要由報告者來追查罪魁禍首,因爲維護者往往沒有時間或手頭設置不便來自行 +重現它。 + +有一個叫做「二分」的過程可以來尋找變化,這在 +「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」文檔中進行了詳細 +的描述,這個過程通常需要你構建十到二十個內核鏡像,每次都嘗試在構建下一個鏡像 +之前重現問題。是的,這需要花費一些時間,但不用擔心,它比大多數人想像的要快得多。 +多虧了「binary search二進位搜索」,這將引導你在原始碼管理系統中找到導致回歸的提交。 +一旦你找到它,就在網上搜索其主題、提交ID和縮短的提交ID(提交ID的前12個字符)。 +如果有的話,這將引導您找到關於它的現有報告。 + +需要注意的是,二分法需要一點竅門,不是每個人都懂得訣竅,也需要相當多的努力, +不是每個人都願意投入。儘管如此,還是強烈建議自己進行一次二分。如果你真的 +不能或者不想走這條路,至少要找出是哪個主線內核引入的回歸。比如說從 5.5.15 +切換到 5.8.4 的時候出現了一些問題,那麼至少可以嘗試一下相近的所有的主線版本 +(5.6、5.7 和 5.8)來檢查它是什麼時候出現的。除非你想在一個穩定版或長期支持 +內核中找到一個回歸,否則要避免測試那些編號有三段的版本(5.6.12、5.7.8),因 +爲那會使結果難以解釋,可能會讓你的測試變得無用。一旦你找到了引入回歸的主要 +版本,就可以放心地繼續報告了。但請記住:在不知道罪魁禍首的情況下,開發人員 +是否能夠提供幫助取決於手頭的問題。有時他們可能會從報告中確認是什麼出現了問 +題,並能修復它;有時他們可能無法提供幫助,除非你進行二分。 + +當處理回歸問題時,請確保你所面臨的問題真的是由內核引起的,而不是由其他東西 +引起的,如上文所述。 + +在整個過程中,請記住:只有當舊內核和新內核的配置相似時,問題才算回歸。最好 +的方法是:把配置文件(``.config``)從舊的工作內核直接複製到你嘗試的每個新內 +核版本。之後運行 ``make oldnoconfig`` 來調整它以適應新版本的需要,而不啓用 +任何新的功能,因爲那些功能也可能導致回歸。 + + +撰寫並發送報告 +--------------- + + *通過詳細描述問題來開始編寫報告。記得包括以下條目:您爲復現而安裝的最新 + 內核版本、使用的Linux發行版以及關於如何復現該問題的說明。如果可能,將內 + 核構建配置(.config)和 ``dmesg`` 的輸出放在網上的某個地方,並連結到它。 + 包含或上傳所有其他可能相關的信息,如Oops的輸出/截圖或來自 ``lspci`` + 的輸出。一旦你寫完了這個主要部分,請在上方插入一個正常長度的段落快速概 + 述問題和影響。再在此之上添加一個簡單描述問題的句子,以得到人們的閱讀。 + 現在給出一個更短的描述性標題或主題。然後就可以像MAINTAINERS文件告訴你的 + 那樣發送或提交報告了,除非你在處理一個「高優先級問題」:它們需要按照下面 + 「高優先級問題的特殊處理」所述特別關照。* + +現在你已經準備好了一切,是時候寫你的報告了。上文前言中連結的三篇文檔對如何 +寫報告做了部分解釋。這就是爲什麼本文將只提到一些基本的內容以及 Linux 內核特 +有的東西。 + +有一點是符合這兩類的:你的報告中最關鍵的部分是標題/主題、第一句話和第一段。 +開發者經常會收到許多郵件。因此,他們往往只是花幾秒鐘的時間瀏覽一下郵件,然 +後再決定繼續下一封或仔細查看。因此,你報告的開頭越好,有人研究並幫助你的機 +會就越大。這就是爲什麼你應該暫時忽略他們,先寫出詳細的報告。;-) + +每份報告都應提及的事項 +~~~~~~~~~~~~~~~~~~~~~~~~ + +詳細描述你的問題是如何發生在你安裝的新純淨內核上的。試著包含你之前寫的和優 +化過的分步說明,概述你和其他人如何重現這個問題;在極少數無法重現的情況下, +儘量描述你做了什麼來觸發它。 + +還應包括其他人爲了解該問題及其環境而可能需要的所有相關信息。實際需要的東西 +在很大程度上取決於具體問題,但有些事項你總是應該包括在內: + + * ``cat /proc/version`` 的輸出,其中包含 Linux 內核版本號和構建時的編譯器。 + + * 機器正在運行的 Linux 發行版( ``hostnamectl | grep 「Operating System「`` ) + + * CPU 和作業系統的架構( ``uname -mi`` ) + + * 如果您正在處理回歸,並進行了二分,請提及導致回歸的變更的主題和提交ID。 + +許多情況下,讓讀你報告的人多了解兩件事也是明智之舉: + + * 用於構建 Linux 內核的配置(「.config」文件) + + * 內核的信息,你從 ``dmesg`` 得到的信息寫到一個文件里。確保它以像「Linux + version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version + 2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020」這樣的行開始,如果沒有,那麼第 + 一次啓動階段的重要信息已經被丟棄了。在這種情況下,可以考慮使用 + ``journalctl -b 0 -k`` ;或者你也可以重啓,重現這個問題,然後調用 + ``dmesg`` 。 + +這兩個文件很大,所以直接把它們放到你的報告中是個壞主意。如果你是在缺陷跟蹤 +器中提交問題,那麼將它們附加到工單中。如果你通過郵件報告問題,不要用附件附 +上它們,因爲那會使郵件變得太大,可以按下列之一做: + + * 將文件上傳到某個公開的地方(你的網站,公共文件粘貼服務,在 + `bugzilla.kernel.org `_ 上創建的工單……), + 並在你的報告中放上連結。理想情況下請使用允許這些文件保存很多年的地方,因 + 爲它們可能在很多年後對別人有用;例如 5 年或 10 年後,一個開發者正在修改 + 一些代碼,而這些代碼正是爲了修復你的問題。 + + * 把文件放在一邊,然後說明你會在他人回復時再單獨發送。只要記得報告發出去後, + 真正做到這一點就可以了。;-) + +提供這些東西可能是明智的 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +根據問題的不同,你可能需要提供更多的背景數據。這裡有一些關於提供什麼比較好 +的建議: + + * 如果你處理的是內核的「warning」、「OOPS」或「panic」,請包含它。如果你不能複製 + 粘貼它,試著用netconsole網絡終端遠程跟蹤或者至少拍一張屏幕的照片。 + + * 如果問題可能與你的電腦硬體有關,請說明你使用的是什麼系統。例如,如果你的 + 顯卡有問題,請提及它的製造商,顯卡的型號,以及使用的晶片。如果是筆記本電 + 腦,請提及它的型號名稱,但儘量確保意義明確。例如「戴爾 XPS 13」就不很明確, + 因爲它可能是 2012 年的那款,那款除了看起來和現在銷售的沒有什麼不同之外, + 兩者沒有任何共同之處。因此,在這種情況下,要加上準確的型號,例如 2019 + 年內推出的 XPS 13 型號爲「9380」或「7390」。像「聯想 Thinkpad T590」這樣的名字 + 也有些含糊不清:這款筆記本有帶獨立顯卡和不帶的子型號,所以要儘量找到準確 + 的型號名稱或註明主要部件。 + + * 說明正在使用的相關軟體。如果你在加載模塊時遇到了問題,你要說明正在使用的 + kmod、systemd 和 udev 的版本。如果其中一個 DRM 驅動出現問題,你要說明 + libdrm 和 Mesa 的版本;還要說明你的 Wayland 合成器或 X-Server 及其驅動。 + 如果你有文件系統問題,請註明相應的文件系統實用程序的版本(e2fsprogs, + btrfs-progs, xfsprogs……)。 + + * 從內核中收集可能有用的額外信息。例如, ``lspci -nn`` 的輸出可以幫助別人 + 識別你使用的硬體。如果你的硬體有問題,你甚至可以給出 ``sudo lspci -vvv`` + 的結果,因爲它提供了組件是如何配置的信息。對於一些問題,可能最好包含 + ``/proc/cpuinfo`` , ``/proc/ioports`` , ``/proc/iomem`` , + ``/proc/modules`` 或 ``/proc/scsi/scsi`` 等文件的內容。一些子系統還提 + 供了收集相關信息的工具。 ``alsa-info.sh`` `就是這樣一個工具,它是音頻/聲 + 音子系統開發者提供的 `_ 。 + +這些例子應該會給你一些知識點,讓你知道附上什麼數據可能是明智的,但你自己也 +要想一想,哪些數據對別人會有幫助。不要太擔心忘記一些東西,因爲開發人員會要 +求提供他們需要的額外細節。但從一開始就把所有重要的東西都提供出來,會增加別 +人仔細查看的機會。 + + +重要部分:報告的開頭 +~~~~~~~~~~~~~~~~~~~~~~ + +現在你已經準備好了報告的詳細部分,讓我們進入最重要的部分:開頭幾句。現在到 +報告的最前面,在你剛才寫的部分之前加上類似「The detailed description:」(詳細 +描述)這樣的內容,並在最前面插入兩個新行。現在寫一個正常長度的段落,大致概 +述這個問題。去掉所有枯燥的細節,把重點放在讀者需要知道的關鍵部分,以讓人了 +解這是怎麼回事;如果你認爲這個缺陷影響了很多用戶,就提一下這點來吸引大家關 +注。 + +做好這一點後,在頂部再插入兩行,寫一句話的摘要,快速解釋報告的內容。之後你 +要更加抽象,爲報告寫一個更短的主題/標題。 + +現在你已經寫好了這部分,請花點時間來優化它,因爲它是你的報告中最重要的部分: +很多人會先讀這部分,然後才會決定是否值得花時間閱讀其他部分。 + +現在就像 :ref:`MAINTAINERS ` 維護者文件告訴你的那樣發送或提交 +報告,除非它是前面概述的那些「高優先級問題」之一:在這種情況下,請先閱讀下一 +小節,然後再發送報告。 + +高優先級問題的特殊處理 +~~~~~~~~~~~~~~~~~~~~~~~~ + +高優先級問題的報告需要特殊處理。 + +**非常嚴重的缺陷** :確保在主題或工單標題以及第一段中明顯標出 severeness +(非常嚴重的)。 + +**回歸** :如果問題是一個回歸,請在郵件的主題或缺陷跟蹤器的標題中添加 +[REGRESSION]。如果您沒有進行二分,請至少註明您測試的最新主線版本(比如 5.7) +和出現問題的最新版本(比如 5.8)。如果您成功地進行了二分,請註明導致回歸 +的提交ID和主題。也請添加該變更的作者到你的報告中;如果您需要將您的缺陷提交 +到缺陷跟蹤器中,請將報告以私人郵件的形式轉發給他,並註明報告提交地點。 + +**安全問題** :對於這種問題,你將必須評估:如果細節被公開披露,是否會對其他 +用戶產生短期風險。如果不會,只需按照所述繼續報告問題。如果有此風險,你需要 +稍微調整一下報告流程。 + + * 如果 MAINTAINERS 文件指示您通過郵件報告問題,請不要抄送任何公共郵件列表。 + + * 如果你應該在缺陷跟蹤器中提交問題,請確保將工單標記爲「私有」或「安全問題」。 + 如果缺陷跟蹤器沒有提供保持報告私密性的方法,那就別想了,把你的報告以私人 + 郵件的形式發送給維護者吧。 + +在這兩種情況下,都一定要將報告發到 MAINTAINERS 文件中「安全聯絡」部分列出的 +地址。理想的情況是在發送報告的時候直接抄送他們。如果您在缺陷跟蹤器中提交了 +報告,請將報告的文本轉發到這些地址;但請在報告的頂部加上注釋,表明您提交了 +報告,並附上工單連結。 + +更多信息請參見「Documentation/translations/zh_TW/admin-guide/security-bugs.rst」。 + + +發布報告後的責任 +------------------ + + *等待別人的反應,繼續推進事情,直到你能夠接受這樣或那樣的結果。因此,請 + 公開和及時地回應任何詢問。測試提出的修復。積極地測試:至少重新測試每個 + 新主線版本的首個候選版本(RC),並報告你的結果。如果出現拖延,就友好地 + 提醒一下。如果你沒有得到任何幫助或者未能滿意,請試著自己幫助自己。* + +如果你的報告非常優秀,而且你真的很幸運,那麼某個開發者可能會立即發現導致問 +題的原因;然後他們可能會寫一個補丁來修復、測試它,並直接發送給主線集成,同 +時標記它以便以後回溯到需要它的穩定版和長期支持內核。那麼你需要做的就是回復 +一句「Thank you very much」(非常感謝),然後在發布後換上修復好的版本。 + +但這種理想狀況很少發生。這就是爲什麼你把報告拿出來之後工作才開始。你要做的 +事情要視情況而定,但通常會是下面列出的事情。但在深入研究細節之前,這裡有幾 +件重要的事情,你需要記住這部分的過程。 + + +關於進一步互動的一般建議 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**總是公開回復** :當你在缺陷跟蹤器中提交問題時,一定要在那裡回復,不要私下 +聯繫任何開發者。對於郵件報告,在回復您收到的任何郵件時,總是使用「全部回復」 +功能。這包括帶有任何你可能想要添加到你的報告中的額外數據的郵件:進入郵件應 +用程序「已發送」文件夾,並在郵件上使用「全部回復」來回復報告。這種方法可以確保 +公共郵件列表和其他所有參與者都能及時了解情況;它還能保持郵件線程的完整性, +這對於郵件列表將所有相關郵件歸爲一類是非常重要的。 + +只有兩種情況不適合在缺陷跟蹤器或「全部回復」中發表評論: + + * 有人讓你私下發東西。 + + * 你被告知要發送一些東西,但注意到其中包含需要保密的敏感信息。在這種情況下, + 可以私下發送給要求發送的開發者。但要在工單或郵件中註明你是這麼做的,這 + 樣其他人就知道你尊重了這個要求。 + +**在請求解釋或幫助之前先研究一下** :在這部分過程中,有人可能會告訴你用尚未 +掌握的技能做一些事情。例如你可能會被要求使用一些你從未聽說過的測試工具;或 +者你可能會被要求在 Linux 內核原始碼上應用一個補丁來測試它是否有幫助。在某些 +情況下,發個回復詢問如何做就可以了。但在走這條路之前,儘量通過在網際網路上搜 +索自行找到答案;或者考慮在其他地方詢問建議。比如詢問朋友,或者到你平時常去 +的聊天室或論壇發帖諮詢。 + +**要有耐心** :如果你真的很幸運,你可能會在幾個小時內收到對你的報告的答覆。 +但大多數情況下會花費更多的時間,因爲維護者分散在全球各地,因此可能在不同的 +時區——在那裡他們已經享受著遠離鍵盤的夜晚。 + +一般來說,內核開發者需要一到五個工作日來回復報告。有時會花費更長的時間,因 +爲他們可能正忙於合併窗口、其他工作、參加開發者會議,或者只是在享受一個漫長 +的暑假。 + +「高優先級的問題」(見上面的解釋)例外:維護者應該儘快解決這些問題;這就是爲 +什麼你應該最多等待一個星期(如果是緊急的事情,則只需兩天),然後再發送友好 +的提醒。 + +有時維護者可能沒有及時回復;有時候可能會出現分歧,例如一個問題是否符合回歸 +的條件。在這種情況下,在郵件列表上提出你的顧慮,並請求其他人公開或私下回復 +如何繼續推進。如果失敗了,可能應該讓更高級別的維護者介入。如果是 WiFi 驅動, +那就是無線維護者;如果沒有更高級別的維護者,或者其他一切努力都失敗了,那 +這可能是一種罕見的、可以讓 Linus Torvalds 參與進來的情況。 + +**主動測試** :每當一個新的主線內核版本的第一個預發布版本(rc1)發布的時候, +去檢查一下這個問題是否得到了解決,或者是否有什麼重要的變化。在工單中或在 +回復報告的郵件中提及結果(確保所有參與討論的人都被抄送)。這將表明你的承諾 +和你願意幫忙。如果問題持續存在,它也會提醒開發者確保他們不會忘記它。其他一 +些不定期的重新測試(例如用rc3、rc5 和最終版本)也是一個好主意,但只有在相關 +的東西發生變化或者你正在寫什麼東西的時候才報告你的結果。 + +這些些常規的事情就不說了,我們來談談報告後如何幫助解決問題的細節。 + +查詢和測試請求 +~~~~~~~~~~~~~~~ + +如果你的報告得到了回復則需履行以下責任: + +**檢查與你打交道的人** :大多數情況下,會是維護者或特定代碼區域的開發人員對 +你的報告做出回應。但由於問題通常是公開報告的,所以回復的可能是任何人——包括 +那些想要幫忙的人,但最後可能會用他們的問題或請求引導你完全偏離軌道。這很少 +發生,但這是快速上網搜搜看你正在與誰互動是明智之舉的許多原因之一。通過這樣 +做,你也可以知道你的報告是否被正確的人聽到,因爲如果討論沒有導致滿意的問題 +解決方案而淡出,之後可能需要提醒維護者(見下文)。 + +**查詢數據** :通常你會被要求測試一些東西或提供更多細節。儘快提供所要求的信 +息,因爲你已經得到了可能會幫助你的人的注意,你等待的時間越長就有越可能失去 +關注;如果你不在數個工作日內提供信息,甚至可能出現這種結果。 + +**測試請求** :當你被要求測試一個診斷補丁或可能的修復時,也要儘量及時測試。 +但要做得恰當,一定不要急於求成:混淆事情很容易發生,這會給所有人帶來許多困 +惑。例如一個常見的錯誤是以爲應用了一個帶修復的建議補丁,但事實上並沒有。即 +使是有經驗的測試人員也會偶爾發生這樣的事情,但當有修復的內核和沒有修復的內 +核表現得一樣時,他們大多時候會注意到。 + +當沒有任何實質性進展時該怎麼辦 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +有些報告不會得到負有相關責任的 Linux 內核開發者的任何反應;或者圍繞這個問題 +的討論有所發展,但漸漸淡出,沒有任何實質內容產出。 + +在這種情況下,要等兩個星期(最好是三個星期)後再發出友好的提醒:也許當你的 +報告到達時,維護者剛剛離開鍵盤一段時間,或者有更重要的事情要處理。在寫提醒 +信的時候,要善意地問一下,是否還需要你這邊提供什麼來讓事情推進下去。如果報 +告是通過郵件發出來的,那就在郵件的第一行回覆你的初始郵件(見上文),其中包 +括下方的原始報告的完整引用:這是少數幾種情況下,這樣的「TOFU」(Text Over, +Fullquote Under文字在上,完整引用在下)是正確的做法,因爲這樣所有的收件人都 +會以適當的順序立即讓細節到手頭上來。 + +在提醒之後,再等三周的回覆。如果你仍然沒有得到適當的反饋,你首先應該重新考 +慮你的方法。你是否可能嘗試接觸了錯誤的人?是不是報告也許令人反感或者太混亂, +以至於人們決定完全遠離它?排除這些因素的最好方法是:把報告給一兩個熟悉 +FLOSS 問題報告的人看,詢問他們的意見。同時徵求他們關於如何繼續推進的建議。 +這可能意味著:準備一份更好的報告,讓這些人在你發出去之前對它進行審查。這樣 +的方法完全可以;只需說明這是關於這個問題的第二份改進的報告,並附上第一份報 +告的連結。 + +如果報告是恰當的,你可以發送第二封提醒信;在其中詢問爲什麼報告沒有得到任何 +回復。第二封提醒郵件的好時機是在新 Linux 內核版本的首個預發布版本('rc1') +發布後不久,因爲無論如何你都應該在那個時候重新測試並提供狀態更新(見上文)。 + +如果第二次提醒的結果又在一周內沒有任何反應,可以嘗試聯繫上級維護者詢問意見: +即使再忙的維護者在這時候也至少應該發過某種確認。 + +記住要做好失望的準備:理想狀況下維護者最好對每一個問題報告做出回應,但他們 +只有義務解決之前列出的「高優先級問題」。所以,如果你得到的回覆是「謝謝你的報告, +我目前有更重要的問題要處理,在可預見的未來沒有時間去研究這個問題」,那請不 +要太沮喪。 + +也有可能在缺陷跟蹤器或列表中進行了一些討論之後,什麼都沒有發生,提醒也無助 +於激勵大家進行修復。這種情況可能是毀滅性的,但在 Linux 內核開發中確實會發生。 +這些和其他得不到幫助的原因在本文結尾處的「爲什麼有些問題在被報告後沒有得到 +任何回應或者仍然沒有修復」中進行了解釋。 + +如果你沒有得到任何幫助或問題最終沒有得到解決,不要沮喪:Linux 內核是 FLOSS, +因此你仍然可以自己幫助自己。例如,你可以試著找到其他受影響的人,和他們一 +起合作來解決這個問題。這樣的團隊可以一起準備一份新的報告,提到團隊有多少人, +爲什麼你們認爲這是應該得到解決的事情。也許你們還可以一起縮小確切原因或引 +入回歸的變化,這往往會使修復更容易。而且如果運氣好的話,團隊中可能會有懂點 +編程的人,也許能寫出一個修複方案。 + + + +「報告穩定版和長期支持內核線的回歸」的參考 +------------------------------------------ + +本小節提供了在穩定版和長期支持內核線中面對回歸時需要執行的步驟的詳細信息。 + +確保特定版本線仍然受支持 +~~~~~~~~~~~~~~~~~~~~~~~~~ + + *檢查內核開發人員是否仍然維護你關心的Linux內核版本線:去 kernel.org 的 + 首頁,確保此特定版本線的最新版沒有「[EOL]」標記。* + +大多數內核版本線只支持三個月左右,因爲延長維護時間會帶來相當多的工作。因此, +每年只會選擇一個版本來支持至少兩年(通常是六年)。這就是爲什麼你需要檢查 +內核開發者是否還支持你關心的版本線。 + +注意,如果 `kernel.org `_ 在首頁上列出了兩個「穩定」版本, +你應該考慮切換到較新的版本,而忘掉較舊的版本:對它的支持可能很快就會結束。 +然後,它將被標記爲「生命周期結束」(EOL)。達到這個程度的版本線仍然會在 +`kernel.org `_ 首頁上被顯示一兩周,但不適合用於測試和 +報告。 + +搜索穩定版郵件列表 +~~~~~~~~~~~~~~~~~~~ + + *檢查Linux穩定版郵件列表中的現有報告。* + +也許你所面臨的問題已經被發現,並且已經或即將被修復。因此,請在 `Linux 穩定 +版郵件列表的檔案 `_ 中搜索類似問題的報告。 +如果你找到任何匹配的問題,可以考慮加入討論,除非修復工作已經完成並計劃很快 +得到應用。 + +用最新版本復現問題 +~~~~~~~~~~~~~~~~~~~ + + *從特定的版本線安裝最新版本作爲純淨內核。確保這個內核沒有被汙染,並且仍 + 然存在問題,因爲問題可能已經在那裡被修復了。* + +在投入更多時間到這個過程中之前,你要檢查這個問題是否在你關注的版本線的最新 +版本中已經得到了修復。這個內核需要是純淨的,在問題發生之前不應該被汙染,正 +如上面已經在測試主線的過程中詳細介紹過的一樣。 + +您是否是第一次注意到供應商內核的回歸?供應商的更改可能會發生變化。你需要重新 +檢查排除來這個問題。當您從5.10.4-vendor.42更新到5.10.5-vendor.43時,記錄損壞 +的信息。然後在測試了前一段中所述的最新5.10版本之後,檢查Linux 5.10.4的普通版本 +是否也可以正常工作。如果問題在那裡出現,那就不符合上游回歸的條件,您需要切換 +回主逐步指南來報告問題。 + +報告回歸 +~~~~~~~~~~ + + *向Linux穩定版郵件列表發送一個簡短的問題報告(stable@vger.kernel.org)。 + 大致描述問題,並解釋如何復現。講清楚首個出現問題的版本和最後一個工作正常 + 的版本。然後等待進一步的指示。* + +當報告在穩定版或長期支持內核線內發生的回歸(例如在從5.10.4更新到5.10.5時), +一份簡短的報告足以快速報告問題。因此只需要粗略的描述。 + +但是請注意,如果您能夠指明引入問題的確切版本,這將對開發人員有很大幫助。因此 +如果有時間的話,請嘗試使用普通內核找到該版本。讓我們假設發行版發布Linux內核 +5.10.5到5.10.8的更新時發生了故障。那麼按照上面的指示,去檢查該版本線中的最新 +內核,比如5.10.9。如果問題出現,請嘗試普通5.10.5,以確保供應商應用的補丁不會 +干擾。如果問題沒有出現,那麼嘗試5.10.7,然後直到5.10.8或5.10.6(取決於結果) +找到第一個引入問題的版本。在報告中寫明這一點,並指出5.10.9仍然存在故障。 + +前一段基本粗略地概述了「二分」方法。一旦報告出來,您可能會被要求做一個正確的 +報告,因爲它允許精確地定位導致問題的確切更改(然後很容易被恢復以快速修復問題)。 +因此如果時間允許,考慮立即進行適當的二分。有關如何詳細信息,請參閱「對回歸的 +特別關照」部分和文檔「Documentation/translations/zh_TW/admin-guide/bug-bisect.rst」。 + + +「報告僅在舊內核版本線中發生的問題」的參考 +------------------------------------------ + +本節詳細介紹了如果無法用主線內核重現問題,但希望在舊版本線(又稱穩定版內核和 +長期支持內核)中修復問題時需要採取的步驟。 + +有些修復太複雜 +~~~~~~~~~~~~~~~ + + *請做好準備,接下來的幾個步驟可能無法在舊版本中解決問題:修復可能太大或 + 太冒險,無法移植到那裡。* + +即使是微小的、看似明顯的代碼變化,有時也會帶來新的、完全意想不到的問題。穩 +定版和長期支持內核的維護者非常清楚這一點,因此他們只對這些內核進行符合 +「Documentation/translations/zh_TW/process/stable-kernel-rules.rst」中所列出的 +規則的修改。 + +複雜或有風險的修改不符合條件,因此只能應用於主線。其他的修復很容易被回溯到 +最新的穩定版和長期支持內核,但是風險太大,無法集成到舊版內核中。所以要注意 +你所希望的修復可能是那些不會被回溯到你所關心的版本線的修復之一。在這種情況 +下,你將別無選擇,要麼忍受這個問題,要麼切換到一個較新的 Linux 版本,除非你 +想自己把修復補丁應用到你的內核中。 + +通用準備 +~~~~~~~~~~ + + *執行上面「報告僅在舊內核版本線中發生的問題」一節中的前三個步驟。* + +您需要執行本指南另一節中已經描述的幾個步驟。這些步驟將讓您: + + * 檢查內核開發人員是否仍然維護您關心的Linux內核版本行。 + + * 在Linux穩定郵件列表中搜索退出的報告。 + + * 檢查最新版本。 + + +檢查代碼歷史和搜索現有的討論 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + *在Linux內核版本控制系統中搜索修復主線問題的更改,因爲它的提交消息可能 + 會告訴你修復是否已經計劃好了支持。如果你沒有找到,搜索適當的郵件列表, + 尋找討論此類問題或同行評議可能修復的帖子;然後檢查討論是否認爲修復不適 + 合支持。如果支持根本不被考慮,加入最新的討論,詢問是否有可能。* + +在許多情況下,你所處理的問題會發生在主線上,但已在主線上得到了解決。修正它 +的提交也需要被回溯才能解決這個問題。這就是爲什麼你要搜索它或任何相關討論。 + + * 首先嘗試在存放 Linux 內核原始碼的 Git 倉庫中找到修復。你可以通過 + `kernel.org 上的網頁 + `_ + 或 `GitHub 上的鏡像 `_ 來實現;如果你 + 有一個本地克隆,你也可以在命令行用 ``git log --grep=`` 來搜索。 + + 如果你找到了修復,請查看提交消息的尾部是否包含了類似這樣的「穩定版標籤」: + + Cc: # 5.4+ + + 像上面這行,開發者標記了安全修復可以回傳到 5.4 及以後的版本。大多數情況 + 下,它會在兩周內被應用到那裡,但有時需要更長的時間。 + + * 如果提交沒有告訴你任何東西,或者你找不到修復,請再找找關於這個問題的討論。 + 用你最喜歡的搜尋引擎搜索網絡,以及 `Linux kernel developers mailing + list 內核開發者郵件列表 `_ 的檔案。也可以 + 閱讀上面的 `定位導致問題的內核區域` 一節,然後按照說明找到導致問題的子系 + 統:它的缺陷跟蹤器或郵件列表存檔中可能有你要找的答案。 + + * 如果你看到了一個計劃的修復,請按上所述在版本控制系統中搜索它,因爲提交可 + 能會告訴你是否可以進行回溯。 + + * 檢查討論中是否有任何跡象表明,該修復程序可能風險太大,無法回溯到你關心 + 的版本線。如果是這樣的話,你必須忍受這個問題,或者切換到應用了修復的內 + 核版本線。 + + * 如果修復的問題未包含穩定版標籤,並且沒有討論過回溯問題,請加入討論:如 + 果合適的話,請提及你所面對的問題的版本,以及你希望看到它被修復。 + + +請求建議 +~~~~~~~~~ + + *前面的步驟之一應該會給出一個解決方案。如果仍未能成功,請向可能引起問題 + 的子系統的維護人員詢問建議;抄送特定子系統的郵件列表以及穩定版郵件列表。* + +如果前面的三個步驟都沒有讓你更接近解決方案,那麼只剩下一個選擇:請求建議。 +在你發給可能是問題根源的子系統的維護者的郵件中這樣做;抄送子系統的郵件列表 +以及穩定版郵件列表(stable@vger.kernel.org)。 + + +爲什麼有些問題在報告後沒有任何回應或仍未解決? +=============================================== + +當向 Linux 開發者報告問題時,要注意只有「高優先級的問題」(回歸、安全問題、嚴 +重問題)才一定會得到解決。如果維護者或其他人都失敗了,Linus Torvalds 他自己 +會確保這一點。他們和其他內核開發者也會解決很多其他問題。但是要知道,有時他 +們也會不能或不願幫忙;有時甚至沒有人發報告給他們。 + +最好的解釋就是那些內核開發者常常是在業餘時間爲 Linux 內核做出貢獻。內核中的 +不少驅動程序都是由這樣的程式設計師編寫的,往往只是因爲他們想讓自己的硬體可以在 +自己喜歡的作業系統上使用。 + +這些程式設計師大多數時候會很樂意修復別人報告的問題。但是沒有人可以強迫他們這樣 +做,因爲他們是自願貢獻的。 + +還有一些情況下,這些開發者真的很想解決一個問題,但卻不能解決:有時他們缺乏 +硬體編程文檔來解決問題。這種情況往往由於公開的文檔太簡陋,或者驅動程序是通 +過逆向工程編寫的。 + +業餘開發者遲早也會不再關心某驅動。也許他們的測試硬體壞了,被更高級的玩意取 +代了,或者是太老了以至於只能在計算機博物館裡找到。有時開發者根本就不關心他 +們的代碼和 Linux 了,因爲在他們的生活中一些不同的東西變得更重要了。在某些情 +況下,沒有人願意接手維護者的工作——也沒有人可以被強迫,因爲對 Linux 內核的貢 +獻是自願的。然而被遺棄的驅動程序仍然存在於內核中:它們對人們仍然有用,刪除 +它們可能導致回歸。 + +對於那些爲 Linux 內核工作而獲得報酬的開發者來說,情況並沒有什麼不同。這些人 +現在貢獻了大部分的變更。但是他們的僱主遲早也會停止關注他們的代碼或者讓程序 +員專注於其他事情。例如,硬體廠商主要通過銷售新硬體來賺錢;因此,他們中的不 +少人並沒有投入太多時間和精力來維護他們多年前就停止銷售的東西的 Linux 內核驅 +動。企業級 Linux 發行商往往持續維護的時間比較長,但在新版本中往往會把對老舊 +和稀有硬體的支持放在一邊,以限制範圍。一旦公司拋棄了一些代碼,往往由業餘貢 +獻者接手,但正如上面提到的:他們遲早也會放下代碼。 + +優先級是一些問題沒有被修復的另一個原因,因爲維護者相當多的時候是被迫設置這 +些優先級的,因爲在 Linux 上工作的時間是有限的。對於業餘時間或者僱主給予他們 +的開發人員用於上游內核維護工作的時間也是如此。有時維護人員也會被報告淹沒, +即使一個驅動程序幾乎完美地工作。爲了不被完全纏住,程式設計師可能別無選擇,只能 +對問題報告進行優先級排序而拒絕其中的一些報告。 + +不過這些都不用太過擔心,很多驅動都有積極的維護者,他們對儘可能多的解決問題 +相當感興趣。 + + +結束語 +======= + +與其他免費/自由&開源軟體(Free/Libre & Open Source Software,FLOSS)相比, +向 Linux 內核開發者報告問題是很難的:這個文檔的長度和複雜性以及字裡行間的內 +涵都說明了這一點。但目前就是這樣了。這篇文字的主要作者希望通過記錄現狀來爲 +以後改善這種狀況打下一些基礎。 + diff --git a/Documentation/translations/zh_TW/admin-guide/security-bugs.rst b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst new file mode 100644 index 000000000000..eed260ef0c37 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/security-bugs.rst @@ -0,0 +1,78 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/security-bugs` + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +安全缺陷 +========= + +Linux內核開發人員非常重視安全性。因此我們想知道何時發現了安全漏洞,以便儘快 +修復和披露。請向Linux內核安全團隊報告安全漏洞。 + +聯絡 +----- + +可以通過電子郵件聯繫Linux內核安全團隊。這是一個安全人員 +的私有列表,他們將幫助驗證錯誤報告並開發和發布修復程序。如果您已經有了一個 +修復,請將其包含在您的報告中,這樣可以大大加快進程。安全團隊可能會從區域維護 +人員那裡獲得額外的幫助,以理解和修復安全漏洞。 + +與任何缺陷一樣,提供的信息越多,診斷和修復就越容易。如果您不清楚哪些信息有用, +請查看「Documentation/translations/zh_TW/admin-guide/reporting-issues.rst」中 +概述的步驟。任何利用漏洞的攻擊代碼都非常有用,未經報告者同意不會對外發布,除 +非已經公開。 + +請儘可能發送無附件的純文本電子郵件。如果所有的細節都藏在附件里,那麼就很難對 +一個複雜的問題進行上下文引用的討論。把它想像成一個 +:doc:`常規的補丁提交 <../process/submitting-patches>` (即使你還沒有補丁): +描述問題和影響,列出復現步驟,然後給出一個建議的解決方案,所有這些都是純文本的。 + +披露和限制信息 +--------------- + +安全列表不是公開渠道。爲此,請參見下面的協作。 + +一旦開發出了健壯的補丁,發布過程就開始了。對公開的缺陷的修復會立即發布。 + +儘管我們傾向於在未公開缺陷的修復可用時即發布補丁,但應報告者或受影響方的請求, +這可能會被推遲到發布過程開始後的7日內,如果根據缺陷的嚴重性需要更多的時間, +則可額外延長到14天。推遲發布修復的唯一有效原因是爲了適應QA的邏輯和需要發布 +協調的大規模部署。 + +雖然可能與受信任的個人共享受限信息以開發修復,但未經報告者許可,此類信息不會 +與修復程序一起發布或發布在任何其他披露渠道上。這包括但不限於原始錯誤報告和 +後續討論(如有)、漏洞、CVE信息或報告者的身份。 + +換句話說,我們唯一感興趣的是修復缺陷。提交給安全列表的所有其他資料以及對報告 +的任何後續討論,即使在解除限制之後,也將永久保密。 + +協調 +------ + +對敏感缺陷(例如那些可能導致權限提升的缺陷)的修復可能需要與私有郵件列表 +進行協調,以便分發供應商做好準備,在公開披露 +上游補丁時發布一個已修復的內核。發行版將需要一些時間來測試建議的補丁,通常 +會要求至少幾天的限制,而供應商更新發布更傾向於周二至周四。若合適,安全團隊 +可以協助這種協調,或者報告者可以從一開始就包括linux發行版。在這種情況下,請 +記住在電子郵件主題行前面加上「[vs]」,如linux發行版wiki中所述: +。 + +CVE分配 +-------- + +安全團隊通常不分配CVE,我們也不需要它們來進行報告或修復,因爲這會使過程不必 +要的複雜化,並可能耽誤缺陷處理。如果報告者希望在公開披露之前分配一個CVE編號, +他們需要聯繫上述的私有linux-distros列表。當在提供補丁之前已有這樣的CVE編號時, +如報告者願意,最好在提交消息中提及它。 + +保密協議 +--------- + +Linux內核安全團隊不是一個正式的機構實體,因此無法簽訂任何保密協議。 + diff --git a/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst new file mode 100644 index 000000000000..d7b3c4276417 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/tainted-kernels.rst @@ -0,0 +1,161 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :doc:`../../../admin-guide/tainted-kernels` + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +受汙染的內核 +------------- + +當發生一些在稍後調查問題時可能相關的事件時,內核會將自己標記爲「受汙染 +(tainted)」的。不用太過擔心,大多數情況下運行受汙染的內核沒有問題;這些信息 +主要在有人想調查某個問題時才有意義的,因爲問題的真正原因可能是導致內核受汙染 +的事件。這就是爲什麼來自受汙染內核的缺陷報告常常被開發人員忽略,因此請嘗試用 +未受汙染的內核重現問題。 + +請注意,即使在您消除導致汙染的原因(亦即卸載專有內核模塊)之後,內核仍將保持 +汙染狀態,以表示內核仍然不可信。這也是爲什麼內核在注意到內部問題(「kernel +bug」)、可恢復錯誤(「kernel oops」)或不可恢復錯誤(「kernel panic」)時會列印 +受汙染狀態,並將有關此的調試信息寫入日誌 ``dmesg`` 輸出。也可以通過 +``/proc/`` 中的文件在運行時檢查受汙染的狀態。 + + +BUG、Oops或Panics消息中的汙染標誌 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +在頂部以「CPU:」開頭的一行中可以找到受汙染的狀態;內核是否受到汙染和原因會顯示 +在進程ID(「PID:」)和觸發事件命令的縮寫名稱(「Comm:」)之後:: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + Oops: 0002 [#1] SMP PTI + CPU: 0 PID: 4424 Comm: insmod Tainted: P W O 4.20.0-0.rc6.fc30 #1 + Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 + RIP: 0010:my_oops_init+0x13/0x1000 [kpanic] + [...] + +如果內核在事件發生時沒有被汙染,您將在那裡看到「Not-tainted:」;如果被汙染,那 +麼它將是「Tainted:」以及字母或空格。在上面的例子中,它看起來是這樣的:: + + Tainted: P W O + +下表解釋了這些字符的含義。在本例中,由於加載了專有模塊( ``P`` ),出現了 +警告( ``W`` ),並且加載了外部構建的模塊( ``O`` ),所以內核早些時候受到 +了汙染。要解碼其他字符,請使用下表。 + + +解碼運行時的汙染狀態 +~~~~~~~~~~~~~~~~~~~~~ + +在運行時,您可以通過讀取 ``cat /proc/sys/kernel/tainted`` 來查詢受汙染狀態。 +如果返回 ``0`` ,則內核沒有受到汙染;任何其他數字都表示受到汙染的原因。解碼 +這個數字的最簡單方法是使用腳本 ``tools/debugging/kernel-chktaint`` ,您的 +發行版可能會將其作爲名爲 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分提 +供;如果沒有,您可以從 +`git.kernel.org `_ +網站下載此腳本並用 ``sh kernel-chktaint`` 執行,它會在上面引用的日誌中有類似 +語句的機器上列印這樣的內容:: + + Kernel is Tainted for following reasons: + * Proprietary module was loaded (#0) + * Kernel issued warning (#9) + * Externally-built ('out-of-tree') module was loaded (#12) + See Documentation/admin-guide/tainted-kernels.rst in the Linux kernel or + https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html for + a more details explanation of the various taint flags. + Raw taint value as int/string: 4609/'P W O ' + +你也可以試著自己解碼這個數字。如果內核被汙染的原因只有一個,那麼這很簡單, +在本例中您可以通過下表找到數字。如果你需要解碼有多個原因的數字,因爲它是一 +個位域(bitfield),其中每個位表示一個特定類型的汙染的存在或不存在,最好讓 +前面提到的腳本來處理。但是如果您需要快速看一下,可以使用這個shell命令來檢查 +設置了哪些位:: + + $ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done + +汙染狀態代碼表 +~~~~~~~~~~~~~~~ + +=== ===== ====== ======================================================== + 位 日誌 數字 內核被汙染的原因 +=== ===== ====== ======================================================== + 0 G/P 1 已加載專用模塊 + 1 _/F 2 模塊被強制加載 + 2 _/S 4 內核運行在不合規範的系統上 + 3 _/R 8 模塊被強制卸載 + 4 _/M 16 處理器報告了機器檢測異常(MCE) + 5 _/B 32 引用了錯誤的頁或某些意外的頁標誌 + 6 _/U 64 用戶空間應用程式請求的汙染 + 7 _/D 128 內核最近死機了,即曾出現OOPS或BUG + 8 _/A 256 ACPI表被用戶覆蓋 + 9 _/W 512 內核發出警告 + 10 _/C 1024 已加載staging驅動程序 + 11 _/I 2048 已應用平台固件缺陷的解決方案 + 12 _/O 4096 已加載外部構建(「樹外」)模塊 + 13 _/E 8192 已加載未簽名的模塊 + 14 _/L 16384 發生軟鎖定 + 15 _/K 32768 內核已實時打補丁 + 16 _/X 65536 備用汙染,爲發行版定義並使用 + 17 _/T 131072 內核是用結構隨機化插件構建的 +=== ===== ====== ======================================================== + +註:字符 ``_`` 表示空白,以便於閱讀表。 + +汙染的更詳細解釋 +~~~~~~~~~~~~~~~~~ + + 0) ``G`` 加載的所有模塊都有GPL或兼容許可證, ``P`` 加載了任何專有模塊。 + 沒有MODULE_LICENSE(模塊許可證)或MODULE_LICENSE未被insmod認可爲GPL + 兼容的模塊被認爲是專有的。 + + + 1) ``F`` 任何模塊被 ``insmod -f`` 強制加載, ``' '`` 所有模塊正常加載。 + + 2) ``S`` 內核運行在不合規範的處理器或系統上:硬體已運行在不受支持的配置中, + 因此無法保證正確執行。內核將被汙染,例如: + + - 在x86上:PAE是通過intel CPU(如Pentium M)上的forcepae強制執行的,這些 + CPU不報告PAE,但可能有功能實現,SMP內核在非官方支持的SMP Athlon CPU上 + 運行,MSR被暴露到用戶空間中。 + - 在arm上:在某些CPU(如Keystone 2)上運行的內核,沒有啓用某些內核特性。 + - 在arm64上:CPU之間存在不匹配的硬體特性,引導加載程序以不同的模式引導CPU。 + - 某些驅動程序正在被用在不受支持的體系結構上(例如x86_64以外的其他系統 + 上的scsi/snic,非x86/x86_64/itanium上的scsi/ips,已經損壞了arm64上 + irqchip/irq-gic的固件設置…)。 + + 3) ``R`` 模塊被 ``rmmod -f`` 強制卸載, ``' '`` 所有模塊都正常卸載。 + + 4) ``M`` 任何處理器報告了機器檢測異常, ``' '`` 未發生機器檢測異常。 + + 5) ``B`` 頁面釋放函數發現錯誤的頁面引用或某些意外的頁面標誌。這表示硬體問題 + 或內核錯誤;日誌中應該有其他信息指示發生此汙染的原因。 + + 6) ``U`` 用戶或用戶應用程式特意請求設置受汙染標誌,否則應爲 ``' '`` 。 + + 7) ``D`` 內核最近死機了,即出現了OOPS或BUG。 + + 8) ``A`` ACPI表被重寫。 + + 9) ``W`` 內核之前已發出過警告(儘管有些警告可能會設置更具體的汙染標誌)。 + + 10) ``C`` 已加載staging驅動程序。 + + 11) ``I`` 內核正在處理平台固件(BIOS或類似軟體)中的嚴重錯誤。 + + 12) ``O`` 已加載外部構建(「樹外」)模塊。 + + 13) ``E`` 在支持模塊簽名的內核中加載了未簽名的模塊。 + + 14) ``L`` 系統上先前發生過軟鎖定。 + + 15) ``K`` 內核已經實時打了補丁。 + + 16) ``X`` 備用汙染,由Linux發行版定義和使用。 + + 17) ``T`` 內核構建時使用了randstruct插件,它可以有意生成非常不尋常的內核結構 + 布局(甚至是性能病態的布局),這在調試時非常有用。於構建時設置。 + diff --git a/Documentation/translations/zh_TW/admin-guide/unicode.rst b/Documentation/translations/zh_TW/admin-guide/unicode.rst new file mode 100644 index 000000000000..720875be5ef8 --- /dev/null +++ b/Documentation/translations/zh_TW/admin-guide/unicode.rst @@ -0,0 +1,174 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: Documentation/admin-guide/unicode.rst + +:譯者: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +Unicode(統一碼)支持 +====================== + + (英文版)上次更新:2005-01-17,版本號 1.4 + +此文檔由H. Peter Anvin 管理,是Linux註冊名稱與編號管理局 +(Linux Assigned Names And Numbers Authority,LANANA)項目的一部分。 +現行版本請見: + + http://www.lanana.org/docs/unicode/admin-guide/unicode.rst + +簡介 +----- + +Linux內核代碼已被重寫以使用Unicode來將字符映射到字體。下載一個Unicode到字體 +(Unicode-to-font)表,八位字符集與UTF-8模式都將改用此字體來顯示。 + +這微妙地改變了八位字符表的語義。現在的四個字符表是: + +=============== =============================== ================ +映射代號 映射名稱 Escape代碼 (G0) +=============== =============================== ================ +LAT1_MAP Latin-1 (ISO 8859-1) ESC ( B +GRAF_MAP DEC VT100 pseudographics ESC ( 0 +IBMPC_MAP IBM code page 437 ESC ( U +USER_MAP User defined ESC ( K +=============== =============================== ================ + +特別是 ESC ( U 不再是「直通字體」,因爲字體可能與IBM字符集完全不同。 +例如,即使加載了一個Latin-1字體,也允許使用塊圖形(block graphics)。 + +請注意,儘管這些代碼與ISO 2022類似,但這些代碼及其用途都與ISO 2022不匹配; +Linux有兩個八位代碼(G0和G1),而ISO 2022有四個七位代碼(G0-G3)。 + +根據Unicode標準/ISO 10646,U+F000到U+F8FF被保留用於作業系統範圍內的分配 +(Unicode標準將其稱爲「團體區域(Corporate Zone)」,因爲這對於Linux是不準確 +的,所以我們稱之爲「Linux區域」)。選擇U+F000作爲起點,因爲它允許直接映射 +區域以2的大倍數開始(以防需要1024或2048個字符的字體)。這就留下U+E000到 +U+EFFF作爲最終用戶區。 + +[v1.2]:Unicodes範圍從U+F000到U+F7FF已經被硬編碼爲直接映射到加載的字體, +繞過了翻譯表。用戶定義的映射現在默認爲U+F000到U+F0FF,模擬前述行爲。實際上, +此範圍可能較短;例如,vgacon只能處理256字符(U+F000..U+F0FF)或512字符 +(U+F000..U+F1FF)字體。 + +Linux 區域中定義的實際字符 +--------------------------- + +此外,還定義了Unicode 1.1.4中不存在的以下字符;這些字符由DEC VT圖形映射使用。 +[v1.2]此用法已過時,不應再使用;請參見下文。 + +====== ====================================== +U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1 +U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3 +U+F803 DEC VT GRAPHICS HORIZONTAL LINE SCAN 7 +U+F804 DEC VT GRAPHICS HORIZONTAL LINE SCAN 9 +====== ====================================== + +DEC VT220使用6x10字符矩陣,這些字符在DEC VT圖形字符集中形成一個平滑的過渡。 +我省略了掃描5行,因爲它也被用作塊圖形字符,因此被編碼爲U+2500 FORMS LIGHT +HORIZONTAL。 + +[v1.3]:這些字符已正式添加到Unicode 3.2.0中;它們在U+23BA、U+23BB、U+23BC、 +U+23BD處添加。Linux現在使用新值。 + +[v1.2]:添加了以下字符來表示常見的鍵盤符號,這些符號不太可能被添加到Unicode +中,因爲它們非常討厭地取決於特定供應商。當然,這是糟糕設計的一個好例子。 + +====== ====================================== +U+F810 KEYBOARD SYMBOL FLYING FLAG +U+F811 KEYBOARD SYMBOL PULLDOWN MENU +U+F812 KEYBOARD SYMBOL OPEN APPLE +U+F813 KEYBOARD SYMBOL SOLID APPLE +====== ====================================== + +克林貢(Klingon)語支持 +------------------------ + +1996年,Linux是世界上第一個添加對人工語言克林貢支持的作業系統,克林貢是由 +Marc Okrand爲《星際迷航》電視連續劇創造的。這種編碼後來被徵募Unicode註冊表 +(ConScript Unicode Registry,CSUR)採用,並建議(但最終被拒絕)納入Unicode +平面一。不過,它仍然是Linux區域中的Linux/CSUR私有分配。 + +這種編碼已經得到克林貢語言研究所(Klingon Language Institute)的認可。 +有關更多信息,請聯繫他們: + + http://www.kli.org/ + +由於Linux CZ開頭部分的字符大多是dingbats/symbols/forms類型,而且這是一種 +語言,因此根據標準Unicode慣例,我將它放置在16單元的邊界上。 + +.. note:: + + 這個範圍現在由徵募Unicode註冊表正式管理。規範性引用文件爲: + + https://www.evertype.com/standards/csur/klingon.html + +克林貢語有一個26個字符的字母表,一個10位數的位置數字書寫系統,從左到右 +,從上到下書寫。 + +克林貢字母的幾種字形已經被提出。但是由於這組符號看起來始終是一致的,只有實際 +的形狀不同,因此按照標準Unicode慣例,這些差異被認爲是字體變體。 + +====== ======================================================= +U+F8D0 KLINGON LETTER A +U+F8D1 KLINGON LETTER B +U+F8D2 KLINGON LETTER CH +U+F8D3 KLINGON LETTER D +U+F8D4 KLINGON LETTER E +U+F8D5 KLINGON LETTER GH +U+F8D6 KLINGON LETTER H +U+F8D7 KLINGON LETTER I +U+F8D8 KLINGON LETTER J +U+F8D9 KLINGON LETTER L +U+F8DA KLINGON LETTER M +U+F8DB KLINGON LETTER N +U+F8DC KLINGON LETTER NG +U+F8DD KLINGON LETTER O +U+F8DE KLINGON LETTER P +U+F8DF KLINGON LETTER Q + - Written in standard Okrand Latin transliteration +U+F8E0 KLINGON LETTER QH + - Written in standard Okrand Latin transliteration +U+F8E1 KLINGON LETTER R +U+F8E2 KLINGON LETTER S +U+F8E3 KLINGON LETTER T +U+F8E4 KLINGON LETTER TLH +U+F8E5 KLINGON LETTER U +U+F8E6 KLINGON LETTER V +U+F8E7 KLINGON LETTER W +U+F8E8 KLINGON LETTER Y +U+F8E9 KLINGON LETTER GLOTTAL STOP + +U+F8F0 KLINGON DIGIT ZERO +U+F8F1 KLINGON DIGIT ONE +U+F8F2 KLINGON DIGIT TWO +U+F8F3 KLINGON DIGIT THREE +U+F8F4 KLINGON DIGIT FOUR +U+F8F5 KLINGON DIGIT FIVE +U+F8F6 KLINGON DIGIT SIX +U+F8F7 KLINGON DIGIT SEVEN +U+F8F8 KLINGON DIGIT EIGHT +U+F8F9 KLINGON DIGIT NINE + +U+F8FD KLINGON COMMA +U+F8FE KLINGON FULL STOP +U+F8FF KLINGON SYMBOL FOR EMPIRE +====== ======================================================= + +其他虛構和人工字母 +------------------- + +自從分配了克林貢Linux Unicode塊之後,John Cowan +和 Michael Everson 建立了一個虛構和人工字母的註冊表。 +徵募Unicode註冊表請訪問: + + https://www.evertype.com/standards/csur/ + +所使用的範圍位於最終用戶區域的低端,因此無法進行規範化分配,但建議希望對虛構 +字母進行編碼的人員使用這些代碼,以實現互操作性。對於克林貢語,CSUR採用了Linux +編碼。CSUR的人正在推動將Tengwar和Cirth添加到Unicode平面一;將克林貢添加到 +Unicode平面一被拒絕,因此上述編碼仍然是官方的。 + diff --git a/Documentation/translations/zh_TW/disclaimer-zh_TW.rst b/Documentation/translations/zh_TW/disclaimer-zh_TW.rst new file mode 100644 index 000000000000..f4cf87d03dc5 --- /dev/null +++ b/Documentation/translations/zh_TW/disclaimer-zh_TW.rst @@ -0,0 +1,11 @@ +:orphan: + +.. warning:: + 此文件的目的是爲讓中文讀者更容易閱讀和理解,而不是作爲一個分支。因此, + 如果您對此文件有任何意見或改動,請先嘗試更新原始英文文件。如果要更改或 + 修正某處翻譯文件,請將意見或補丁發送給維護者(聯繫方式見下)。 + +.. note:: + 如果您發現本文檔與原始文件有任何不同或者有翻譯問題,請聯繫該文件的譯者, + 或者發送電子郵件給胡皓文以獲取幫助:。 + diff --git a/Documentation/translations/zh_TW/gpio.txt b/Documentation/translations/zh_TW/gpio.txt new file mode 100644 index 000000000000..e3c076dd75a5 --- /dev/null +++ b/Documentation/translations/zh_TW/gpio.txt @@ -0,0 +1,651 @@ +Chinese translated version of Documentation/admin-guide/gpio + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Maintainer: Grant Likely + Linus Walleij +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/admin-guide/gpio 的繁體中文翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +英文版維護者: Grant Likely + Linus Walleij +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen +繁體中文版校譯者: 胡皓文 Hu Haowen + +以下爲正文 +--------------------------------------------------------------------- +GPIO 接口 + +本文檔提供了一個在Linux下訪問GPIO的公約概述。 + +這些函數以 gpio_* 作爲前綴。其他的函數不允許使用這樣的前綴或相關的 +__gpio_* 前綴。 + + +什麼是GPIO? +========== +"通用輸入/輸出口"(GPIO)是一個靈活的由軟體控制的數位訊號。他們可 +由多種晶片提供,且對於從事嵌入式和定製硬體的 Linux 開發者來說是 +比較熟悉。每個GPIO 都代表一個連接到特定引腳或球柵陣列(BGA)封裝中 +「球珠」的一個位。電路板原理圖顯示了 GPIO 與外部硬體的連接關係。 +驅動可以編寫成通用代碼,以使板級啓動代碼可傳遞引腳配置數據給驅動。 + +片上系統 (SOC) 處理器對 GPIO 有很大的依賴。在某些情況下,每個 +非專用引腳都可配置爲 GPIO,且大多數晶片都最少有一些 GPIO。 +可編程邏輯器件(類似 FPGA) 可以方便地提供 GPIO。像電源管理和 +音頻編解碼器這樣的多功能晶片經常留有一些這樣的引腳來幫助那些引腳 +匱乏的 SOC。同時還有通過 I2C 或 SPI 串行總線連接的「GPIO擴展器」 +晶片。大多數 PC 的南橋有一些擁有 GPIO 能力的引腳 (只有BIOS +固件才知道如何使用他們)。 + +GPIO 的實際功能因系統而異。通常用法有: + + - 輸出值可寫 (高電平=1,低電平=0)。一些晶片也有如何驅動這些值的選項, + 例如只允許輸出一個值、支持「線與」及其他取值類似的模式(值得注意的是 + 「開漏」信號) + + - 輸入值可讀(1、0)。一些晶片支持引腳在配置爲「輸出」時回讀,這對於類似 + 「線與」的情況(以支持雙向信號)是非常有用的。GPIO 控制器可能有輸入 + 去毛刺/消抖邏輯,這有時需要軟體控制。 + + - 輸入通常可作爲 IRQ 信號,一般是沿觸發,但有時是電平觸發。這樣的 IRQ + 可能配置爲系統喚醒事件,以將系統從低功耗狀態下喚醒。 + + - 通常一個 GPIO 根據不同產品電路板的需求,可以配置爲輸入或輸出,也有僅 + 支持單向的。 + + - 大部分 GPIO 可以在持有自旋鎖時訪問,但是通常由串行總線擴展的 GPIO + 不允許持有自旋鎖。但某些系統也支持這種類型。 + +對於給定的電路板,每個 GPIO 都用於某個特定的目的,如監控 MMC/SD 卡的 +插入/移除、檢測卡的防寫狀態、驅動 LED、配置收發器、模擬串行總線、 +復位硬體看門狗、感知開關狀態等等。 + + +GPIO 公約 +========= +注意,這個叫做「公約」,因爲這不是強制性的,不遵循這個公約是無傷大雅的, +因爲此時可移植性並不重要。GPIO 常用於板級特定的電路邏輯,甚至可能 +隨著電路板的版本而改變,且不可能在不同走線的電路板上使用。僅有在少數 +功能上才具有可移植性,其他功能是平台特定。這也是由於「膠合」的邏輯造成的。 + +此外,這不需要任何的執行框架,只是一個接口。某個平台可能通過一個簡單地 +訪問晶片寄存器的內聯函數來實現它,其他平台可能通過委託一系列不同的GPIO +控制器的抽象函數來實現它。(有一些可選的代碼能支持這種策略的實現,本文檔 +後面會介紹,但作爲 GPIO 接口的客戶端驅動程序必須與它的實現無關。) + +也就是說,如果在他們的平台上支持這個公約,驅動應儘可能的使用它。同時,平台 +必須在 Kconfig 中選擇 ARCH_REQUIRE_GPIOLIB 或者 ARCH_WANT_OPTIONAL_GPIOLIB +選項。那些調用標準 GPIO 函數的驅動應該在 Kconfig 入口中聲明依賴GENERIC_GPIO。 +當驅動包含文件: + + #include + +則 GPIO 函數是可用,無論是「真實代碼」還是經優化過的語句。如果你遵守 +這個公約,當你的代碼完成後,對其他的開發者來說會更容易看懂和維護。 + +注意,這些操作包含所用平台的 I/O 屏障代碼,驅動無須顯式地調用他們。 + + +標識 GPIO +--------- +GPIO 是通過無符號整型來標識的,範圍是 0 到 MAX_INT。保留「負」數 +用於其他目的,例如標識信號「在這個板子上不可用」或指示錯誤。未接觸底層 +硬體的代碼會忽略這些整數。 + +平台會定義這些整數的用法,且通常使用 #define 來定義 GPIO,這樣 +板級特定的啓動代碼可以直接關聯相應的原理圖。相對來說,驅動應該僅使用 +啓動代碼傳遞過來的 GPIO 編號,使用 platform_data 保存板級特定 +引腳配置數據 (同時還有其他須要的板級特定數據),避免可能出現的問題。 + +例如一個平台使用編號 32-159 來標識 GPIO,而在另一個平台使用編號0-63 +標識一組 GPIO 控制器,64-79標識另一類 GPIO 控制器,且在一個含有 +FPGA 的特定板子上使用 80-95。編號不一定要連續,那些平台中,也可以 +使用編號2000-2063來標識一個 I2C 接口的 GPIO 擴展器中的 GPIO。 + +如果你要初始化一個帶有無效 GPIO 編號的結構體,可以使用一些負編碼 +(如"-EINVAL"),那將使其永遠不會是有效。來測試這樣一個結構體中的編號 +是否關聯一個 GPIO,你可使用以下斷言: + + int gpio_is_valid(int number); + +如果編號不存在,則請求和釋放 GPIO 的函數將拒絕執行相關操作(見下文)。 +其他編號也可能被拒絕,比如一個編號可能存在,但暫時在給定的電路上不可用。 + +一個平台是否支持多個 GPIO 控制器爲平台特定的實現問題,就像是否可以 +在 GPIO 編號空間中有「空洞」和是否可以在運行時添加新的控制器一樣。 +這些問題會影響其他事情,包括相鄰的 GPIO 編號是否存在等。 + +使用 GPIO +--------- +對於一個 GPIO,系統應該做的第一件事情就是通過 gpio_request() +函數分配它,見下文。 + +接下來是設置I/O方向,這通常是在板級啓動代碼中爲所使用的 GPIO 設置 +platform_device 時完成。 + + /* 設置爲輸入或輸出, 返回 0 或負的錯誤代碼 */ + int gpio_direction_input(unsigned gpio); + int gpio_direction_output(unsigned gpio, int value); + +返回值爲零代表成功,否則返回一個負的錯誤代碼。這個返回值需要檢查,因爲 +get/set(獲取/設置)函數調用沒法返回錯誤,且有可能是配置錯誤。通常, +你應該在進程上下文中調用這些函數。然而,對於自旋鎖安全的 GPIO,在板子 +啓動的早期、進程啓動前使用他們也是可以的。 + +對於作爲輸出的 GPIO,爲其提供初始輸出值,對於避免在系統啓動期間出現 +信號毛刺是很有幫助的。 + +爲了與傳統的 GPIO 接口兼容, 在設置一個 GPIO 方向時,如果它還未被申請, +則隱含了申請那個 GPIO 的操作(見下文)。這種兼容性正在從可選的 gpiolib +框架中移除。 + +如果這個 GPIO 編碼不存在,或者特定的 GPIO 不能用於那種模式,則方向 +設置可能失敗。依賴啓動固件來正確地設置方向通常是一個壞主意,因爲它可能 +除了啓動Linux,並沒有做更多的驗證工作。(同理, 板子的啓動代碼可能需要 +將這個復用的引腳設置爲 GPIO,並正確地配置上拉/下拉電阻。) + + +訪問自旋鎖安全的 GPIO +------------------- +大多數 GPIO 控制器可以通過內存讀/寫指令來訪問。這些指令不會休眠,可以 +安全地在硬(非線程)中斷例程和類似的上下文中完成。 + +對於那些用 gpio_cansleep()測試總是返回失敗的 GPIO(見下文),使用 +以下的函數訪問: + + /* GPIO 輸入:返回零或非零 */ + int gpio_get_value(unsigned gpio); + + /* GPIO 輸出 */ + void gpio_set_value(unsigned gpio, int value); + +GPIO值是布爾值,零表示低電平,非零表示高電平。當讀取一個輸出引腳的值時, +返回值應該是引腳上的值。這個值不總是和輸出值相符,因爲存在開漏輸出信號和 +輸出延遲問題。 + +以上的 get/set 函數無錯誤返回值,因爲之前 gpio_direction_*()應已檢查過 +其是否爲「無效GPIO」。此外,還需要注意的是並不是所有平台都可以從輸出引腳 +中讀取數據,對於不能讀取的引腳應總返回零。另外,對那些在原子上下文中無法 +安全訪問的 GPIO (譯者註:因爲訪問可能導致休眠)使用這些函數是不合適的 +(見下文)。 + +在 GPIO 編號(還有輸出、值)爲常數的情況下,鼓勵通過平台特定的實現來優化 +這兩個函數來訪問 GPIO 值。這種情況(讀寫一個硬體寄存器)下只需要幾條指令 +是很正常的,且無須自旋鎖。這種優化函數比起那些在子程序上花費許多指令的 +函數可以使得模擬接口(譯者注:例如 GPIO 模擬 I2C、1-wire 或 SPI)的 +應用(在空間和時間上都)更具效率。 + + +訪問可能休眠的 GPIO +----------------- +某些 GPIO 控制器必須通過基於總線(如 I2C 或 SPI)的消息訪問。讀或寫這些 +GPIO 值的命令需要等待其信息排到隊首才發送命令,再獲得其反饋。期間需要 +休眠,這不能在 IRQ 例程(中斷上下文)中執行。 + +支持此類 GPIO 的平台通過以下函數返回非零值來區分出這種 GPIO。(此函數需要 +一個之前通過 gpio_request 分配到的有效 GPIO 編號): + + int gpio_cansleep(unsigned gpio); + +爲了訪問這種 GPIO,內核定義了一套不同的函數: + + /* GPIO 輸入:返回零或非零 ,可能會休眠 */ + int gpio_get_value_cansleep(unsigned gpio); + + /* GPIO 輸出,可能會休眠 */ + void gpio_set_value_cansleep(unsigned gpio, int value); + + +訪問這樣的 GPIO 需要一個允許休眠的上下文,例如線程 IRQ 處理例程,並用以上的 +訪問函數替換那些沒有 cansleep()後綴的自旋鎖安全訪問函數。 + +除了這些訪問函數可能休眠,且它們操作的 GPIO 不能在硬體 IRQ 處理例程中訪問的 +事實,這些處理例程實際上和自旋鎖安全的函數是一樣的。 + +** 除此之外 ** 調用設置和配置此類 GPIO 的函數也必須在允許休眠的上下文中, +因爲它們可能也需要訪問 GPIO 控制器晶片: (這些設置函數通常在板級啓動代碼或者 +驅動探測/斷開代碼中,所以這是一個容易滿足的約束條件。) + + gpio_direction_input() + gpio_direction_output() + gpio_request() + +## gpio_request_one() +## gpio_request_array() +## gpio_free_array() + + gpio_free() + gpio_set_debounce() + + + +聲明和釋放 GPIO +---------------------------- +爲了有助於捕獲系統配置錯誤,定義了兩個函數。 + + /* 申請 GPIO, 返回 0 或負的錯誤代碼. + * 非空標籤可能有助於診斷. + */ + int gpio_request(unsigned gpio, const char *label); + + /* 釋放之前聲明的 GPIO */ + void gpio_free(unsigned gpio); + +將無效的 GPIO 編碼傳遞給 gpio_request()會導致失敗,申請一個已使用這個 +函數聲明過的 GPIO 也會失敗。gpio_request()的返回值必須檢查。你應該在 +進程上下文中調用這些函數。然而,對於自旋鎖安全的 GPIO,在板子啓動的早期、 +進入進程之前是可以申請的。 + +這個函數完成兩個基本的目標。一是標識那些實際上已作爲 GPIO 使用的信號線, +這樣便於更好地診斷;系統可能需要服務幾百個可用的 GPIO,但是對於任何一個 +給定的電路板通常只有一些被使用。另一個目的是捕獲衝突,查明錯誤:如兩個或 +更多驅動錯誤地認爲他們已經獨占了某個信號線,或是錯誤地認爲移除一個管理著 +某個已激活信號的驅動是安全的。也就是說,申請 GPIO 的作用類似一種鎖機制。 + +某些平台可能也使用 GPIO 作爲電源管理激活信號(例如通過關閉未使用晶片區和 +簡單地關閉未使用時鐘)。 + +對於 GPIO 使用 pinctrl 子系統已知的引腳,子系統應該被告知其使用情況; +一個 gpiolib 驅動的 .request()操作應調用 pinctrl_gpio_request(), +而 gpiolib 驅動的 .free()操作應調用 pinctrl_gpio_free()。pinctrl +子系統允許 pinctrl_gpio_request()在某個引腳或引腳組以復用形式「屬於」 +一個設備時都成功返回。 + +任何須將 GPIO 信號導向適當引腳的引腳復用硬體的編程應該發生在 GPIO +驅動的 .direction_input()或 .direction_output()函數中,以及 +任何輸出 GPIO 值的設置之後。這樣可使從引腳特殊功能到 GPIO 的轉換 +不會在引腳產生毛刺波形。有時當用一個 GPIO 實現其信號驅動一個非 GPIO +硬體模塊的解決方案時,就需要這種機制。 + +某些平台允許部分或所有 GPIO 信號使用不同的引腳。類似的,GPIO 或引腳的 +其他方面也需要配置,如上拉/下拉。平台軟體應該在對這些 GPIO 調用 +gpio_request()前將這類細節配置好,例如使用 pinctrl 子系統的映射表, +使得 GPIO 的用戶無須關注這些細節。 + +還有一個值得注意的是在釋放 GPIO 前,你必須停止使用它。 + + +注意:申請一個 GPIO 並沒有以任何方式配置它,只不過標識那個 GPIO 處於使用 +狀態。必須有另外的代碼來處理引腳配置(如控制 GPIO 使用的引腳、上拉/下拉)。 +考慮到大多數情況下聲明 GPIO 之後就會立即配置它們,所以定義了以下三個輔助函數: + + /* 申請一個 GPIO 信號, 同時通過特定的'flags'初始化配置, + * 其他和 gpio_request()的參數和返回值相同 + * + */ + int gpio_request_one(unsigned gpio, unsigned long flags, const char *label); + + /* 在單個函數中申請多個 GPIO + */ + int gpio_request_array(struct gpio *array, size_t num); + + /* 在單個函數中釋放多個 GPIO + */ + void gpio_free_array(struct gpio *array, size_t num); + +這裡 'flags' 當前定義可指定以下屬性: + + * GPIOF_DIR_IN - 配置方向爲輸入 + * GPIOF_DIR_OUT - 配置方向爲輸出 + + * GPIOF_INIT_LOW - 在作爲輸出時,初始值爲低電平 + * GPIOF_INIT_HIGH - 在作爲輸出時,初始值爲高電平 + * GPIOF_OPEN_DRAIN - gpio引腳爲開漏信號 + * GPIOF_OPEN_SOURCE - gpio引腳爲源極開路信號 + + * GPIOF_EXPORT_DIR_FIXED - 將 gpio 導出到 sysfs,並保持方向 + * GPIOF_EXPORT_DIR_CHANGEABLE - 同樣是導出, 但允許改變方向 + +因爲 GPIOF_INIT_* 僅有在配置爲輸出的時候才存在,所以有效的組合爲: + + * GPIOF_IN - 配置爲輸入 + * GPIOF_OUT_INIT_LOW - 配置爲輸出,並初始化爲低電平 + * GPIOF_OUT_INIT_HIGH - 配置爲輸出,並初始化爲高電平 + +當設置 flag 爲 GPIOF_OPEN_DRAIN 時,則假設引腳是開漏信號。這樣的引腳 +將不會在輸出模式下置1。這樣的引腳需要連接上拉電阻。通過使能這個標誌,gpio庫 +將會在被要求輸出模式下置1時將引腳變爲輸入狀態來使引腳置高。引腳在輸出模式下 +通過置0使其輸出低電平。 + +當設置 flag 爲 GPIOF_OPEN_SOURCE 時,則假設引腳爲源極開路信號。這樣的引腳 +將不會在輸出模式下置0。這樣的引腳需要連接下拉電阻。通過使能這個標誌,gpio庫 +將會在被要求輸出模式下置0時將引腳變爲輸入狀態來使引腳置低。引腳在輸出模式下 +通過置1使其輸出高電平。 + +將來這些標誌可能擴展到支持更多的屬性。 + +更進一步,爲了更簡單地聲明/釋放多個 GPIO,'struct gpio'被引進來封裝所有 +這三個領域: + + struct gpio { + unsigned gpio; + unsigned long flags; + const char *label; + }; + +一個典型的用例: + + static struct gpio leds_gpios[] = { + { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* 默認開啓 */ + { 33, GPIOF_OUT_INIT_LOW, "Green LED" }, /* 默認關閉 */ + { 34, GPIOF_OUT_INIT_LOW, "Red LED" }, /* 默認關閉 */ + { 35, GPIOF_OUT_INIT_LOW, "Blue LED" }, /* 默認關閉 */ + { ... }, + }; + + err = gpio_request_one(31, GPIOF_IN, "Reset Button"); + if (err) + ... + + err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios)); + if (err) + ... + + gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios)); + + +GPIO 映射到 IRQ +-------------------- +GPIO 編號是無符號整數;IRQ 編號也是。這些構成了兩個邏輯上不同的命名空間 +(GPIO 0 不一定使用 IRQ 0)。你可以通過以下函數在它們之間實現映射: + + /* 映射 GPIO 編號到 IRQ 編號 */ + int gpio_to_irq(unsigned gpio); + + /* 映射 IRQ 編號到 GPIO 編號 (儘量避免使用) */ + int irq_to_gpio(unsigned irq); + +它們的返回值爲對應命名空間的相關編號,或是負的錯誤代碼(如果無法映射)。 +(例如,某些 GPIO 無法做爲 IRQ 使用。)以下的編號錯誤是未經檢測的:使用一個 +未通過 gpio_direction_input()配置爲輸入的 GPIO 編號,或者使用一個 +並非來源於gpio_to_irq()的 IRQ 編號。 + +這兩個映射函數可能會在信號編號的加減計算過程上花些時間。它們不可休眠。 + +gpio_to_irq()返回的非錯誤值可以傳遞給 request_irq()或者 free_irq()。 +它們通常通過板級特定的初始化代碼存放到平台設備的 IRQ 資源中。注意:IRQ +觸發選項是 IRQ 接口的一部分,如 IRQF_TRIGGER_FALLING,系統喚醒能力 +也是如此。 + +irq_to_gpio()返回的非錯誤值大多數通常可以被 gpio_get_value()所使用, +比如在 IRQ 是沿觸發時初始化或更新驅動狀態。注意某些平台不支持反映射,所以 +你應該儘量避免使用它。 + + +模擬開漏信號 +---------------------------- +有時在只有低電平信號作爲實際驅動結果(譯者注:多個輸出連接於一點,邏輯電平 +結果爲所有輸出的邏輯與)的時候,共享的信號線需要使用「開漏」信號。(該術語 +適用於 CMOS 管;而 TTL 用「集電極開路」。)一個上拉電阻使信號爲高電平。這 +有時被稱爲「線與」。實際上,從負邏輯(低電平爲真)的角度來看,這是一個「線或」。 + +一個開漏信號的常見例子是共享的低電平使能 IRQ 信號線。此外,有時雙向數據總線 +信號也使用漏極開路信號。 + +某些 GPIO 控制器直接支持開漏輸出,還有許多不支持。當你需要開漏信號,但 +硬體又不直接支持的時候,一個常用的方法是用任何即可作輸入也可作輸出的 GPIO +引腳來模擬: + + LOW: gpio_direction_output(gpio, 0) ... 這代碼驅動信號並覆蓋 + 上拉配置。 + + HIGH: gpio_direction_input(gpio) ... 這代碼關閉輸出,所以上拉電阻 + (或其他的一些器件)控制了信號。 + +如果你將信號線「驅動」爲高電平,但是 gpio_get_value(gpio)報告了一個 +低電平(在適當的上升時間後),你就可以知道是其他的一些組件將共享信號線拉低了。 +這不一定是錯誤的。一個常見的例子就是 I2C 時鐘的延長:一個需要較慢時鐘的 +從設備延遲 SCK 的上升沿,而 I2C 主設備相應地調整其信號傳輸速率。 + + +這些公約忽略了什麼? +================ +這些公約忽略的最大一件事就是引腳復用,因爲這屬於高度晶片特定的屬性且 +沒有可移植性。某個平台可能不需要明確的復用信息;有的對於任意給定的引腳 +可能只有兩個功能選項;有的可能每個引腳有八個功能選項;有的可能可以將 +幾個引腳中的任何一個作爲給定的 GPIO。(是的,這些例子都來自於當前運行 +Linux 的系統。) + +在某些系統中,與引腳復用相關的是配置和使能集成的上、下拉模式。並不是所有 +平台都支持這種模式,或者不會以相同的方式來支持這種模式;且任何給定的電路板 +可能使用外置的上拉(或下拉)電阻,這時晶片上的就不應該使用。(當一個電路需要 +5kOhm 的拉動電阻,晶片上的 100 kOhm 電阻就不能做到。)同樣的,驅動能力 +(2 mA vs 20 mA)和電壓(1.8V vs 3.3V)是平台特定問題,就像模型一樣在 +可配置引腳和 GPIO 之間(沒)有一一對應的關係。 + +還有其他一些系統特定的機制沒有在這裡指出,例如上述的輸入去毛刺和線與輸出 +選項。硬體可能支持批量讀或寫 GPIO,但是那一般是配置相關的:對於處於同一 +塊區(bank)的GPIO。(GPIO 通常以 16 或 32 個組成一個區塊,一個給定的 +片上系統一般有幾個這樣的區塊。)某些系統可以通過輸出 GPIO 觸發 IRQ, +或者從並非以 GPIO 管理的引腳取值。這些機制的相關代碼沒有必要具有可移植性。 + +當前,動態定義 GPIO 並不是標準的,例如作爲配置一個帶有某些 GPIO 擴展器的 +附加電路板的副作用。 + +GPIO 實現者的框架 (可選) +===================== +前面提到了,有一個可選的實現框架,讓平台使用相同的編程接口,更加簡單地支持 +不同種類的 GPIO 控制器。這個框架稱爲"gpiolib"。 + +作爲一個輔助調試功能,如果 debugfs 可用,就會有一個 /sys/kernel/debug/gpio +文件。通過這個框架,它可以列出所有註冊的控制器,以及當前正在使用中的 GPIO +的狀態。 + + +控制器驅動: gpio_chip +------------------- +在框架中每個 GPIO 控制器都包裝爲一個 "struct gpio_chip",他包含了 +該類型的每個控制器的常用信息: + + - 設置 GPIO 方向的方法 + - 用於訪問 GPIO 值的方法 + - 告知調用其方法是否可能休眠的標誌 + - 可選的 debugfs 信息導出方法 (顯示類似上拉配置一樣的額外狀態) + - 診斷標籤 + +也包含了來自 device.platform_data 的每個實例的數據:它第一個 GPIO 的 +編號和它可用的 GPIO 的數量。 + +實現 gpio_chip 的代碼應支持多控制器實例,這可能使用驅動模型。那些代碼要 +配置每個 gpio_chip,並發起gpiochip_add()。卸載一個 GPIO 控制器很少見, +但在必要的時候可以使用 gpiochip_remove()。 + +大部分 gpio_chip 是一個實例特定結構體的一部分,而並不將 GPIO 接口單獨 +暴露出來,比如編址、電源管理等。類似編解碼器這樣的晶片會有複雜的非 GPIO +狀態。 + +任何一個 debugfs 信息導出方法通常應該忽略還未申請作爲 GPIO 的信號線。 +他們可以使用 gpiochip_is_requested()測試,當這個 GPIO 已經申請過了 +就返回相關的標籤,否則返回 NULL。 + + +平台支持 +------- +爲了支持這個框架,一個平台的 Kconfig 文件將會 "select"(選擇) +ARCH_REQUIRE_GPIOLIB 或 ARCH_WANT_OPTIONAL_GPIOLIB,並讓它的 + 包含 ,同時定義三個方法: +gpio_get_value()、gpio_set_value()和 gpio_cansleep()。 + +它也應提供一個 ARCH_NR_GPIOS 的定義值,這樣可以更好地反映該平台 GPIO +的實際數量,節省靜態表的空間。(這個定義值應該包含片上系統內建 GPIO 和 +GPIO 擴展器中的數據。) + +ARCH_REQUIRE_GPIOLIB 意味著 gpiolib 核心在這個構架中將總是編譯進內核。 + +ARCH_WANT_OPTIONAL_GPIOLIB 意味著 gpiolib 核心默認關閉,且用戶可以 +使能它,並將其編譯進內核(可選)。 + +如果這些選項都沒被選擇,該平台就不通過 GPIO-lib 支持 GPIO,且代碼不可以 +被用戶使能。 + +以下這些方法的實現可以直接使用框架代碼,並總是通過 gpio_chip 調度: + + #define gpio_get_value __gpio_get_value + #define gpio_set_value __gpio_set_value + #define gpio_cansleep __gpio_cansleep + +這些定義可以用更理想的實現方法替代,那就是使用經過邏輯優化的內聯函數來訪問 +基於特定片上系統的 GPIO。例如,若引用的 GPIO (寄存器位偏移)是常量「12」, +讀取或設置它可能只需少則兩或三個指令,且不會休眠。當這樣的優化無法實現時, +那些函數必須使用框架提供的代碼,那就至少要幾十條指令才可以實現。對於用 GPIO +模擬的 I/O 接口, 如此精簡指令是很有意義的。 + +對於片上系統,平台特定代碼爲片上 GPIO 每個區(bank)定義並註冊 gpio_chip +實例。那些 GPIO 應該根據晶片廠商的文檔進行編碼/標籤,並直接和電路板原理圖 +對應。他們應該開始於零並終止於平台特定的限制。這些 GPIO(代碼)通常從 +arch_initcall()或者更早的地方集成進平台初始化代碼,使這些 GPIO 總是可用, +且他們通常可以作爲 IRQ 使用。 + +板級支持 +------- +對於外部 GPIO 控制器(例如 I2C 或 SPI 擴展器、專用晶片、多功能器件、FPGA +或 CPLD),大多數常用板級特定代碼都可以註冊控制器設備,並保證他們的驅動知道 +gpiochip_add()所使用的 GPIO 編號。他們的起始編號通常跟在平台特定的 GPIO +編號之後。 + +例如板級啓動代碼應該創建結構體指明晶片公開的 GPIO 範圍,並使用 platform_data +將其傳遞給每個 GPIO 擴展器晶片。然後晶片驅動中的 probe()例程可以將這個 +數據傳遞給 gpiochip_add()。 + +初始化順序很重要。例如,如果一個設備依賴基於 I2C 的(擴展)GPIO,那麼它的 +probe()例程就應該在那個 GPIO 有效以後才可以被調用。這意味著設備應該在 +GPIO 可以工作之後才可被註冊。解決這類依賴的的一種方法是讓這種 gpio_chip +控制器向板級特定代碼提供 setup()和 teardown()回調函數。一旦所有必須的 +資源可用之後,這些板級特定的回調函數將會註冊設備,並可以在這些 GPIO 控制器 +設備變成無效時移除它們。 + + +用戶空間的 Sysfs 接口(可選) +======================== +使用「gpiolib」實現框架的平台可以選擇配置一個 GPIO 的 sysfs 用戶接口。 +這不同於 debugfs 接口,因爲它提供的是對 GPIO方向和值的控制,而不只顯示 +一個GPIO 的狀態摘要。此外,它可以出現在沒有調試支持的產品級系統中。 + +例如,通過適當的系統硬體文檔,用戶空間可以知道 GIOP #23 控制 Flash +存儲器的防寫(用於保護其中 Bootloader 分區)。產品的系統升級可能需要 +臨時解除這個保護:首先導入一個 GPIO,改變其輸出狀態,然後在重新使能防寫 +前升級代碼。通常情況下,GPIO #23 是不會被觸及的,並且內核也不需要知道他。 + +根據適當的硬體文檔,某些系統的用戶空間 GPIO 可以用於確定系統配置數據, +這些數據是標準內核不知道的。在某些任務中,簡單的用戶空間 GPIO 驅動可能是 +系統真正需要的。 + +注意:標準內核驅動中已經存在通用的「LED 和按鍵」GPIO 任務,分別是: +"leds-gpio" 和 "gpio_keys"。請使用這些來替代直接訪問 GPIO,因爲集成在 +內核框架中的這類驅動比你在用戶空間的代碼更好。 + + +Sysfs 中的路徑 +-------------- +在/sys/class/gpio 中有 3 類入口: + + - 用於在用戶空間控制 GPIO 的控制接口; + + - GPIOs 本身;以及 + + - GPIO 控制器 ("gpio_chip" 實例)。 + +除了這些標準的文件,還包含「device」符號連結。 + +控制接口是只寫的: + + /sys/class/gpio/ + + "export" ... 用戶空間可以通過寫其編號到這個文件,要求內核導出 + 一個 GPIO 的控制到用戶空間。 + + 例如: 如果內核代碼沒有申請 GPIO #19,"echo 19 > export" + 將會爲 GPIO #19 創建一個 "gpio19" 節點。 + + "unexport" ... 導出到用戶空間的逆操作。 + + 例如: "echo 19 > unexport" 將會移除使用"export"文件導出的 + "gpio19" 節點。 + +GPIO 信號的路徑類似 /sys/class/gpio/gpio42/ (對於 GPIO #42 來說), +並有如下的讀/寫屬性: + + /sys/class/gpio/gpioN/ + + "direction" ... 讀取得到 "in" 或 "out"。這個值通常運行寫入。 + 寫入"out" 時,其引腳的默認輸出爲低電平。爲了確保無故障運行, + "low" 或 "high" 的電平值應該寫入 GPIO 的配置,作爲初始輸出值。 + + 注意:如果內核不支持改變 GPIO 的方向,或者在導出時內核代碼沒有 + 明確允許用戶空間可以重新配置 GPIO 方向,那麼這個屬性將不存在。 + + "value" ... 讀取得到 0 (低電平) 或 1 (高電平)。如果 GPIO 配置爲 + 輸出,這個值允許寫操作。任何非零值都以高電平看待。 + + 如果引腳可以配置爲中斷信號,且如果已經配置了產生中斷的模式 + (見"edge"的描述),你可以對這個文件使用輪詢操作(poll(2)), + 且輪詢操作會在任何中斷觸發時返回。如果你使用輪詢操作(poll(2)), + 請在 events 中設置 POLLPRI 和 POLLERR。如果你使用輪詢操作 + (select(2)),請在 exceptfds 設置你期望的文件描述符。在 + 輪詢操作(poll(2))返回之後,既可以通過 lseek(2)操作讀取 + sysfs 文件的開始部分,也可以關閉這個文件並重新打開它來讀取數據。 + + "edge" ... 讀取得到「none」、「rising」、「falling」或者「both」。 + 將這些字符串寫入這個文件可以選擇沿觸發模式,會使得輪詢操作 + (select(2))在"value"文件中返回。 + + 這個文件僅有在這個引腳可以配置爲可產生中斷輸入引腳時,才存在。 + + "active_low" ... 讀取得到 0 (假) 或 1 (真)。寫入任何非零值可以 + 翻轉這個屬性的(讀寫)值。已存在或之後通過"edge"屬性設置了"rising" + 和 "falling" 沿觸發模式的輪詢操作(poll(2))將會遵循這個設置。 + +GPIO 控制器的路徑類似 /sys/class/gpio/gpiochip42/ (對於從#42 GPIO +開始實現控制的控制器),並有著以下只讀屬性: + + /sys/class/gpio/gpiochipN/ + + "base" ... 與以上的 N 相同,代表此晶片管理的第一個 GPIO 的編號 + + "label" ... 用於診斷 (並不總是只有唯一值) + + "ngpio" ... 此控制器所管理的 GPIO 數量(而 GPIO 編號從 N 到 + N + ngpio - 1) + +大多數情況下,電路板的文檔應當標明每個 GPIO 的使用目的。但是那些編號並不總是 +固定的,例如在擴展卡上的 GPIO會根據所使用的主板或所在堆疊架構中其他的板子而 +有所不同。在這種情況下,你可能需要使用 gpiochip 節點(儘可能地結合電路圖)來 +確定給定信號所用的 GPIO 編號。 + + +從內核代碼中導出 +------------- +內核代碼可以明確地管理那些已通過 gpio_request()申請的 GPIO 的導出: + + /* 導出 GPIO 到用戶空間 */ + int gpio_export(unsigned gpio, bool direction_may_change); + + /* gpio_export()的逆操作 */ + void gpio_unexport(); + + /* 創建一個 sysfs 連接到已導出的 GPIO 節點 */ + int gpio_export_link(struct device *dev, const char *name, + unsigned gpio) + +在一個內核驅動申請一個 GPIO 之後,它可以通過 gpio_export()使其在 sysfs +接口中可見。該驅動可以控制信號方向是否可修改。這有助於防止用戶空間代碼無意間 +破壞重要的系統狀態。 + +這個明確的導出有助於(通過使某些實驗更容易來)調試,也可以提供一個始終存在的接口, +與文檔配合作爲板級支持包的一部分。 + +在 GPIO 被導出之後,gpio_export_link()允許在 sysfs 文件系統的任何地方 +創建一個到這個 GPIO sysfs 節點的符號連結。這樣驅動就可以通過一個描述性的 +名字,在 sysfs 中他們所擁有的設備下提供一個(到這個 GPIO sysfs 節點的)接口。 + diff --git a/Documentation/translations/zh_TW/index.rst b/Documentation/translations/zh_TW/index.rst new file mode 100644 index 000000000000..cab58e428825 --- /dev/null +++ b/Documentation/translations/zh_TW/index.rst @@ -0,0 +1,162 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. raw:: latex + + \renewcommand\thesection* + \renewcommand\thesubsection* + \kerneldocCJKon + +.. _linux_doc_zh_tw: + +繁體中文翻譯 +============ + + +.. note:: + 內核文檔繁體中文版的翻譯工作正在進行中。如果您願意並且有時間參與這項工 + 作,歡迎提交補丁給胡皓文 。 + +許可證文檔 +---------- + +下面的文檔介紹了Linux內核原始碼的許可證(GPLv2)、如何在原始碼樹中正確標記 +單個文件的許可證、以及指向完整許可證文本的連結。 + +TODOList: + +* Documentation/translations/zh_TW/process/license-rules.rst + +用戶文檔 +-------- + +下面的手冊是爲內核用戶編寫的——即那些試圖讓它在給定系統上以最佳方式工作的 +用戶。 + +.. toctree:: + :maxdepth: 2 + + admin-guide/index + +TODOList: + +* kbuild/index + +固件相關文檔 +------------ + +下列文檔描述了內核需要的平台固件相關信息。 + +TODOList: + +* firmware-guide/index +* devicetree/index + +應用程式開發人員文檔 +-------------------- + +用戶空間API手冊涵蓋了描述應用程式開發人員可見內核接口方面的文檔。 + +TODOlist: + +* userspace-api/index + +內核開發簡介 +------------ + +這些手冊包含有關如何開發內核的整體信息。內核社區非常龐大,一年下來有數千名 +開發人員做出貢獻。與任何大型社區一樣,知道如何完成任務將使得更改合併的過程 +變得更加容易。 + +TODOList: + +* process/index +* dev-tools/index +* doc-guide/index +* kernel-hacking/index +* trace/index +* maintainer/index +* fault-injection/index +* livepatch/index +* rust/index + +內核API文檔 +----------- + +以下手冊從內核開發人員的角度詳細介紹了特定的內核子系統是如何工作的。這裡的 +大部分信息都是直接從內核原始碼獲取的,並根據需要添加補充材料(或者至少是在 +我們設法添加的時候——可能不是所有的都是有需要的)。 + +TODOList: + +* driver-api/index +* core-api/index +* locking/index +* accounting/index +* block/index +* cdrom/index +* cpu-freq/index +* ide/index +* fb/index +* fpga/index +* hid/index +* i2c/index +* iio/index +* isdn/index +* infiniband/index +* leds/index +* netlabel/index +* networking/index +* pcmcia/index +* power/index +* target/index +* timers/index +* spi/index +* w1/index +* watchdog/index +* virt/index +* input/index +* hwmon/index +* gpu/index +* security/index +* sound/index +* crypto/index +* filesystems/index +* vm/index +* bpf/index +* usb/index +* PCI/index +* scsi/index +* misc-devices/index +* scheduler/index +* mhi/index + +體系結構無關文檔 +---------------- + +TODOList: + +* asm-annotations + +特定體系結構文檔 +---------------- + +TODOList: + +* arch + +其他文檔 +-------- + +有幾份未排序的文檔似乎不適合放在文檔的其他部分,或者可能需要進行一些調整和/或 +轉換爲reStructureText格式,也有可能太舊。 + +TODOList: + +* staging/index +* watch_queue + +目錄和表格 +---------- + +* :ref:`genindex` + diff --git a/Documentation/translations/zh_TW/io_ordering.txt b/Documentation/translations/zh_TW/io_ordering.txt new file mode 100644 index 000000000000..1e99206c8421 --- /dev/null +++ b/Documentation/translations/zh_TW/io_ordering.txt @@ -0,0 +1,68 @@ +Chinese translated version of Documentation/driver-api/io_ordering.rst + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/driver-api/io_ordering.rst 的繁體中文翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen +繁體中文版校譯者: 胡皓文 Hu Haowen + + +以下爲正文 +--------------------------------------------------------------------- + +在某些平台上,所謂的內存映射I/O是弱順序。在這些平台上,驅動開發者有責任 +保證I/O內存映射地址的寫操作按程序圖意的順序達到設備。通常讀取一個「安全」 +設備寄存器或橋寄存器,觸發IO晶片清刷未處理的寫操作到達設備後才處理讀操作, +而達到保證目的。驅動程序通常在spinlock保護的臨界區退出之前使用這種技術。 +這也可以保證後面的寫操作只在前面的寫操作之後到達設備(這非常類似於內存 +屏障操作,mb(),不過僅適用於I/O)。 + +假設一個設備驅動程的具體例子: + + ... +CPU A: spin_lock_irqsave(&dev_lock, flags) +CPU A: val = readl(my_status); +CPU A: ... +CPU A: writel(newval, ring_ptr); +CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... +CPU B: spin_lock_irqsave(&dev_lock, flags) +CPU B: val = readl(my_status); +CPU B: ... +CPU B: writel(newval2, ring_ptr); +CPU B: spin_unlock_irqrestore(&dev_lock, flags) + ... + +上述例子中,設備可能會先接收到newval2的值,然後接收到newval的值,問題就 +發生了。不過很容易通過下面方法來修復: + + ... +CPU A: spin_lock_irqsave(&dev_lock, flags) +CPU A: val = readl(my_status); +CPU A: ... +CPU A: writel(newval, ring_ptr); +CPU A: (void)readl(safe_register); /* 配置寄存器?*/ +CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... +CPU B: spin_lock_irqsave(&dev_lock, flags) +CPU B: val = readl(my_status); +CPU B: ... +CPU B: writel(newval2, ring_ptr); +CPU B: (void)readl(safe_register); /* 配置寄存器?*/ +CPU B: spin_unlock_irqrestore(&dev_lock, flags) + +在解決方案中,讀取safe_register寄存器,觸發IO晶片清刷未處理的寫操作, +再處理後面的讀操作,防止引發數據不一致問題。 + diff --git a/Documentation/translations/zh_TW/oops-tracing.txt b/Documentation/translations/zh_TW/oops-tracing.txt new file mode 100644 index 000000000000..be8e59f2abaf --- /dev/null +++ b/Documentation/translations/zh_TW/oops-tracing.txt @@ -0,0 +1,212 @@ +Chinese translated version of Documentation/admin-guide/bug-hunting.rst + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/admin-guide/bug-hunting.rst 的繁體中文版翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen +繁體中文版校譯者: 胡皓文 Hu Haowen + +以下爲正文 +--------------------------------------------------------------------- + +注意: ksymoops 在2.6中是沒有用的。 請以原有格式使用Oops(來自dmesg,等等)。 +忽略任何這樣那樣關於「解碼Oops」或者「通過ksymoops運行」的文檔。 如果你貼出運行過 +ksymoops的來自2.6的Oops,人們只會讓你重貼一次。 + +快速總結 +------------- + +發現Oops並發送給看似相關的內核領域的維護者。別太擔心對不上號。如果你不確定就發給 +和你所做的事情相關的代碼的負責人。 如果可重現試著描述怎樣重構。 那甚至比oops更有 +價值。 + +如果你對於發送給誰一無所知, 發給linux-kernel@vger.kernel.org。感謝你幫助Linux +儘可能地穩定。 + +Oops在哪裡? +---------------------- + +通常Oops文本由klogd從內核緩衝區里讀取並傳給syslogd,由syslogd寫到syslog文件中, +典型地是/var/log/messages(依賴於/etc/syslog.conf)。有時klogd崩潰了,這種情況下你 +能夠運行dmesg > file來從內核緩衝區中讀取數據並保存下來。 否則你可以 +cat /proc/kmsg > file, 然而你必須介入中止傳輸, kmsg是一個「永不結束的文件」。如 +果機器崩潰壞到你不能輸入命令或者磁碟不可用那麼你有三種選擇:- + +(1) 手抄屏幕上的文本待機器重啓後再輸入計算機。 麻煩但如果沒有針對崩潰的準備, +這是僅有的選擇。 另外,你可以用數位相機把屏幕拍下來-不太好,但比沒有強。 如果信 +息滾動到了終端的上面,你會發現以高分辯率啓動(比如,vga=791)會讓你讀到更多的文 +本。(注意:這需要vesafb,所以對『早期』的oops沒有幫助) + +(2)用串口終端啓動(請參看Documentation/admin-guide/serial-console.rst),運行一個null +modem到另一台機器並用你喜歡的通訊工具獲取輸出。Minicom工作地很好。 + +(3)使用Kdump(請參看Documentation/admin-guide/kdump/kdump.rst), +使用在Documentation/admin-guide/kdump/gdbmacros.txt中定義的dmesg gdb宏,從舊的內存中提取內核 +環形緩衝區。 + +完整信息 +---------------- + +注意:以下來自於Linus的郵件適用於2.4內核。 我因爲歷史原因保留了它,並且因爲其中 +一些信息仍然適用。 特別注意的是,請忽略任何ksymoops的引用。 + +From: Linus Torvalds + +怎樣跟蹤Oops.. [原發到linux-kernel的一封郵件] + +主要的竅門是有五年和這些煩人的oops消息打交道的經驗;-) + +實際上,你有辦法使它更簡單。我有兩個不同的方法: + + gdb /usr/src/linux/vmlinux + gdb> disassemble + +那是發現問題的簡單辦法,至少如果bug報告做的好的情況下(象這個一樣-運行ksymoops +得到oops發生的函數及函數內的偏移)。 + +哦,如果報告發生的內核以相同的編譯器和相似的配置編譯它會有幫助的。 + +另一件要做的事是反彙編bug報告的「Code」部分:ksymoops也會用正確的工具來做這件事, +但如果沒有那些工具你可以寫一個傻程序: + + char str[] = "\xXX\xXX\xXX..."; + main(){} + +並用gcc -g編譯它然後執行「disassemble str」(XX部分是由Oops報告的值-你可以僅剪切 +粘貼並用「\x」替換空格-我就是這麼做的,因爲我懶得寫程序自動做這一切)。 + +另外,你可以用scripts/decodecode這個shell腳本。它的使用方法是: +decodecode < oops.txt + +「Code」之後的十六進位字節可能(在某些架構上)有一些當前指令之前的指令字節以及 +當前和之後的指令字節 + +Code: f9 0f 8d f9 00 00 00 8d 42 0c e8 dd 26 11 c7 a1 60 ea 2b f9 8b 50 08 a1 +64 ea 2b f9 8d 34 82 8b 1e 85 db 74 6d 8b 15 60 ea 2b f9 <8b> 43 04 39 42 54 +7e 04 40 89 42 54 8b 43 04 3b 05 00 f6 52 c0 + +最後,如果你想知道代碼來自哪裡,你可以: + + cd /usr/src/linux + make fs/buffer.s # 或任何產生BUG的文件 + +然後你會比gdb反彙編更清楚的知道發生了什麼。 + +現在,問題是把你所擁有的所有數據結合起來:C源碼(關於它應該怎樣的一般知識), +彙編代碼及其反彙編得到的代碼(另外還有從「oops」消息得到的寄存器狀態-對了解毀壞的 +指針有用,而且當你有了彙編代碼你也能拿其它的寄存器和任何它們對應的C表達式做匹配 +)。 + +實際上,你僅需看看哪裡不匹配(這個例子是「Code」反彙編和編譯器生成的代碼不匹配)。 +然後你須要找出爲什麼不匹配。通常很簡單-你看到代碼使用了空指針然後你看代碼想知道 +空指針是怎麼出現的,還有檢查它是否合法.. + +現在,如果明白這是一項耗時的工作而且需要一丁點兒的專心,沒錯。這就是我爲什麼大多 +只是忽略那些沒有符號表信息的崩潰報告的原因:簡單的說太難查找了(我有一些 +程序用於在內核代碼段中搜索特定的模式,而且有時我也已經能找出那些崩潰的地方,但是 +僅僅是找出正確的序列也確實需要相當紮實的內核知識) + +_有時_會發生這種情況,我僅看到崩潰中的反彙編代碼序列, 然後我馬上就明白問題出在 +哪裡。這時我才意識到自己幹這個工作已經太長時間了;-) + + Linus + + +--------------------------------------------------------------------------- +關於Oops跟蹤的註解: + +爲了幫助Linus和其它內核開發者,klogd納入了大量的支持來處理保護錯誤。爲了擁有對 +地址解析的完整支持至少應該使用1.3-pl3的sysklogd包。 + +當保護錯誤發生時,klogd守護進程自動把內核日誌信息中的重要地址翻譯成它們相應的符 +號。 + +klogd執行兩種類型的地址解析。首先是靜態翻譯其次是動態翻譯。靜態翻譯和ksymoops +一樣使用System.map文件。爲了做靜態翻譯klogd守護進程必須在初始化時能找到system +map文件。關於klogd怎樣搜索map文件請參看klogd手冊頁。 + +動態地址翻譯在使用內核可裝載模塊時很重要。 因爲內核模塊的內存是從內核動態內存池 +里分配的,所以不管是模塊開始位置還是模塊中函數和符號的位置都不是固定的。 + +內核支持允許程序決定裝載哪些模塊和它們在內存中位置的系統調用。使用這些系統調用 +klogd守護進程生成一張符號表用於調試發生在可裝載模塊中的保護錯誤。 + +至少klogd會提供產生保護錯誤的模塊名。還可有額外的符號信息供可裝載模塊開發者選擇 +以從模塊中輸出符號信息。 + +因爲內核模塊環境可能是動態的,所以必須有一種機制當模塊環境發生改變時來通知klogd +守護進程。 有一些可用的命令行選項允許klogd向當前執行中的守護進程發送信號,告知符 +號信息應該被刷新了。 更多信息請參看klogd手冊頁。 + +sysklogd發布時包含一個補丁修改了modules-2.0.0包,無論何時一個模塊裝載或者卸載都 +會自動向klogd發送信號。打上這個補丁提供了必要的對調試發生於內核可裝載模塊的保護 +錯誤的無縫支持。 + +以下是被klogd處理過的發生在可裝載模塊中的一個保護錯誤例子: +--------------------------------------------------------------------------- +Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc +Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 +Aug 29 09:51:01 blizard kernel: *pde = 00000000 +Aug 29 09:51:01 blizard kernel: Oops: 0002 +Aug 29 09:51:01 blizard kernel: CPU: 0 +Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] +Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 +Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c +Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c +Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 +Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) +Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 +Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 +Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 +Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] +Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 +--------------------------------------------------------------------------- + +Dr. G.W. Wettstein Oncology Research Div. Computing Facility +Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com +820 4th St. N. +Fargo, ND 58122 +Phone: 701-234-7556 + + +--------------------------------------------------------------------------- +受汙染的內核 + +一些oops報告在程序記數器之後包含字符串'Tainted: '。這表明內核已經被一些東西給汙 +染了。 該字符串之後緊跟著一系列的位置敏感的字符,每個代表一個特定的汙染值。 + + 1:'G'如果所有裝載的模塊都有GPL或相容的許可證,'P'如果裝載了任何的專有模塊。 +沒有模塊MODULE_LICENSE或者帶有insmod認爲是與GPL不相容的的MODULE_LICENSE的模塊被 +認定是專有的。 + + 2:'F'如果有任何通過「insmod -f」被強制裝載的模塊,' '如果所有模塊都被正常裝載。 + + 3:'S'如果oops發生在SMP內核中,運行於沒有證明安全運行多處理器的硬體。 當前這種 +情況僅限於幾種不支持SMP的速龍處理器。 + + 4:'R'如果模塊通過「insmod -f」被強制裝載,' '如果所有模塊都被正常裝載。 + + 5:'M'如果任何處理器報告了機器檢查異常,' '如果沒有發生機器檢查異常。 + + 6:'B'如果頁釋放函數發現了一個錯誤的頁引用或者一些非預期的頁標誌。 + + 7:'U'如果用戶或者用戶應用程式特別請求設置汙染標誌,否則' '。 + + 8:'D'如果內核剛剛死掉,比如有OOPS或者BUG。 + +使用'Tainted: '字符串的主要原因是要告訴內核調試者,這是否是一個乾淨的內核亦或發 +生了任何的不正常的事。汙染是永久的:即使出錯的模塊已經被卸載了,汙染值仍然存在, +以表明內核不再值得信任。 + diff --git a/Documentation/translations/zh_TW/sparse.txt b/Documentation/translations/zh_TW/sparse.txt new file mode 100644 index 000000000000..c9acb2c926cb --- /dev/null +++ b/Documentation/translations/zh_TW/sparse.txt @@ -0,0 +1,91 @@ +Chinese translated version of Documentation/dev-tools/sparse.rst + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/dev-tools/sparse.rst 的繁體中文翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen + +以下爲正文 +--------------------------------------------------------------------- + +Copyright 2004 Linus Torvalds +Copyright 2004 Pavel Machek +Copyright 2006 Bob Copeland + +使用 sparse 工具做類型檢查 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +"__bitwise" 是一種類型屬性,所以你應該這樣使用它: + + typedef int __bitwise pm_request_t; + + enum pm_request { + PM_SUSPEND = (__force pm_request_t) 1, + PM_RESUME = (__force pm_request_t) 2 + }; + +這樣會使 PM_SUSPEND 和 PM_RESUME 成爲位方式(bitwise)整數(使用"__force" +是因爲 sparse 會抱怨改變位方式的類型轉換,但是這裡我們確實需要強制進行轉 +換)。而且因爲所有枚舉值都使用了相同的類型,這裡的"enum pm_request"也將 +會使用那個類型做爲底層實現。 + +而且使用 gcc 編譯的時候,所有的 __bitwise/__force 都會消失,最後在 gcc +看來它們只不過是普通的整數。 + +坦白來說,你並不需要使用枚舉類型。上面那些實際都可以濃縮成一個特殊的"int +__bitwise"類型。 + +所以更簡單的辦法只要這樣做: + + typedef int __bitwise pm_request_t; + + #define PM_SUSPEND ((__force pm_request_t) 1) + #define PM_RESUME ((__force pm_request_t) 2) + +現在你就有了嚴格的類型檢查所需要的所有基礎架構。 + +一個小提醒:常數整數"0"是特殊的。你可以直接把常數零當作位方式整數使用而 +不用擔心 sparse 會抱怨。這是因爲"bitwise"(恰如其名)是用來確保不同位方 +式類型不會被弄混(小尾模式,大尾模式,cpu尾模式,或者其他),對他們來說 +常數"0"確實是特殊的。 + +獲取 sparse 工具 +~~~~~~~~~~~~~~~~ + +你可以從 Sparse 的主頁獲取最新的發布版本: + + http://www.kernel.org/pub/linux/kernel/people/josh/sparse/ + +或者,你也可以使用 git 克隆最新的 sparse 開發版本: + + git://git.kernel.org/pub/scm/linux/kernel/git/josh/sparse.git + +一旦你下載了源碼,只要以普通用戶身份運行: + + make + make install + +它將會被自動安裝到你的 ~/bin 目錄下。 + +使用 sparse 工具 +~~~~~~~~~~~~~~~~ + +用"make C=1"命令來編譯內核,會對所有重新編譯的 C 文件使用 sparse 工具。 +或者使用"make C=2"命令,無論文件是否被重新編譯都會對其使用 sparse 工具。 +如果你已經編譯了內核,用後一種方式可以很快地檢查整個源碼樹。 + +make 的可選變量 CHECKFLAGS 可以用來向 sparse 工具傳遞參數。編譯系統會自 +動向 sparse 工具傳遞 -Wbitwise 參數。 + -- cgit v1.2.3-70-g09d2 From 390f915a12a668c2add6a37bbf4dc30bc6a0e4d4 Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Thu, 29 Jul 2021 23:56:26 +0800 Subject: docs/zh_TW: add translations for zh_TW/process Create new translations for zh_TW/process and link them to index. Signed-off-by: Hu Haowen Reviewed-by: Pan Yunwang Link: https://lore.kernel.org/r/20210729155627.41744-2-src.res@email.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_TW/index.rst | 10 +- .../translations/zh_TW/process/1.Intro.rst | 199 +++++ .../translations/zh_TW/process/2.Process.rst | 369 ++++++++ .../translations/zh_TW/process/3.Early-stage.rst | 172 ++++ .../translations/zh_TW/process/4.Coding.rst | 297 +++++++ .../translations/zh_TW/process/5.Posting.rst | 251 ++++++ .../translations/zh_TW/process/6.Followthrough.rst | 156 ++++ .../zh_TW/process/7.AdvancedTopics.rst | 137 +++ .../translations/zh_TW/process/8.Conclusion.rst | 74 ++ .../process/code-of-conduct-interpretation.rst | 112 +++ .../translations/zh_TW/process/code-of-conduct.rst | 76 ++ .../translations/zh_TW/process/coding-style.rst | 958 +++++++++++++++++++++ .../zh_TW/process/development-process.rst | 30 + .../translations/zh_TW/process/email-clients.rst | 252 ++++++ .../zh_TW/process/embargoed-hardware-issues.rst | 232 +++++ Documentation/translations/zh_TW/process/howto.rst | 500 +++++++++++ Documentation/translations/zh_TW/process/index.rst | 67 ++ .../zh_TW/process/kernel-driver-statement.rst | 203 +++++ .../zh_TW/process/kernel-enforcement-statement.rst | 155 ++++ .../translations/zh_TW/process/license-rules.rst | 374 ++++++++ .../translations/zh_TW/process/magic-number.rst | 148 ++++ .../zh_TW/process/management-style.rst | 211 +++++ .../zh_TW/process/programming-language.rst | 76 ++ .../zh_TW/process/stable-api-nonsense.rst | 159 ++++ .../zh_TW/process/stable-kernel-rules.rst | 68 ++ .../zh_TW/process/submit-checklist.rst | 109 +++ .../zh_TW/process/submitting-drivers.rst | 164 ++++ .../zh_TW/process/submitting-patches.rst | 686 +++++++++++++++ .../zh_TW/process/volatile-considered-harmful.rst | 110 +++ 29 files changed, 6351 insertions(+), 4 deletions(-) create mode 100644 Documentation/translations/zh_TW/process/1.Intro.rst create mode 100644 Documentation/translations/zh_TW/process/2.Process.rst create mode 100644 Documentation/translations/zh_TW/process/3.Early-stage.rst create mode 100644 Documentation/translations/zh_TW/process/4.Coding.rst create mode 100644 Documentation/translations/zh_TW/process/5.Posting.rst create mode 100644 Documentation/translations/zh_TW/process/6.Followthrough.rst create mode 100644 Documentation/translations/zh_TW/process/7.AdvancedTopics.rst create mode 100644 Documentation/translations/zh_TW/process/8.Conclusion.rst create mode 100644 Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst create mode 100644 Documentation/translations/zh_TW/process/code-of-conduct.rst create mode 100644 Documentation/translations/zh_TW/process/coding-style.rst create mode 100644 Documentation/translations/zh_TW/process/development-process.rst create mode 100644 Documentation/translations/zh_TW/process/email-clients.rst create mode 100644 Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst create mode 100644 Documentation/translations/zh_TW/process/howto.rst create mode 100644 Documentation/translations/zh_TW/process/index.rst create mode 100644 Documentation/translations/zh_TW/process/kernel-driver-statement.rst create mode 100644 Documentation/translations/zh_TW/process/kernel-enforcement-statement.rst create mode 100644 Documentation/translations/zh_TW/process/license-rules.rst create mode 100644 Documentation/translations/zh_TW/process/magic-number.rst create mode 100644 Documentation/translations/zh_TW/process/management-style.rst create mode 100644 Documentation/translations/zh_TW/process/programming-language.rst create mode 100644 Documentation/translations/zh_TW/process/stable-api-nonsense.rst create mode 100644 Documentation/translations/zh_TW/process/stable-kernel-rules.rst create mode 100644 Documentation/translations/zh_TW/process/submit-checklist.rst create mode 100644 Documentation/translations/zh_TW/process/submitting-drivers.rst create mode 100644 Documentation/translations/zh_TW/process/submitting-patches.rst create mode 100644 Documentation/translations/zh_TW/process/volatile-considered-harmful.rst diff --git a/Documentation/translations/zh_TW/index.rst b/Documentation/translations/zh_TW/index.rst index cab58e428825..76981b2111f6 100644 --- a/Documentation/translations/zh_TW/index.rst +++ b/Documentation/translations/zh_TW/index.rst @@ -22,9 +22,7 @@ 下面的文檔介紹了Linux內核原始碼的許可證(GPLv2)、如何在原始碼樹中正確標記 單個文件的許可證、以及指向完整許可證文本的連結。 -TODOList: - -* Documentation/translations/zh_TW/process/license-rules.rst +Documentation/translations/zh_TW/process/license-rules.rst 用戶文檔 -------- @@ -67,9 +65,13 @@ TODOlist: 開發人員做出貢獻。與任何大型社區一樣,知道如何完成任務將使得更改合併的過程 變得更加容易。 +.. toctree:: + :maxdepth: 2 + + process/index + TODOList: -* process/index * dev-tools/index * doc-guide/index * kernel-hacking/index diff --git a/Documentation/translations/zh_TW/process/1.Intro.rst b/Documentation/translations/zh_TW/process/1.Intro.rst new file mode 100644 index 000000000000..ca2b931be6c5 --- /dev/null +++ b/Documentation/translations/zh_TW/process/1.Intro.rst @@ -0,0 +1,199 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/1.Intro.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_process_intro: + +引言 +==== + +內容提要 +-------- + +本節的其餘部分涵蓋了內核開發的過程,以及開發人員及其僱主在這方面可能遇到的 +各種問題。有很多原因使內核代碼應被合併到正式的(「主線」)內核中,包括對用戶 +的自動可用性、多種形式的社區支持以及影響內核開發方向的能力。提供給Linux內核 +的代碼必須在與GPL兼容的許可證下可用。 + +:ref:`tw_development_process` 介紹了開發過程、內核發布周期和合併窗口的機制。 +涵蓋了補丁開發、審查和合併周期中的各個階段。還有一些關於工具和郵件列表的討論? +鼓勵希望開始內核開發的開發人員跟蹤並修復缺陷以作爲初步練習。 + + +:ref:`tw_development_early_stage` 包括項目的早期規劃,重點是儘快讓開發社區 +參與進來。 + +:ref:`tw_development_coding` 是關於編程過程的;介紹了其他開發人員遇到的幾個 +陷阱。也涵蓋了對補丁的一些要求,並且介紹了一些工具,這些工具有助於確保內核 +補丁是正確的。 + +:ref:`tw_development_posting` 描述發布補丁以供評審的過程。爲了讓開發社區能 +認真對待,補丁必須被正確格式化和描述,並且必須發送到正確的地方。遵循本節中的 +建議有助於確保您的工作能被較好地接納。 + +:ref:`tw_development_followthrough` 介紹了發布補丁之後發生的事情;工作在這時 +還遠遠沒有完成。與審閱者一起工作是開發過程中的一個重要部分;本節提供了一些 +關於如何在這個重要階段避免問題的提示。當補丁被合併到主線中時,開發人員要注意 +不要假定任務已經完成。 + +:ref:`tw_development_advancedtopics` 介紹了兩個「高級」主題:使用Git管理補丁 +和查看其他人發布的補丁。 + +:ref:`tw_development_conclusion` 總結了有關內核開發的更多信息,附帶有相關資源 +連結。 + +這個文檔是關於什麼的 +-------------------- + +Linux內核有超過800萬行代碼,每個版本的貢獻者超過1000人,是現存最大、最活躍的 +免費軟體項目之一。從1991年開始,這個內核已經發展成爲一個最好的作業系統組件, +運行在袖珍數位音樂播放器、桌上型電腦、現存最大的超級計算機以及所有類型的系統上。 +它是一種適用於幾乎任何情況的健壯、高效和可擴展的解決方案。 + +隨著Linux的發展,希望參與其開發的開發人員(和公司)的數量也在增加。硬體供應商 +希望確保Linux能夠很好地支持他們的產品,使這些產品對Linux用戶具有吸引力。嵌入 +式系統供應商使用Linux作爲集成產品的組件,希望Linux能夠儘可能地勝任手頭的任務。 +分銷商和其他基於Linux的軟體供應商切實關心Linux內核的功能、性能和可靠性。最終 +用戶也常常希望修改Linux,使之能更好地滿足他們的需求。 + +Linux最引人注目的特性之一是這些開發人員可以訪問它;任何具備必要技能的人都可以 +改進Linux並影響其開發方向。專有產品不能提供這種開放性,這是自由軟體的一個特點。 +如果有什麼不同的話,那就是內核比大多數其他自由軟體項目更開放。一個典型的三個 +月內核開發周期可以涉及1000多個開發人員,他們爲100多個不同的公司(或者根本不 +隸屬公司)工作。 + +與內核開發社區合作並不是特別困難。但儘管如此,仍有許多潛在的貢獻者在嘗試做 +內核工作時遇到了困難。內核社區已經發展出自己獨特的操作方式,使其能夠在每天 +都要更改數千行代碼的環境中順利運行(並生成高質量的產品)。因此,Linux內核開發 +過程與專有的開發模式有很大的不同也就不足爲奇了。 + +對於新開發人員來說,內核的開發過程可能會讓人感到奇怪和恐懼,但這背後有充分的 +理由和堅實的經驗。一個不了解內核社區工作方式的開發人員(或者更糟的是,他們 +試圖拋棄或規避之)會得到令人沮喪的體驗。開發社區在幫助那些試圖學習的人的同時, +沒有時間幫助那些不願意傾聽或不關心開發過程的人。 + +希望閱讀本文的人能夠避免這種令人沮喪的經歷。這些材料很長,但閱讀它們時所做的 +努力會在短時間內得到回報。開發社區總是需要能讓內核變更好的開發人員;下面的 +文字應該幫助您或爲您工作的人員加入我們的社區。 + +致謝 +---- + +本文檔由Jonathan Corbet 撰寫。以下人員的建議使之更爲完善: +Johannes Berg, James Berry, Alex Chiang, Roland Dreier, Randy Dunlap, +Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh, Amanda McPherson, +Andrew Morton, Andrew Price, Tsugikazu Shibata 和 Jochen Voß 。 + +這項工作得到了Linux基金會的支持,特別感謝Amanda McPherson,他看到了這項工作 +的價值並將其變成現實。 + +代碼進入主線的重要性 +-------------------- + +有些公司和開發人員偶爾會想,爲什麼他們要費心學習如何與內核社區合作,並將代碼 +放入主線內核(「主線」是由Linus Torvalds維護的內核,Linux發行商將其用作基礎)。 +在短期內,貢獻代碼看起來像是一種可以避免的開銷;維護獨立代碼並直接支持用戶 +似乎更容易。事實上,保持代碼獨立(「樹外」)是在經濟上是錯誤的。 + +爲了說明樹外代碼成本,下面給出內核開發過程的一些相關方面;本文稍後將更詳細地 +討論其中的大部分內容。請考慮: + +- 所有Linux用戶都可以使用合併到主線內核中的代碼。它將自動出現在所有啓用它的 + 發行版上。無需驅動程序磁碟、額外下載,也不需要爲多個發行版的多個版本提供 + 支持;這一切將方便所有開發人員和用戶。併入主線解決了大量的分發和支持問題。 + +- 當內核開發人員努力維護一個穩定的用戶空間接口時,內核內部API處於不斷變化之中。 + 不維持穩定的內部接口是一個慎重的設計決策;它允許在任何時候進行基本的改進, + 並產出更高質量的代碼。但該策略導致結果是,若要使用新的內核,任何樹外代碼都 + 需要持續的維護。維護樹外代碼會需要大量的工作才能使代碼保持正常運行。 + + 相反,位於主線中的代碼不需要這樣做,因爲基本規則要求進行API更改的任何開發 + 人員也必須修復由於該更改而破壞的任何代碼。因此,合併到主線中的代碼大大降低 + 了維護成本。 + +- 除此之外,內核中的代碼通常會被其他開發人員改進。您授權的用戶社區和客戶對您 + 產品的改進可能會令人驚喜。 + +- 內核代碼在合併到主線之前和之後都要經過審查。無論原始開發人員的技能有多強, + 這個審查過程總是能找到改進代碼的方法。審查經常發現嚴重的錯誤和安全問題。 + 對於在封閉環境中開發的代碼尤其如此;這種代碼從外部開發人員的審查中獲益匪淺。 + 樹外代碼是低質量代碼。 + +- 參與開發過程是您影響內核開發方向的方式。旁觀者的抱怨會被聽到,但是活躍的 + 開發人員有更強的聲音——並且能夠實現使內核更好地滿足其需求的更改。 + +- 當單獨維護代碼時,總是存在第三方爲類似功能提供不同實現的可能性。如果發生 + 這種情況,合併代碼將變得更加困難——甚至成爲不可能。之後,您將面臨以下令人 + 不快的選擇:(1)無限期地維護樹外的非標準特性,或(2)放棄代碼並將用戶遷移 + 到樹內版本。 + +- 代碼的貢獻是使整個流程工作的根本。通過貢獻代碼,您可以向內核添加新功能,並 + 提供其他內核開發人員使用的功能和示例。如果您已經爲Linux開發了代碼(或者正在 + 考慮這樣做),那麼您顯然對這個平台的持續成功感興趣;貢獻代碼是確保成功的 + 最好方法之一。 + +上述所有理由都適用於任何樹外內核代碼,包括以專有的、僅二進位形式分發的代碼。 +然而,在考慮任何類型的純二進位內核代碼分布之前,還需要考慮其他因素。包括: + +- 圍繞專有內核模塊分發的法律問題其實較爲模糊;相當多的內核版權所有者認爲, + 大多數僅二進位的模塊是內核的派生產品,因此,它們的分發違反了GNU通用公共 + 許可證(下面將詳細介紹)。本文作者不是律師,本文檔中的任何內容都不可能被 + 視爲法律建議。封閉原始碼模塊的真實法律地位只能由法院決定。但不管怎樣,困擾 + 這些模塊的不確定性仍然存在。 + +- 二進位模塊大大增加了調試內核問題的難度,以至於大多數內核開發人員甚至都不會 + 嘗試。因此,只分發二進位模塊將使您的用戶更難從社區獲得支持。 + +- 對於僅二進位的模塊的發行者來說,支持也更加困難,他們必須爲他們希望支持的 + 每個發行版和每個內核版本提供不同版本的模塊。爲了提供較爲全面的覆蓋範圍, + 可能需要一個模塊的幾十個構建,並且每次升級內核時,您的用戶都必須單獨升級 + 這些模塊。 + +- 上面提到的關於代碼評審的所有問題都更加存在於封閉原始碼中。由於該代碼根本 + 不可得,因此社區無法對其進行審查,毫無疑問,它將存在嚴重問題。 + +尤其是嵌入式系統的製造商,可能會傾向於忽視本節中所說的大部分內容;因爲他們 +相信自己正在商用一種使用凍結內核版本的獨立產品,在發布後不需要再進行開發。 +這個論點忽略了廣泛的代碼審查的價值以及允許用戶向產品添加功能的價值。但這些 +產品的商業壽命有限,之後必須發布新版本的產品。在這一點上,代碼在主線上並得到 +良好維護的供應商將能夠更好地占位,以使新產品快速上市。 + +許可 +---- + +代碼是根據一些許可證提供給Linux內核的,但是所有代碼都必須與GNU通用公共許可 +證(GPLV2)的版本2兼容,該版本是覆蓋整個內核分發的許可證。在實踐中,這意味 +著所有代碼貢獻都由GPLv2(可選地,語言允許在更高版本的GPL下分發)或3子句BSD +許可(New BSD License,譯者注)覆蓋。任何不包含在兼容許可證中的貢獻都不會 +被接受到內核中。 + +貢獻給內核的代碼不需要(或請求)版權分配。合併到主線內核中的所有代碼都保留 +其原始所有權;因此,內核現在擁有數千個所有者。 + +這種所有權結構也暗示著,任何改變內核許可的嘗試都註定會失敗。很少有實際情況 +可以獲得所有版權所有者的同意(或者從內核中刪除他們的代碼)。因此,尤其是在 +可預見的將來,許可證不大可能遷移到GPL的版本3。 + +所有貢獻給內核的代碼都必須是合法的免費軟體。因此,不接受匿名(或化名)貢獻 +者的代碼。所有貢獻者都需要在他們的代碼上「sign off(簽發)」,聲明代碼可以 +在GPL下與內核一起分發。無法提供未被其所有者許可爲免費軟體的代碼,或可能爲 +內核造成版權相關問題的代碼(例如,由缺乏適當保護的反向工程工作派生的代碼) +不能被接受。 + +有關版權問題的提問在Linux開發郵件列表中很常見。這樣的問題通常會得到不少答案, +但請記住,回答這些問題的人不是律師,不能提供法律諮詢。如果您有關於Linux原始碼 +的法律問題,沒有什麼可以代替諮詢了解這一領域的律師。依賴從技術郵件列表中獲得 +的答案是一件冒險的事情。 + + diff --git a/Documentation/translations/zh_TW/process/2.Process.rst b/Documentation/translations/zh_TW/process/2.Process.rst new file mode 100644 index 000000000000..b01cdd3a39ae --- /dev/null +++ b/Documentation/translations/zh_TW/process/2.Process.rst @@ -0,0 +1,369 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/2.Process.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_process: + +開發流程如何進行 +================ + +90年代早期的Linux內核開發是一件相當鬆散的事情,涉及的用戶和開發人員相對較少。 +由於擁有數以百萬計的用戶羣,且每年有大約2000名開發人員參與進來,內核因此必須 +發展出許多既定流程來保證開發的順利進行。要參與到流程中來,需要對此流程的進行 +方式有一個紮實的理解。 + +總覽 +---- + +內核開發人員使用一個鬆散的基於時間的發布過程,每兩到三個月發布一次新的主要 +內核版本。最近的發布歷史記錄如下: + + ====== ================= + 5.0 2019年3月3日 + 5.1 2019年5月5日 + 5.2 2019年7月7日 + 5.3 2019年9月15日 + 5.4 2019年11月24日 + 5.5 2020年1月6日 + ====== ================= + +每個5.x版本都是一個主要的內核版本,具有新特性、內部API更改等等。一個典型的5.x +版本包含大約13000個變更集,變更了幾十萬行代碼。因此,5.x是Linux內核開發的前 +沿;內核使用滾動開發模型,不斷集成重大變化。 + +對於每個版本的補丁合併,遵循一個相對簡單的規則。在每個開發周期的開頭,「合併 +窗口」被打開。這時,被認爲足夠穩定(並且被開發社區接受)的代碼被合併到主線內 +核中。在這段時間內,新開發周期的大部分變更(以及所有主要變更)將以接近每天 +1000次變更(「補丁」或「變更集」)的速度合併。 + +(順便說一句,值得注意的是,合併窗口期間集成的更改並不是憑空產生的;它們是經 +提前收集、測試和分級的。稍後將詳細描述該過程的工作方式。) + +合併窗口持續大約兩周。在這段時間結束時,LinusTorvalds將聲明窗口已關閉,並 +釋放第一個「rc」內核。例如,對於目標爲5.6的內核,在合併窗口結束時發生的釋放 +將被稱爲5.6-rc1。-rc1 版本是一個信號,表示合併新特性的時間已經過去,穩定下一 +個內核的時間已經到來。 + +在接下來的6到10周內,只有修復問題的補丁才應該提交給主線。有時會允許更大的 +更改,但這種情況很少發生;試圖在合併窗口外合併新功能的開發人員往往受不到 +友好的接待。一般來說,如果您錯過了給定特性的合併窗口,最好的做法是等待下一 +個開發周期。(偶爾會對未支持硬體的驅動程序進行例外;如果它們不改變已有代碼, +則不會導致回歸,應該可以隨時被安全地加入)。 + +隨著修復程序進入主線,補丁速度將隨著時間的推移而變慢。Linus大約每周發布一次 +新的-rc內核;在內核被認爲足夠穩定並最終發布前,一般會達到-rc6到-rc9之間。 +然後,整個過程又重新開始了。 + +例如,這裡是5.4的開發周期進行情況(2019年): + + ============== ============================== + 九月 15 5.3 穩定版發布 + 九月 30 5.4-rc1 合併窗口關閉 + 十月 6 5.4-rc2 + 十月 13 5.4-rc3 + 十月 20 5.4-rc4 + 十月 27 5.4-rc5 + 十一月 3 5.4-rc6 + 十一月 10 5.4-rc7 + 十一月 17 5.4-rc8 + 十一月 24 5.4 穩定版發布 + ============== ============================== + +開發人員如何決定何時結束開發周期並創建穩定版本?最重要的指標是以前版本的 +回歸列表。不歡迎出現任何錯誤,但是那些破壞了以前能工作的系統的錯誤被認爲是 +特別嚴重的。因此,導致回歸的補丁是不受歡迎的,很可能在穩定期內刪除。 + +開發人員的目標是在穩定發布之前修復所有已知的回歸。在現實世界中,這種完美是 +很難實現的;在這種規模的項目中,變數太多了。需要說明的是,延遲最終版本只會 +使問題變得更糟;等待下一個合併窗口的更改將變多,導致下次出現更多的回歸錯誤。 +因此,大多數5.x內核都有一些已知的回歸錯誤,不過,希望沒有一個是嚴重的。 + +一旦一個穩定的版本發布,它的持續維護工作就被移交給「穩定團隊」,目前由 +Greg Kroah-Hartman領導。穩定團隊將使用5.x.y編號方案不定期地發布穩定版本的 +更新。要合入更新版本,補丁必須(1)修復一個重要的缺陷,且(2)已經合併到 +下一個開發版本主線中。內核通常會在其初始版本後的一個以上的開發周期內收到 +穩定版更新。例如,5.2內核的歷史如下(2019年): + + ============== =============================== + 七月 7 5.2 穩定版發布 + 七月 13 5.2.1 + 七月 21 5.2.2 + 七月 26 5.2.3 + 七月 28 5.2.4 + 七月 31 5.2.5 + ... ... + 十月 11 5.2.21 + ============== =============================== + +5.2.21是5.2版本的最終穩定更新。 + +有些內核被指定爲「長期」內核;它們將得到更長時間的支持。在本文中,當前的長期 +內核及其維護者是: + + ====== ================================ ================ + 3.16 Ben Hutchings (長期穩定內核) + 4.4 Greg Kroah-Hartman & Sasha Levin (長期穩定內核) + 4.9 Greg Kroah-Hartman & Sasha Levin + 4.14 Greg Kroah-Hartman & Sasha Levin + 4.19 Greg Kroah-Hartman & Sasha Levin + 5.4 Greg Kroah-Hartman & Sasha Levin + ====== ================================ ================ + +長期支持內核的選擇純粹是維護人員是否有需求和時間來維護該版本的問題。 +目前還沒有爲即將發布的任何特定版本提供長期支持的已知計劃。 + +補丁的生命周期 +-------------- + +補丁不會直接從開發人員的鍵盤進入主線內核。相反,有一個稍微複雜(如果有些非 +正式)的過程,旨在確保對每個補丁進行質量審查,並確保每個補丁實現了一個在主線 +中需要的更改。對於小的修復,這個過程可能會很快完成,,而對於較大或有爭議的 +變更,可能會持續數年。許多開發人員的沮喪來自於對這個過程缺乏理解或者試圖繞過它。 + +爲了減少這種挫敗,本文將描述補丁如何進入內核。下面的介紹以一種較爲理想化的 +方式描述了這個過程。更詳細的過程將在後面的章節中介紹。 + +補丁通常要經歷以下階段: + +- 設計。這就是補丁的真正需求——以及滿足這些需求的方式——所在。設計工作通常 + 是在不涉及社區的情況下完成的,但是如果可能的話,最好是在公開的情況下完成 + 這項工作;這樣可以節省很多稍後再重新設計的時間。 + +- 早期評審。補丁被發布到相關的郵件列表中,列表中的開發人員會回復他們可能有 + 的任何評論。如果一切順利的話,這個過程應該會發現補丁的任何主要問題。 + +- 更廣泛的評審。當補丁接近準備好納入主線時,它應該被相關的子系統維護人員 + 接受——儘管這種接受並不能保證補丁會一直延伸到主線。補丁將出現在維護人員的 + 子系統樹中,並進入 -next 樹(如下所述)。當流程進行時,此步驟將會對補丁 + 進行更廣泛的審查,並發現由於將此補丁與其他人所做的工作合併而導致的任何 + 問題。 + +- 請注意,大多數維護人員也有日常工作,因此合併補丁可能不是他們的最優先工作。 + 如果您的補丁得到了需要更改的反饋,那麼您應該進行這些更改,或者解釋爲何 + 不應該進行這些更改。如果您的補丁沒有評審意見,也沒有被其相應的子系統或 + 驅動程序維護者接受,那麼您應該堅持不懈地將補丁更新到當前內核使其可被正常 + 應用,並不斷地發送它以供審查和合併。 + +- 合併到主線。最終,一個成功的補丁將被合併到由LinusTorvalds管理的主線存儲庫 + 中。此時可能會出現更多的評論和/或問題;對開發人員來說應對這些問題並解決 + 出現的任何問題仍很重要。 + +- 穩定版發布。大量用戶可能受此補丁影響,因此可能再次出現新的問題。 + +- 長期維護。雖然開發人員在合併代碼後可能會忘記代碼,但這種行爲往往會給開發 + 社區留下不良印象。合併代碼消除了一些維護負擔,因爲其他人將修復由API更改 + 引起的問題。但是,如果代碼要長期保持可用,原始開發人員應該繼續爲代碼負責。 + +內核開發人員(或他們的僱主)犯的最大錯誤之一是試圖將流程簡化爲一個「合併到 +主線」步驟。這種方法總是會讓所有相關人員感到沮喪。 + +補丁如何進入內核 +---------------- + +只有一個人可以將補丁合併到主線內核存儲庫中:LinusTorvalds。但是,在進入 +2.6.38內核的9500多個補丁中,只有112個(大約1.3%)是由Linus自己直接選擇的。 +內核項目已經發展到一個沒有一個開發人員可以在沒有支持的情況下檢查和選擇每個 +補丁的規模。內核開發人員處理這種增長的方式是使用圍繞信任鏈構建的助理系統。 + +內核代碼庫在邏輯上被分解爲一組子系統:網絡、特定體系結構支持、內存管理、視 +頻設備等。大多數子系統都有一個指定的維護人員,其總體負責該子系統中的代碼。 +這些子系統維護者(鬆散地)是他們所管理的內核部分的「守門員」;他們(通常) +會接受一個補丁以包含到主線內核中。 + +子系統維護人員每個人都管理著自己版本的內核原始碼樹,通常(並非總是)使用Git。 +Git等工具(以及Quilt或Mercurial等相關工具)允許維護人員跟蹤補丁列表,包括作者 +信息和其他元數據。在任何給定的時間,維護人員都可以確定他或她的存儲庫中的哪 +些補丁在主線中找不到。 + +當合併窗口打開時,頂級維護人員將要求Linus從存儲庫中「拉出」他們爲合併選擇 +的補丁。如果Linus同意,補丁流將流向他的存儲庫,成爲主線內核的一部分。 +Linus對拉取中接收到的特定補丁的關注程度各不相同。很明顯,有時他看起來很 +關注。但是一般來說,Linus相信子系統維護人員不會向上游發送壞補丁。 + +子系統維護人員反過來也可以從其他維護人員那裡獲取補丁。例如,網絡樹是由首先 +在專用於網絡設備驅動程序、無線網絡等的樹中積累的補丁構建的。此存儲鏈可以 +任意長,但很少超過兩個或三個連結。由於鏈中的每個維護者都信任那些管理較低 +級別樹的維護者,所以這個過程稱爲「信任鏈」。 + +顯然,在這樣的系統中,獲取內核補丁取決於找到正確的維護者。直接向Linus發送 +補丁通常不是正確的方法。 + +Next 樹 +------- + +子系統樹鏈引導補丁流到內核,但它也提出了一個有趣的問題:如果有人想查看爲 +下一個合併窗口準備的所有補丁怎麼辦?開發人員將感興趣的是,還有什麼其他的 +更改有待解決,以了解是否存在需要擔心的衝突;例如,更改核心內核函數原型的 +修補程序將與使用該函數舊形式的任何其他修補程序衝突。審查人員和測試人員希望 +在所有這些變更到達主線內核之前,能夠訪問它們的集成形式的變更。您可以從所有 +相關的子系統樹中提取更改,但這將是一項複雜且容易出錯的工作。 + +解決方案以-next樹的形式出現,在這裡子系統樹被收集以供測試和審查。這些樹中 +由Andrew Morton維護的較老的一個,被稱爲「-mm」(用於內存管理,創建時爲此)。 +-mm 樹集成了一長串子系統樹中的補丁;它還包含一些旨在幫助調試的補丁。 + +除此之外,-mm 還包含大量由Andrew直接選擇的補丁。這些補丁可能已經發布在郵件 +列表上,或者它們可能應用於內核中未指定子系統樹的部分。同時,-mm 作爲最後 +手段的子系統樹;如果沒有其他明顯的路徑可以讓補丁進入主線,那麼它很可能最 +終選擇-mm 樹。累積在-mm 中的各種補丁最終將被轉發到適當的子系統樹,或者直接 +發送到Linus。在典型的開發周期中,大約5-10%的補丁通過-mm 進入主線。 + +當前-mm 補丁可在「mmotm」(-mm of the moment)目錄中找到: + + https://www.ozlabs.org/~akpm/mmotm/ + +然而,使用MMOTM樹可能會十分令人頭疼;它甚至可能無法編譯。 + +下一個周期補丁合併的主要樹是linux-next,由Stephen Rothwell 維護。根據設計 +linux-next 是下一個合併窗口關閉後主線的快照。linux-next樹在Linux-kernel 和 +Linux-next 郵件列表中發布,可從以下位置下載: + + https://www.kernel.org/pub/linux/kernel/next/ + +Linux-next 已經成爲內核開發過程中不可或缺的一部分;在一個給定的合併窗口中合併 +的所有補丁都應該在合併窗口打開之前的一段時間內找到進入Linux-next 的方法。 + +Staging 樹 +---------- + +內核原始碼樹包含drivers/staging/目錄,其中有許多驅動程序或文件系統的子目錄 +正在被添加到內核樹中。它們在仍然需要更多的修正的時候可以保留在driver/staging/ +目錄中;一旦完成,就可以將它們移到內核中。這是一種跟蹤不符合Linux內核編碼或 +質量標準的驅動程序的方法,人們可能希望使用它們並跟蹤開發。 + +Greg Kroah Hartman 目前負責維護staging 樹。仍需要修正的驅動程序將發送給他, +每個驅動程序在drivers/staging/中都有自己的子目錄。除了驅動程序源文件之外, +目錄中還應該有一個TODO文件。TODO文件列出了驅動程序需要接受的暫停的工作, +以及驅動程序的任何補丁都應該抄送的人員列表。當前的規則要求,staging的驅動 +程序必須至少正確編譯。 + +Staging 是一種讓新的驅動程序進入主線的相對容易的方法,它們會幸運地引起其他 +開發人員的注意,並迅速改進。然而,進入staging並不是故事的結尾;staging中 +沒有看到常規進展的代碼最終將被刪除。經銷商也傾向於相對不願意使用staging驅動 +程序。因此,在成爲一個合適的主線驅動的路上,staging 僅是一個中轉站。 + +工具 +---- + +從上面的文本可以看出,內核開發過程在很大程度上依賴於在不同方向上聚集補丁的 +能力。如果沒有適當強大的工具,整個系統將無法在任何地方正常工作。關於如何使用 +這些工具的教程遠遠超出了本文檔的範圍,但還是用一點篇幅介紹一些關鍵點。 + +到目前爲止,內核社區使用的主要原始碼管理系統是git。Git是在自由軟體社區中開發 +的許多分布式版本控制系統之一。它非常適合內核開發,因爲它在處理大型存儲庫和 +大量補丁時性能非常好。它也以難以學習和使用而著稱,儘管隨著時間的推移它變得 +更好了。對於內核開發人員來說,對Git的某種熟悉幾乎是一種要求;即使他們不將它 +用於自己的工作,他們也需要Git來跟上其他開發人員(以及主線)正在做的事情。 + +現在幾乎所有的Linux發行版都打包了Git。Git主頁位於: + + https://git-scm.com/ + +此頁面包含了文檔和教程的連結。 + +在不使用git的內核開發人員中,最流行的選擇幾乎肯定是Mercurial: + + http://www.seleric.com/mercurial/ + +Mercurial與Git共享許多特性,但它提供了一個界面,許多人覺得它更易於使用。 + +另一個值得了解的工具是Quilt: + + https://savannah.nongnu.org/projects/quilt + +Quilt 是一個補丁管理系統,而不是原始碼管理系統。它不會隨著時間的推移跟蹤歷史; +相反,它面向根據不斷發展的代碼庫跟蹤一組特定的更改。一些主要的子系統維護人員 +使用Quilt來管理打算向上游移動的補丁。對於某些樹的管理(例如-mm),quilt 是 +最好的工具。 + +郵件列表 +-------- + +大量的Linux內核開發工作是通過郵件列表完成的。如果不加入至少一個某個列表, +就很難成爲社區中的一個「全功能」成員。但是,Linux郵件列表對開發人員來說也是 +一個潛在的危險,他們可能會被一堆電子郵件淹沒、違反Linux列表上使用的約定, +或者兩者兼而有之。 + +大多數內核郵件列表都在vger.kernel.org上運行;主列表位於: + + http://vger.kernel.org/vger-lists.html + +不過,也有一些列表託管在別處;其中一些列表位於 +redhat.com/mailman/listinfo。 + +當然,內核開發的核心郵件列表是linux-kernel。這個列表是一個令人生畏的地方: +每天的信息量可以達到500條,噪音很高,談話技術性很強,且參與者並不總是表現出 +高度的禮貌。但是,沒有其他地方可以讓內核開發社區作爲一個整體聚集在一起; +不使用此列表的開發人員將錯過重要信息。 + +以下一些提示可以幫助在linux-kernel生存: + +- 將郵件轉移到單獨的文件夾,而不是主郵箱文件夾。我們必須能夠持續地忽略洪流。 + +- 不要試圖跟上每一次談話——沒人會這樣。重要的是要篩選感興趣的主題(但請注意 + 長時間的對話可能會偏離原來的主題,儘管未改變電子郵件的主題)和參與的人。 + +- 不要回復挑事的人。如果有人試圖激起憤怒,請忽略他們。 + +- 當回復Linux內核電子郵件(或其他列表上的電子郵件)時,請爲所有相關人員保留 + Cc: 抄送頭。如果沒有確實的理由(如明確的請求),則不應刪除收件人。一定要 + 確保你要回復的人在抄送列表中。這個慣例也使你不必在回覆郵件時明確要求被抄送。 + +- 在提出問題之前,搜索列表存檔(和整個網絡)。有些開發人員可能會對那些顯然 + 沒有完成家庭作業的人感到不耐煩。 + +- 避免頂部回復(把你的答案放在你要回復的引文上面的做法)。這會讓你的回答更難 + 理解,印象也很差。 + +- 在正確的郵件列表發問。linux-kernel 可能是通用的討論場所,但它不是尋找所有 + 子系統開發人員的最佳場所。 + +最後一點——找到正確的郵件列表——是開發人員常出錯的地方。在linux-kernel上 +提出與網絡相關的問題的人幾乎肯定會收到一個禮貌的建議,轉到netdev列表上提出, +因爲這是大多數網絡開發人員經常出現的列表。還有其他列表可用於scsi、video4linux、 +ide、filesystem等子系統。查找郵件列表的最佳位置是與內核原始碼一起打包的 +MAINTAINERS文件。 + +開始內核開發 +------------ + +關於如何開始內核開發過程的問題很常見——個人和公司皆然。同樣常見的是失誤,這 +使得關係的開始比本應的更困難。 + +公司通常希望聘請知名的開發人員來啓動開發團隊。實際上,這是一種有效的技術。 +但它也往往是昂貴的,而且對增加有經驗的內核開發人員的數量沒有多大幫助。考 +慮到時間投入,可以讓內部開發人員加快Linux內核的開發速度。利用這段時間可以 +讓僱主擁有一批既了解內核又了解公司的開發人員,還可以幫助培訓其他人。從中期 +來看,這通常是更有利可圖的方法。 + +可以理解的是,單個開發人員往往對起步感到茫然。從一個大型項目開始可能會很 +嚇人;人們往往想先用一些較小的東西來試試水。由此,一些開發人員開始創建修補 +拼寫錯誤或輕微編碼風格問題的補丁。不幸的是,這樣的補丁會產生一定程度的噪音, +這會分散整個開發社區的注意力,因此,它們越來越被人不看重。希望向社區介紹 +自己的新開發人員將無法通過這些方式獲得他們期待的反響。 + +Andrew Morton 爲有抱負的內核開發人員提供了如下建議 + +:: + + 所有內核開發者的第一個項目肯定應該是「確保內核在您可以操作的所有 + 機器上始終完美運行」。通常的方法是和其他人一起解決問題(這可能需 + 要堅持!),但就是如此——這是內核開發的一部分。 + +(http://lwn.net/articles/283982/) + +在沒有明顯問題需要解決的情況下,通常建議開發人員查看當前的回歸和開放缺陷 +列表。從來都不缺少需要解決的問題;通過解決這些問題,開發人員將從該過程獲得 +經驗,同時與開發社區的其他成員建立相互尊重。 + diff --git a/Documentation/translations/zh_TW/process/3.Early-stage.rst b/Documentation/translations/zh_TW/process/3.Early-stage.rst new file mode 100644 index 000000000000..ab2a45fd65a4 --- /dev/null +++ b/Documentation/translations/zh_TW/process/3.Early-stage.rst @@ -0,0 +1,172 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/3.Early-stage.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_early_stage: + +早期規劃 +======== + +當考慮一個Linux內核開發項目時,很可能會直接跳進去開始編碼。然而,與任何重要 +的項目一樣,許多成功的基礎最好是在第一行代碼編寫之前就打下。在早期計劃和 +溝通中花費一些時間可以在之後節省更多的時間。 + +搞清問題 +-------- + +與任何工程項目一樣,成功的內核改善從清晰描述要解決的問題開始。在某些情況 +下,這個步驟很容易:例如當某個特定硬體需要驅動程序時。不過,在其他情況下, +很容易將實際問題與建議的解決方案混在一起,這可能會導致麻煩。 + +舉個例子:幾年前,Linux音頻的開發人員尋求一種方法來運行應用程式,而不會因 +系統延遲過大而導致退出或其他問題。他們得到的解決方案是一個連接到Linux安全 +模塊(LSM)框架中的內核模塊;這個模塊可以配置爲允許特定的應用程式訪問實時 +調度程序。這個模塊被實現並發到linux-kernel郵件列表,在那裡它立即遇到了麻煩。 + +對於音頻開發人員來說,這個安全模塊足以解決他們當前的問題。但是,對於更廣泛的 +內核社區來說,這被視爲對LSM框架的濫用(LSM框架並不打算授予他們原本不具備的 +進程特權),並對系統穩定性造成風險。他們首選的解決方案包括短期的通過rlimit +機制進行實時調度訪問,以及長期的減少延遲的工作。 + +然而,音頻社區無法超越他們實施的特定解決方案來看問題;他們不願意接受替代方案。 +由此產生的分歧使這些開發人員對整個內核開發過程感到失望;其中一個開發人員返回 +到audio列表並發布了以下內容: + + 有很多非常好的Linux內核開發人員,但他們往往會被一羣傲慢的傻瓜所壓倒。 + 試圖向這些人傳達用戶需求是浪費時間。他們太「聰明」了,根本聽不到少數 + 人的話。 + +(http://lwn.net/articles/131776/) + +實際情況卻是不同的;與特定模塊相比,內核開發人員更關心系統穩定性、長期維護 +以及找到問題的正確解決方案。這個故事的寓意是把重點放在問題上——而不是具體的 +解決方案上——並在開始編寫代碼之前與開發社區討論這個問題。 + +因此,在考慮一個內核開發項目時,我們應該得到一組簡短問題的答案: + + - 需要解決的問題究竟是什麼? + + - 受此問題影響的用戶有哪些?解決方案應該解決哪些使用案例? + + - 內核現在爲何沒能解決這個問題? + +只有這樣,才能開始考慮可能的解決方案。 + + +早期討論 +-------- + +在計劃內核開發項目時,在開始實施之前與社區進行討論是很有意義的。早期溝通可以 +通過多種方式節省時間和麻煩: + + - 很可能問題是由內核以您不理解的方式解決的。Linux內核很大,具有許多不明顯 + 的特性和功能。並不是所有的內核功能都像人們所希望的那樣有文檔記錄,而且很 + 容易遺漏一些東西。某作者發布了一個完整的驅動程序,重複了一個其不 + 知道的現有驅動程序。重新發明現有輪子的代碼不僅浪費,而且不會被接受到主線 + 內核中。 + + - 建議的解決方案中可能有一些要素不適合併入主線。在編寫代碼之前,最好先了解 + 這樣的問題。 + + - 其他開發人員完全有可能考慮過這個問題;他們可能有更好的解決方案的想法,並且 + 可能願意幫助創建這個解決方案。 + +在內核開發社區的多年經驗給了我們一個明確的教訓:閉門設計和開發的內核代碼總是 +有一些問題,這些問題只有在代碼發布到社區中時才會被發現。有時這些問題很嚴重, +需要數月或數年的努力才能使代碼達到內核社區的標準。例如: + + - 設計並實現了單處理器系統的DeviceScape網絡棧。只有使其適合於多處理器系統, + 才能將其合併到主線中。在代碼中修改鎖等等是一項困難的任務;因此,這段代碼 + (現在稱爲mac80211)的合併被推遲了一年多。 + + - Reiser4文件系統包含許多功能,核心內核開發人員認爲這些功能應該在虛擬文件 + 系統層中實現。它還包括一些特性,這些特性在不將系統暴露於用戶引起的死鎖的 + 情況下是不容易實現的。這些問題過遲發現——以及拒絕處理其中一些問題——已經 + 導致Reiser4置身主線內核之外。 + + - Apparmor安全模塊以被認爲不安全和不可靠的方式使用內部虛擬文件系統數據結構。 + 這種擔心(包括其他)使Apparmor多年來無法進入主線。 + +在這些情況下,與內核開發人員的早期討論,可以避免大量的痛苦和額外的工作。 + +找誰交流? +---------- + +當開發人員決定公開他們的計劃時,下一個問題是:我們從哪裡開始?答案是找到正確 +的郵件列表和正確的維護者。對於郵件列表,最好的方法是在維護者(MAINTAINERS)文件 +中查找要發布的相關位置。如果有一個合適的子系統列表,那麼其上發布通常比在 +linux-kernel上發布更可取;您更有可能接觸到在相關子系統中具有專業知識的開發 +人員,並且環境可能具支持性。 + +找到維護人員可能會有點困難。同樣,維護者文件是開始的地方。但是,該文件往往不 +是最新的,並且並非所有子系統都在那裡顯示。實際上,維護者文件中列出的人員可能 +不是當前實際擔任該角色的人員。因此,當對聯繫誰有疑問時,一個有用的技巧是使用 +git(尤其是「git-log」)查看感興趣的子系統中當前活動的用戶。看看誰在寫補丁、 +誰會在這些補丁上加上Signed-off-by行簽名(如有)。這些人將是幫助新開發項目的 +最佳人選。 + +找到合適的維護者有時是非常具有挑戰性的,以至於內核開發人員添加了一個腳本來 +簡化這個過程: + +:: + + .../scripts/get_maintainer.pl + +當給定「-f」選項時,此腳本將返回指定文件或目錄的當前維護者。如果在命令行上 +給出了一個補丁,它將列出可能接收補丁副本的維護人員。有許多選項可以調節 +get_maintainer.pl搜索維護者的嚴格程度;請小心使用更激進的選項,因爲最終結果 +可能會包括對您正在修改的代碼沒有真正興趣的開發人員。 + +如果所有其他方法都失敗了,那麼與Andrew Morton交流是跟蹤特定代碼段維護人員 +的一種有效方法。 + +何時郵寄? +---------- + +如果可能的話,在早期階段發布你的計劃只會更有幫助。描述正在解決的問題以及已經 +制定的關於如何實施的任何計劃。您可以提供的任何信息都可以幫助開發社區爲項目 +提供有用的輸入。 + +在這個階段可能發生的一件令人沮喪的事情不是得到反對意見,而是很少或根本沒有 +反饋。令人傷心的事實是:(1)內核開發人員往往很忙;(2)不缺少有宏偉計劃但 +代碼(甚至代碼設想)很少的人去支持他們;(3)沒有人有義務審查或評論別人發表 +的想法。除此之外,高層級的設計常常隱藏著一些問題,這些問題只有在有人真正嘗試 +實現這些設計時才會被發現;因此,內核開發人員寧願看到代碼。 + +如果發布請求評論(RFC)並沒得到什麼有用的評論,不要以爲這意味著無人對此項目 +有興趣,同時你也不能假設你的想法沒有問題。在這種情況下,最好的做法是繼續進 +行,把你的進展隨時通知社區。 + +獲得官方認可 +----------------------- + +如果您的工作是在公司環境中完成的,就像大多數Linux內核工作一樣;顯然,在您將 +公司的計劃或代碼發布到公共郵件列表之前,必須獲得有適當權利經理的許可。發布 +不確定是否兼容GPL的代碼尤其會帶來問題;公司的管理層和法律人員越早能夠就發布 +內核開發項目達成一致,對參與的每個人都越好。 + +一些讀者可能會認爲他們的核心工作是爲了支持還沒有正式承認存在的產品。將僱主 +的計劃公布在公共郵件列表上可能不是一個可行的選擇。在這種情況下,有必要考慮 +保密是否真的是必要的;通常不需要把開發計劃關在門內。 + +的確,有些情況下一家公司在開發過程的早期無法合法地披露其計劃。擁有經驗豐富 +的內核開發人員的公司可能選擇以開環的方式進行開發,前提是他們以後能夠避免 +嚴重的集成問題。對於沒有這種內部專業知識的公司,最好的選擇往往是聘請外部 +開發者根據保密協議審查計劃。Linux基金會運行了一個NDA程序,旨在幫助解決這種 +情況;更多信息參見: + + http://www.linuxfoundation.org/nda/ + +這種審查通常足以避免以後出現嚴重問題,而無需公開披露項目。 + diff --git a/Documentation/translations/zh_TW/process/4.Coding.rst b/Documentation/translations/zh_TW/process/4.Coding.rst new file mode 100644 index 000000000000..ccc3946227a0 --- /dev/null +++ b/Documentation/translations/zh_TW/process/4.Coding.rst @@ -0,0 +1,297 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/4.Coding.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_coding: + +使代碼正確 +====================== + +雖然一個堅實的、面向社區的設計過程有很多值得說道的,但是任何內核開發項目工作 +的證明都反映在代碼中。它是將由其他開發人員檢查併合並(或不合併)到主線樹中 +的代碼。所以這段代碼的質量決定了項目的最終成功。 + +本節將檢查編碼過程。我們將從內核開發人員常犯的幾種錯誤開始。然後重點將轉移 +到正確的做法和相關有用的工具上。 + +陷阱 +---- + +代碼風格 +******** + +內核長期以來都有其標準的代碼風格,如 +:ref:`Documentation/translations/zh_TW/process/coding-style.rst ` +中所述。在多數時候,該文檔中描述的準則至多被認爲是建議性的。因此,內核中存在 +大量不符合代碼風格準則的代碼。這種代碼的存在會給內核開發人員帶來兩方面的危害。 + +首先,相信內核代碼標準並不重要,也不強制執行。但事實上,如果沒有按照標準 +編寫代碼,那麼新代碼將很難加入到內核中;許多開發人員甚至會在審查代碼之前要求 +對代碼進行重新格式化。一個像內核這麼大的代碼庫需要一些統一格式的代碼,以使 +開發人員能夠快速理解其中的任何部分。所以再也經不起奇怪格式的代碼的折騰了。 + +內核的代碼風格偶爾會與僱主的強制風格發生衝突。在這種情況下,必須在代碼合併 +之前遵從內核代碼風格。將代碼放入內核意味著以多種方式放棄一定程度的控制權—— +包括控制代碼樣式。 + +另一個危害是認爲已經在內核中的代碼迫切需要修復代碼樣式。開發者可能會開始編寫 +重新格式化補丁,作爲熟悉開發過程的一種方式,或者作爲將其名字寫入內核變更日誌 +的一種方式,或者兩者兼而有之。但是純代碼風格的修復被開發社區視爲噪音,它們往 +往受到冷遇。因此,最好避免編寫這種類型的補丁。在由於其他原因處理一段代碼的 +同時順帶修復其樣式是很自然的,但是不應該僅爲了更改代碼樣式而更改之。 + +代碼風格文檔也不應該被視爲絕對不可違反的規則。如果有一個足夠的理由反對這種 +樣式(例如爲了80列限制拆分行會導致可讀性大大降低),那麼就這樣做吧。 + +注意您還可以使用 ``clang-format`` 工具來幫助您處理這些規則,快速自動重新格式 +化部分代碼,和審閱完整的文件以發現代碼樣式錯誤、拼寫錯誤和可能的改進。它還 +可以方便地排序 ``#includes`` 、對齊變量/宏、重排文本和其他類似任務。有關詳細 +信息,請參閱文檔 :ref:`Documentation/process/clang-format.rst ` + +抽象層 +****** + +計算機科學教授教學生以靈活性和信息隱藏的名義廣泛使用抽象層。當然,內核廣泛 +地使用了抽象;任何涉及數百萬行代碼的項目都必須做到這一點以存續下來。但經驗 +表明,過度或過早的抽象可能和過早的優化一樣有害。抽象應用在適當層級, +不要過度。 + +簡單點,先考慮一個調用時始終只有一個參數且總爲零的函數。我們可以保留這個參數, +以在需要使用它時提供的額外靈活性。不過,在那時實現了這個額外參數的代碼很有 +可能以某種從未被注意到的微妙方式被破壞——因爲它從未被使用過。或者當需要額外 +的靈活性時,它並未以符合程式設計師當初期望的方式來實現。內核開發人員通常會提交 +補丁來刪除未使用的參數;一般來說,一開始就不應該添加這些參數。 + +隱藏硬體訪問的抽象層——通常爲了允許大量的驅動程序兼容多個作業系統——尤其不受 +歡迎。這樣的層使代碼變得模糊,可能會造成性能損失;它們不屬於Linux內核。 + +另一方面,如果您發現自己從另一個內核子系統複製了大量的代碼,那麼是時候 +了解一下:是否需要將這些代碼中的部分提取到單獨的庫中,或者在更高的層次上 +實現這些功能。在整個內核中複製相同的代碼沒有價值。 + +#ifdef 和預處理 +*************** + +C預處理器似乎給一些C程式設計師帶來了強大的誘惑,他們認爲它是一種將大量靈活性加入 +原始碼中的方法。但是預處理器不是C,大量使用它會導致代碼對其他人來說更難閱讀, +對編譯器來說更難檢查正確性。使用了大量預處理器幾乎總是代碼需要一些 +清理工作的標誌。 + +使用#ifdef的條件編譯實際上是一個強大的功能,它在內核中使用。但是很少有人希望 +看到代碼被鋪滿#ifdef塊。一般規定,ifdef的使用應儘可能限制在頭文件中。條件 +編譯代碼可以限制函數,如果代碼不存在,這些函數就直接變成空的。然後編譯器將 +悄悄地優化對空函數的調用。使得代碼更加清晰,更容易理解。 + +C預處理器宏存在許多危險性,包括可能對具有副作用且沒有類型安全的表達式進行多 +重評估。如果您試圖定義宏,請考慮創建一個內聯函數替代。結果相同的代碼,內聯 +函數更容易閱讀,不會多次計算其參數,並且允許編譯器對參數和返回值執行類型檢查。 + +內聯函數 +******** + +不過,內聯函數本身也存在風險。程式設計師可以傾心於避免函數調用和用內聯函數填充源 +文件所固有的效率。然而,這些功能實際上會降低性能。因爲它們的代碼在每個調用站 +點都被複製一遍,所以最終會增加編譯內核的大小。此外,這也對處理器的內存緩存 +造成壓力,從而大大降低執行速度。通常內聯函數應該非常小,而且相對較少。畢竟 +函數調用的成本並不高;大量創建內聯函數是過早優化的典型例子。 + +一般來說,內核程式設計師會自冒風險忽略緩存效果。在數據結構課程開頭中的經典 +時間/空間權衡通常不適用於當代硬體。空間 *就是* 時間,因爲一個大的程序比一個 +更緊湊的程序運行得慢。 + +較新的編譯器越來越激進地決定一個給定函數是否應該內聯。因此,隨意放置使用 +「inline」關鍵字可能不僅僅是過度的,也可能是無用的。 + +鎖 +** + +2006年5月,「deviceescape」網絡堆棧在前呼後擁下以GPL發布,並被納入主線內核。 +這是一個受歡迎的消息;Linux中對無線網絡的支持充其量被認爲是不合格的,而 +Deviceescape堆棧承諾修復這種情況。然而直到2007年6月(2.6.22),這段代碼才真 +正進入主線。發生了什麼? + +這段代碼出現了許多閉門造車的跡象。但一個大麻煩是,它並不是爲多處理器系統而 +設計。在合併這個網絡堆棧(現在稱爲mac80211)之前,需要對其進行一個鎖方案的 +改造。 + +曾經,Linux內核代碼可以在不考慮多處理器系統所帶來的並發性問題的情況下進行 +開發。然而現在,這個文檔就是在雙核筆記本電腦上寫的。即使在單處理器系統上, +爲提高響應能力所做的工作也會提高內核內的並發性水平。編寫內核代碼而不考慮鎖 +的日子早已遠去。 + +可以由多個線程並發訪問的任何資源(數據結構、硬體寄存器等)必須由鎖保護。新 +的代碼應該謹記這一要求;事後修改鎖是一項相當困難的任務。內核開發人員應該花 +時間充分了解可用的鎖原語,以便爲工作選擇正確的工具。對並發性缺乏關注的代碼 +很難進入主線。 + +回歸 +**** + +最後一個值得一提的危險是回歸:它可能會引起導致現有用戶的某些東西中斷的改變 +(這也可能會帶來很大的改進)。這種變化被稱爲「回歸」,回歸已經成爲主線內核 +最不受歡迎的問題。除了少數例外情況,如果回歸不能及時修正,會導致回歸的修改 +將被取消。最好首先避免回歸發生。 + +人們常常爭論,如果回歸帶來的功能遠超過產生的問題,那麼回歸是否爲可接受的。 +如果它破壞了一個系統卻爲十個系統帶來新的功能,爲何不改改態度呢?2007年7月, +Linus對這個問題給出了最佳答案: + +:: + + 所以我們不會通過引入新問題來修復錯誤。這種方式是靠不住的,沒人知道 + 是否真的有進展。是前進兩步、後退一步,還是前進一步、後退兩步? + +(http://lwn.net/articles/243460/) + +特別不受歡迎的一種回歸類型是用戶空間ABI的任何變化。一旦接口被導出到用戶空間, +就必須無限期地支持它。這一事實使得用戶空間接口的創建特別具有挑戰性:因爲它們 +不能以不兼容的方式進行更改,所以必須一次就對。因此,用戶空間接口總是需要大量 +的思考、清晰的文檔和廣泛的審查。 + + +代碼檢查工具 +------------ + +至少目前,編寫無錯誤代碼仍然是我們中很少人能達到的理想狀態。不過,我們希望做 +的是,在代碼進入主線內核之前,儘可能多地捕獲並修復這些錯誤。爲此,內核開發人 +員已經提供了一系列令人印象深刻的工具,可以自動捕獲各種各樣的隱藏問題。計算機 +發現的任何問題都是一個以後不會困擾用戶的問題,因此,只要有可能,就應該使用 +自動化工具。 + +第一步是注意編譯器產生的警告。當前版本的GCC可以檢測(並警告)大量潛在錯誤。 +通常,這些警告都指向真正的問題。提交以供審閱的代碼一般不會產生任何編譯器警告。 +在消除警告時,注意了解真正的原因,並儘量避免僅「修復」使警告消失而不解決其原因。 + +請注意,並非所有編譯器警告都默認啓用。使用「make KCFLAGS=-W」構建內核以 +獲得完整集合。 + +內核提供了幾個配置選項,可以打開調試功能;大多數配置選項位於「kernel hacking」 +子菜單中。對於任何用於開發或測試目的的內核,都應該啓用其中幾個選項。特別是, +您應該打開: + + - FRAME_WARN 獲取大於給定數量的堆棧幀的警告。 + 這些警告生成的輸出可能比較冗長,但您不必擔心來自內核其他部分的警告。 + + - DEBUG_OBJECTS 將添加代碼以跟蹤內核創建的各種對象的生命周期,並在出現問題 + 時發出警告。如果你要添加創建(和導出)關於其自己的複雜對象的子系統,請 + 考慮打開對象調試基礎結構的支持。 + + - DEBUG_SLAB 可以發現各種內存分配和使用錯誤;它應該用於大多數開發內核。 + + - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP 和 DEBUG_MUTEXES 會發現許多常見的 + 鎖錯誤。 + +還有很多其他調試選項,其中一些將在下面討論。其中一些有顯著的性能影響,不應 +一直使用。在學習可用選項上花費一些時間,可能會在短期內得到許多回報。 + +其中一個較重的調試工具是鎖檢查器或「lockdep」。該工具將跟蹤系統中每個鎖 +(spinlock或mutex)的獲取和釋放、獲取鎖的相對順序、當前中斷環境等等。然後, +它可以確保總是以相同的順序獲取鎖,相同的中斷假設適用於所有情況等等。換句話 +說,lockdep可以找到許多導致系統死鎖的場景。在部署的系統中,這種問題可能會 +很痛苦(對於開發人員和用戶而言);LockDep允許提前以自動方式發現問題。具有 +任何類型的非普通鎖的代碼在提交合併前應在啓用lockdep的情況下運行測試。 + +作爲一個勤奮的內核程式設計師,毫無疑問,您將檢查任何可能失敗的操作(如內存分配) +的返回狀態。然而,事實上,最終的故障復現路徑可能完全沒有經過測試。未測試的 +代碼往往會出問題;如果所有這些錯誤處理路徑都被執行了幾次,那麼您可能對代碼 +更有信心。 + +內核提供了一個可以做到這一點的錯誤注入框架,特別是在涉及內存分配的情況下。 +啓用故障注入後,內存分配的可配置失敗的百分比;這些失敗可以限定在特定的代碼 +範圍內。在啓用了故障注入的情況下運行,程式設計師可以看到當情況惡化時代碼如何響 +應。有關如何使用此工具的詳細信息,請參閱 +Documentation/fault-injection/fault-injection.rst。 + +「sparse」靜態分析工具可以發現其他類型的錯誤。sparse可以警告程式設計師用戶空間 +和內核空間地址之間的混淆、大端序與小端序的混淆、在需要一組位標誌的地方傳遞 +整數值等等。sparse必須單獨安裝(如果您的分發伺服器沒有將其打包, +可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到), +然後可以通過在make命令中添加「C=1」在代碼上運行它。 + +「Coccinelle」工具 :ref:`http://coccinelle.lip6.fr/ ` +能夠發現各種潛在的編碼問題;它還可以爲這些問題提出修複方案。在 +scripts/coccinelle目錄下已經打包了相當多的內核「語義補丁」;運行 +「make coccicheck」將運行這些語義補丁並報告發現的任何問題。有關詳細信息,請參閱 +:ref:`Documentation/dev-tools/coccinelle.rst ` + + +其他類型的可移植性錯誤最好通過爲其他體系結構編譯代碼來發現。如果沒有S/390系統 +或Blackfin開發板,您仍然可以執行編譯步驟。可以在以下位置找到一大堆用於x86系統的 +交叉編譯器: + + https://www.kernel.org/pub/tools/crosstool/ + +花一些時間安裝和使用這些編譯器將有助於避免以後的尷尬。 + +文檔 +---- + +文檔通常比內核開發規則更爲例外。即便如此,足夠的文檔將有助於簡化將新代碼合併 +到內核中的過程,使其他開發人員的生活更輕鬆,並對您的用戶有所幫助。在許多情況 +下,添加文檔已基本上是強制性的。 + +任何補丁的第一個文檔是其關聯的變更日誌。日誌條目應該描述正在解決的問題、解決 +方案的形式、處理補丁的人員、對性能的任何相關影響,以及理解補丁可能需要的任何 +其他內容。確保變更日誌說明了*爲什麼*補丁值得應用;大量開發者未能提供這些信息。 + +任何添加新用戶空間接口的代碼——包括新的sysfs或/proc文件——都應該包含該接口 +的文檔,該文檔使用戶空間開發人員能夠知道他們在使用什麼。請參閱 +Documentation/ABI/README,了解如何此文檔格式以及需要提供哪些信息。 + +文檔 :ref:`Documentation/admin-guide/kernel-parameters.rst ` +描述了內核的所有引導時間參數。任何添加新參數的補丁都應該向該文檔添加適當的 +條目。 + +任何新的配置選項都必須附有幫助文本,幫助文本需清楚地解釋這些選項以及用戶可能 +希望何時使用它們。 + +許多子系統的內部API信息通過專門格式化的注釋進行記錄;這些注釋可以通過 +「kernel-doc」腳本以多種方式提取和格式化。如果您在具有kerneldoc注釋的子系統中 +工作,則應該維護它們,並根據需要爲外部可用的功能添加它們。即使在沒有如此記錄 +的領域中,爲將來添加kerneldoc注釋也沒有壞處;實際上,這對於剛開始開發內核的人 +來說是一個有用的活動。這些注釋的格式以及如何創建kerneldoc模板的一些信息可以在 +:ref:`Documentation/doc-guide/ ` 上找到。 + +任何閱讀大量現有內核代碼的人都會注意到,注釋的缺失往往是最值得注意的。同時, +對新代碼的要求比過去更高;合併未注釋的代碼將更加困難。這就是說,人們並不期望 +詳細注釋的代碼。代碼本身應該是自解釋的,注釋闡釋了更微妙的方面。 + +某些事情應該總是被注釋。使用內存屏障時,應附上一行文字,解釋爲什麼需要設置內存 +屏障。數據結構的鎖規則通常需要在某個地方解釋。一般來說,主要數據結構需要全面 +的文檔。應該指出代碼中分立的位之間不明顯的依賴性。任何可能誘使代碼管理人進行 +錯誤的「清理」的事情都需要一個注釋來說明爲什麼要這樣做。等等。 + + +內部API更改 +----------- + +內核提供給用戶空間的二進位接口不能被破壞,除非逼不得已。而內核的內部編程接口 +是高度流動的,當需要時可以更改。如果你發現自己不得不處理一個內核API,或者僅 +僅因爲它不滿足你的需求導致無法使用特定的功能,這可能是API需要改變的一個標誌。 +作爲內核開發人員,您有權進行此類更改。 + +的確可以進行API更改,但更改必須是合理的。因此任何進行內部API更改的補丁都應該 +附帶關於更改內容和必要原因的描述。這種變化也應該拆分成一個單獨的補丁,而不是 +埋在一個更大的補丁中。 + +另一個要點是,更改內部API的開發人員通常要負責修復內核樹中被更改破壞的任何代碼。 +對於一個廣泛使用的函數,這個責任可以導致成百上千的變化,其中許多變化可能與其他 +開發人員正在做的工作相衝突。不用說,這可能是一項大工程,所以最好確保理由是 +可靠的。請注意,coccinelle工具可以幫助進行廣泛的API更改。 + +在進行不兼容的API更改時,應儘可能確保編譯器捕獲未更新的代碼。這將幫助您確保找 +到該接口的樹內用處。它還將警告開發人員樹外代碼存在他們需要響應的更改。支持樹外 +代碼不是內核開發人員需要擔心的事情,但是我們也不必使樹外開發人員的生活有不必要 +的困難。 + diff --git a/Documentation/translations/zh_TW/process/5.Posting.rst b/Documentation/translations/zh_TW/process/5.Posting.rst new file mode 100644 index 000000000000..5578bca403e6 --- /dev/null +++ b/Documentation/translations/zh_TW/process/5.Posting.rst @@ -0,0 +1,251 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/5.Posting.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_posting: + +發布補丁 +======== + +您的工作遲早會準備好提交給社區進行審查,並最終包含到主線內核中。毫不稀奇, +內核開發社區已經發展出一套用於發布補丁的約定和過程;遵循這些約定和過程將使 +參與其中的每個人的生活更加輕鬆。本文檔試圖描述這些約定的部分細節;更多信息 +也可在以下文檔中找到 +:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst `, +:ref:`Documentation/translations/zh_TW/process/submitting-drivers.rst ` +和 :ref:`Documentation/translations/zh_TW/process/submit-checklist.rst `。 + +何時郵寄 +-------- + +在補丁完全「準備好」之前,避免發布補丁是一種持續的誘惑。對於簡單的補丁,這 +不是問題。但是如果正在完成的工作很複雜,那麼在工作完成之前從社區獲得反饋就 +可以獲得很多好處。因此,您應該考慮發布正在進行的工作,甚至維護一個可用的Git +樹,以便感興趣的開發人員可以隨時趕上您的工作。 + +當發布中有尚未準備好被包含的代碼,最好在發布中說明。還應提及任何有待完成的 +主要工作和任何已知問題。很少有人會願意看那些被認爲是半生不熟的補丁,但是 +那些願意的人會帶著他們的點子來一起幫助你把工作推向正確的方向。 + +創建補丁之前 +------------ + +在考慮將補丁發送到開發社區之前,有許多事情應該做。包括: + + - 儘可能地測試代碼。利用內核的調試工具,確保內核使用了所有可能的配置選項組合 + 進行構建,使用交叉編譯器爲不同的體系結構進行構建等。 + + - 確保您的代碼符合內核代碼風格指南。 + + - 您的更改是否具有性能影響?如果是這樣,您應該運行基準測試來顯示您的變更的 + 影響(或好處);結果的摘要應該包含在補丁中。 + + - 確保您有權發布代碼。如果這項工作是爲僱主完成的,僱主對這項工作具有所有權, + 並且必須同意根據GPL對其進行發布。 + +一般來說,在發布代碼之前進行一些額外的思考,幾乎總是能在短時間內得到回報。 + +補丁準備 +-------- + +準備補丁發布的工作量可能很驚人,但在此嘗試節省時間通常是不明智的,即使在短期 +內亦然。 + +必須針對內核的特定版本準備補丁。一般來說,補丁應該基於Linus的Git樹中的當前 +主線。當以主線爲基礎時,請從一個衆所周知的發布點開始——如穩定版本或 -rc +版本發布點——而不是在一個任意的主線分支點。 + +也可能需要針對-mm、linux-next或子系統樹生成版本,以便於更廣泛的測試和審查。 +根據補丁的區域以及其他地方的情況,針對其他樹建立的補丁可能需要大量的工作來 +解決衝突和處理API更改。 + +只有最簡單的更改才應格式化爲單個補丁;其他所有更改都應作爲一系列邏輯更改進行。 +分割補丁是一門藝術;一些開發人員花了很長時間來弄清楚如何按照社區期望的方式來 +分割。不過,這些經驗法則也許有幫助: + + - 您發布的補丁系列幾乎肯定不會是開發過程中版本控制系統中的一系列更改。相反, + 需要對您所做更改的最終形式加以考慮,然後以有意義的方式進行拆分。開發人員對 + 離散的、自包含的更改感興趣,而不是您創造這些更改的原始路徑。 + + - 每個邏輯上獨立的變更都應該格式化爲單獨的補丁。這些更改可以是小的(如「向 + 此結構體添加欄位」)或大的(如添加一個重要的新驅動程序),但它們在概念上 + 應該是小的,並且可以在一行內簡述。每個補丁都應該做一個特定的、可以單獨 + 檢查並驗證它所做的事情的更改。 + + - 換種方式重申上述準則,也就是說:不要在同一補丁中混合不同類型的更改。如果 + 一個補丁修復了一個關鍵的安全漏洞,又重新排列了一些結構,還重新格式化了代 + 碼,那麼它很有可能會被忽略,從而導致重要的修復丟失。 + + - 每個補丁都應該能創建一個可以正確地構建和運行的內核;如果補丁系列在中間被 + 斷開,那麼結果仍應是一個正常工作的內核。部分應用一系列補丁是使用 + 「git bisct」工具查找回歸的一個常見場景;如果結果是一個損壞的內核,那麼將使 + 那些從事追蹤問題的高尚工作的開發人員和用戶的生活更加艱難。 + + - 不要過分分割。一位開發人員曾經將一組針對單個文件的編輯分成500個單獨的補丁 + 發布,這並沒有使他成爲內核郵件列表中最受歡迎的人。一個補丁可以相當大, + 只要它仍然包含一個單一的 *邏輯* 變更。 + + - 用一系列補丁添加一個全新的基礎設施,但是該設施在系列中的最後一個補丁啓用 + 整個變更之前不能使用,這看起來很誘人。如果可能的話,應該避免這種誘惑; + 如果這個系列增加了回歸,那麼二分法將指出最後一個補丁是導致問題的補丁, + 即使真正的bug在其他地方。只要有可能,添加新代碼的補丁程序應該立即激活該 + 代碼。 + +創建完美補丁系列的工作可能是一個令人沮喪的過程,在完成「真正的工作」之後需要 +花費大量的時間和思考。但是如果做得好,花費的時間就是值得的。 + +補丁格式和更改日誌 +------------------ + +所以現在你有了一系列完美的補丁可以發布,但是這項工作還沒有完成。每個補丁都 +需要被格式化成一條消息,以快速而清晰地將其目的傳達到世界其他地方。爲此, +每個補丁將由以下部分組成: + + - 可選的「From」行,表明補丁作者。只有當你通過電子郵件發送別人的補丁時,這一行 + 才是必須的,但是爲防止疑問加上它也不會有什麼壞處。 + + - 一行描述,說明補丁的作用。對於在沒有其他上下文的情況下看到該消息的讀者來說, + 該消息應足以確定修補程序的範圍;此行將顯示在「short form(簡短格式)」變更 + 日誌中。此消息通常需要先加上子系統名稱前綴,然後是補丁的目的。例如: + + :: + + gpio: fix build on CONFIG_GPIO_SYSFS=n + + - 一行空白,後接補丁內容的詳細描述。此描述可以是任意需要的長度;它應該說明補丁 + 的作用以及爲什麼它應該應用於內核。 + + - 一個或多個標記行,至少有一個由補丁作者的 Signed-off-by 簽名。標記將在下面 + 詳細描述。 + +上面的項目一起構成補丁的變更日誌。寫一則好的變更日誌是一門至關重要但常常被 +忽視的藝術;值得花一點時間來討論這個問題。當你編寫變更日誌時,你應該記住有 +很多不同的人會讀你的話。其中包括子系統維護人員和審查人員,他們需要決定是否 +應該合併補丁,分銷商和其他維護人員試圖決定是否應該將補丁反向移植到其他內核, +缺陷搜尋人員想知道補丁是否導致他們正在追查的問題,以及想知道內核如何變化的 +用戶等等。一個好的變更日誌以最直接和最簡潔的方式向所有這些人傳達所需的信息。 + +在結尾,總結行應該描述變更的影響和動機,以及在一行約束條件下可能發生的變化。 +然後,詳細的描述可以詳述這些主題,並提供任何需要的附加信息。如果補丁修復了 +一個缺陷,請引用引入該缺陷的提交(如果可能,請在引用提交時同時提供其 id 和 +標題)。如果某個問題與特定的日誌或編譯器輸出相關聯,請包含該輸出以幫助其他 +人搜索同一問題的解決方案。如果更改是爲了支持以後補丁中的其他更改,那麼應當 +說明。如果更改了內部API,請詳細說明這些更改以及其他開發人員應該如何響應。 +一般來說,你越把自己放在每個閱讀你變更日誌的人的位置上,變更日誌(和內核 +作爲一個整體)就越好。 + +不消說,變更日誌是將變更提交到版本控制系統時使用的文本。接下來將是: + + - 補丁本身,採用統一的(「-u」)補丁格式。使用「-p」選項來diff將使函數名與 + 更改相關聯,從而使結果補丁更容易被其他人讀取。 + +您應該避免在補丁中包括與更改不相關文件(例如,構建過程生成的文件或編輯器 +備份文件)。文檔目錄中的「dontdiff」文件在這方面有幫助;使用「-X」選項將 +其傳遞給diff。 + +上面提到的標籤(tag)用於描述各種開發人員如何與這個補丁的開發相關聯。 +:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` +文檔中對它們進行了詳細描述;下面是一個簡短的總結。每一行的格式如下: + +:: + + tag: Full Name optional-other-stuff + +常用的標籤有: + + - Signed-off-by: 這是一個開發人員的證明,證明他或她有權提交補丁以包含到內核 + 中。這表明同意開發者來源認證協議,其全文見 + :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` + 如果沒有合適的簽字,則不能合併到主線中。 + + - Co-developed-by: 聲明補丁是由多個開發人員共同創建的;當幾個人在一個補丁上 + 工作時,它用於給出共同作者(除了 From: 所給出的作者之外)。由於 + Co-developed-by: 表示作者身份,所以每個共同開發人,必須緊跟在相關合作作者 + 的Signed-off-by之後。具體內容和示例見以下文件 + :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` + + - Acked-by: 表示另一個開發人員(通常是相關代碼的維護人員)同意補丁適合包含 + 在內核中。 + + - Tested-by: 聲明某人已經測試了補丁並確認它可以工作。 + + - Reviewed-by: 表示某開發人員已經審查了補丁的正確性;有關詳細信息,請參閱 + :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` + + - Reported-by: 指定報告此補丁修復的問題的用戶;此標記用於表示感謝。 + + - Cc:指定某人收到了補丁的副本,並有機會對此發表評論。 + +在補丁中添加標籤時要小心:只有Cc:才適合在沒有指定人員明確許可的情況下添加。 + +發送補丁 +-------- + +在寄出補丁之前,您還需要注意以下幾點: + + - 您確定您的郵件發送程序不會損壞補丁嗎?被郵件客戶端更改空白或修飾了行的補丁 + 無法被另一端接受,並且通常不會進行任何詳細檢查。如果有任何疑問,先把補丁寄 + 給你自己,讓你自己確定它是完好無損的。 + + :ref:`Documentation/translations/zh_TW/process/email-clients.rst ` + 提供了一些有用的提示,可以讓特定的郵件客戶端正常發送補丁。 + + - 你確定你的補丁沒有荒唐的錯誤嗎?您應該始終通過scripts/checkpatch.pl檢查 + 補丁程序,並解決它提出的問題。請記住,checkpatch.pl,雖然體現了對內核補丁 + 應該是什麼樣的大量思考,但它並不比您聰明。如果修復checkpatch.pl給的問題會 + 使代碼變得更糟,請不要這樣做。 + +補丁應始終以純文本形式發送。請不要將它們作爲附件發送;這使得審閱者在答覆中更難 +引用補丁的部分。相反,只需將補丁直接放到您的消息中。 + +寄出補丁時,重要的是將副本發送給任何可能感興趣的人。與其他一些項目不同,內核 +鼓勵人們甚至錯誤地發送過多的副本;不要假定相關人員會看到您在郵件列表中的發布。 +尤其是,副本應發送至: + + - 受影響子系統的維護人員。如前所述,維護人員文件是查找這些人員的首選地方。 + + - 其他在同一領域工作的開發人員,尤其是那些現在可能在那裡工作的開發人員。使用 + git查看還有誰修改了您正在處理的文件,這很有幫助。 + + - 如果您對某錯誤報告或功能請求做出響應,也可以抄送原始發送人。 + + - 將副本發送到相關郵件列表,或者若無相關列表,則發送到linux-kernel列表。 + + - 如果您正在修復一個缺陷,請考慮該修復是否應進入下一個穩定更新。如果是這樣, + 補丁副本也應發到stable@vger.kernel.org 。另外,在補丁本身的標籤中添加一個 + 「Cc: stable@vger.kernel.org」;這將使穩定版團隊在修復進入主線時收到通知。 + +當爲一個補丁選擇接收者時,最好清楚你認爲誰最終會接受這個補丁並將其合併。雖然 +可以將補丁直接發給Linus Torvalds並讓他合併,但通常情況下不會這樣做。Linus很 +忙,並且有子系統維護人員負責監視內核的特定部分。通常您會希望維護人員合併您的 +補丁。如果沒有明顯的維護人員,Andrew Morton通常是最後的補丁接收者。 + +補丁需要好的主題行。補丁主題行的規範格式如下: + +:: + + [PATCH nn/mm] subsys: one-line description of the patch + +其中「nn」是補丁的序號,「mm」是系列中補丁的總數,「subsys」是受影響子系統的 +名稱。當然,一個單獨的補丁可以省略nn/mm。 + +如果您有一系列重要的補丁,那麼通常發送一個簡介作爲第〇部分。不過,這個約定 +並沒有得到普遍遵循;如果您使用它,請記住簡介中的信息不會進入內核變更日誌。 +因此,請確保補丁本身具有完整的變更日誌信息。 + +一般來說,多部分補丁的第二部分和後續部分應作爲對第一部分的回覆發送,以便它們 +在接收端都連接在一起。像git和coilt這樣的工具有命令,可以通過適當的線程發送 +一組補丁。但是,如果您有一長串補丁,並正使用git,請不要使用–-chain-reply-to +選項,以避免創建過深的嵌套。 + diff --git a/Documentation/translations/zh_TW/process/6.Followthrough.rst b/Documentation/translations/zh_TW/process/6.Followthrough.rst new file mode 100644 index 000000000000..4af782742db3 --- /dev/null +++ b/Documentation/translations/zh_TW/process/6.Followthrough.rst @@ -0,0 +1,156 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/6.Followthrough.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_followthrough: + +跟進 +==== + +此時,您已經遵循了到目前爲止給出的指導方針,並且,隨著您自己的工程技能的增加, +已經發布了一系列完美的補丁。即使是經驗豐富的內核開發人員也能犯的最大錯誤之一 +是,認爲他們的工作現在已經完成了。事實上,發布補丁意味著進入流程的下一個階段, +可能還需要做很多工作。 + +一個補丁在首次發布時就非常出色、沒有改進的餘地,這是很罕見的。內核開發流程已 +認識到這一事實,因此它非常注重對已發布代碼的改進。作爲代碼的作者,您應該與 +內核社區合作,以確保您的代碼符合內核的質量標準。如果不參與這個過程,很可能會 +無法將補丁合併到主線中。 + +與審閱者合作 +------------ + +任何意義上的補丁都會導致其他開發人員在審查代碼時發表大量評論。對於許多開發 +人員來說,與審閱人員合作可能是內核開發過程中最令人生畏的部分。但是如果你 +記住一些事情,生活會變得容易得多: + + - 如果你已經很好地解釋了你的補丁,審閱人員會理解它的價值,以及爲什麼你會 + 費盡心思去寫它。但是這個並不能阻止他們提出一個基本的問題:在五年或十年後 + 維護含有此代碼的內核會怎麼樣?你可能被要求做出的許多改變——從編碼風格的 + 調整到大量的重寫——都來自於對Linux的理解,即從現在起十年後,Linux仍將 + 在開發中。 + + - 代碼審查是一項艱苦的工作,這是一項相對吃力不討好的工作;人們記得誰編寫了 + 內核代碼,但對於那些審查它的人來說,幾乎沒有什麼長久的名聲。因此,審閱 + 人員可能會變得暴躁,尤其是當他們看到同樣的錯誤被一遍又一遍地犯下時。如果 + 你得到了一個看起來憤怒、侮辱或完全冒犯你的評論,請抑制以同樣方式回應的衝動。 + 代碼審查是關於代碼的,而不是關於人的,代碼審閱人員不會親自攻擊您。 + + - 同樣,代碼審閱人員也不想以犧牲你僱主的利益爲代價來宣傳他們僱主的議程。 + 內核開發人員通常希望今後幾年能在內核上工作,但他們明白他們的僱主可能會改 + 變。他們真的,幾乎毫無例外地,致力於創造他們所能做到的最好的內核;他們並 + 沒有試圖給僱主的競爭對手造成不適。 + +所有這些歸根結底就是,當審閱者向您發送評論時,您需要注意他們正在進行的技術 +評論。不要讓他們的表達方式或你自己的驕傲阻止此事。當你在一個補丁上得到評論 +時,花點時間去理解評論人想說什麼。如果可能的話,請修覆審閱者要求您修復的內 +容。然後回覆審閱者:謝謝他們,並描述你將如何回答他們的問題。 + +請注意,您不必同意審閱者建議的每個更改。如果您認爲審閱者誤解了您的代碼,請 +解釋到底發生了什麼。如果您對建議的更改有技術上的異議,請描述它並證明您對該 +問題的解決方案是正確的。如果你的解釋有道理,審閱者會接受的。不過,如果你的 +解釋證明缺乏說服力,尤其是當其他人開始同意審稿人的觀點時,請花些時間重新考慮 +一下。你很容易對自己解決問題的方法視而不見,以至於你沒有意識到某些東西完全 +是錯誤的,或者你甚至沒有解決正確的問題。 + +Andrew Morton建議,每一個不會導致代碼更改的審閱評論都應該產生一個額外的代碼 +注釋;這可以幫助未來的審閱人員避免第一次出現的問題。 + +一個致命的錯誤是忽視評論,希望它們會消失。它們不會走的。如果您在沒有對之前 +收到的評論做出響應的情況下重新發布代碼,那麼很可能會發現補丁毫無用處。 + +說到重新發布代碼:請記住,審閱者不會記住您上次發布的代碼的所有細節。因此, +提醒審閱人員以前提出的問題以及您如何處理這些問題總是一個好主意;補丁變更 +日誌是提供此類信息的好地方。審閱者不必搜索列表檔案來熟悉上次所說的內容; +如果您幫助他們直接開始,當他們重新查看您的代碼時,心情會更好。 + +如果你已經試著做正確的事情,但事情仍然沒有進展呢?大多數技術上的分歧都可以 +通過討論來解決,但有時人們仍需要做出決定。如果你真的認爲這個決定對你不利, +你可以試著向有更高權力的人上訴。對於本文,更高權力的人是 Andrew Morton 。 +Andrew 在內核開發社區中非常受尊敬;他經常爲似乎被絕望阻塞的事情清障。儘管 +如此,不應輕易就直接找 Andrew ,也不應在所有其他替代方案都被嘗試之前找他。 +當然,記住,他也可能不同意你的意見。 + +接下來會發生什麼 +---------------- + +如果一個補丁被認爲適合添加到內核中,並且大多數審查問題得到解決,下一步通常 +是進入子系統維護人員的樹中。工作方式因子系統而異;每個維護人員都有自己的 +工作方式。特別是可能有不止一棵樹——也許一棵樹專門用於計劃下一個合併窗口的 +補丁,另一棵樹用於長期工作。 + +對於應用到不屬於明顯子系統樹(例如內存管理修補程序)的區域的修補程序,默認樹 +通常上溯到-mm。影響多個子系統的補丁也可以最終進入-mm樹。 + +包含在子系統樹中可以提高補丁的可見性。現在,使用該樹的其他開發人員將默認獲 +得補丁。子系統樹通常也爲Linux提供支持,使其內容對整個開發社區可見。在這一點 +上,您很可能會從一組新的審閱者那裡得到更多的評論;這些評論需要像上一輪那樣 +得到回應。 + +在這時也會發生點什麼,這取決於你的補丁的性質,是否與其他人正在做的工作發生 +衝突。在最壞的情況下,嚴重的補丁衝突可能會導致一些工作被擱置,以便剩餘的補丁 +可以成形併合並。另一些時候,衝突解決將涉及到與其他開發人員合作,可能還會 +在樹之間移動一些補丁,以確保所有的應用都是乾淨的。這項工作可能是一件痛苦的 +事情,但也需慶幸現在的幸福:在linux-next樹出現之前,這些衝突通常只在合併窗口 +中出現,必須迅速解決。現在可以在合併窗口打開之前的空閒時間解決這些問題。 + +有朝一日,如果一切順利,您將登錄並看到您的補丁已經合併到主線內核中。祝賀你! +然而,一旦慶祝完了(並且您已經將自己添加到維護人員文件中),就一定要記住 +一個重要的小事實:工作仍然沒有完成。併入主線也帶來了它的挑戰。 + +首先,補丁的可見性再次提高。可能會有以前不知道這個補丁的開發者的新一輪評論。 +忽略它們可能很有誘惑力,因爲您的代碼不再存在任何被合併的問題。但是,要抵制 +這種誘惑,您仍然需要對有問題或建議的開發人員作出響應。 + +不過,更重要的是:將代碼包含在主線中會將代碼交給更多的一些測試人員。即使您 +爲尚未可用的硬體提供了驅動程序,您也會驚訝於有多少人會將您的代碼構建到內核 +中。當然,如果有測試人員,也可能會有錯誤報告。 + +最糟糕的錯誤報告是回歸。如果你的補丁導致回歸,你會發現多到讓你不舒服的眼睛盯 +著你;回歸需要儘快修復。如果您不願意或無法修復回歸(其他人都不會爲您修復), +那麼在穩定期內,您的補丁幾乎肯定會被移除。除了否定您爲使補丁進入主線所做的 +所有工作之外,如果由於未能修復回歸而取消補丁,很可能會使將來的工作更難被合併。 + +在處理完任何回歸之後,可能還有其他普通缺陷需要處理。穩定期是修復這些錯誤並 +確保代碼在主線內核版本中的首次發布儘可能可靠的最好機會。所以,請回應錯誤 +報告,並儘可能解決問題。這就是穩定期的目的;一旦解決了舊補丁的任何問題,就 +可以開始盡情創建新補丁。 + +別忘了,還有其他節點也可能會創建缺陷報告:下一個主線穩定版本,當著名的發行 +商選擇包含您補丁的內核版本時等等。繼續響應這些報告是您工作的基本素養。但是 +如果這不能提供足夠的動機,那麼也需要考慮:開發社區會記住那些在合併後對代碼 +失去興趣的開發人員。下一次你發布補丁時,他們會以你以後不會持續維護它爲前提 +來評估它。 + +其他可能發生的事情 +------------------ + +某天,當你打開你的郵件客戶端時,看到有人給你寄了一個代碼補丁。畢竟,這是 +讓您的代碼公開存在的好處之一。如果您同意這個補丁,您可以將它轉發給子系統 +維護人員(確保包含一個正確的From:行,這樣屬性是正確的,並添加一個您自己的 +signoff ),或者回復一個 Acked-by: 讓原始發送者向上發送它。 + +如果您不同意補丁,請禮貌地回復,解釋原因。如果可能的話,告訴作者需要做哪些 +更改才能讓您接受補丁。合併代碼的編寫者和維護者所反對的補丁的確存在著一定的 +阻力,但僅此而已。如果你被認爲不必要的阻礙了好的工作,那麼這些補丁最終會 +繞過你並進入主線。在Linux內核中,沒有人對任何代碼擁有絕對的否決權。可能除 +了Linus。 + +在非常罕見的情況下,您可能會看到完全不同的東西:另一個開發人員發布了針對您 +的問題的不同解決方案。在這時,兩個補丁之一可能不會被合併,「我的補丁首先 +發布」不被認爲是一個令人信服的技術論據。如果有別人的補丁取代了你的補丁而進 +入了主線,那麼只有一種方法可以回應你:很高興你的問題解決了,請繼續工作吧。 +以這種方式把某人的工作推到一邊可能導致傷心和氣餒,但是社區會記住你的反應, +即使很久以後他們已經忘記了誰的補丁真正被合併。 + diff --git a/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst b/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst new file mode 100644 index 000000000000..3de093d0f170 --- /dev/null +++ b/Documentation/translations/zh_TW/process/7.AdvancedTopics.rst @@ -0,0 +1,137 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/7.AdvancedTopics.rst ` + +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_advancedtopics: + +高級主題 +======== + +現在,希望您能夠掌握開發流程的工作方式。然而,還有更多的東西要學!本節將介紹 +一些主題,這些主題對希望成爲Linux內核開發過程常規部分的開發人員有幫助。 + +使用Git管理補丁 +--------------- + +內核使用分布式版本控制始於2002年初,當時Linus首次開始使用專有的Bitkeeper應用 +程序。雖然BitKeeper存在爭議,但它所體現的軟體版本管理方法卻肯定不是。分布式 +版本控制可以立即加速內核開發項目。現在有好幾種免費的BitKeeper替代品。 +但無論好壞,內核項目都已經選擇了Git作爲其工具。 + +使用Git管理補丁可以使開發人員的生活更加輕鬆,尤其是隨著補丁數量的增長。Git也 +有其粗糙的邊角和一定的危險性,它是一個年輕和強大的工具,仍然在其開發人員完善 +中。本文檔不會試圖教會讀者如何使用git;這會是個巨長的文檔。相反,這裡的重點 +將是Git如何特別適合內核開發過程。想要加快用Git速度的開發人員可以在以下網站上 +找到更多信息: + + https://git-scm.com/ + + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + +同時網上也能找到各種各樣的教程。 + +在嘗試使用它生成補丁供他人使用之前,第一要務是閱讀上述網頁,對Git的工作方式 +有一個紮實的了解。使用Git的開發人員應能進行拉取主線存儲庫的副本,查詢修訂 +歷史,提交對樹的更改,使用分支等操作。了解Git用於重寫歷史的工具(如rebase) +也很有用。Git有自己的術語和概念;Git的新用戶應該了解引用、遠程分支、索引、 +快進合併、推拉、游離頭等。一開始可能有點嚇人,但這些概念不難通過一點學習來 +理解。 + +使用git生成通過電子郵件提交的補丁是提高速度的一個很好的練習。 + +當您準備好開始建立Git樹供其他人查看時,無疑需要一個可以從中拉取的伺服器。 +如果您有一個可以訪問網際網路的系統,那麼使用git-daemon設置這樣的伺服器相對 +簡單。同時,免費的公共託管網站(例如github)也開始出現在網絡上。成熟的開發 +人員可以在kernel.org上獲得一個帳戶,但這些帳戶並不容易得到;更多有關信息, +請參閱 https://kernel.org/faq/ 。 + +正常的Git工作流程涉及到許多分支的使用。每一條開發線都可以分爲單獨的「主題 +分支」,並獨立維護。Git的分支很容易使用,沒有理由不使用它們。而且,在任何 +情況下,您都不應該在任何您打算讓其他人從中拉取的分支中進行開發。應該小心地 +創建公開可用的分支;當開發分支處於完整狀態並已準備好時(而不是之前)才合併 +開發分支的補丁。 + +Git提供了一些強大的工具,可以讓您重寫開發歷史。一個不方便的補丁(比如說, +一個打破二分法的補丁,或者有其他一些明顯的缺陷)可以在適當的位置修復,或者 +完全從歷史中消失。一個補丁系列可以被重寫,就好像它是在今天的主線上寫的一樣, +即使你已經花了幾個月的時間在寫它。可以透明地將更改從一個分支轉移到另一個 +分支。等等。明智地使用git修改歷史的能力可以幫助創建問題更少的乾淨補丁集。 + +然而,過度使用這種功能可能會導致其他問題,而不僅僅是對創建完美項目歷史的 +簡單癡迷。重寫歷史將重寫該歷史中包含的更改,將經過測試(希望如此)的內核樹 +變爲未經測試的內核樹。除此之外,如果開發人員沒有共享項目歷史,他們就無法 +輕鬆地協作;如果您重寫了其他開發人員拉入他們存儲庫的歷史,您將使這些開發 +人員的生活更加困難。因此,這裡有一個簡單的經驗法則:被導出到其他地方的歷史 +在此後通常被認爲是不可變的。 + +因此,一旦將一組更改推送到公開可用的伺服器上,就不應該重寫這些更改。如果您 +嘗試強制進行無法快進合併的更改(即不共享同一歷史記錄的更改),Git將嘗試強制 +執行此規則。這可能覆蓋檢查,有時甚至需要重寫導出的樹。在樹之間移動變更集以 +避免linux-next中的衝突就是一個例子。但這種行爲應該是罕見的。這就是爲什麼 +開發應該在私有分支中進行(必要時可以重寫)並且只有在公共分支處於合理的較新 +狀態時才轉移到公共分支中的原因之一。 + +當主線(或其他一組變更所基於的樹)前進時,很容易與該樹合併以保持領先地位。 +對於一個私有的分支,rebasing 可能是一個很容易跟上另一棵樹的方法,但是一旦 +一棵樹被導出到外界,rebasing就不可取了。一旦發生這種情況,就必須進行完全 +合併(merge)。合併有時是很有意義的,但是過於頻繁的合併會不必要地擾亂歷史。 +在這種情況下建議的做法是不要頻繁合併,通常只在特定的發布點(如主線-rc發布) +合併。如果您對特定的更改感到緊張,則可以始終在私有分支中執行測試合併。在 +這種情況下,git「rerere」工具很有用;它能記住合併衝突是如何解決的,這樣您 +就不必重複相同的工作。 + +關於Git這樣的工具的一個最大的反覆抱怨是:補丁從一個存儲庫到另一個存儲庫的 +大量移動使得很容易陷入錯誤建議的變更中,這些變更避開審查雷達進入主線。當內 +核開發人員看到這種情況發生時,他們往往會感到不高興;在Git樹上放置未審閱或 +主題外的補丁可能會影響您將來讓樹被拉取的能力。引用Linus的話: + +:: + + 你可以給我發補丁,但當我從你那裡拉取一個Git補丁時,我需要知道你清楚 + 自己在做什麼,我需要能夠相信事情而 *無需* 手動檢查每個單獨的更改。 + +(http://lwn.net/articles/224135/)。 + +爲了避免這種情況,請確保給定分支中的所有補丁都與相關主題緊密相關;「驅動程序 +修復」分支不應更改核心內存管理代碼。而且,最重要的是,不要使用Git樹來繞過 +審查過程。不時的將樹的摘要發布到相關的列表中,在合適時候請求linux-next中 +包含該樹。 + +如果其他人開始發送補丁以包含到您的樹中,不要忘記審閱它們。還要確保您維護正確 +的作者信息; git 「am」工具在這方面做得最好,但是如果補丁通過第三方轉發給您, +您可能需要在補丁中添加「From:」行。 + +請求拉取時,請務必提供所有相關信息:樹的位置、要拉取的分支以及拉取將導致的 +更改。在這方面 git request-pull 命令非常有用;它將按照其他開發人員所期望的 +格式化請求,並檢查以確保您已記得將這些更改推送到公共伺服器。 + +審閱補丁 +-------- + +一些讀者顯然會反對將本節與「高級主題」放在一起,因爲即使是剛開始的內核開發人員 +也應該審閱補丁。當然,沒有比查看其他人發布的代碼更好的方法來學習如何在內核環境 +中編程了。此外,審閱者永遠供不應求;通過審閱代碼,您可以對整個流程做出重大貢獻。 + +審查代碼可能是一副令人生畏的圖景,特別是對一個新的內核開發人員來說,他們 +可能會對公開詢問代碼感到緊張,而這些代碼是由那些有更多經驗的人發布的。不過, +即使是最有經驗的開發人員編寫的代碼也可以得到改進。也許對(所有)審閱者最好 +的建議是:把審閱評論當成問題而不是批評。詢問「在這條路徑中如何釋放鎖?」 +總是比說「這裡的鎖是錯誤的」更好。 + +不同的開發人員將從不同的角度審查代碼。部分人會主要關注代碼風格以及代碼行是 +否有尾隨空格。其他人會主要關注補丁作爲一個整體實現的變更是否對內核有好處。 +同時也有人會檢查是否存在鎖問題、堆棧使用過度、可能的安全問題、在其他地方 +發現的代碼重複、足夠的文檔、對性能的不利影響、用戶空間ABI更改等。所有類型 +的檢查,只要它們能引導更好的代碼進入內核,都是受歡迎和值得的。 + diff --git a/Documentation/translations/zh_TW/process/8.Conclusion.rst b/Documentation/translations/zh_TW/process/8.Conclusion.rst new file mode 100644 index 000000000000..7572b17667d9 --- /dev/null +++ b/Documentation/translations/zh_TW/process/8.Conclusion.rst @@ -0,0 +1,74 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/8.Conclusion.rst ` +:Translator: + + 時奎亮 Alex Shi + +:校譯: + + 吳想成 Wu XiangCheng + 胡皓文 Hu Haowen + +.. _tw_development_conclusion: + +更多信息 +======== + +關於Linux內核開發和相關主題的信息來源很多。首先是在內核原始碼分發中找到的 +文檔目錄。頂級 +:ref:`Documentation/translations/zh_TW/process/howto.rst ` +文件是一個重要的起點; +:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` +和 :ref:`Documentation/translations/zh_TW/process/submitting-drivers.rst ` +也是所有內核開發人員都應該閱讀的內容。許多內部內核API都是使用kerneldoc機制 +記錄的;「make htmldocs」或「make pdfdocs」可用於以HTML或PDF格式生成這些文檔 +(儘管某些發行版提供的tex版本會遇到內部限制,無法正確處理文檔)。 + +不同的網站在各個細節層次上討論內核開發。本文作者想謙虛地建議用 https://lwn.net/ +作爲來源;有關許多特定內核主題的信息可以通過以下網址的 LWN 內核索引找到: + + http://lwn.net/kernel/index/ + +除此之外,內核開發人員的一個寶貴資源是: + + https://kernelnewbies.org/ + +當然,也不應該忘記 https://kernel.org/ ,這是內核發布信息的最終位置。 + +關於內核開發有很多書: + + 《Linux設備驅動程序》第三版(Jonathan Corbet、Alessandro Rubini和Greg Kroah Hartman) + 線上版本在 http://lwn.net/kernel/ldd3/ + + 《Linux內核設計與實現》(Robert Love) + + 《深入理解Linux內核》(Daniel Bovet和Marco Cesati) + +然而,所有這些書都有一個共同的缺點:它們上架時就往往有些過時,而且已經上架 +一段時間了。不過,在那裡還是可以找到相當多的好信息。 + +有關git的文檔,請訪問: + + https://www.kernel.org/pub/software/scm/git/docs/ + + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + +結論 +==== + +祝賀所有通過這篇冗長的文檔的人。希望它能夠幫助您理解Linux內核是如何開發的, +以及您如何參與這個過程。 + +最後,重要的是參與。任何開源軟體項目都不會超過其貢獻者投入其中的總和。Linux +內核的發展速度和以前一樣快,因爲它得到了大量開發人員的幫助,他們都在努力使它 +變得更好。內核是一個最成功的例子,說明了當成千上萬的人爲了一個共同的目標一起 +工作時,可以做出什麼。 + +不過,內核總是可以從更大的開發人員基礎中獲益。總有更多的工作要做。但是同樣 +重要的是,Linux生態系統中的大多數其他參與者可以通過爲內核做出貢獻而受益。使 +代碼進入主線是提高代碼質量、降低維護和分發成本、提高對內核開發方向的影響程度 +等的關鍵。這是一種共贏的局面。啓動你的編輯器,來加入我們吧;你會非常受歡迎的。 + diff --git a/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst b/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst new file mode 100644 index 000000000000..949d831aaf6c --- /dev/null +++ b/Documentation/translations/zh_TW/process/code-of-conduct-interpretation.rst @@ -0,0 +1,112 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/code-of-conduct-interpretation.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_code_of_conduct_interpretation: + +Linux內核貢獻者契約行為準則解釋 +=============================== + +:ref:`tw_code_of_conduct` 準則是一個通用文檔,旨在爲幾乎所有開源社區提供一套規則。 +每個開源社區都是獨一無二的,Linux內核也不例外。因此,本文描述了Linux內核社區中 +如何解釋它。我們也不希望這種解釋隨著時間的推移是靜態的,並將根據需要進行調整。 + +與開發軟體的「傳統」方法相比,Linux內核開發工作是一個非常個人化的過程。你的貢獻 +和背後的想法將被仔細審查,往往導致批判和批評。審查將幾乎總是需要改進,材料才 +能包括在內核中。要知道這是因爲所有相關人員都希望看到Linux整體成功的最佳解決方 +案。這個開發過程已經被證明可以創建有史以來最健壯的作業系統內核,我們不想做任何 +事情來導致提交質量和最終結果的下降。 + +維護者 +------ + +行為準則多次使用「維護者」一詞。在內核社區中,「維護者」是負責子系統、驅動程序或 +文件的任何人,並在內核原始碼樹的維護者文件中列出。 + +責任 +---- + +《行為準則》提到了維護人員的權利和責任,這需要進一步澄清。 + +首先,最重要的是,有一個合理的期望是由維護人員通過實例來領導。 + +也就是說,我們的社區是廣闊的,對維護者沒有新的要求,他們單方面處理其他人在 +他們活躍的社區的行爲。這一責任由我們所有人承擔,最終《行為準則》記錄了最終的 +上訴路徑,以防有關行爲問題的問題懸而未決。 + +維護人員應該願意在出現問題時提供幫助,並在需要時與社區中的其他人合作。如果您 +不確定如何處理出現的情況,請不要害怕聯繫技術諮詢委員會(TAB)或其他維護人員。 +除非您願意,否則不會將其視爲違規報告。如果您不確定是否該聯繫TAB 或任何其他維 +護人員,請聯繫我們的衝突調解人 Mishi Choudhary 。 + +最後,「善待對方」才是每個人的最終目標。我們知道每個人都是人,有時我們都會失敗, +但我們所有人的首要目標應該是努力友好地解決問題。執行行為準則將是最後的選擇。 + +我們的目標是創建一個強大的、技術先進的作業系統,以及所涉及的技術複雜性,這自 +然需要專業知識和決策。 + +所需的專業知識因貢獻領域而異。它主要由上下文和技術複雜性決定,其次由貢獻者和 +維護者的期望決定。 + +專家的期望和決策都要經過討論,但在最後,爲了取得進展,必須能夠做出決策。這一 +特權掌握在維護人員和項目領導的手中,預計將善意使用。 + +因此,設定專業知識期望、作出決定和拒絕不適當的貢獻不被視爲違反行為準則。 + +雖然維護人員一般都歡迎新來者,但他們幫助(新)貢獻者克服障礙的能力有限,因此 +他們必須確定優先事項。這也不應被視爲違反了行為準則。內核社區意識到這一點,並 +以各種形式提供入門級節目,如 kernelnewbies.org 。 + +範圍 +---- + +Linux內核社區主要在一組公共電子郵件列表上進行交互,這些列表分布在由多個不同 +公司或個人控制的多個不同伺服器上。所有這些列表都在內核原始碼樹中的 +MAINTAINERS 文件中定義。發送到這些郵件列表的任何電子郵件都被視爲包含在行爲 +準則中。 + +使用 kernel.org bugzilla和其他子系統bugzilla 或bug跟蹤工具的開發人員應該遵循 +行為準則的指導原則。Linux內核社區沒有「官方」項目電子郵件地址或「官方」社交媒體 +地址。使用kernel.org電子郵件帳戶執行的任何活動必須遵循爲kernel.org發布的行爲 +準則,就像任何使用公司電子郵件帳戶的個人必須遵循該公司的特定規則一樣。 + +行為準則並不禁止在郵件列表消息、內核更改日誌消息或代碼注釋中繼續包含名稱、 +電子郵件地址和相關注釋。 + +其他論壇中的互動包括在適用於上述論壇的任何規則中,通常不包括在行為準則中。 +除了在極端情況下可考慮的例外情況。 + +提交給內核的貢獻應該使用適當的語言。在行為準則之前已經存在的內容現在不會被 +視爲違反。然而,不適當的語言可以被視爲一個bug;如果任何相關方提交補丁, +這樣的bug將被更快地修復。當前屬於用戶/內核API的一部分的表達式,或者反映已 +發布標準或規範中使用的術語的表達式,不被視爲bug。 + +執行 +---- + +行為準則中列出的地址屬於行為準則委員會。https://kernel.org/code-of-conduct.html +列出了在任何給定時間接收這些電子郵件的確切成員。成員不能訪問在加入委員會之前 +或離開委員會之後所做的報告。 + +最初的行為準則委員會由TAB的志願者以及作爲中立第三方的專業調解人組成。委員會 +的首要任務是建立文件化的流程,並將其公開。 + +如果報告人不希望將整個委員會納入投訴或關切,可直接聯繫委員會的任何成員,包括 +調解人。 + +行為準則委員會根據流程審查案例(見上文),並根據需要和適當與TAB協商,例如請求 +和接收有關內核社區的信息。 + +委員會做出的任何決定都將提交到表中,以便在必要時與相關維護人員一起執行。行爲 +準則委員會的決定可以通過三分之二的投票推翻。 + +每季度,行為準則委員會和標籤將提供一份報告,概述行為準則委員會收到的匿名報告 +及其狀態,以及任何否決決定的細節,包括完整和可識別的投票細節。 + +我們希望在啓動期之後爲行為準則委員會人員配備建立一個不同的流程。發生此情況時, +將使用該信息更新此文檔。 + diff --git a/Documentation/translations/zh_TW/process/code-of-conduct.rst b/Documentation/translations/zh_TW/process/code-of-conduct.rst new file mode 100644 index 000000000000..716e5843b6e9 --- /dev/null +++ b/Documentation/translations/zh_TW/process/code-of-conduct.rst @@ -0,0 +1,76 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/code-of-conduct.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_code_of_conduct: + +貢獻者契約行為準則 +++++++++++++++++++ + +我們的誓言 +========== + +爲了營造一個開放、友好的環境,我們作爲貢獻者和維護人承諾,讓我們的社區和參 +與者,擁有一個無騷擾的體驗,無論年齡、體型、殘疾、種族、性別特徵、性別認同 +和表達、經驗水平、教育程度、社會狀況,經濟地位、國籍、個人外貌、種族、宗教 +或性身份和取向。 + +我們的標準 +========== + +有助於創造積極環境的行爲包括: + +* 使用歡迎和包容的語言 +* 尊重不同的觀點和經驗 +* 優雅地接受建設性的批評 +* 關注什麼對社區最有利 +* 對其他社區成員表示同情 + +參與者的不可接受行爲包括: + +* 使用性意味的語言或意象以及不受歡迎的性注意或者更過分的行爲 +* 煽動、侮辱/貶損評論以及個人或政治攻擊 +* 公開或私下騷擾 +* 未經明確許可,發布他人的私人信息,如物理或電子地址。 +* 在專業場合被合理認爲不適當的其他行爲 + +我們的責任 +========== + +維護人員負責澄清可接受行爲的標準,並應針對任何不可接受行爲採取適當和公平的 +糾正措施。 + +維護人員有權和責任刪除、編輯或拒絕與本行為準則不一致的評論、承諾、代碼、 +wiki編輯、問題和其他貢獻,或暫時或永久禁止任何貢獻者從事他們認爲不適當、 +威脅、冒犯或有害的其他行爲。 + +範圍 +==== + +當個人代表項目或其社區時,本行為準則既適用於項目空間,也適用於公共空間。 +代表一個項目或社區的例子包括使用一個正式的項目電子郵件地址,通過一個正式 +的社交媒體帳戶發布,或者在在線或離線事件中擔任指定的代表。項目維護人員可以 +進一步定義和澄清項目的表示。 + +執行 +==== + +如有濫用、騷擾或其他不可接受的行爲,可聯繫行為準則委員會。 +所有投訴都將接受審查和調查,並將得到必要和適當的答覆。行為準則委員會有義務 +對事件報告人保密。具體執行政策的進一步細節可單獨公布。 + +歸屬 +==== + +本行為準則改編自《貢獻者契約》,版本1.4,可從 +https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 獲取。 + +解釋 +==== + +有關Linux內核社區如何解釋此文檔,請參閱 :ref:`tw_code_of_conduct_interpretation` + diff --git a/Documentation/translations/zh_TW/process/coding-style.rst b/Documentation/translations/zh_TW/process/coding-style.rst new file mode 100644 index 000000000000..61e614aad6a7 --- /dev/null +++ b/Documentation/translations/zh_TW/process/coding-style.rst @@ -0,0 +1,958 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/coding-style.rst ` + +.. _tw_codingstyle: + +譯者:: + + 中文版維護者: 張樂 Zhang Le + 中文版翻譯者: 張樂 Zhang Le + 中文版校譯者: 王聰 Wang Cong + wheelz + 管旭東 Xudong Guan + Li Zefan + Wang Chen + Hu Haowen + +Linux 內核代碼風格 +========================= + +這是一個簡短的文檔,描述了 linux 內核的首選代碼風格。代碼風格是因人而異的, +而且我不願意把自己的觀點強加給任何人,但這就像我去做任何事情都必須遵循的原則 +那樣,我也希望在絕大多數事上保持這種的態度。請 (在寫代碼時) 至少考慮一下這裡 +的代碼風格。 + +首先,我建議你列印一份 GNU 代碼規範,然後不要讀。燒了它,這是一個具有重大象徵 +性意義的動作。 + +不管怎樣,現在我們開始: + + +1) 縮進 +-------------- + +制表符是 8 個字符,所以縮進也是 8 個字符。有些異端運動試圖將縮進變爲 4 (甚至 +2!) 字符深,這幾乎相當於嘗試將圓周率的值定義爲 3。 + +理由:縮進的全部意義就在於清楚的定義一個控制塊起止於何處。尤其是當你盯著你的 +屏幕連續看了 20 小時之後,你將會發現大一點的縮進會使你更容易分辨縮進。 + +現在,有些人會抱怨 8 個字符的縮進會使代碼向右邊移動的太遠,在 80 個字符的終端 +屏幕上就很難讀這樣的代碼。這個問題的答案是,如果你需要 3 級以上的縮進,不管用 +何種方式你的代碼已經有問題了,應該修正你的程序。 + +簡而言之,8 個字符的縮進可以讓代碼更容易閱讀,還有一個好處是當你的函數嵌套太 +深的時候可以給你警告。留心這個警告。 + +在 switch 語句中消除多級縮進的首選的方式是讓 ``switch`` 和從屬於它的 ``case`` +標籤對齊於同一列,而不要 ``兩次縮進`` ``case`` 標籤。比如: + +.. code-block:: c + + switch (suffix) { + case 'G': + case 'g': + mem <<= 30; + break; + case 'M': + case 'm': + mem <<= 20; + break; + case 'K': + case 'k': + mem <<= 10; + fallthrough; + default: + break; + } + +不要把多個語句放在一行里,除非你有什麼東西要隱藏: + +.. code-block:: c + + if (condition) do_this; + do_something_everytime; + +也不要在一行里放多個賦值語句。內核代碼風格超級簡單。就是避免可能導致別人誤讀 +的表達式。 + +除了注釋、文檔和 Kconfig 之外,不要使用空格來縮進,前面的例子是例外,是有意爲 +之。 + +選用一個好的編輯器,不要在行尾留空格。 + + +2) 把長的行和字符串打散 +------------------------------ + +代碼風格的意義就在於使用平常使用的工具來維持代碼的可讀性和可維護性。 + +每一行的長度的限制是 80 列,我們強烈建議您遵守這個慣例。 + +長於 80 列的語句要打散成有意義的片段。除非超過 80 列能顯著增加可讀性,並且不 +會隱藏信息。子片段要明顯短於母片段,並明顯靠右。這同樣適用於有著很長參數列表 +的函數頭。然而,絕對不要打散對用戶可見的字符串,例如 printk 信息,因爲這樣就 +很難對它們 grep。 + + +3) 大括號和空格的放置 +------------------------------ + +C 語言風格中另外一個常見問題是大括號的放置。和縮進大小不同,選擇或棄用某种放 +置策略並沒有多少技術上的原因,不過首選的方式,就像 Kernighan 和 Ritchie 展示 +給我們的,是把起始大括號放在行尾,而把結束大括號放在行首,所以: + +.. code-block:: c + + if (x is true) { + we do y + } + +這適用於所有的非函數語句塊 (if, switch, for, while, do)。比如: + +.. code-block:: c + + switch (action) { + case KOBJ_ADD: + return "add"; + case KOBJ_REMOVE: + return "remove"; + case KOBJ_CHANGE: + return "change"; + default: + return NULL; + } + +不過,有一個例外,那就是函數:函數的起始大括號放置於下一行的開頭,所以: + +.. code-block:: c + + int function(int x) + { + body of function + } + +全世界的異端可能會抱怨這個不一致性是... 呃... 不一致的,不過所有思維健全的人 +都知道 (a) K&R 是 **正確的** 並且 (b) K&R 是正確的。此外,不管怎樣函數都是特 +殊的 (C 函數是不能嵌套的)。 + +注意結束大括號獨自占據一行,除非它後面跟著同一個語句的剩餘部分,也就是 do 語 +句中的 "while" 或者 if 語句中的 "else",像這樣: + +.. code-block:: c + + do { + body of do-loop + } while (condition); + +和 + +.. code-block:: c + + if (x == y) { + .. + } else if (x > y) { + ... + } else { + .... + } + +理由:K&R。 + +也請注意這種大括號的放置方式也能使空 (或者差不多空的) 行的數量最小化,同時不 +失可讀性。因此,由於你的屏幕上的新行是不可再生資源 (想想 25 行的終端屏幕),你 +將會有更多的空行來放置注釋。 + +當只有一個單獨的語句的時候,不用加不必要的大括號。 + +.. code-block:: c + + if (condition) + action(); + +和 + +.. code-block:: c + + if (condition) + do_this(); + else + do_that(); + +這並不適用於只有一個條件分支是單語句的情況;這時所有分支都要使用大括號: + +.. code-block:: c + + if (condition) { + do_this(); + do_that(); + } else { + otherwise(); + } + +3.1) 空格 +******************** + +Linux 內核的空格使用方式 (主要) 取決於它是用於函數還是關鍵字。(大多數) 關鍵字 +後要加一個空格。值得注意的例外是 sizeof, typeof, alignof 和 __attribute__,這 +些關鍵字某些程度上看起來更像函數 (它們在 Linux 里也常常伴隨小括號而使用,儘管 +在 C 里這樣的小括號不是必需的,就像 ``struct fileinfo info;`` 聲明過後的 +``sizeof info``)。 + +所以在這些關鍵字之後放一個空格:: + + if, switch, case, for, do, while + +但是不要在 sizeof, typeof, alignof 或者 __attribute__ 這些關鍵字之後放空格。 +例如, + +.. code-block:: c + + s = sizeof(struct file); + +不要在小括號里的表達式兩側加空格。這是一個 **反例** : + +.. code-block:: c + + s = sizeof( struct file ); + +當聲明指針類型或者返回指針類型的函數時, ``*`` 的首選使用方式是使之靠近變量名 +或者函數名,而不是靠近類型名。例子: + +.. code-block:: c + + char *linux_banner; + unsigned long long memparse(char *ptr, char **retptr); + char *match_strdup(substring_t *s); + +在大多數二元和三元操作符兩側使用一個空格,例如下面所有這些操作符:: + + = + - < > * / % | & ^ <= >= == != ? : + +但是一元操作符後不要加空格:: + + & * + - ~ ! sizeof typeof alignof __attribute__ defined + +後綴自加和自減一元操作符前不加空格:: + + ++ -- + +前綴自加和自減一元操作符後不加空格:: + + ++ -- + +``.`` 和 ``->`` 結構體成員操作符前後不加空格。 + +不要在行尾留空白。有些可以自動縮進的編輯器會在新行的行首加入適量的空白,然後 +你就可以直接在那一行輸入代碼。不過假如你最後沒有在那一行輸入代碼,有些編輯器 +就不會移除已經加入的空白,就像你故意留下一個只有空白的行。包含行尾空白的行就 +這樣產生了。 + +當 git 發現補丁包含了行尾空白的時候會警告你,並且可以應你的要求去掉行尾空白; +不過如果你是正在打一系列補丁,這樣做會導致後面的補丁失敗,因爲你改變了補丁的 +上下文。 + + +4) 命名 +------------------------------ + +C 是一個簡樸的語言,你的命名也應該這樣。和 Modula-2 和 Pascal 程式設計師不同, +C 程式設計師不使用類似 ThisVariableIsATemporaryCounter 這樣華麗的名字。C 程式設計師會 +稱那個變量爲 ``tmp`` ,這樣寫起來會更容易,而且至少不會令其難於理解。 + +不過,雖然混用大小寫的名字是不提倡使用的,但是全局變量還是需要一個具描述性的 +名字。稱一個全局函數爲 ``foo`` 是一個難以饒恕的錯誤。 + +全局變量 (只有當你 **真正** 需要它們的時候再用它) 需要有一個具描述性的名字,就 +像全局函數。如果你有一個可以計算活動用戶數量的函數,你應該叫它 +``count_active_users()`` 或者類似的名字,你不應該叫它 ``cntuser()`` 。 + +在函數名中包含函數類型 (所謂的匈牙利命名法) 是腦子出了問題——編譯器知道那些類 +型而且能夠檢查那些類型,這樣做只能把程式設計師弄糊塗了。難怪微軟總是製造出有問題 +的程序。 + +本地變量名應該簡短,而且能夠表達相關的含義。如果你有一些隨機的整數型的循環計 +數器,它應該被稱爲 ``i`` 。叫它 ``loop_counter`` 並無益處,如果它沒有被誤解的 +可能的話。類似的, ``tmp`` 可以用來稱呼任意類型的臨時變量。 + +如果你怕混淆了你的本地變量名,你就遇到另一個問題了,叫做函數增長荷爾蒙失衡綜 +合症。請看第六章 (函數)。 + + +5) Typedef +----------- + +不要使用類似 ``vps_t`` 之類的東西。 + +對結構體和指針使用 typedef 是一個 **錯誤** 。當你在代碼里看到: + +.. code-block:: c + + vps_t a; + +這代表什麼意思呢? + +相反,如果是這樣 + +.. code-block:: c + + struct virtual_container *a; + +你就知道 ``a`` 是什麼了。 + +很多人認爲 typedef ``能提高可讀性`` 。實際不是這樣的。它們只在下列情況下有用: + + (a) 完全不透明的對象 (這種情況下要主動使用 typedef 來 **隱藏** 這個對象實際上 + 是什麼)。 + + 例如: ``pte_t`` 等不透明對象,你只能用合適的訪問函數來訪問它們。 + + .. note:: + + 不透明性和 "訪問函數" 本身是不好的。我們使用 pte_t 等類型的原因在於真 + 的是完全沒有任何共用的可訪問信息。 + + (b) 清楚的整數類型,如此,這層抽象就可以 **幫助** 消除到底是 ``int`` 還是 + ``long`` 的混淆。 + + u8/u16/u32 是完全沒有問題的 typedef,不過它們更符合類別 (d) 而不是這裡。 + + .. note:: + + 要這樣做,必須事出有因。如果某個變量是 ``unsigned long`` ,那麼沒有必要 + + typedef unsigned long myflags_t; + + 不過如果有一個明確的原因,比如它在某種情況下可能會是一個 ``unsigned int`` + 而在其他情況下可能爲 ``unsigned long`` ,那麼就不要猶豫,請務必使用 + typedef。 + + (c) 當你使用 sparse 按字面的創建一個 **新** 類型來做類型檢查的時候。 + + (d) 和標準 C99 類型相同的類型,在某些例外的情況下。 + + 雖然讓眼睛和腦筋來適應新的標準類型比如 ``uint32_t`` 不需要花很多時間,可 + 是有些人仍然拒絕使用它們。 + + 因此,Linux 特有的等同於標準類型的 ``u8/u16/u32/u64`` 類型和它們的有符號 + 類型是被允許的——儘管在你自己的新代碼中,它們不是強制要求要使用的。 + + 當編輯已經使用了某個類型集的已有代碼時,你應該遵循那些代碼中已經做出的選 + 擇。 + + (e) 可以在用戶空間安全使用的類型。 + + 在某些用戶空間可見的結構體裡,我們不能要求 C99 類型而且不能用上面提到的 + ``u32`` 類型。因此,我們在與用戶空間共享的所有結構體中使用 __u32 和類似 + 的類型。 + +可能還有其他的情況,不過基本的規則是 **永遠不要** 使用 typedef,除非你可以明 +確的應用上述某個規則中的一個。 + +總的來說,如果一個指針或者一個結構體裡的元素可以合理的被直接訪問到,那麼它們 +就不應該是一個 typedef。 + + +6) 函數 +------------------------------ + +函數應該簡短而漂亮,並且只完成一件事情。函數應該可以一屏或者兩屏顯示完 (我們 +都知道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。 + +一個函數的最大長度是和該函數的複雜度和縮進級數成反比的。所以,如果你有一個理 +論上很簡單的只有一個很長 (但是簡單) 的 case 語句的函數,而且你需要在每個 case +里做很多很小的事情,這樣的函數儘管很長,但也是可以的。 + +不過,如果你有一個複雜的函數,而且你懷疑一個天分不是很高的高中一年級學生可能 +甚至搞不清楚這個函數的目的,你應該嚴格遵守前面提到的長度限制。使用輔助函數, +並爲之取個具描述性的名字 (如果你覺得它們的性能很重要的話,可以讓編譯器內聯它 +們,這樣的效果往往會比你寫一個複雜函數的效果要好。) + +函數的另外一個衡量標準是本地變量的數量。此數量不應超過 5-10 個,否則你的函數 +就有問題了。重新考慮一下你的函數,把它分拆成更小的函數。人的大腦一般可以輕鬆 +的同時跟蹤 7 個不同的事物,如果再增多的話,就會糊塗了。即便你聰穎過人,你也可 +能會記不清你 2 個星期前做過的事情。 + +在源文件里,使用空行隔開不同的函數。如果該函數需要被導出,它的 **EXPORT** 宏 +應該緊貼在它的結束大括號之下。比如: + +.. code-block:: c + + int system_is_up(void) + { + return system_state == SYSTEM_RUNNING; + } + EXPORT_SYMBOL(system_is_up); + +在函數原型中,包含函數名和它們的數據類型。雖然 C 語言裡沒有這樣的要求,在 +Linux 里這是提倡的做法,因爲這樣可以很簡單的給讀者提供更多的有價值的信息。 + + +7) 集中的函數退出途徑 +------------------------------ + +雖然被某些人聲稱已經過時,但是 goto 語句的等價物還是經常被編譯器所使用,具體 +形式是無條件跳轉指令。 + +當一個函數從多個位置退出,並且需要做一些類似清理的常見操作時,goto 語句就很方 +便了。如果並不需要清理操作,那麼直接 return 即可。 + +選擇一個能夠說明 goto 行爲或它爲何存在的標籤名。如果 goto 要釋放 ``buffer``, +一個不錯的名字可以是 ``out_free_buffer:`` 。別去使用像 ``err1:`` 和 ``err2:`` +這樣的GW_BASIC 名稱,因爲一旦你添加或刪除了 (函數的) 退出路徑,你就必須對它們 +重新編號,這樣會難以去檢驗正確性。 + +使用 goto 的理由是: + +- 無條件語句容易理解和跟蹤 +- 嵌套程度減小 +- 可以避免由於修改時忘記更新個別的退出點而導致錯誤 +- 讓編譯器省去刪除冗餘代碼的工作 ;) + +.. code-block:: c + + int fun(int a) + { + int result = 0; + char *buffer; + + buffer = kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result = 1; + goto out_free_buffer; + } + ... + out_free_buffer: + kfree(buffer); + return result; + } + +一個需要注意的常見錯誤是 ``一個 err 錯誤`` ,就像這樣: + +.. code-block:: c + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +這段代碼的錯誤是,在某些退出路徑上 ``foo`` 是 NULL。通常情況下,通過把它分離 +成兩個錯誤標籤 ``err_free_bar:`` 和 ``err_free_foo:`` 來修復這個錯誤: + +.. code-block:: c + + err_free_bar: + kfree(foo->bar); + err_free_foo: + kfree(foo); + return ret; + +理想情況下,你應該模擬錯誤來測試所有退出路徑。 + + +8) 注釋 +------------------------------ + +注釋是好的,不過有過度注釋的危險。永遠不要在注釋里解釋你的代碼是如何運作的: +更好的做法是讓別人一看你的代碼就可以明白,解釋寫的很差的代碼是浪費時間。 + +一般的,你想要你的注釋告訴別人你的代碼做了什麼,而不是怎麼做的。也請你不要把 +注釋放在一個函數體內部:如果函數複雜到你需要獨立的注釋其中的一部分,你很可能 +需要回到第六章看一看。你可以做一些小注釋來註明或警告某些很聰明 (或者槽糕) 的 +做法,但不要加太多。你應該做的,是把注釋放在函數的頭部,告訴人們它做了什麼, +也可以加上它做這些事情的原因。 + +當注釋內核 API 函數時,請使用 kernel-doc 格式。請看 +Documentation/doc-guide/ 和 scripts/kernel-doc 以獲得詳細信息。 + +長 (多行) 注釋的首選風格是: + +.. code-block:: c + + /* + * This is the preferred style for multi-line + * comments in the Linux kernel source code. + * Please use it consistently. + * + * Description: A column of asterisks on the left side, + * with beginning and ending almost-blank lines. + */ + +對於在 net/ 和 drivers/net/ 的文件,首選的長 (多行) 注釋風格有些不同。 + +.. code-block:: c + + /* The preferred comment style for files in net/ and drivers/net + * looks like this. + * + * It is nearly the same as the generally preferred comment style, + * but there is no initial almost-blank line. + */ + +注釋數據也是很重要的,不管是基本類型還是衍生類型。爲了方便實現這一點,每一行 +應只聲明一個數據 (不要使用逗號來一次聲明多個數據)。這樣你就有空間來爲每個數據 +寫一段小注釋來解釋它們的用途了。 + + +9) 你已經把事情弄糟了 +------------------------------ + +這沒什麼,我們都是這樣。可能你的使用了很長時間 Unix 的朋友已經告訴你 +``GNU emacs`` 能自動幫你格式化 C 原始碼,而且你也注意到了,確實是這樣,不過它 +所使用的默認值和我們想要的相去甚遠 (實際上,甚至比隨機打的還要差——無數個猴子 +在 GNU emacs 里打字永遠不會創造出一個好程序) (譯註:Infinite Monkey Theorem) + +所以你要麼放棄 GNU emacs,要麼改變它讓它使用更合理的設定。要採用後一個方案, +你可以把下面這段粘貼到你的 .emacs 文件里。 + +.. code-block:: none + + (defun c-lineup-arglist-tabs-only (ignored) + "Line up argument lists by tabs, not spaces" + (let* ((anchor (c-langelem-pos c-syntactic-element)) + (column (c-langelem-2nd-pos c-syntactic-element)) + (offset (- (1+ column) anchor)) + (steps (floor offset c-basic-offset))) + (* (max steps 1) + c-basic-offset))) + + (dir-locals-set-class-variables + 'linux-kernel + '((c-mode . ( + (c-basic-offset . 8) + (c-label-minimum-indentation . 0) + (c-offsets-alist . ( + (arglist-close . c-lineup-arglist-tabs-only) + (arglist-cont-nonempty . + (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) + (arglist-intro . +) + (brace-list-intro . +) + (c . c-lineup-C-comments) + (case-label . 0) + (comment-intro . c-lineup-comment) + (cpp-define-intro . +) + (cpp-macro . -1000) + (cpp-macro-cont . +) + (defun-block-intro . +) + (else-clause . 0) + (func-decl-cont . +) + (inclass . +) + (inher-cont . c-lineup-multi-inher) + (knr-argdecl-intro . 0) + (label . -1000) + (statement . 0) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-cont . +) + (substatement . +) + )) + (indent-tabs-mode . t) + (show-trailing-whitespace . t) + )))) + + (dir-locals-set-directory-class + (expand-file-name "~/src/linux-trees") + 'linux-kernel) + +這會讓 emacs 在 ``~/src/linux-trees`` 下的 C 源文件獲得更好的內核代碼風格。 + +不過就算你嘗試讓 emacs 正確的格式化代碼失敗了,也並不意味著你失去了一切:還可 +以用 ``indent`` 。 + +不過,GNU indent 也有和 GNU emacs 一樣有問題的設定,所以你需要給它一些命令選 +項。不過,這還不算太糟糕,因爲就算是 GNU indent 的作者也認同 K&R 的權威性 +(GNU 的人並不是壞人,他們只是在這個問題上被嚴重的誤導了),所以你只要給 indent +指定選項 ``-kr -i8`` (代表 ``K&R,8 字符縮進``),或使用 ``scripts/Lindent`` +這樣就可以以最時髦的方式縮進原始碼。 + +``indent`` 有很多選項,特別是重新格式化注釋的時候,你可能需要看一下它的手冊。 +不過記住: ``indent`` 不能修正壞的編程習慣。 + + +10) Kconfig 配置文件 +------------------------------ + +對於遍布源碼樹的所有 Kconfig* 配置文件來說,它們縮進方式有所不同。緊挨著 +``config`` 定義的行,用一個制表符縮進,然而 help 信息的縮進則額外增加 2 個空 +格。舉個例子:: + + config AUDIT + bool "Auditing support" + depends on NET + help + Enable auditing infrastructure that can be used with another + kernel subsystem, such as SELinux (which requires this for + logging of avc messages output). Does not do system-call + auditing without CONFIG_AUDITSYSCALL. + +而那些危險的功能 (比如某些文件系統的寫支持) 應該在它們的提示字符串里顯著的聲 +明這一點:: + + config ADFS_FS_RW + bool "ADFS write support (DANGEROUS)" + depends on ADFS_FS + ... + +要查看配置文件的完整文檔,請看 Documentation/kbuild/kconfig-language.rst。 + + +11) 數據結構 +------------------------------ + +如果一個數據結構,在創建和銷毀它的單線執行環境之外可見,那麼它必須要有一個引 +用計數器。內核里沒有垃圾收集 (並且內核之外的垃圾收集慢且效率低下),這意味著你 +絕對需要記錄你對這種數據結構的使用情況。 + +引用計數意味著你能夠避免上鎖,並且允許多個用戶並行訪問這個數據結構——而不需要 +擔心這個數據結構僅僅因爲暫時不被使用就消失了,那些用戶可能不過是沉睡了一陣或 +者做了一些其他事情而已。 + +注意上鎖 **不能** 取代引用計數。上鎖是爲了保持數據結構的一致性,而引用計數是一 +個內存管理技巧。通常二者都需要,不要把兩個搞混了。 + +很多數據結構實際上有 2 級引用計數,它們通常有不同 ``類`` 的用戶。子類計數器統 +計子類用戶的數量,每當子類計數器減至零時,全局計數器減一。 + +這種 ``多級引用計數`` 的例子可以在內存管理 (``struct mm_struct``: mm_users 和 +mm_count),和文件系統 (``struct super_block``: s_count 和 s_active) 中找到。 + +記住:如果另一個執行線索可以找到你的數據結構,但這個數據結構沒有引用計數器, +這裡幾乎肯定是一個 bug。 + + +12) 宏,枚舉和RTL +------------------------------ + +用於定義常量的宏的名字及枚舉里的標籤需要大寫。 + +.. code-block:: c + + #define CONSTANT 0x12345 + +在定義幾個相關的常量時,最好用枚舉。 + +宏的名字請用大寫字母,不過形如函數的宏的名字可以用小寫字母。 + +一般的,如果能寫成內聯函數就不要寫成像函數的宏。 + +含有多個語句的宏應該被包含在一個 do-while 代碼塊里: + +.. code-block:: c + + #define macrofun(a, b, c) \ + do { \ + if (a == 5) \ + do_this(b, c); \ + } while (0) + +使用宏的時候應避免的事情: + +1) 影響控制流程的宏: + +.. code-block:: c + + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) + +**非常** 不好。它看起來像一個函數,不過卻能導致 ``調用`` 它的函數退出;不要打 +亂讀者大腦里的語法分析器。 + +2) 依賴於一個固定名字的本地變量的宏: + +.. code-block:: c + + #define FOO(val) bar(index, val) + +可能看起來像是個不錯的東西,不過它非常容易把讀代碼的人搞糊塗,而且容易導致看起 +來不相關的改動帶來錯誤。 + +3) 作爲左值的帶參數的宏: FOO(x) = y;如果有人把 FOO 變成一個內聯函數的話,這 + 種用法就會出錯了。 + +4) 忘記了優先級:使用表達式定義常量的宏必須將表達式置於一對小括號之內。帶參數 + 的宏也要注意此類問題。 + +.. code-block:: c + + #define CONSTANT 0x4000 + #define CONSTEXP (CONSTANT | 3) + +5) 在宏里定義類似函數的本地變量時命名衝突: + +.. code-block:: c + + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret = calc_ret(x); \ + (ret); \ + }) + +ret 是本地變量的通用名字 - __foo_ret 更不容易與一個已存在的變量衝突。 + +cpp 手冊對宏的講解很詳細。gcc internals 手冊也詳細講解了 RTL,內核里的彙編語 +言經常用到它。 + + +13) 列印內核消息 +------------------------------ + +內核開發者應該是受過良好教育的。請一定注意內核信息的拼寫,以給人以好的印象。 +不要用不規範的單詞比如 ``dont``,而要用 ``do not`` 或者 ``don't`` 。保證這些信 +息簡單明了,無歧義。 + +內核信息不必以英文句號結束。 + +在小括號里列印數字 (%d) 沒有任何價值,應該避免這樣做。 + + 里有一些驅動模型診斷宏,你應該使用它們,以確保信息對應於正確 +的設備和驅動,並且被標記了正確的消息級別。這些宏有:dev_err(), dev_warn(), +dev_info() 等等。對於那些不和某個特定設備相關連的信息, 定義 +了 pr_notice(), pr_info(), pr_warn(), pr_err() 和其他。 + +寫出好的調試信息可以是一個很大的挑戰;一旦你寫出後,這些信息在遠程除錯時能提 +供極大的幫助。然而列印調試信息的處理方式同列印非調試信息不同。其他 pr_XXX() +函數能無條件地列印,pr_debug() 卻不;默認情況下它不會被編譯,除非定義了 DEBUG +或設定了 CONFIG_DYNAMIC_DEBUG。實際這同樣是爲了 dev_dbg(),一個相關約定是在一 +個已經開啓了 DEBUG 時,使用 VERBOSE_DEBUG 來添加 dev_vdbg()。 + +許多子系統擁有 Kconfig 調試選項來開啓 -DDEBUG 在對應的 Makefile 裡面;在其他 +情況下,特殊文件使用 #define DEBUG。當一條調試信息需要被無條件列印時,例如, +如果已經包含一個調試相關的 #ifdef 條件,printk(KERN_DEBUG ...) 就可被使用。 + + +14) 分配內存 +------------------------------ + +內核提供了下面的一般用途的內存分配函數: +kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。 +請參考 API 文檔以獲取有關它們的詳細信息。 + +傳遞結構體大小的首選形式是這樣的: + +.. code-block:: c + + p = kmalloc(sizeof(*p), ...); + +另外一種傳遞方式中,sizeof 的操作數是結構體的名字,這樣會降低可讀性,並且可能 +會引入 bug。有可能指針變量類型被改變時,而對應的傳遞給內存分配函數的 sizeof +的結果不變。 + +強制轉換一個 void 指針返回值是多餘的。C 語言本身保證了從 void 指針到其他任何 +指針類型的轉換是沒有問題的。 + +分配一個數組的首選形式是這樣的: + +.. code-block:: c + + p = kmalloc_array(n, sizeof(...), ...); + +分配一個零長數組的首選形式是這樣的: + +.. code-block:: c + + p = kcalloc(n, sizeof(...), ...); + +兩種形式檢查分配大小 n * sizeof(...) 的溢出,如果溢出返回 NULL。 + + +15) 內聯弊病 +------------------------------ + +有一個常見的誤解是 ``內聯`` 是 gcc 提供的可以讓代碼運行更快的一個選項。雖然使 +用內聯函數有時候是恰當的 (比如作爲一種替代宏的方式,請看第十二章),不過很多情 +況下不是這樣。inline 的過度使用會使內核變大,從而使整個系統運行速度變慢。 +因爲體積大內核會占用更多的指令高速緩存,而且會導致 pagecache 的可用內存減少。 +想像一下,一次 pagecache 未命中就會導致一次磁碟尋址,將耗時 5 毫秒。5 毫秒的 +時間內 CPU 能執行很多很多指令。 + +一個基本的原則是如果一個函數有 3 行以上,就不要把它變成內聯函數。這個原則的一 +個例外是,如果你知道某個參數是一個編譯時常量,而且因爲這個常量你確定編譯器在 +編譯時能優化掉你的函數的大部分代碼,那仍然可以給它加上 inline 關鍵字。 +kmalloc() 內聯函數就是一個很好的例子。 + +人們經常主張給 static 的而且只用了一次的函數加上 inline,如此不會有任何損失, +因爲沒有什麼好權衡的。雖然從技術上說這是正確的,但是實際上這種情況下即使不加 +inline gcc 也可以自動使其內聯。而且其他用戶可能會要求移除 inline,由此而來的 +爭論會抵消 inline 自身的潛在價值,得不償失。 + + +16) 函數返回值及命名 +------------------------------ + +函數可以返回多種不同類型的值,最常見的一種是表明函數執行成功或者失敗的值。這樣 +的一個值可以表示爲一個錯誤代碼整數 (-Exxx=失敗,0=成功) 或者一個 ``成功`` +布爾值 (0=失敗,非0=成功)。 + +混合使用這兩種表達方式是難於發現的 bug 的來源。如果 C 語言本身嚴格區分整形和 +布爾型變量,那麼編譯器就能夠幫我們發現這些錯誤... 不過 C 語言不區分。爲了避免 +產生這種 bug,請遵循下面的慣例:: + + 如果函數的名字是一個動作或者強制性的命令,那麼這個函數應該返回錯誤代 + 碼整數。如果是一個判斷,那麼函數應該返回一個 "成功" 布爾值。 + +比如, ``add work`` 是一個命令,所以 add_work() 在成功時返回 0,在失敗時返回 +-EBUSY。類似的,因爲 ``PCI device present`` 是一個判斷,所以 pci_dev_present() +在成功找到一個匹配的設備時應該返回 1,如果找不到時應該返回 0。 + +所有 EXPORTed 函數都必須遵守這個慣例,所有的公共函數也都應該如此。私有 +(static) 函數不需要如此,但是我們也推薦這樣做。 + +返回值是實際計算結果而不是計算是否成功的標誌的函數不受此慣例的限制。一般的, +他們通過返回一些正常值範圍之外的結果來表示出錯。典型的例子是返回指針的函數, +他們使用 NULL 或者 ERR_PTR 機制來報告錯誤。 + + +17) 不要重新發明內核宏 +------------------------------ + +頭文件 include/linux/kernel.h 包含了一些宏,你應該使用它們,而不要自己寫一些 +它們的變種。比如,如果你需要計算一個數組的長度,使用這個宏 + +.. code-block:: c + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +類似的,如果你要計算某結構體成員的大小,使用 + +.. code-block:: c + + #define sizeof_field(t, f) (sizeof(((t*)0)->f)) + +還有可以做嚴格的類型檢查的 min() 和 max() 宏,如果你需要可以使用它們。你可以 +自己看看那個頭文件里還定義了什麼你可以拿來用的東西,如果有定義的話,你就不應 +在你的代碼里自己重新定義。 + + +18) 編輯器模式行和其他需要羅嗦的事情 +-------------------------------------------------- + +有一些編輯器可以解釋嵌入在源文件里的由一些特殊標記標明的配置信息。比如,emacs +能夠解釋被標記成這樣的行: + +.. code-block:: c + + -*- mode: c -*- + +或者這樣的: + +.. code-block:: c + + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ + +Vim 能夠解釋這樣的標記: + +.. code-block:: c + + /* vim:set sw=8 noet */ + +不要在原始碼中包含任何這樣的內容。每個人都有他自己的編輯器配置,你的源文件不 +應該覆蓋別人的配置。這包括有關縮進和模式配置的標記。人們可以使用他們自己定製 +的模式,或者使用其他可以產生正確的縮進的巧妙方法。 + + +19) 內聯彙編 +------------------------------ + +在特定架構的代碼中,你可能需要內聯彙編與 CPU 和平台相關功能連接。需要這麼做時 +就不要猶豫。然而,當 C 可以完成工作時,不要平白無故地使用內聯彙編。在可能的情 +況下,你可以並且應該用 C 和硬體溝通。 + +請考慮去寫捆綁通用位元 (wrap common bits) 的內聯彙編的簡單輔助函數,別去重複 +地寫下只有細微差異內聯彙編。記住內聯彙編可以使用 C 參數。 + +大型,有一定複雜度的彙編函數應該放在 .S 文件內,用相應的 C 原型定義在 C 頭文 +件中。彙編函數的 C 原型應該使用 ``asmlinkage`` 。 + +你可能需要把彙編語句標記爲 volatile,用來阻止 GCC 在沒發現任何副作用後就把它 +移除了。你不必總是這樣做,儘管,這不必要的舉動會限制優化。 + +在寫一個包含多條指令的單個內聯彙編語句時,把每條指令用引號分割而且各占一行, +除了最後一條指令外,在每個指令結尾加上 \n\t,讓彙編輸出時可以正確地縮進下一條 +指令: + +.. code-block:: c + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + + +20) 條件編譯 +------------------------------ + +只要可能,就不要在 .c 文件裡面使用預處理條件 (#if, #ifdef);這樣做讓代碼更難 +閱讀並且更難去跟蹤邏輯。替代方案是,在頭文件中用預處理條件提供給那些 .c 文件 +使用,再給 #else 提供一個空樁 (no-op stub) 版本,然後在 .c 文件內無條件地調用 +那些 (定義在頭文件內的) 函數。這樣做,編譯器會避免爲樁函數 (stub) 的調用生成 +任何代碼,產生的結果是相同的,但邏輯將更加清晰。 + +最好傾向於編譯整個函數,而不是函數的一部分或表達式的一部分。與其放一個 ifdef +在表達式內,不如分解出部分或全部表達式,放進一個單獨的輔助函數,並應用預處理 +條件到這個輔助函數內。 + +如果你有一個在特定配置中,可能變成未使用的函數或變量,編譯器會警告它定義了但 +未使用,把它標記爲 __maybe_unused 而不是將它包含在一個預處理條件中。(然而,如 +果一個函數或變量總是未使用,就直接刪除它。) + +在代碼中,儘可能地使用 IS_ENABLED 宏來轉化某個 Kconfig 標記爲 C 的布爾 +表達式,並在一般的 C 條件中使用它: + +.. code-block:: c + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +編譯器會做常量摺疊,然後就像使用 #ifdef 那樣去包含或排除代碼塊,所以這不會帶 +來任何運行時開銷。然而,這種方法依舊允許 C 編譯器查看塊內的代碼,並檢查它的正 +確性 (語法,類型,符號引用,等等)。因此,如果條件不滿足,代碼塊內的引用符號就 +不存在時,你還是必須去用 #ifdef。 + +在任何有意義的 #if 或 #ifdef 塊的末尾 (超過幾行的),在 #endif 同一行的後面寫下 +註解,注釋這個條件表達式。例如: + +.. code-block:: c + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + + +附錄 I) 參考 +------------------- + +The C Programming Language, 第二版 +作者:Brian W. Kernighan 和 Denni M. Ritchie. +Prentice Hall, Inc., 1988. +ISBN 0-13-110362-8 (軟皮), 0-13-110370-9 (硬皮). + +The Practice of Programming +作者:Brian W. Kernighan 和 Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. + +GNU 手冊 - 遵循 K&R 標準和此文本 - cpp, gcc, gcc internals and indent, +都可以從 https://www.gnu.org/manual/ 找到 + +WG14 是 C 語言的國際標準化工作組,URL: http://www.open-std.org/JTC1/SC22/WG14/ + +Kernel process/coding-style.rst,作者 greg@kroah.com 發表於 OLS 2002: +http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ + diff --git a/Documentation/translations/zh_TW/process/development-process.rst b/Documentation/translations/zh_TW/process/development-process.rst new file mode 100644 index 000000000000..45e6385647cd --- /dev/null +++ b/Documentation/translations/zh_TW/process/development-process.rst @@ -0,0 +1,30 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/development-process.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_development_process_main: + +內核開發過程指南 +================ + +內容: + +.. toctree:: + :numbered: + :maxdepth: 2 + + 1.Intro + 2.Process + 3.Early-stage + 4.Coding + 5.Posting + 6.Followthrough + 7.AdvancedTopics + 8.Conclusion + +本文檔的目的是幫助開發人員(及其經理)以最小的挫折感與開發社區合作。它試圖記錄這個社區如何以一種不熟悉Linux內核開發(或者實際上是自由軟體開發)的人可以訪問的方式工作。雖然這裡有一些技術資料,但這是一個面向過程的討論,不需要深入了解內核編程就可以理解。 + diff --git a/Documentation/translations/zh_TW/process/email-clients.rst b/Documentation/translations/zh_TW/process/email-clients.rst new file mode 100644 index 000000000000..4ba543d06f3b --- /dev/null +++ b/Documentation/translations/zh_TW/process/email-clients.rst @@ -0,0 +1,252 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_email_clients: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/email-clients.rst ` + +譯者:: + + 中文版維護者: 賈威威 Harry Wei + 中文版翻譯者: 賈威威 Harry Wei + 時奎亮 Alex Shi + 中文版校譯者: Yinglin Luan + Xiaochen Wang + yaxinsn + Hu Haowen + +Linux郵件客戶端配置信息 +======================= + +Git +--- + +現在大多數開發人員使用 ``git send-email`` 而不是常規的電子郵件客戶端。這方面 +的手冊非常好。在接收端,維護人員使用 ``git am`` 加載補丁。 + +如果你是 ``git`` 新手,那麼把你的第一個補丁發送給你自己。將其保存爲包含所有 +標題的原始文本。運行 ``git am raw_email.txt`` ,然後使用 ``git log`` 查看更 +改日誌。如果工作正常,再將補丁發送到相應的郵件列表。 + + +普通配置 +-------- +Linux內核補丁是通過郵件被提交的,最好把補丁作爲郵件體的內嵌文本。有些維護者 +接收附件,但是附件的內容格式應該是"text/plain"。然而,附件一般是不贊成的, +因爲這會使補丁的引用部分在評論過程中變的很困難。 + +用來發送Linux內核補丁的郵件客戶端在發送補丁時應該處於文本的原始狀態。例如, +他們不能改變或者刪除制表符或者空格,甚至是在每一行的開頭或者結尾。 + +不要通過"format=flowed"模式發送補丁。這樣會引起不可預期以及有害的斷行。 + +不要讓你的郵件客戶端進行自動換行。這樣也會破壞你的補丁。 + +郵件客戶端不能改變文本的字符集編碼方式。要發送的補丁只能是ASCII或者UTF-8編碼方式, +如果你使用UTF-8編碼方式發送郵件,那麼你將會避免一些可能發生的字符集問題。 + +郵件客戶端應該形成並且保持 References: 或者 In-Reply-To: 標題,那麼 +郵件話題就不會中斷。 + +複製粘帖(或者剪貼粘帖)通常不能用於補丁,因爲制表符會轉換爲空格。使用xclipboard, xclip +或者xcutsel也許可以,但是最好測試一下或者避免使用複製粘帖。 + +不要在使用PGP/GPG署名的郵件中包含補丁。這樣會使得很多腳本不能讀取和適用於你的補丁。 +(這個問題應該是可以修復的) + +在給內核郵件列表發送補丁之前,給自己發送一個補丁是個不錯的主意,保存接收到的 +郵件,將補丁用'patch'命令打上,如果成功了,再給內核郵件列表發送。 + + +一些郵件客戶端提示 +------------------ +這裡給出一些詳細的MUA配置提示,可以用於給Linux內核發送補丁。這些並不意味是 +所有的軟體包配置總結。 + +說明: +TUI = 以文本爲基礎的用戶接口 +GUI = 圖形界面用戶接口 + +Alpine (TUI) +~~~~~~~~~~~~ + +配置選項: +在"Sending Preferences"部分: + +- "Do Not Send Flowed Text"必須開啓 +- "Strip Whitespace Before Sending"必須關閉 + +當寫郵件時,光標應該放在補丁會出現的地方,然後按下CTRL-R組合鍵,使指定的 +補丁文件嵌入到郵件中。 + +Evolution (GUI) +~~~~~~~~~~~~~~~ + +一些開發者成功的使用它發送補丁 + +當選擇郵件選項:Preformat + 從Format->Heading->Preformatted (Ctrl-7)或者工具欄 + +然後使用: + Insert->Text File... (Alt-n x)插入補丁文件。 + +你還可以"diff -Nru old.c new.c | xclip",選擇Preformat,然後使用中間鍵進行粘帖。 + +Kmail (GUI) +~~~~~~~~~~~ + +一些開發者成功的使用它發送補丁。 + +默認設置不爲HTML格式是合適的;不要啓用它。 + +當書寫一封郵件的時候,在選項下面不要選擇自動換行。唯一的缺點就是你在郵件中輸入的任何文本 +都不會被自動換行,因此你必須在發送補丁之前手動換行。最簡單的方法就是啓用自動換行來書寫郵件, +然後把它保存爲草稿。一旦你在草稿中再次打開它,它已經全部自動換行了,那麼你的郵件雖然沒有 +選擇自動換行,但是還不會失去已有的自動換行。 + +在郵件的底部,插入補丁之前,放上常用的補丁定界符:三個連字號(---)。 + +然後在"Message"菜單條目,選擇插入文件,接著選取你的補丁文件。還有一個額外的選項,你可以 +通過它配置你的郵件建立工具欄菜單,還可以帶上"insert file"圖標。 + +你可以安全地通過GPG標記附件,但是內嵌補丁最好不要使用GPG標記它們。作爲內嵌文本的簽發補丁, +當從GPG中提取7位編碼時會使他們變的更加複雜。 + +如果你非要以附件的形式發送補丁,那麼就右鍵點擊附件,然後選中屬性,突出"Suggest automatic +display",這樣內嵌附件更容易讓讀者看到。 + +當你要保存將要發送的內嵌文本補丁,你可以從消息列表窗格選擇包含補丁的郵件,然後右擊選擇 +"save as"。你可以使用一個沒有更改的包含補丁的郵件,如果它是以正確的形式組成。當你正真在它 +自己的窗口之下察看,那時沒有選項可以保存郵件--已經有一個這樣的bug被匯報到了kmail的bugzilla +並且希望這將會被處理。郵件是以只針對某個用戶可讀寫的權限被保存的,所以如果你想把郵件複製到其他地方, +你不得不把他們的權限改爲組或者整體可讀。 + +Lotus Notes (GUI) +~~~~~~~~~~~~~~~~~ + +不要使用它。 + +Mutt (TUI) +~~~~~~~~~~ + +很多Linux開發人員使用mutt客戶端,所以證明它肯定工作的非常漂亮。 + +Mutt不自帶編輯器,所以不管你使用什麼編輯器都不應該帶有自動斷行。大多數編輯器都帶有 +一個"insert file"選項,它可以通過不改變文件內容的方式插入文件。 + +'vim'作爲mutt的編輯器: + set editor="vi" + + 如果使用xclip,敲入以下命令 + :set paste + 按中鍵之前或者shift-insert或者使用 + :r filename + +如果想要把補丁作爲內嵌文本。 +(a)ttach工作的很好,不帶有"set paste"。 + +你可以通過 ``git format-patch`` 生成補丁,然後用 Mutt發送它們:: + + $ mutt -H 0001-some-bug-fix.patch + +配置選項: +它應該以默認設置的形式工作。 +然而,把"send_charset"設置爲"us-ascii::utf-8"也是一個不錯的主意。 + +Mutt 是高度可配置的。 這裡是個使用mutt通過 Gmail 發送的補丁的最小配置:: + + # .muttrc + # ================ IMAP ==================== + set imap_user = 'yourusername@gmail.com' + set imap_pass = 'yourpassword' + set spoolfile = imaps://imap.gmail.com/INBOX + set folder = imaps://imap.gmail.com/ + set record="imaps://imap.gmail.com/[Gmail]/Sent Mail" + set postponed="imaps://imap.gmail.com/[Gmail]/Drafts" + set mbox="imaps://imap.gmail.com/[Gmail]/All Mail" + + # ================ SMTP ==================== + set smtp_url = "smtp://username@smtp.gmail.com:587/" + set smtp_pass = $imap_pass + set ssl_force_tls = yes # Require encrypted connection + + # ================ Composition ==================== + set editor = `echo \$EDITOR` + set edit_headers = yes # See the headers when editing + set charset = UTF-8 # value of $LANG; also fallback for send_charset + # Sender, email address, and sign-off line must match + unset use_domain # because joe@localhost is just embarrassing + set realname = "YOUR NAME" + set from = "username@gmail.com" + set use_from = yes + +Mutt文檔含有更多信息: + + http://dev.mutt.org/trac/wiki/UseCases/Gmail + + http://dev.mutt.org/doc/manual.html + +Pine (TUI) +~~~~~~~~~~ + +Pine過去有一些空格刪減問題,但是這些現在應該都被修復了。 + +如果可以,請使用alpine(pine的繼承者) + +配置選項: +- 最近的版本需要消除流程文本 +- "no-strip-whitespace-before-send"選項也是需要的。 + + +Sylpheed (GUI) +~~~~~~~~~~~~~~ + +- 內嵌文本可以很好的工作(或者使用附件)。 +- 允許使用外部的編輯器。 +- 對於目錄較多時非常慢。 +- 如果通過non-SSL連接,無法使用TLS SMTP授權。 +- 在組成窗口中有一個很有用的ruler bar。 +- 給地址本中添加地址就不會正確的了解顯示名。 + +Thunderbird (GUI) +~~~~~~~~~~~~~~~~~ + +默認情況下,thunderbird很容易損壞文本,但是還有一些方法可以強制它變得更好。 + +- 在用戶帳號設置里,組成和尋址,不要選擇"Compose messages in HTML format"。 + +- 編輯你的Thunderbird配置設置來使它不要拆行使用:user_pref("mailnews.wraplength", 0); + +- 編輯你的Thunderbird配置設置,使它不要使用"format=flowed"格式:user_pref("mailnews. + send_plaintext_flowed", false); + +- 你需要使Thunderbird變爲預先格式方式: + 如果默認情況下你書寫的是HTML格式,那不是很難。僅僅從標題欄的下拉框中選擇"Preformat"格式。 + 如果默認情況下你書寫的是文本格式,你不得把它改爲HTML格式(僅僅作爲一次性的)來書寫新的消息, + 然後強制使它回到文本格式,否則它就會拆行。要實現它,在寫信的圖標上使用shift鍵來使它變爲HTML + 格式,然後標題欄的下拉框中選擇"Preformat"格式。 + +- 允許使用外部的編輯器: + 針對Thunderbird打補丁最簡單的方法就是使用一個"external editor"擴展,然後使用你最喜歡的 + $EDITOR來讀取或者合併補丁到文本中。要實現它,可以下載並且安裝這個擴展,然後添加一個使用它的 + 按鍵View->Toolbars->Customize...最後當你書寫信息的時候僅僅點擊它就可以了。 + +TkRat (GUI) +~~~~~~~~~~~ + +可以使用它。使用"Insert file..."或者外部的編輯器。 + +Gmail (Web GUI) +~~~~~~~~~~~~~~~ + +不要使用它發送補丁。 + +Gmail網頁客戶端自動地把制表符轉換爲空格。 + +雖然制表符轉換爲空格問題可以被外部編輯器解決,同時它還會使用回車換行把每行拆分爲78個字符。 + +另一個問題是Gmail還會把任何不是ASCII的字符的信息改爲base64編碼。它把東西變的像歐洲人的名字。 + + ### + diff --git a/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst b/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst new file mode 100644 index 000000000000..6c76fc96131a --- /dev/null +++ b/Documentation/translations/zh_TW/process/embargoed-hardware-issues.rst @@ -0,0 +1,232 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/embargoed-hardware-issues.rst ` +:Translator: Alex Shi + Hu Haowen + +被限制的硬體問題 +================ + +範圍 +---- + +導致安全問題的硬體問題與只影響Linux內核的純軟體錯誤是不同的安全錯誤類別。 + +必須區別對待諸如熔毀(Meltdown)、Spectre、L1TF等硬體問題,因爲它們通常會影響 +所有作業系統(「OS」),因此需要在不同的OS供應商、發行版、硬體供應商和其他各方 +之間進行協調。對於某些問題,軟體緩解可能依賴於微碼或固件更新,這需要進一步的 +協調。 + +.. _tw_Contact: + +接觸 +---- + +Linux內核硬體安全小組獨立於普通的Linux內核安全小組。 + +該小組只負責協調被限制的硬體安全問題。Linux內核中純軟體安全漏洞的報告不由該 +小組處理,報告者將被引導至常規Linux內核安全小組(:ref:`Documentation/admin-guide/ +`)聯繫。 + +可以通過電子郵件 與小組聯繫。這是一份私密的安全 +官名單,他們將幫助您根據我們的文檔化流程協調問題。 + +郵件列表是加密的,發送到列表的電子郵件可以通過PGP或S/MIME加密,並且必須使用報告 +者的PGP密鑰或S/MIME證書籤名。該列表的PGP密鑰和S/MIME證書可從 +https://www.kernel.org/.... 獲得。 + +雖然硬體安全問題通常由受影響的硬體供應商處理,但我們歡迎發現潛在硬體缺陷的研究 +人員或個人與我們聯繫。 + +硬體安全官 +^^^^^^^^^^ + +目前的硬體安全官小組: + + - Linus Torvalds(Linux基金會院士) + - Greg Kroah Hartman(Linux基金會院士) + - Thomas Gleixner(Linux基金會院士) + +郵件列表的操作 +^^^^^^^^^^^^^^ + +處理流程中使用的加密郵件列表託管在Linux Foundation的IT基礎設施上。通過提供這項 +服務,Linux基金會的IT基礎設施安全總監在技術上有能力訪問被限制的信息,但根據他 +的僱傭合同,他必須保密。Linux基金會的IT基礎設施安全總監還負責 kernel.org 基礎 +設施。 + +Linux基金會目前的IT基礎設施安全總監是 Konstantin Ryabitsev。 + +保密協議 +-------- + +Linux內核硬體安全小組不是正式的機構,因此無法簽訂任何保密協議。核心社區意識到 +這些問題的敏感性,並提供了一份諒解備忘錄。 + +諒解備忘錄 +---------- + +Linux內核社區深刻理解在不同作業系統供應商、發行商、硬體供應商和其他各方之間 +進行協調時,保持硬體安全問題處於限制狀態的要求。 + +Linux內核社區在過去已經成功地處理了硬體安全問題,並且有必要的機制允許在限制 +限制下進行符合社區的開發。 + +Linux內核社區有一個專門的硬體安全小組負責初始聯繫,並監督在限制規則下處理 +此類問題的過程。 + +硬體安全小組確定開發人員(領域專家),他們將組成特定問題的初始響應小組。最初 +的響應小組可以引入更多的開發人員(領域專家)以最佳的技術方式解決這個問題。 + +所有相關開發商承諾遵守限制規定,並對收到的信息保密。違反承諾將導致立即從當前 +問題中排除,並從所有相關郵件列表中刪除。此外,硬體安全小組還將把違反者排除在 +未來的問題之外。這一後果的影響在我們社區是一種非常有效的威懾。如果發生違規 +情況,硬體安全小組將立即通知相關方。如果您或任何人發現潛在的違規行爲,請立即 +向硬體安全人員報告。 + +流程 +^^^^ + +由於Linux內核開發的全球分布式特性,面對面的會議幾乎不可能解決硬體安全問題。 +由於時區和其他因素,電話會議很難協調,只能在絕對必要時使用。加密電子郵件已被 +證明是解決此類問題的最有效和最安全的通信方法。 + +開始披露 +"""""""" + +披露內容首先通過電子郵件聯繫Linux內核硬體安全小組。此初始聯繫人應包含問題的 +描述和任何已知受影響硬體的列表。如果您的組織製造或分發受影響的硬體,我們建議 +您也考慮哪些其他硬體可能會受到影響。 + +硬體安全小組將提供一個特定於事件的加密郵件列表,用於與報告者進行初步討論、 +進一步披露和協調。 + +硬體安全小組將向披露方提供一份開發人員(領域專家)名單,在與開發人員確認他們 +將遵守本諒解備忘錄和文件化流程後,應首先告知開發人員有關該問題的信息。這些開發 +人員組成初始響應小組,並在初始接觸後負責處理問題。硬體安全小組支持響應小組, +但不一定參與緩解開發過程。 + +雖然個別開發人員可能通過其僱主受到保密協議的保護,但他們不能以Linux內核開發 +人員的身份簽訂個別保密協議。但是,他們將同意遵守這一書面程序和諒解備忘錄。 + +披露方應提供已經或應該被告知該問題的所有其他實體的聯繫人名單。這有幾個目的: + + - 披露的實體列表允許跨行業通信,例如其他作業系統供應商、硬體供應商等。 + + - 可聯繫已披露的實體,指定應參與緩解措施開發的專家。 + + - 如果需要處理某一問題的專家受僱於某一上市實體或某一上市實體的成員,則響應 + 小組可要求該實體披露該專家。這確保專家也是實體反應小組的一部分。 + +披露 +"""" + +披露方通過特定的加密郵件列表向初始響應小組提供詳細信息。 + +根據我們的經驗,這些問題的技術文檔通常是一個足夠的起點,最好通過電子郵件進行 +進一步的技術澄清。 + +緩解開發 +"""""""" + +初始響應小組設置加密郵件列表,或在適當的情況下重新修改現有郵件列表。 + +使用郵件列表接近於正常的Linux開發過程,並且在過去已經成功地用於爲各種硬體安全 +問題開發緩解措施。 + +郵件列表的操作方式與正常的Linux開發相同。發布、討論和審查修補程序,如果同意, +則應用於非公共git存儲庫,參與開發人員只能通過安全連接訪問該存儲庫。存儲庫包含 +針對主線內核的主開發分支,並根據需要爲穩定的內核版本提供向後移植分支。 + +最初的響應小組將根據需要從Linux內核開發人員社區中確定更多的專家。引進專家可以 +在開發過程中的任何時候發生,需要及時處理。 + +如果專家受僱於披露方提供的披露清單上的實體或其成員,則相關實體將要求其參與。 + +否則,披露方將被告知專家參與的情況。諒解備忘錄涵蓋了專家,要求披露方確認參與。 +如果披露方有令人信服的理由提出異議,則必須在五個工作日內提出異議,並立即與事件 +小組解決。如果披露方在五個工作日內未作出回應,則視爲默許。 + +在確認或解決異議後,專家由事件小組披露,並進入開發過程。 + +協調發布 +"""""""" + +有關各方將協商限制結束的日期和時間。此時,準備好的緩解措施集成到相關的內核樹中 +並發布。 + +雖然我們理解硬體安全問題需要協調限制時間,但限制時間應限制在所有有關各方制定、 +測試和準備緩解措施所需的最短時間內。人爲地延長限制時間以滿足會議討論日期或其他 +非技術原因,會給相關的開發人員和響應小組帶來了更多的工作和負擔,因爲補丁需要 +保持最新,以便跟蹤正在進行的上游內核開發,這可能會造成衝突的更改。 + +CVE分配 +""""""" + +硬體安全小組和初始響應小組都不分配CVE,開發過程也不需要CVE。如果CVE是由披露方 +提供的,則可用於文檔中。 + +流程專使 +-------- + +爲了協助這一進程,我們在各組織設立了專使,他們可以回答有關報告流程和進一步處理 +的問題或提供指導。專使不參與特定問題的披露,除非響應小組或相關披露方提出要求。 +現任專使名單: + + ============= ======================================================== + ARM + AMD Tom Lendacky + IBM + Intel Tony Luck + Qualcomm Trilok Soni + + Microsoft Sasha Levin + VMware + Xen Andrew Cooper + + Canonical John Johansen + Debian Ben Hutchings + Oracle Konrad Rzeszutek Wilk + Red Hat Josh Poimboeuf + SUSE Jiri Kosina + + Amazon + Google Kees Cook + ============= ======================================================== + +如果要將您的組織添加到專使名單中,請與硬體安全小組聯繫。被提名的專使必須完全 +理解和支持我們的過程,並且在Linux內核社區中很容易聯繫。 + +加密郵件列表 +------------ + +我們使用加密郵件列表進行通信。這些列表的工作原理是,發送到列表的電子郵件使用 +列表的PGP密鑰或列表的/MIME證書進行加密。郵件列表軟體對電子郵件進行解密,並 +使用訂閱者的PGP密鑰或S/MIME證書爲每個訂閱者分別對其進行重新加密。有關郵件列表 +軟體和用於確保列表安全和數據保護的設置的詳細信息,請訪問: +https://www.kernel.org/.... + +關鍵點 +^^^^^^ + +初次接觸見 :ref:`tw_Contact`. 對於特定於事件的郵件列表,密鑰和S/MIME證書通過 +特定列表發送的電子郵件傳遞給訂閱者。 + +訂閱事件特定列表 +^^^^^^^^^^^^^^^^ + +訂閱由響應小組處理。希望參與通信的披露方將潛在訂戶的列表發送給響應組,以便 +響應組可以驗證訂閱請求。 + +每個訂戶都需要通過電子郵件向響應小組發送訂閱請求。電子郵件必須使用訂閱伺服器 +的PGP密鑰或S/MIME證書籤名。如果使用PGP密鑰,則必須從公鑰伺服器獲得該密鑰, +並且理想情況下該密鑰連接到Linux內核的PGP信任網。另請參見: +https://www.kernel.org/signature.html. + +響應小組驗證訂閱者,並將訂閱者添加到列表中。訂閱後,訂閱者將收到來自郵件列表 +的電子郵件,該郵件列表使用列表的PGP密鑰或列表的/MIME證書籤名。訂閱者的電子郵件 +客戶端可以從簽名中提取PGP密鑰或S/MIME證書,以便訂閱者可以向列表發送加密電子 +郵件。 + diff --git a/Documentation/translations/zh_TW/process/howto.rst b/Documentation/translations/zh_TW/process/howto.rst new file mode 100644 index 000000000000..2043691b92e3 --- /dev/null +++ b/Documentation/translations/zh_TW/process/howto.rst @@ -0,0 +1,500 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_process_howto: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/howto.rst ` + +譯者:: + + 英文版維護者: Greg Kroah-Hartman + 中文版維護者: 李陽 Li Yang + 中文版翻譯者: 李陽 Li Yang + 時奎亮 Alex Shi + 中文版校譯者: + 鍾宇 TripleX Chung + 陳琦 Maggie Chen + 王聰 Wang Cong + 胡皓文 Hu Haowen + +如何參與Linux內核開發 +===================== + +這是一篇將如何參與Linux內核開發的相關問題一網打盡的終極祕笈。它將指導你 +成爲一名Linux內核開發者,並且學會如何同Linux內核開發社區合作。它儘可能不 +包括任何關於內核編程的技術細節,但會給你指引一條獲得這些知識的正確途徑。 + +如果這篇文章中的任何內容不再適用,請給文末列出的文件維護者發送補丁。 + + +入門 +---- + +你想了解如何成爲一名Linux內核開發者?或者老闆吩咐你「給這個設備寫個Linux +驅動程序」?這篇文章的目的就是教會你達成這些目標的全部訣竅,它將描述你需 +要經過的流程以及給出如何同內核社區合作的一些提示。它還將試圖解釋內核社區 +爲何這樣運作。 + +Linux內核大部分是由C語言寫成的,一些體系結構相關的代碼用到了彙編語言。要 +參與內核開發,你必須精通C語言。除非你想爲某個架構開發底層代碼,否則你並 +不需要了解(任何體系結構的)彙編語言。下面列舉的書籍雖然不能替代紮實的C +語言教育和多年的開發經驗,但如果需要的話,做爲參考還是不錯的: + + - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall] + 《C程序設計語言(第2版·新版)》(徐寶文 李志 譯)[機械工業出版社] + - "Practical C Programming" by Steve Oualline [O'Reilly] + 《實用C語言編程(第三版)》(郭大海 譯)[中國電力出版社] + - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] + 《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社] + +Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些 +標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以 +並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許 +使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目 +前還沒有明確的參考資料可以解釋它們。請查閱gcc信息頁(使用「info gcc」命令 +顯示)獲得一些這方面信息。 + +請記住你是在學習怎麼和已經存在的開發社區打交道。它由一羣形形色色的人組成, +他們對代碼、風格和過程有著很高的標準。這些標準是在長期實踐中總結出來的, +適應於地理上分散的大型開發團隊。它們已經被很好得整理成檔,建議你在開發 +之前儘可能多的學習這些標準,而不要期望別人來適應你或者你公司的行爲方式。 + + +法律問題 +-------- + +Linux內核原始碼都是在GPL(通用公共許可證)的保護下發布的。要了解這種許可 +的細節請查看原始碼主目錄下的COPYING文件。Linux內核許可準則和如何使用 +`SPDX ` 標誌符說明在這個文件中 +:ref:`Documentation/translations/zh_TW/process/license-rules.rst ` +如果你對它還有更深入問題請聯繫律師,而不要在Linux內核郵件組上提問。因爲 +郵件組裡的人並不是律師,不要期望他們的話有法律效力。 + +對於GPL的常見問題和解答,請訪問以下連結: + https://www.gnu.org/licenses/gpl-faq.html + + +文檔 +---- + +Linux內核代碼中包含有大量的文檔。這些文檔對於學習如何與內核社區互動有著 +不可估量的價值。當一個新的功能被加入內核,最好把解釋如何使用這個功能的文 +檔也放進內核。當內核的改動導致面向用戶空間的接口發生變化時,最好將相關信 +息或手冊頁(manpages)的補丁發到mtk.manpages@gmail.com,以向手冊頁(manpages) +的維護者解釋這些變化。 + +以下是內核代碼中需要閱讀的文檔: + :ref:`Documentation/admin-guide/README.rst ` + 文件簡要介紹了Linux內核的背景,並且描述了如何配置和編譯內核。內核的 + 新用戶應該從這裡開始。 + + + :ref:`Documentation/process/changes.rst ` + 文件給出了用來編譯和使用內核所需要的最小軟體包列表。 + + :ref:`Documentation/translations/zh_TW/process/coding-style.rst ` + 描述Linux內核的代碼風格和理由。所有新代碼需要遵守這篇文檔中定義的規 + 范。大多數維護者只會接收符合規定的補丁,很多人也只會幫忙檢查符合風格 + 的代碼。 + + :ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` + :ref:`Documentation/process/submitting-drivers.rst ` + + 這兩份文檔明確描述如何創建和發送補丁,其中包括(但不僅限於): + - 郵件內容 + - 郵件格式 + - 選擇收件人 + + 遵守這些規定並不能保證提交成功(因爲所有補丁需要通過嚴格的內容和風格 + 審查),但是忽視他們幾乎就意味著失敗。 + + 其他關於如何正確地生成補丁的優秀文檔包括: + "The Perfect Patch" + + https://www.ozlabs.org/~akpm/stuff/tpp.txt + + "Linux kernel patch submission format" + + https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html + + :ref:`Documentation/translations/zh_TW/process/stable-api-nonsense.rst ` + 論證內核爲什麼特意不包括穩定的內核內部API,也就是說不包括像這樣的特 + 性: + + - 子系統中間層(爲了兼容性?) + - 在不同作業系統間易於移植的驅動程序 + - 減緩(甚至阻止)內核代碼的快速變化 + + 這篇文檔對於理解Linux的開發哲學至關重要。對於將開發平台從其他操作系 + 統轉移到Linux的人來說也很重要。 + + :ref:`Documentation/admin-guide/security-bugs.rst ` + 如果你認爲自己發現了Linux內核的安全性問題,請根據這篇文檔中的步驟來 + 提醒其他內核開發者並幫助解決這個問題。 + + :ref:`Documentation/translations/zh_TW/process/management-style.rst ` + + 描述內核維護者的工作方法及其共有特點。這對於剛剛接觸內核開發(或者對 + 它感到好奇)的人來說很重要,因爲它解釋了很多對於內核維護者獨特行爲的 + 普遍誤解與迷惑。 + + :ref:`Documentation/process/stable-kernel-rules.rst ` + 解釋了穩定版內核發布的規則,以及如何將改動放入這些版本的步驟。 + + :ref:`Documentation/process/kernel-docs.rst ` + 有助於內核開發的外部文檔列表。如果你在內核自帶的文檔中沒有找到你想找 + 的內容,可以查看這些文檔。 + + :ref:`Documentation/process/applying-patches.rst ` + 關於補丁是什麼以及如何將它打在不同內核開發分支上的好介紹 + +內核還擁有大量從代碼自動生成或者從 ReStructuredText(ReST) 標記生成的文檔, +比如這個文檔,它包含內核內部API的全面介紹以及如何妥善處理加鎖的規則。所有 +這些文檔都可以通過運行以下命令從內核代碼中生成爲PDF或HTML文檔:: + + make pdfdocs + make htmldocs + +ReST格式的文檔會生成在 Documentation/output. 目錄中。 +它們也可以用下列命令生成 LaTeX 和 ePub 格式文檔:: + + make latexdocs + make epubdocs + +如何成爲內核開發者 +------------------ +如果你對Linux內核開發一無所知,你應該訪問「Linux內核新手」計劃: + + https://kernelnewbies.org + +它擁有一個可以問各種最基本的內核開發問題的郵件列表(在提問之前一定要記得 +查找已往的郵件,確認是否有人已經回答過相同的問題)。它還擁有一個可以獲得 +實時反饋的IRC聊天頻道,以及大量對於學習Linux內核開發相當有幫助的文檔。 + +網站簡要介紹了原始碼組織結構、子系統劃分以及目前正在進行的項目(包括內核 +中的和單獨維護的)。它還提供了一些基本的幫助信息,比如如何編譯內核和打補 +丁。 + +如果你想加入內核開發社區並協助完成一些任務,卻找不到從哪裡開始,可以訪問 +「Linux內核房管員」計劃: + + https://kernelnewbies.org/KernelJanitors + +這是極佳的起點。它提供一個相對簡單的任務列表,列出內核代碼中需要被重新 +整理或者改正的地方。通過和負責這個計劃的開發者們一同工作,你會學到將補丁 +集成進內核的基本原理。如果還沒有決定下一步要做什麼的話,你還可能會得到方 +向性的指點。 + +在真正動手修改內核代碼之前,理解要修改的代碼如何運作是必需的。要達到這個 +目的,沒什麼辦法比直接讀代碼更有效了(大多數花招都會有相應的注釋),而且 +一些特製的工具還可以提供幫助。例如,「Linux代碼交叉引用」項目就是一個值得 +特別推薦的幫助工具,它將原始碼顯示在有編目和索引的網頁上。其中一個更新及 +時的內核源碼庫,可以通過以下地址訪問: + + https://elixir.bootlin.com/ + + +開發流程 +-------- + +目前Linux內核開發流程包括幾個「主內核分支」和很多子系統相關的內核分支。這 +些分支包括: + + - Linus 的內核源碼樹 + - 多個主要版本的穩定版內核樹 + - 子系統相關的內核樹 + - linux-next 集成測試樹 + + +主線樹 +------ +主線樹是由Linus Torvalds 維護的。你可以在https://kernel.org 網站或者代碼 +庫中下找到它。它的開發遵循以下步驟: + + - 每當一個新版本的內核被發布,爲期兩周的集成窗口將被打開。在這段時間裡 + 維護者可以向Linus提交大段的修改,通常這些修改已經被放到-mm內核中幾個 + 星期了。提交大量修改的首選方式是使用git工具(內核的代碼版本管理工具 + ,更多的信息可以在 https://git-scm.com/ 獲取),不過使用普通補丁也是 + 可以的。 + - 兩個星期以後-rc1版本內核發布。之後只有不包含可能影響整個內核穩定性的 + 新功能的補丁才可能被接受。請注意一個全新的驅動程序(或者文件系統)有 + 可能在-rc1後被接受是因爲這樣的修改完全獨立,不會影響其他的代碼,所以 + 沒有造成內核退步的風險。在-rc1以後也可以用git向Linus提交補丁,不過所 + 有的補丁需要同時被發送到相應的公衆郵件列表以徵詢意見。 + - 當Linus認爲當前的git源碼樹已經達到一個合理健全的狀態足以發布供人測試 + 時,一個新的-rc版本就會被發布。計劃是每周都發布新的-rc版本。 + - 這個過程一直持續下去直到內核被認爲達到足夠穩定的狀態,持續時間大概是 + 6個星期。 + +關於內核發布,值得一提的是Andrew Morton在linux-kernel郵件列表中如是說: + 「沒有人知道新內核何時會被發布,因爲發布是根據已知bug的情況來決定 + 的,而不是根據一個事先制定好的時間表。」 + +子系統特定樹 +------------ + +各種內核子系統的維護者——以及許多內核子系統開發人員——在原始碼庫中公開了他們 +當前的開發狀態。這樣,其他人就可以看到內核的不同區域發生了什麼。在開發速度 +很快的領域,可能會要求開發人員將提交的內容建立在這樣的子系統內核樹上,這樣 +就避免了提交與其他已經進行的工作之間的衝突。 + +這些存儲庫中的大多數都是Git樹,但是也有其他的scm在使用,或者補丁隊列被發布 +爲Quilt系列。這些子系統存儲庫的地址列在MAINTAINERS文件中。其中許多可以在 +https://git.kernel.org/上瀏覽。 + +在將一個建議的補丁提交到這樣的子系統樹之前,需要對它進行審查,審查主要發生 +在郵件列表上(請參見下面相應的部分)。對於幾個內核子系統,這個審查過程是通 +過工具補丁跟蹤的。Patchwork提供了一個Web界面,顯示補丁發布、對補丁的任何評 +論或修訂,維護人員可以將補丁標記爲正在審查、接受或拒絕。大多數補丁網站都列 +在 https://patchwork.kernel.org/ + +Linux-next 集成測試樹 +--------------------- + +在將子系統樹的更新合併到主線樹之前,需要對它們進行集成測試。爲此,存在一個 +特殊的測試存儲庫,其中幾乎每天都會提取所有子系統樹: + + https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git + +通過這種方式,Linux-next 對下一個合併階段將進入主線內核的內容給出了一個概要 +展望。非常歡冒險的測試者運行測試Linux-next。 + +多個主要版本的穩定版內核樹 +----------------------------------- +由3個數字組成的內核版本號說明此內核是-stable版本。它們包含內核的相對較小且 +至關重要的修補,這些修補針對安全性問題或者嚴重的內核退步。 + +這種版本的內核適用於那些期望獲得最新的穩定版內核並且不想參與測試開發版或 +者實驗版的用戶。 + +穩定版內核樹版本由「穩定版」小組(郵件地址)維護,一般 +隔周發布新版本。 + +內核源碼中的 :ref:`Documentation/process/stable-kernel-rules.rst ` +文件具體描述了可被穩定版內核接受的修改類型以及發布的流程。 + + +報告bug +------- + +bugzilla.kernel.org是Linux內核開發者們用來跟蹤內核Bug的網站。我們鼓勵用 +戶在這個工具中報告找到的所有bug。如何使用內核bugzilla的細節請訪問: + + http://test.kernel.org/bugzilla/faq.html + +內核源碼主目錄中的:ref:`admin-guide/reporting-bugs.rst ` +文件里有一個很好的模板。它指導用戶如何報告可能的內核bug以及需要提供哪些信息 +來幫助內核開發者們找到問題的根源。 + + +利用bug報告 +----------- + +練習內核開發技能的最好辦法就是修改其他人報告的bug。你不光可以幫助內核變 +得更加穩定,還可以學會如何解決實際問題從而提高自己的技能,並且讓其他開發 +者感受到你的存在。修改bug是贏得其他開發者讚譽的最好辦法,因爲並不是很多 +人都喜歡浪費時間去修改別人報告的bug。 + +要嘗試修改已知的bug,請訪問 http://bugzilla.kernel.org 網址。 + + +郵件列表 +-------- + +正如上面的文檔所描述,大多數的骨幹內核開發者都加入了Linux Kernel郵件列 +表。如何訂閱和退訂列表的細節可以在這裡找到: + + http://vger.kernel.org/vger-lists.html#linux-kernel + +網上很多地方都有這個郵件列表的存檔(archive)。可以使用搜尋引擎來找到這些 +存檔。比如: + + http://dir.gmane.org/gmane.linux.kernel + +在發信之前,我們強烈建議你先在存檔中搜索你想要討論的問題。很多已經被詳細 +討論過的問題只在郵件列表的存檔中可以找到。 + +大多數內核子系統也有自己獨立的郵件列表來協調各自的開發工作。從 +MAINTAINERS文件中可以找到不同話題對應的郵件列表。 + +很多郵件列表架設在kernel.org伺服器上。這些列表的信息可以在這裡找到: + + http://vger.kernel.org/vger-lists.html + +在使用這些郵件列表時,請記住保持良好的行爲習慣。下面的連結提供了與這些列 +表(或任何其它郵件列表)交流的一些簡單規則,雖然內容有點濫竽充數。 + + http://www.albion.com/netiquette/ + +當有很多人回覆你的郵件時,郵件的抄送列表會變得很長。請不要將任何人從抄送 +列表中刪除,除非你有足夠的理由這麼做。也不要只回復到郵件列表。請習慣於同 +一封郵件接收兩次(一封來自發送者一封來自郵件列表),而不要試圖通過添加一 +些奇特的郵件頭來解決這個問題,人們不會喜歡的。 + +記住保留你所回復內容的上下文和源頭。在你回覆郵件的頂部保留「某某某說到……」 +這幾行。將你的評論加在被引用的段落之間而不要放在郵件的頂部。 + +如果你在郵件中附帶補丁,請確認它們是可以直接閱讀的純文本(如 +:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` +文檔中所述)。內核開發者們不希望遇到附件或者被壓縮了的補丁。只有這樣才能 +保證他們可以直接評論你的每行代碼。請確保你使用的郵件發送程序不會修改空格 +和制表符。一個防範性的測試方法是先將郵件發送給自己,然後自己嘗試是否可以 +順利地打上收到的補丁。如果測試不成功,請調整或者更換你的郵件發送程序直到 +它正確工作爲止。 + +總而言之,請尊重其他的郵件列表訂閱者。 + + +同內核社區合作 +---------------- + +內核社區的目標就是提供盡善盡美的內核。所以當你提交補丁期望被接受進內核的 +時候,它的技術價值以及其他方面都將被評審。那麼你可能會得到什麼呢? + + - 批評 + - 評論 + - 要求修改 + - 要求證明修改的必要性 + - 沉默 + +要記住,這些是把補丁放進內核的正常情況。你必須學會聽取對補丁的批評和評論, +從技術層面評估它們,然後要麼重寫你的補丁要麼簡明扼要地論證修改是不必要 +的。如果你發的郵件沒有得到任何回應,請過幾天後再試一次,因爲有時信件會湮 +沒在茫茫信海中。 + +你不應該做的事情: + + - 期望自己的補丁不受任何質疑就直接被接受 + - 翻臉 + - 忽略別人的評論 + - 沒有按照別人的要求做任何修改就重新提交 + +在一個努力追尋最好技術方案的社區里,對於一個補丁有多少好處總會有不同的見 +解。你必須要抱著合作的態度,願意改變自己的觀點來適應內核的風格。或者至少 +願意去證明你的想法是有價值的。記住,犯錯誤是允許的,只要你願意朝著正確的 +方案去努力。 + +如果你的第一個補丁換來的是一堆修改建議,這是很正常的。這並不代表你的補丁 +不會被接受,也不意味著有人和你作對。你只需要改正所有提出的問題然後重新發 +送你的補丁。 + +內核社區和公司文化的差異 +------------------------ + +內核社區的工作模式同大多數傳統公司開發隊伍的工作模式並不相同。下面這些例 +子,可以幫助你避免某些可能發生問題: +用這些話介紹你的修改提案會有好處: + + - 它同時解決了多個問題 + - 它刪除了2000行代碼 + - 這是補丁,它已經解釋了我想要說明的 + - 我在5種不同的體系結構上測試過它…… + - 這是一系列小補丁用來…… + - 這個修改提高了普通機器的性能…… + +應該避免如下的說法: + + - 我們在AIX/ptx/Solaris就是這麼做的,所以這麼做肯定是好的…… + - 我做這行已經20年了,所以…… + - 爲了我們公司賺錢考慮必須這麼做 + - 這是我們的企業產品線所需要的 + - 這裡是描述我觀點的1000頁設計文檔 + - 這是一個5000行的補丁用來…… + - 我重寫了現在亂七八糟的代碼,這就是…… + - 我被規定了最後期限,所以這個補丁需要立刻被接受 + +另外一個內核社區與大部分傳統公司的軟體開發隊伍不同的地方是無法面對面地交 +流。使用電子郵件和IRC聊天工具做爲主要溝通工具的一個好處是性別和種族歧視 +將會更少。Linux內核的工作環境更能接受婦女和少數族羣,因爲每個人在別人眼 +里只是一個郵件地址。國際化也幫助了公平的實現,因爲你無法通過姓名來判斷人 +的性別。男人有可能叫李麗,女人也有可能叫王剛。大多數在Linux內核上工作過 +並表達過看法的女性對在linux上工作的經歷都給出了正面的評價。 + +對於一些不習慣使用英語的人來說,語言可能是一個引起問題的障礙。在郵件列表 +中要正確地表達想法必需良好地掌握語言,所以建議你在發送郵件之前最好檢查一 +下英文寫得是否正確。 + + +拆分修改 +-------- + +Linux內核社區並不喜歡一下接收大段的代碼。修改需要被恰當地介紹、討論並且 +拆分成獨立的小段。這幾乎完全和公司中的習慣背道而馳。你的想法應該在開發最 +開始的階段就讓大家知道,這樣你就可以及時獲得對你正在進行的開發的反饋。這 +樣也會讓社區覺得你是在和他們協作,而不是僅僅把他們當作傾銷新功能的對象。 +無論如何,你不要一次性地向郵件列表發送50封信,你的補丁序列應該永遠用不到 +這麼多。 + +將補丁拆開的原因如下: + +1) 小的補丁更有可能被接受,因爲它們不需要太多的時間和精力去驗證其正確性。 + 一個5行的補丁,可能在維護者看了一眼以後就會被接受。而500行的補丁則 + 需要數個小時來審查其正確性(所需時間隨補丁大小增加大約呈指數級增長)。 + + 當出了問題的時候,小的補丁也會讓調試變得非常容易。一個一個補丁地回溯 + 將會比仔細剖析一個被打上的大補丁(這個補丁破壞了其他東西)容易得多。 + +2)不光發送小的補丁很重要,在提交之前重新編排、化簡(或者僅僅重新排列) + 補丁也是很重要的。 + +這裡有內核開發者Al Viro打的一個比方: + 「想像一個老師正在給學生批改數學作業。老師並不希望看到學生爲了得 + 到正確解法所進行的嘗試和產生的錯誤。他希望看到的是最乾淨最優雅的 + 解答。好學生了解這點,絕不會把最終解決之前的中間方案提交上去。」 + + 內核開發也是這樣。維護者和評審者不希望看到一個人在解決問題時的思 + 考過程。他們只希望看到簡單和優雅的解決方案。 + +直接給出一流的解決方案,和社區一起協作討論尚未完成的工作,這兩者之間似乎 +很難找到一個平衡點。所以最好儘早開始收集有利於你進行改進的反饋;同時也要 +保證修改分成很多小塊,這樣在整個項目都準備好被包含進內核之前,其中的一部 +分可能會先被接收。 + +必須了解這樣做是不可接受的:試圖將未完成的工作提交進內核,然後再找時間修 +復。 + + +證明修改的必要性 +---------------- +除了將補丁拆成小塊,很重要的一點是讓Linux社區了解他們爲什麼需要這樣修改。 +你必須證明新功能是有人需要的並且是有用的。 + + +記錄修改 +-------- + +當你發送補丁的時候,需要特別留意郵件正文的內容。因爲這裡的信息將會做爲補 +丁的修改記錄(ChangeLog),會被一直保留以備大家查閱。它需要完全地描述補丁, +包括: + + - 爲什麼需要這個修改 + - 補丁的總體設計 + - 實現細節 + - 測試結果 + +想了解它具體應該看起來像什麼,請查閱以下文檔中的「ChangeLog」章節: + 「The Perfect Patch」 + https://www.ozlabs.org/~akpm/stuff/tpp.txt + + +這些事情有時候做起來很難。要在任何方面都做到完美可能需要好幾年時間。這是 +一個持續提高的過程,它需要大量的耐心和決心。只要不放棄,你一定可以做到。 +很多人已經做到了,而他們都曾經和現在的你站在同樣的起點上。 + + +感謝 +---- +感謝Paolo Ciarrocchi允許「開發流程」部分基於他所寫的文章 +(http://www.kerneltravel.net/newbie/2.6-development_process),感謝Randy +Dunlap和Gerrit Huizenga完善了應該說和不該說的列表。感謝Pat Mochel, Hanna +Linder, Randy Dunlap, Kay Sievers, Vojtech Pavlik, Jan Kara, Josh Boyer, +Kees Cook, Andrew Morton, Andi Kleen, Vadim Lobanov, Jesper Juhl, Adrian +Bunk, Keri Harris, Frans Pop, David A. Wheeler, Junio Hamano, Michael +Kerrisk和Alex Shepard的評審、建議和貢獻。沒有他們的幫助,這篇文檔是不可 +能完成的。 + + + +英文版維護者: Greg Kroah-Hartman + diff --git a/Documentation/translations/zh_TW/process/index.rst b/Documentation/translations/zh_TW/process/index.rst new file mode 100644 index 000000000000..ec7ad14bfd13 --- /dev/null +++ b/Documentation/translations/zh_TW/process/index.rst @@ -0,0 +1,67 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. raw:: latex + + \renewcommand\thesection* + \renewcommand\thesubsection* + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/index.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_process_index: + +與Linux 內核社區一起工作 +======================== + +你想成爲Linux內核開發人員嗎?歡迎之至!在學習許多關於內核的技術知識的同時, +了解我們社區的工作方式也很重要。閱讀這些文檔可以讓您以更輕鬆的、麻煩更少的 +方式將更改合併到內核。 + +以下是每位開發人員都應閱讀的基本指南: + +.. toctree:: + :maxdepth: 1 + + howto + code-of-conduct + code-of-conduct-interpretation + submitting-patches + programming-language + coding-style + development-process + email-clients + license-rules + kernel-enforcement-statement + kernel-driver-statement + +其它大多數開發人員感興趣的社區指南: + + +.. toctree:: + :maxdepth: 1 + + submitting-drivers + submit-checklist + stable-api-nonsense + stable-kernel-rules + management-style + embargoed-hardware-issues + +這些是一些總體性技術指南,由於不大好分類而放在這裡: + +.. toctree:: + :maxdepth: 1 + + magic-number + volatile-considered-harmful + +.. only:: subproject and html + + 目錄 + ==== + + * :ref:`genindex` + diff --git a/Documentation/translations/zh_TW/process/kernel-driver-statement.rst b/Documentation/translations/zh_TW/process/kernel-driver-statement.rst new file mode 100644 index 000000000000..8f225379b12c --- /dev/null +++ b/Documentation/translations/zh_TW/process/kernel-driver-statement.rst @@ -0,0 +1,203 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _zh_process_statement_driver: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/kernel-driver-statement.rst ` +:Translator: Alex Shi + Hu Haowen + +內核驅動聲明 +------------ + +關於Linux內核模塊的立場聲明 +=========================== + +我們,以下署名的Linux內核開發人員,認爲任何封閉源Linux內核模塊或驅動程序都是 +有害的和不可取的。我們已經一再發現它們對Linux用戶,企業和更大的Linux生態系統 +有害。這樣的模塊否定了Linux開發模型的開放性,穩定性,靈活性和可維護性,並使 +他們的用戶無法使用Linux社區的專業知識。提供閉源內核模塊的供應商迫使其客戶 +放棄Linux的主要優勢或選擇新的供應商。因此,爲了充分利用開源所提供的成本節省和 +共享支持優勢,我們敦促供應商採取措施,以開源內核代碼在Linux上爲其客戶提供支持。 + +我們只爲自己說話,而不是我們今天可能會爲之工作,過去或將來會爲之工作的任何公司。 + + - Dave Airlie + - Nick Andrew + - Jens Axboe + - Ralf Baechle + - Felipe Balbi + - Ohad Ben-Cohen + - Muli Ben-Yehuda + - Jiri Benc + - Arnd Bergmann + - Thomas Bogendoerfer + - Vitaly Bordug + - James Bottomley + - Josh Boyer + - Neil Brown + - Mark Brown + - David Brownell + - Michael Buesch + - Franck Bui-Huu + - Adrian Bunk + - François Cami + - Ralph Campbell + - Luiz Fernando N. Capitulino + - Mauro Carvalho Chehab + - Denis Cheng + - Jonathan Corbet + - Glauber Costa + - Alan Cox + - Magnus Damm + - Ahmed S. Darwish + - Robert P. J. Day + - Hans de Goede + - Arnaldo Carvalho de Melo + - Helge Deller + - Jean Delvare + - Mathieu Desnoyers + - Sven-Thorsten Dietrich + - Alexey Dobriyan + - Daniel Drake + - Alex Dubov + - Randy Dunlap + - Michael Ellerman + - Pekka Enberg + - Jan Engelhardt + - Mark Fasheh + - J. Bruce Fields + - Larry Finger + - Jeremy Fitzhardinge + - Mike Frysinger + - Kumar Gala + - Robin Getz + - Liam Girdwood + - Jan-Benedict Glaw + - Thomas Gleixner + - Brice Goglin + - Cyrill Gorcunov + - Andy Gospodarek + - Thomas Graf + - Krzysztof Halasa + - Harvey Harrison + - Stephen Hemminger + - Michael Hennerich + - Tejun Heo + - Benjamin Herrenschmidt + - Kristian Høgsberg + - Henrique de Moraes Holschuh + - Marcel Holtmann + - Mike Isely + - Takashi Iwai + - Olof Johansson + - Dave Jones + - Jesper Juhl + - Matthias Kaehlcke + - Kenji Kaneshige + - Jan Kara + - Jeremy Kerr + - Russell King + - Olaf Kirch + - Roel Kluin + - Hans-Jürgen Koch + - Auke Kok + - Peter Korsgaard + - Jiri Kosina + - Aaro Koskinen + - Mariusz Kozlowski + - Greg Kroah-Hartman + - Michael Krufky + - Aneesh Kumar + - Clemens Ladisch + - Christoph Lameter + - Gunnar Larisch + - Anders Larsen + - Grant Likely + - John W. Linville + - Yinghai Lu + - Tony Luck + - Pavel Machek + - Matt Mackall + - Paul Mackerras + - Roland McGrath + - Patrick McHardy + - Kyle McMartin + - Paul Menage + - Thierry Merle + - Eric Miao + - Akinobu Mita + - Ingo Molnar + - James Morris + - Andrew Morton + - Paul Mundt + - Oleg Nesterov + - Luca Olivetti + - S.Çağlar Onur + - Pierre Ossman + - Keith Owens + - Venkatesh Pallipadi + - Nick Piggin + - Nicolas Pitre + - Evgeniy Polyakov + - Richard Purdie + - Mike Rapoport + - Sam Ravnborg + - Gerrit Renker + - Stefan Richter + - David Rientjes + - Luis R. Rodriguez + - Stefan Roese + - Francois Romieu + - Rami Rosen + - Stephen Rothwell + - Maciej W. Rozycki + - Mark Salyzyn + - Yoshinori Sato + - Deepak Saxena + - Holger Schurig + - Amit Shah + - Yoshihiro Shimoda + - Sergei Shtylyov + - Kay Sievers + - Sebastian Siewior + - Rik Snel + - Jes Sorensen + - Alexey Starikovskiy + - Alan Stern + - Timur Tabi + - Hirokazu Takata + - Eliezer Tamir + - Eugene Teo + - Doug Thompson + - FUJITA Tomonori + - Dmitry Torokhov + - Marcelo Tosatti + - Steven Toth + - Theodore Tso + - Matthias Urlichs + - Geert Uytterhoeven + - Arjan van de Ven + - Ivo van Doorn + - Rik van Riel + - Wim Van Sebroeck + - Hans Verkuil + - Horst H. von Brand + - Dmitri Vorobiev + - Anton Vorontsov + - Daniel Walker + - Johannes Weiner + - Harald Welte + - Matthew Wilcox + - Dan J. Williams + - Darrick J. Wong + - David Woodhouse + - Chris Wright + - Bryan Wu + - Rafael J. Wysocki + - Herbert Xu + - Vlad Yasevich + - Peter Zijlstra + - Bartlomiej Zolnierkiewicz + diff --git a/Documentation/translations/zh_TW/process/kernel-enforcement-statement.rst b/Documentation/translations/zh_TW/process/kernel-enforcement-statement.rst new file mode 100644 index 000000000000..99e21d22800d --- /dev/null +++ b/Documentation/translations/zh_TW/process/kernel-enforcement-statement.rst @@ -0,0 +1,155 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_process_statement_kernel: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/kernel-enforcement-statement.rst ` +:Translator: Alex Shi + Hu Haowen + +Linux 內核執行聲明 +------------------ + +作爲Linux內核的開發人員,我們對如何使用我們的軟體以及如何實施軟體許可證有著 +濃厚的興趣。遵守GPL-2.0的互惠共享義務對我們軟體和社區的長期可持續性至關重要。 + +雖然有權強制執行對我們社區的貢獻中的單獨版權權益,但我們有共同的利益,即確保 +個人強制執行行動的方式有利於我們的社區,不會對我們軟體生態系統的健康和增長 +產生意外的負面影響。爲了阻止無益的執法行動,我們同意代表我們自己和我們版權 +利益的任何繼承人對Linux內核用戶作出以下符合我們開發社區最大利益的承諾: + + 儘管有GPL-2.0的終止條款,我們同意,採用以下GPL-3.0條款作爲我們許可證下的 + 附加許可,作爲任何對許可證下權利的非防禦性主張,這符合我們開發社區的最佳 + 利益。 + + 但是,如果您停止所有違反本許可證的行爲,則您從特定版權持有人處獲得的 + 許可證將被恢復:(a)暫時恢復,除非版權持有人明確並最終終止您的許可證; + 以及(b)永久恢復, 如果版權持有人未能在你終止違反後60天內以合理方式 + 通知您違反本許可證的行爲,則永久恢復您的許可證。 + + 此外,如果版權所有者以某種合理的方式通知您違反了本許可,這是您第一次 + 從該版權所有者處收到違反本許可的通知(對於任何作品),並且您在收到通知 + 後的30天內糾正違規行爲。則您從特定版權所有者處獲得的許可將永久恢復. + +我們提供這些保證的目的是鼓勵更多地使用該軟體。我們希望公司和個人使用、修改和 +分發此軟體。我們希望以公開和透明的方式與用戶合作,以消除我們對法規遵從性或強制 +執行的任何不確定性,這些不確定性可能會限制我們軟體的採用。我們將法律行動視爲 +最後手段,只有在其他社區努力未能解決這一問題時才採取行動。 + +最後,一旦一個不合規問題得到解決,我們希望用戶會感到歡迎,加入我們爲之努力的 +這個項目。共同努力,我們會更強大。 + +除了下面提到的以外,我們只爲自己說話,而不是爲今天、過去或將來可能爲之工作的 +任何公司說話。 + + - Laura Abbott + - Bjorn Andersson (Linaro) + - Andrea Arcangeli + - Neil Armstrong + - Jens Axboe + - Pablo Neira Ayuso + - Khalid Aziz + - Ralf Baechle + - Felipe Balbi + - Arnd Bergmann + - Ard Biesheuvel + - Tim Bird + - Paolo Bonzini + - Christian Borntraeger + - Mark Brown (Linaro) + - Paul Burton + - Javier Martinez Canillas + - Rob Clark + - Kees Cook (Google) + - Jonathan Corbet + - Dennis Dalessandro + - Vivien Didelot (Savoir-faire Linux) + - Hans de Goede + - Mel Gorman (SUSE) + - Sven Eckelmann + - Alex Elder (Linaro) + - Fabio Estevam + - Larry Finger + - Bhumika Goyal + - Andy Gross + - Juergen Gross + - Shawn Guo + - Ulf Hansson + - Stephen Hemminger (Microsoft) + - Tejun Heo + - Rob Herring + - Masami Hiramatsu + - Michal Hocko + - Simon Horman + - Johan Hovold (Hovold Consulting AB) + - Christophe JAILLET + - Olof Johansson + - Lee Jones (Linaro) + - Heiner Kallweit + - Srinivas Kandagatla + - Jan Kara + - Shuah Khan (Samsung) + - David Kershner + - Jaegeuk Kim + - Namhyung Kim + - Colin Ian King + - Jeff Kirsher + - Greg Kroah-Hartman (Linux Foundation) + - Christian König + - Vinod Koul + - Krzysztof Kozlowski + - Viresh Kumar + - Aneesh Kumar K.V + - Julia Lawall + - Doug Ledford + - Chuck Lever (Oracle) + - Daniel Lezcano + - Shaohua Li + - Xin Long + - Tony Luck + - Catalin Marinas (Arm Ltd) + - Mike Marshall + - Chris Mason + - Paul E. McKenney + - Arnaldo Carvalho de Melo + - David S. Miller + - Ingo Molnar + - Kuninori Morimoto + - Trond Myklebust + - Martin K. Petersen (Oracle) + - Borislav Petkov + - Jiri Pirko + - Josh Poimboeuf + - Sebastian Reichel (Collabora) + - Guenter Roeck + - Joerg Roedel + - Leon Romanovsky + - Steven Rostedt (VMware) + - Frank Rowand + - Ivan Safonov + - Anna Schumaker + - Jes Sorensen + - K.Y. Srinivasan + - David Sterba (SUSE) + - Heiko Stuebner + - Jiri Kosina (SUSE) + - Willy Tarreau + - Dmitry Torokhov + - Linus Torvalds + - Thierry Reding + - Rik van Riel + - Luis R. Rodriguez + - Geert Uytterhoeven (Glider bvba) + - Eduardo Valentin (Amazon.com) + - Daniel Vetter + - Linus Walleij + - Richard Weinberger + - Dan Williams + - Rafael J. Wysocki + - Arvind Yadav + - Masahiro Yamada + - Wei Yongjun + - Lv Zheng + - Marc Zyngier (Arm Ltd) + diff --git a/Documentation/translations/zh_TW/process/license-rules.rst b/Documentation/translations/zh_TW/process/license-rules.rst new file mode 100644 index 000000000000..ad2b80f97123 --- /dev/null +++ b/Documentation/translations/zh_TW/process/license-rules.rst @@ -0,0 +1,374 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/license-rules.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_kernel_licensing: + +Linux內核許可規則 +================= + +Linux內核根據LICENSES/preferred/GPL-2.0中提供的GNU通用公共許可證版本2 +(GPL-2.0)的條款提供,並在LICENSES/exceptions/Linux-syscall-note中顯式 +描述了例外的系統調用,如COPYING文件中所述。 + +此文檔文件提供了如何對每個源文件進行注釋以使其許可證清晰明確的說明。 +它不會取代內核的許可證。 + +內核原始碼作爲一個整體適用於COPYING文件中描述的許可證,但是單個源文件可以 +具有不同的與GPL-20兼容的許可證:: + + GPL-1.0+ : GNU通用公共許可證v1.0或更高版本 + GPL-2.0+ : GNU通用公共許可證v2.0或更高版本 + LGPL-2.0 : 僅限GNU庫通用公共許可證v2 + LGPL-2.0+: GNU 庫通用公共許可證v2或更高版本 + LGPL-2.1 : 僅限GNU寬通用公共許可證v2.1 + LGPL-2.1+: GNU寬通用公共許可證v2.1或更高版本 + +除此之外,個人文件可以在雙重許可下提供,例如一個兼容的GPL變體,或者BSD, +MIT等許可。 + +用戶空間API(UAPI)頭文件描述了用戶空間程序與內核的接口,這是一種特殊情況。 +根據內核COPYING文件中的注釋,syscall接口是一個明確的邊界,它不會將GPL要求 +擴展到任何使用它與內核通信的軟體。由於UAPI頭文件必須包含在創建在Linux內核 +上運行的可執行文件的任何源文件中,因此此例外必須記錄在特別的許可證表述中。 + +表達源文件許可證的常用方法是將匹配的樣板文本添加到文件的頂部注釋中。由於 +格式,拼寫錯誤等,這些「樣板」很難通過那些在上下文中使用的驗證許可證合規性 +的工具。 + +樣板文本的替代方法是在每個源文件中使用軟體包數據交換(SPDX)許可證標識符。 +SPDX許可證標識符是機器可解析的,並且是用於提供文件內容的許可證的精確縮寫。 +SPDX許可證標識符由Linux 基金會的SPDX 工作組管理,並得到了整個行業,工具 +供應商和法律團隊的合作夥伴的一致同意。有關詳細信息,請參閱 +https://spdx.org/ + +Linux內核需要所有源文件中的精確SPDX標識符。內核中使用的有效標識符在 +`許可標識符`_ 一節中進行了解釋,並且已可以在 +https://spdx.org/licenses/ 上的官方SPDX許可證列表中檢索,並附帶許可證 +文本。 + +許可標識符語法 +-------------- + +1.安置: + +   內核文件中的SPDX許可證標識符應添加到可包含注釋的文件中的第一行。對於大多 + 數文件,這是第一行,除了那些在第一行中需要'#!PATH_TO_INTERPRETER'的腳本。 + 對於這些腳本,SPDX標識符進入第二行。 + +| + +2. 風格: + + SPDX許可證標識符以注釋的形式添加。注釋樣式取決於文件類型:: + + C source: // SPDX-License-Identifier: + C header: /* SPDX-License-Identifier: */ + ASM: /* SPDX-License-Identifier: */ + scripts: # SPDX-License-Identifier: + .rst: .. SPDX-License-Identifier: + .dts{i}: // SPDX-License-Identifier: + + 如果特定工具無法處理標準注釋樣式,則應使用工具接受的相應注釋機制。這是在 + C 頭文件中使用「/\*\*/」樣式注釋的原因。過去在使用生成的.lds文件中觀察到 + 構建被破壞,其中'ld'無法解析C++注釋。現在已經解決了這個問題,但仍然有較 + 舊的彙編程序工具無法處理C++樣式的注釋。 + +| + +3. 句法: + + 是SPDX許可證列表中的SPDX短格式許可證標識符,或者在許可 + 證例外適用時由「WITH」分隔的兩個SPDX短格式許可證標識符的組合。當應用多個許 + 可證時,表達式由分隔子表達式的關鍵字「AND」,「OR」組成,並由「(」,「)」包圍。 + + 帶有「或更高」選項的[L]GPL等許可證的許可證標識符通過使用「+」來表示「或更高」 + 選項來構建。:: + + // SPDX-License-Identifier: GPL-2.0+ + // SPDX-License-Identifier: LGPL-2.1+ + + 當需要修正的許可證時,應使用WITH。 例如,linux內核UAPI文件使用表達式:: + + // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note + // SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note + + 其它在內核中使用WITH例外的事例如下:: + + // SPDX-License-Identifier: GPL-2.0 WITH mif-exception + // SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0 + + 例外只能與特定的許可證標識符一起使用。有效的許可證標識符列在異常文本文件 + 的標記中。有關詳細信息,請參閱 `許可標識符`_ 一章中的 `例外`_ 。 + + 如果文件是雙重許可且只選擇一個許可證,則應使用OR。例如,一些dtsi文件在雙 + 許可下可用:: + + // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + + 內核中雙許可文件中許可表達式的示例:: + + // SPDX-License-Identifier: GPL-2.0 OR MIT + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause + // SPDX-License-Identifier: GPL-2.0 OR Apache-2.0 + // SPDX-License-Identifier: GPL-2.0 OR MPL-1.1 + // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT + // SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause OR OpenSSL + + 如果文件具有多個許可證,其條款全部適用於使用該文件,則應使用AND。例如, + 如果代碼是從另一個項目繼承的,並且已經授予了將其放入內核的權限,但原始 + 許可條款需要保持有效:: + + // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT + + 另一個需要遵守兩套許可條款的例子是:: + + // SPDX-License-Identifier: GPL-1.0+ AND LGPL-2.1+ + +許可標識符 +---------- + +當前使用的許可證以及添加到內核的代碼許可證可以分解爲: + +1. _`優先許可`: + + 應儘可能使用這些許可證,因爲它們已知完全兼容並廣泛使用。這些許可證在內核 + 目錄:: + + LICENSES/preferred/ + + 此目錄中的文件包含完整的許可證文本和 `元標記`_ 。文件名與SPDX許可證標識 + 符相同,後者應用於源文件中的許可證。 + + 例如:: + + LICENSES/preferred/GPL-2.0 + + 包含GPLv2許可證文本和所需的元標籤:: + + LICENSES/preferred/MIT + + 包含MIT許可證文本和所需的元標記 + + _`元標記`: + + 許可證文件中必須包含以下元標記: + + - Valid-License-Identifier: + +   一行或多行, 聲明那些許可標識符在項目內有效, 以引用此特定許可的文本。通 + 常這是一個有效的標識符,但是例如對於帶有'或更高'選項的許可證,兩個標識 + 符都有效。 + + - SPDX-URL: + + SPDX頁面的URL,其中包含與許可證相關的其他信息. + + - Usage-Guidance: + + 使用建議的自由格式文本。該文本必須包含SPDX許可證標識符的正確示例,因爲 + 它們應根據 `許可標識符語法`_ 指南放入源文件中。 + + - License-Text: + + 此標記之後的所有文本都被視爲原始許可文本 + + 文件格式示例:: + + Valid-License-Identifier: GPL-2.0 + Valid-License-Identifier: GPL-2.0+ + SPDX-URL: https://spdx.org/licenses/GPL-2.0.html + Usage-Guide: + To use this license in source code, put one of the following SPDX + tag/value pairs into a comment according to the placement + guidelines in the licensing rules documentation. + For 'GNU General Public License (GPL) version 2 only' use: + SPDX-License-Identifier: GPL-2.0 + For 'GNU General Public License (GPL) version 2 or any later version' use: + SPDX-License-Identifier: GPL-2.0+ + License-Text: + Full license text + + :: + + SPDX-License-Identifier: MIT + SPDX-URL: https://spdx.org/licenses/MIT.html + Usage-Guide: + To use this license in source code, put the following SPDX + tag/value pair into a comment according to the placement + guidelines in the licensing rules documentation. + SPDX-License-Identifier: MIT + License-Text: + Full license text + +| + +2. 不推薦的許可證: + + 這些許可證只應用於現有代碼或從其他項目導入代碼。這些許可證在內核目錄:: + + LICENSES/other/ + + 此目錄中的文件包含完整的許可證文本和 `元標記`_ 。文件名與SPDX許可證標識 + 符相同,後者應用於源文件中的許可證。 + + 例如:: + + LICENSES/other/ISC + + 包含國際系統聯合許可文本和所需的元標籤:: + + LICENSES/other/ZLib + + 包含ZLIB許可文本和所需的元標籤. + + 元標籤: + + 「其他」許可證的元標籤要求與 `優先許可`_ 的要求相同。 + + 文件格式示例:: + + Valid-License-Identifier: ISC + SPDX-URL: https://spdx.org/licenses/ISC.html + Usage-Guide: + Usage of this license in the kernel for new code is discouraged + and it should solely be used for importing code from an already + existing project. + To use this license in source code, put the following SPDX + tag/value pair into a comment according to the placement + guidelines in the licensing rules documentation. + SPDX-License-Identifier: ISC + License-Text: + Full license text + +| + +3. _`例外`: + + 某些許可證可以修改,並允許原始許可證不具有的某些例外權利。這些例外在 + 內核目錄:: + + LICENSES/exceptions/ + + 此目錄中的文件包含完整的例外文本和所需的 `例外元標記`_ 。 + + 例如:: + + LICENSES/exceptions/Linux-syscall-note + + 包含Linux內核的COPYING文件中記錄的Linux系統調用例外,該文件用於UAPI + 頭文件。例如:: + + LICENSES/exceptions/GCC-exception-2.0 + + 包含GCC'連結例外',它允許獨立於其許可證的任何二進位文件與標記有此例外的 + 文件的編譯版本連結。這是從GPL不兼容原始碼創建可運行的可執行文件所必需的。 + + _`例外元標記`: + + 以下元標記必須在例外文件中可用: + + - SPDX-Exception-Identifier: + +   一個可與SPDX許可證標識符一起使用的例外標識符。 + + - SPDX-URL: + + SPDX頁面的URL,其中包含與例外相關的其他信息。 + + - SPDX-Licenses: + +   以逗號分隔的例外可用的SPDX許可證標識符列表。 + + - Usage-Guidance: + + 使用建議的自由格式文本。必須在文本後面加上SPDX許可證標識符的正確示例, + 因爲它們應根據 `許可標識符語法`_ 指南放入源文件中。 + + - Exception-Text: + + 此標記之後的所有文本都被視爲原始異常文本 + + 文件格式示例:: + + SPDX-Exception-Identifier: Linux-syscall-note + SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html + SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+ + Usage-Guidance: + This exception is used together with one of the above SPDX-Licenses + to mark user-space API (uapi) header files so they can be included + into non GPL compliant user-space application code. + To use this exception add it with the keyword WITH to one of the + identifiers in the SPDX-Licenses tag: + SPDX-License-Identifier: WITH Linux-syscall-note + Exception-Text: + Full exception text + + :: + + SPDX-Exception-Identifier: GCC-exception-2.0 + SPDX-URL: https://spdx.org/licenses/GCC-exception-2.0.html + SPDX-Licenses: GPL-2.0, GPL-2.0+ + Usage-Guidance: + The "GCC Runtime Library exception 2.0" is used together with one + of the above SPDX-Licenses for code imported from the GCC runtime + library. + To use this exception add it with the keyword WITH to one of the + identifiers in the SPDX-Licenses tag: + SPDX-License-Identifier: WITH GCC-exception-2.0 + Exception-Text: + Full exception text + + +所有SPDX許可證標識符和例外都必須在LICENSES子目錄中具有相應的文件。這是允許 +工具驗證(例如checkpatch.pl)以及準備好從源讀取和提取許可證所必需的, 這是 +各種FOSS組織推薦的,例如 `FSFE REUSE initiative `_. + +_`模塊許可` +----------------- + + 可加載內核模塊還需要MODULE_LICENSE()標記。此標記既不替代正確的原始碼 + 許可證信息(SPDX-License-Identifier),也不以任何方式表示或確定提供模塊 + 原始碼的確切許可證。 + + 此標記的唯一目的是提供足夠的信息,該模塊是否是自由軟體或者是內核模塊加 + 載器和用戶空間工具的專有模塊。 + + MODULE_LICENSE()的有效許可證字符串是: + + ============================= ============================================= + "GPL" 模塊是根據GPL版本2許可的。這並不表示僅限於 + GPL-2.0或GPL-2.0或更高版本之間的任何區別。 + 最正確許可證信息只能通過相應源文件中的許可證 + 信息來確定 + + "GPL v2" 和"GPL"相同,它的存在是因爲歷史原因。 + + "GPL and additional rights" 表示模塊源在GPL v2變體和MIT許可下雙重許可的 + 歷史變體。請不要在新代碼中使用。 + + "Dual MIT/GPL" 表達該模塊在GPL v2變體或MIT許可證選擇下雙重 + 許可的正確方式。 + + "Dual BSD/GPL" 該模塊根據GPL v2變體或BSD許可證選擇進行雙重 + 許可。 BSD許可證的確切變體只能通過相應源文件 + 中的許可證信息來確定。 + + "Dual MPL/GPL" 該模塊根據GPL v2變體或Mozilla Public License + (MPL)選項進行雙重許可。 MPL許可證的確切變體 + 只能通過相應的源文件中的許可證信息來確定。 + + "Proprietary" 該模塊屬於專有許可。此字符串僅用於專有的第三 + 方模塊,不能用於在內核樹中具有原始碼的模塊。 + 以這種方式標記的模塊在加載時會使用'P'標記汙 + 染內核,並且內核模塊加載器拒絕將這些模塊連結 + 到使用EXPORT_SYMBOL_GPL()導出的符號。 + ============================= ============================================= + + diff --git a/Documentation/translations/zh_TW/process/magic-number.rst b/Documentation/translations/zh_TW/process/magic-number.rst new file mode 100644 index 000000000000..ae321a9aaece --- /dev/null +++ b/Documentation/translations/zh_TW/process/magic-number.rst @@ -0,0 +1,148 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_magicnumbers: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/magic-number.rst ` + +如果想評論或更新本文的內容,請直接發信到LKML。如果你使用英文交流有困難的話,也可 +以向中文版維護者求助。如果本翻譯更新不及時或者翻譯存在問題,請聯繫中文版維護者:: + + 中文版維護者: 賈威威 Jia Wei Wei + 中文版翻譯者: 賈威威 Jia Wei Wei + 中文版校譯者: 賈威威 Jia Wei Wei + 胡皓文 Hu Haowen + +Linux 魔術數 +============ + +這個文件是有關當前使用的魔術值註冊表。當你給一個結構添加了一個魔術值,你也應該把這個魔術值添加到這個文件,因爲我們最好把用於各種結構的魔術值統一起來。 + +使用魔術值來保護內核數據結構是一個非常好的主意。這就允許你在運行期檢查(a)一個結構是否已經被攻擊,或者(b)你已經給一個例行程序通過了一個錯誤的結構。後一種情況特別地有用---特別是當你通過一個空指針指向結構體的時候。tty源碼,例如,經常通過特定驅動使用這種方法並且反覆地排列特定方面的結構。 + +使用魔術值的方法是在結構的開始處聲明的,如下:: + + struct tty_ldisc { + int magic; + ... + }; + +當你以後給內核添加增強功能的時候,請遵守這條規則!這樣就會節省數不清的調試時間,特別是一些古怪的情況,例如,數組超出範圍並且重新寫了超出部分。遵守這個規則,‪這些情況可以被快速地,安全地避免。 + + Theodore Ts'o + 31 Mar 94 + +給當前的Linux 2.1.55添加魔術表。 + + Michael Chastain + + 22 Sep 1997 + +現在應該最新的Linux 2.1.112.因爲在特性凍結期間,不能在2.2.x前改變任何東西。這些條目被數域所排序。 + + Krzysztof G.Baranowski + + 29 Jul 1998 + +更新魔術表到Linux 2.5.45。剛好越過特性凍結,但是有可能還會有一些新的魔術值在2.6.x之前融入到內核中。 + + Petr Baudis + + 03 Nov 2002 + +更新魔術表到Linux 2.5.74。 + + Fabian Frederick + + 09 Jul 2003 + +===================== ================ ======================== ========================================== +魔術數名 數字 結構 文件 +===================== ================ ======================== ========================================== +PG_MAGIC 'P' pg_{read,write}_hdr ``include/linux/pg.h`` +CMAGIC 0x0111 user ``include/linux/a.out.h`` +MKISS_DRIVER_MAGIC 0x04bf mkiss_channel ``drivers/net/mkiss.h`` +HDLC_MAGIC 0x239e n_hdlc ``drivers/char/n_hdlc.c`` +APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c`` +DB_MAGIC 0x4442 fc_info ``drivers/net/iph5526_novram.c`` +DL_MAGIC 0x444d fc_info ``drivers/net/iph5526_novram.c`` +FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h`` +FF_MAGIC 0x4646 fc_info ``drivers/net/iph5526_novram.c`` +PTY_MAGIC 0x5001 ``drivers/char/pty.c`` +PPP_MAGIC 0x5002 ppp ``include/linux/if_pppvar.h`` +SSTATE_MAGIC 0x5302 serial_state ``include/linux/serial.h`` +SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h`` +STRIP_MAGIC 0x5303 strip ``drivers/net/strip.c`` +SIXPACK_MAGIC 0x5304 sixpack ``drivers/net/hamradio/6pack.h`` +AX25_MAGIC 0x5316 ax_disp ``drivers/net/mkiss.h`` +TTY_MAGIC 0x5401 tty_struct ``include/linux/tty.h`` +MGSL_MAGIC 0x5401 mgsl_info ``drivers/char/synclink.c`` +TTY_DRIVER_MAGIC 0x5402 tty_driver ``include/linux/tty_driver.h`` +MGSLPC_MAGIC 0x5402 mgslpc_info ``drivers/char/pcmcia/synclink_cs.c`` +USB_SERIAL_MAGIC 0x6702 usb_serial ``drivers/usb/serial/usb-serial.h`` +FULL_DUPLEX_MAGIC 0x6969 ``drivers/net/ethernet/dec/tulip/de2104x.c`` +USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth ``drivers/usb/class/bluetty.c`` +RFCOMM_TTY_MAGIC 0x6d02 ``net/bluetooth/rfcomm/tty.c`` +USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port ``drivers/usb/serial/usb-serial.h`` +CG_MAGIC 0x00090255 ufs_cylinder_group ``include/linux/ufs_fs.h`` +LSEMAGIC 0x05091998 lse ``drivers/fc4/fc.c`` +GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str ``drivers/scsi/gdth_ioctl.h`` +RIEBL_MAGIC 0x09051990 ``drivers/net/atarilance.c`` +NBD_REQUEST_MAGIC 0x12560953 nbd_request ``include/linux/nbd.h`` +RED_MAGIC2 0x170fc2a5 (any) ``mm/slab.c`` +BAYCOM_MAGIC 0x19730510 baycom_state ``drivers/net/baycom_epp.c`` +ISDN_X25IFACE_MAGIC 0x1e75a2b9 isdn_x25iface_proto_data ``drivers/isdn/isdn_x25iface.h`` +ECP_MAGIC 0x21504345 cdkecpsig ``include/linux/cdk.h`` +LSOMAGIC 0x27091997 lso ``drivers/fc4/fc.c`` +LSMAGIC 0x2a3b4d2a ls ``drivers/fc4/fc.c`` +WANPIPE_MAGIC 0x414C4453 sdla_{dump,exec} ``include/linux/wanpipe.h`` +CS_CARD_MAGIC 0x43525553 cs_card ``sound/oss/cs46xx.c`` +LABELCL_MAGIC 0x4857434c labelcl_info_s ``include/asm/ia64/sn/labelcl.h`` +ISDN_ASYNC_MAGIC 0x49344C01 modem_info ``include/linux/isdn.h`` +CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info ``drivers/s390/net/ctctty.c`` +ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s ``drivers/isdn/i4l/isdn_net_lib.h`` +SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg ``arch/*/amiga/config.c`` +CS_STATE_MAGIC 0x4c4f4749 cs_state ``sound/oss/cs46xx.c`` +SLAB_C_MAGIC 0x4f17a36d kmem_cache ``mm/slab.c`` +COW_MAGIC 0x4f4f4f4d cow_header_v1 ``arch/um/drivers/ubd_user.c`` +I810_CARD_MAGIC 0x5072696E i810_card ``sound/oss/i810_audio.c`` +TRIDENT_CARD_MAGIC 0x5072696E trident_card ``sound/oss/trident.c`` +ROUTER_MAGIC 0x524d4157 wan_device [in ``wanrouter.h`` pre 3.9] +SAVEKMSG_MAGIC1 0x53415645 savekmsg ``arch/*/amiga/config.c`` +GDA_MAGIC 0x58464552 gda ``arch/mips/include/asm/sn/gda.h`` +RED_MAGIC1 0x5a2cf071 (any) ``mm/slab.c`` +EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev ``drivers/atm/lanai.c`` +HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state ``include/linux/hdlcdrv.h`` +PCXX_MAGIC 0x5c6df104 channel ``drivers/char/pcxx.h`` +KV_MAGIC 0x5f4b565f kernel_vars_s ``arch/mips/include/asm/sn/klkernvars.h`` +I810_STATE_MAGIC 0x63657373 i810_state ``sound/oss/i810_audio.c`` +TRIDENT_STATE_MAGIC 0x63657373 trient_state ``sound/oss/trident.c`` +M3_CARD_MAGIC 0x646e6f50 m3_card ``sound/oss/maestro3.c`` +FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fore200e.h`` +SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` +SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` +LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` +M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` +VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` +KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` +PWC_MAGIC 0x89DC10AB pwc_device ``drivers/usb/media/pwc.h`` +NBD_REPLY_MAGIC 0x96744668 nbd_reply ``include/linux/nbd.h`` +ENI155_MAGIC 0xa54b872d midway_eprom ``drivers/atm/eni.h`` +CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h`` +DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram ``drivers/scsi/gdth.h`` +YAM_MAGIC 0xF10A7654 yam_port ``drivers/net/hamradio/yam.c`` +CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c`` +QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c`` +QUEUE_MAGIC_USED 0xf7e1cc33 queue_entry ``drivers/scsi/arm/queue.c`` +HTB_CMAGIC 0xFEFAFEF1 htb_class ``net/sched/sch_htb.c`` +NMI_MAGIC 0x48414d4d455201 nmi_s ``arch/mips/include/asm/sn/nmi.h`` +===================== ================ ======================== ========================================== + + +請注意,在聲音記憶管理中仍然有一些特殊的爲每個驅動定義的魔術值。查看include/sound/sndmagic.h來獲取他們完整的列表信息。很多OSS聲音驅動擁有自己從音效卡PCI ID構建的魔術值-他們也沒有被列在這裡。 + +IrDA子系統也使用了大量的自己的魔術值,查看include/net/irda/irda.h來獲取他們完整的信息。 + +HFS是另外一個比較大的使用魔術值的文件系統-你可以在fs/hfs/hfs.h中找到他們。 + diff --git a/Documentation/translations/zh_TW/process/management-style.rst b/Documentation/translations/zh_TW/process/management-style.rst new file mode 100644 index 000000000000..dce248470063 --- /dev/null +++ b/Documentation/translations/zh_TW/process/management-style.rst @@ -0,0 +1,211 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/management-style.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_managementstyle: + +Linux內核管理風格 +================= + +這是一個簡短的文檔,描述了Linux內核首選的(或胡編的,取決於您問誰)管理風格。 +它的目的是在某種程度上參照 :ref:`process/coding-style.rst ` +主要是爲了避免反覆回答 [#cnf1]_ 相同(或類似)的問題。 + +管理風格是非常個人化的,比簡單的編碼風格規則更難以量化,因此本文檔可能與實 +際情況有關,也可能與實際情況無關。起初它是一個玩笑,但這並不意味著它可能不 +是真的。你得自己決定。 + +順便說一句,在談到「核心管理者」時,主要是技術負責人,而不是在公司內部進行傳 +統管理的人。如果你簽署了採購訂單或者對你的團隊的預算有任何了解,你幾乎肯定 +不是一個核心管理者。這些建議可能適用於您,也可能不適用於您。 + +首先,我建議你購買「高效人的七個習慣」,而不是閱讀它。燒了它,這是一個偉大的 +象徵性姿態。 + +.. [#cnf1] 本文件並不是通過回答問題,而是通過讓提問者痛苦地明白,我們不知道 + 答案是什麼。 + +不管怎樣,這裡是: + +.. _tw_decisions: + +1)決策 +------- + +每個人都認爲管理者做決定,而且決策很重要。決定越大越痛苦,管理者就必須越高級。 +這很明顯,但事實並非如此。 + +遊戲的名字是 **避免** 做出決定。尤其是,如果有人告訴你「選擇(a)或(b), +我們真的需要你來做決定」,你就是陷入麻煩的管理者。你管理的人比你更了解細節, +所以如果他們來找你做技術決策,你完蛋了。你顯然沒有能力爲他們做這個決定。 + +(推論:如果你管理的人不比你更了解細節,你也會被搞砸,儘管原因完全不同。 +也就是說,你的工作是錯的,他們應該管理你的才智) + +所以遊戲的名字是 **避免** 做出決定,至少是那些大而痛苦的決定。做一些小的 +和非結果性的決定是很好的,並且使您看起來好像知道自己在做什麼,所以內核管理者 +需要做的是將那些大的和痛苦的決定變成那些沒有人真正關心的小事情。 + +這有助於認識到一個大的決定和一個小的決定之間的關鍵區別是你是否可以在事後修正 +你的決定。任何決定都可以通過始終確保如果你錯了(而且你一定會錯),你以後總是 +可以通過回溯來彌補損失。突然間,你就要做兩個無關緊要的決定,一個是錯誤的,另 +一個是正確的。 + +人們甚至會認爲這是真正的領導能力(咳,胡說,咳)。 + +因此,避免重大決策的關鍵在於避免做那些無法挽回的事情。不要被引導到一個你無法 +逃離的角落。走投無路的老鼠可能很危險——走投無路的管理者真可憐。 + +事實證明,由於沒有人會愚蠢到讓內核管理者承擔巨大的財政責任,所以通常很容易 +回溯。既然你不可能浪費掉你無法償還的巨額資金,你唯一可以回溯的就是技術決策, +而回溯很容易:只要告訴大家你是個不稱職的傻瓜,說對不起,然後撤銷你去年讓別 +人所做的毫無價值的工作。突然間,你一年前做的決定不在是一個重大的決定,因爲 +它很容易被推翻。 + +事實證明,有些人對接受這種方法有困難,原因有兩個: + + - 承認你是個白癡比看起來更難。我們都喜歡保持形象,在公共場合說你錯了有時 + 確實很難。 + - 如果有人告訴你,你去年所做的工作終究是不值得的,那麼對那些可憐的低級工 + 程師來說也是很困難的,雖然實際的 **工作** 很容易刪除,但你可能已經不可 + 挽回地失去了工程師的信任。記住:「不可撤銷」是我們一開始就試圖避免的, + 而你的決定終究是一個重大的決定。 + +令人欣慰的是,這兩個原因都可以通過預先承認你沒有任何線索,提前告訴人們你的 +決定完全是初步的,而且可能是錯誤的事情來有效地緩解。你應該始終保留改變主意 +的權利,並讓人們 **意識** 到這一點。當你 **還沒有** 做過真正愚蠢的事情的時 +候,承認自己是愚蠢的要容易得多。 + +然後,當它真的被證明是愚蠢的時候,人們就轉動他們的眼珠說「哎呀,下次不要了」。 + +這種對不稱職的先發制人的承認,也可能使真正做這項工作的人也會三思是否值得做。 +畢竟,如果他們不確定這是否是一個好主意,你肯定不應該通過向他們保證他們所做 +的工作將會進入(內核)鼓勵他們。在他們開始一項巨大的努力之前,至少讓他們三 +思而後行。 + +記住:他們最好比你更了解細節,而且他們通常認爲他們對每件事都有答案。作爲一 +個管理者,你能做的最好的事情不是灌輸自信,而是對他們所做的事情進行健康的批 +判性思考。 + +順便說一句,另一種避免做出決定的方法是看起來很可憐的抱怨 「我們不能兩者兼 +得嗎?」 相信我,它是有效的。如果不清楚哪種方法更好,他們最終會弄清楚的。 +最終的答案可能是兩個團隊都會因爲這種情況而感到沮喪,以至於他們放棄了。 + +這聽起來像是一個失敗,但這通常是一個跡象,表明兩個項目都有問題,而參與其中 +的人不能做決定的原因是他們都是錯誤的。你最終會聞到玫瑰的味道,你避免了另一 +個你本可以搞砸的決定。 + +2)人 +----- + +大多數人都是白癡,做一名管理者意味著你必須處理好這件事,也許更重要的是, +**他們** 必須處理好你。 + +事實證明,雖然很容易糾正技術錯誤,但不容易糾正人格障礙。你只能和他們的和 +你的(人格障礙)共處。 + +但是,爲了做好作爲內核管理者的準備,最好記住不要燒掉任何橋樑,不要轟炸任何 +無辜的村民,也不要疏遠太多的內核開發人員。事實證明,疏遠人是相當容易的,而 +親近一個疏遠的人是很難的。因此,「疏遠」立即屬於「不可逆」的範疇,並根據 +:ref:`tw_decisions` 成爲絕不可以做的事情。 + +這裡只有幾個簡單的規則: + + (1) 不要叫人笨蛋(至少不要在公共場合) + (2) 學習如何在忘記規則(1)時道歉 + +問題在於 #1 很容易去做,因爲你可以用數百萬種不同的方式說「你是一個笨蛋」 [#cnf2]_ +有時甚至沒有意識到,而且幾乎總是帶著一種白熱化的信念,認爲你是對的。 + +你越確信自己是對的(讓我們面對現實吧,你可以把幾乎所有人都稱爲壞人,而且你 +經常是對的),事後道歉就越難。 + +要解決此問題,您實際上只有兩個選項: + + - 非常擅長道歉 + - 把「愛」均勻地散開,沒有人會真正感覺到自己被不公平地瞄準了。讓它有足夠的 + 創造性,他們甚至可能會覺得好笑。 + +選擇永遠保持禮貌是不存在的。沒有人會相信一個如此明顯地隱藏了他們真實性格的人。 + +.. [#cnf2] 保羅·西蒙演唱了「離開愛人的50種方法」,因爲坦率地說,「告訴開發者 + 他們是D*CKHEAD" 的100萬種方法都無法確認。但我確信他已經這麼想了。 + +3)人2 - 好人 +------------- + +雖然大多數人都是白癡,但不幸的是,據此推論你也是白癡,儘管我們都自我感覺良 +好,我們比普通人更好(讓我們面對現實吧,沒有人相信他們是普通人或低於普通人), +我們也應該承認我們不是最鋒利的刀,而且會有其他人比你更不像白癡。 + +有些人對聰明人反應不好。其他人利用它們。 + +作爲內核維護人員,確保您在第二組中。接受他們,因爲他們會讓你的工作更容易。 +特別是,他們能夠爲你做決定,這就是遊戲的全部內容。 + +所以當你發現一個比你聰明的人時,就順其自然吧。你的管理職責在很大程度上變成 +了「聽起來像是個好主意——去嘗試吧」,或者「聽起來不錯,但是XXX呢?」「。第二個版 +本尤其是一個很好的方法,要麼學習一些關於「XXX」的新東西,要麼通過指出一些聰明 +人沒有想到的東西來顯得更具管理性。無論哪種情況,你都會贏。 + +要注意的一件事是認識到一個領域的偉大不一定會轉化爲其他領域。所以你可能會向 +特定的方向刺激人們,但讓我們面對現實吧,他們可能擅長他們所做的事情,而且對 +其他事情都很差勁。好消息是,人們往往會自然而然地重拾他們擅長的東西,所以當 +你向某個方向刺激他們時,你並不是在做不可逆轉的事情,只是不要用力推。 + +4)責備 +------- + +事情會出問題的,人們希望去責備人。貼標籤,你就是受責備的人。 + +事實上,接受責備並不難,尤其是當人們意識到這不 **全是** 你的過錯時。這讓我 +們找到了承擔責任的最佳方式:爲別人承擔這件事。你會感覺很好,他們會感覺很好, +沒有受到指責. 那誰,失去了他們的全部36GB色情收藏的人,因爲你的無能將勉強承 +認,你至少沒有試圖逃避責任。 + +然後讓真正搞砸了的開發人員(如果你能找到他們)私下知道他們搞砸了。不僅是爲 +了將來可以避免,而且爲了讓他們知道他們欠你一個人情。而且,也許更重要的是, +他們也可能是能夠解決問題的人。因爲,讓我們面對現實吧,肯定不是你。 + +承擔責任也是你首先成爲管理者的原因。這是讓人們信任你,讓你獲得潛在的榮耀的 +一部分,因爲你就是那個會說「我搞砸了」的人。如果你已經遵循了以前的規則,你現 +在已經很擅長說了。 + +5)應避免的事情 +--------------- + +有一件事人們甚至比被稱爲「笨蛋」更討厭,那就是在一個神聖的聲音中被稱爲「笨蛋」。 +第一個你可以道歉,第二個你不會真正得到機會。即使你做得很好,他們也可能不再 +傾聽。 + +我們都認爲自己比別人強,這意味著當別人裝腔作勢時,這會讓我們很惱火。你也許 +在道德和智力上比你周圍的每個人都優越,但不要試圖太明顯,除非你真的打算激怒 +某人 [#cnf3]_ + +同樣,不要對事情太客氣或太微妙。禮貌很容易落得落花流水,把問題隱藏起來, +正如他們所說,「在網際網路上,沒人能聽到你的含蓄。」用一個鈍器把這一點錘進去, +因爲你不能真的依靠別人來獲得你的觀點。 + +一些幽默可以幫助緩和直率和道德化。過度到荒謬的地步,可以灌輸一個觀點,而不 +會讓接受者感到痛苦,他們只是認爲你是愚蠢的。因此,它可以幫助我們擺脫對批評 +的個人心理障礙。 + +.. [#cnf3] 提示:與你的工作沒有直接關係的網絡新聞組是消除你對他人不滿的好 + 方法。偶爾寫些侮辱性的帖子,打個噴嚏,讓你的情緒得到淨化。別把牢騷帶回家 + +6)爲什麼是我? +--------------- + +既然你的主要責任似乎是爲別人的錯誤承擔責任,並且讓別人痛苦地明白你是不稱職 +的,那麼顯而易見的問題之一就變成了爲什麼首先要這樣做。 + +首先,雖然你可能會或可能不會聽到十幾歲女孩(或男孩,讓我們不要在這裡評判或 +性別歧視)敲你的更衣室門,你會得到一個巨大的個人成就感爲「負責」。別介意你真 +的在領導別人,你要跟上別人,儘可能快地追趕他們。每個人都會認爲你是負責人。 + +如果你可以做到這個, 這是個偉大的工作! + diff --git a/Documentation/translations/zh_TW/process/programming-language.rst b/Documentation/translations/zh_TW/process/programming-language.rst new file mode 100644 index 000000000000..54e3699eadf8 --- /dev/null +++ b/Documentation/translations/zh_TW/process/programming-language.rst @@ -0,0 +1,76 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/programming-language.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_programming_language: + +程序設計語言 +============ + +內核是用C語言 :ref:`c-language ` 編寫的。更準確地說,內核通常是用 :ref:`gcc ` +在 ``-std=gnu89`` :ref:`gcc-c-dialect-options ` 下編譯的:ISO C90的 GNU 方言( +包括一些C99特性) + +這種方言包含對語言 :ref:`gnu-extensions ` 的許多擴展,當然,它們許多都在內核中使用。 + +對於一些體系結構,有一些使用 :ref:`clang ` 和 :ref:`icc ` 編譯內核 +的支持,儘管在編寫此文檔時還沒有完成,仍需要第三方補丁。 + +屬性 +---- + +在整個內核中使用的一個常見擴展是屬性(attributes) :ref:`gcc-attribute-syntax ` +屬性允許將實現定義的語義引入語言實體(如變量、函數或類型),而無需對語言進行 +重大的語法更改(例如添加新關鍵字) :ref:`n2049 ` + +在某些情況下,屬性是可選的(即不支持這些屬性的編譯器仍然應該生成正確的代碼, +即使其速度較慢或執行的編譯時檢查/診斷次數不夠) + +內核定義了僞關鍵字(例如, ``pure`` ),而不是直接使用GNU屬性語法(例如, +``__attribute__((__pure__))`` ),以檢測可以使用哪些關鍵字和/或縮短代碼, 具體 +請參閱 ``include/linux/compiler_attributes.h`` + +.. _tw_c-language: + +c-language + http://www.open-std.org/jtc1/sc22/wg14/www/standards + +.. _tw_gcc: + +gcc + https://gcc.gnu.org + +.. _tw_clang: + +clang + https://clang.llvm.org + +.. _tw_icc: + +icc + https://software.intel.com/en-us/c-compilers + +.. _tw_gcc-c-dialect-options: + +c-dialect-options + https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html + +.. _tw_gnu-extensions: + +gnu-extensions + https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html + +.. _tw_gcc-attribute-syntax: + +gcc-attribute-syntax + https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html + +.. _tw_n2049: + +n2049 + http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf + diff --git a/Documentation/translations/zh_TW/process/stable-api-nonsense.rst b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst new file mode 100644 index 000000000000..22caa5b8d422 --- /dev/null +++ b/Documentation/translations/zh_TW/process/stable-api-nonsense.rst @@ -0,0 +1,159 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_stable_api_nonsense: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/stable-api-nonsense.rst + ` + +譯者:: + + 中文版維護者: 鍾宇 TripleX Chung + 中文版翻譯者: 鍾宇 TripleX Chung + 中文版校譯者: 李陽 Li Yang + 胡皓文 Hu Haowen + +Linux 內核驅動接口 +================== + +寫作本文檔的目的,是爲了解釋爲什麼Linux既沒有二進位內核接口,也沒有穩定 +的內核接口。這裡所說的內核接口,是指內核里的接口,而不是內核和用戶空間 +的接口。內核到用戶空間的接口,是提供給應用程式使用的系統調用,系統調用 +在歷史上幾乎沒有過變化,將來也不會有變化。我有一些老應用程式是在0.9版本 +或者更早版本的內核上編譯的,在使用2.6版本內核的Linux發布上依然用得很好 +。用戶和應用程式作者可以將這個接口看成是穩定的。 + + +執行綱要 +-------- + +你也許以爲自己想要穩定的內核接口,但是你不清楚你要的實際上不是它。你需 +要的其實是穩定的驅動程序,而你只有將驅動程序放到公版內核的原始碼樹里, +才有可能達到這個目的。而且這樣做還有很多其它好處,正是因爲這些好處使得 +Linux能成爲強壯,穩定,成熟的作業系統,這也是你最開始選擇Linux的原因。 + + +入門 +----- + +只有那些寫驅動程序的「怪人」才會擔心內核接口的改變,對廣大用戶來說,既 +看不到內核接口,也不需要去關心它。 + +首先,我不打算討論關於任何非GPL許可的內核驅動的法律問題,這些非GPL許可 +的驅動程序包括不公開原始碼,隱藏原始碼,二進位或者是用原始碼包裝,或者 +是其它任何形式的不能以GPL許可公開原始碼的驅動程序。如果有法律問題,請咨 +詢律師,我只是一個程式設計師,所以我只打算探討技術問題(不是小看法律問題, +法律問題很實際,並且需要一直關注)。 + +既然只談技術問題,我們就有了下面兩個主題:二進位內核接口和穩定的內核源 +代碼接口。這兩個問題是互相關聯的,讓我們先解決掉二進位接口的問題。 + + +二進位內核接口 +-------------- +假如我們有一個穩定的內核原始碼接口,那麼自然而然的,我們就擁有了穩定的 +二進位接口,是這樣的嗎?錯。讓我們看看關於Linux內核的幾點事實: + + - 取決於所用的C編譯器的版本,不同的內核數據結構里的結構體的對齊方 + 式會有差別,代碼中不同函數的表現形式也不一樣(函數是不是被inline + 編譯取決於編譯器行爲)。不同的函數的表現形式並不重要,但是數據 + 結構內部的對齊方式很關鍵。 + + - 取決於內核的配置選項,不同的選項會讓內核的很多東西發生改變: + + - 同一個結構體可能包含不同的成員變量 + - 有的函數可能根本不會被實現(比如編譯的時候沒有選擇SMP支持 + 一些鎖函數就會被定義成空函數)。 + - 內核使用的內存會以不同的方式對齊,這取決於不同的內核配置選 + 項。 + + - Linux可以在很多的不同體系結構的處理器上運行。在某個體系結構上編 + 譯好的二進位驅動程序,不可能在另外一個體系結構上正確的運行。 + +對於一個特定的內核,滿足這些條件並不難,使用同一個C編譯器和同樣的內核配 +置選項來編譯驅動程序模塊就可以了。這對於給一個特定Linux發布的特定版本提 +供驅動程序,是完全可以滿足需求的。但是如果你要給不同發布的不同版本都發 +布一個驅動程序,就需要在每個發布上用不同的內核設置參數都編譯一次內核, +這簡直跟噩夢一樣。而且還要注意到,每個Linux發布還提供不同的Linux內核, +這些內核都針對不同的硬體類型進行了優化(有很多種不同的處理器,還有不同 +的內核設置選項)。所以每發布一次驅動程序,都需要提供很多不同版本的內核 +模塊。 + +相信我,如果你真的要採取這種發布方式,一定會慢慢瘋掉,我很久以前就有過 +深刻的教訓... + + +穩定的內核原始碼接口 +-------------------- + +如果有人不將他的內核驅動程序,放入公版內核的原始碼樹,而又想讓驅動程序 +一直保持在最新的內核中可用,那麼這個話題將會變得沒完沒了。 +內核開發是持續而且快節奏的,從來都不會慢下來。內核開發人員在當前接口中 +找到bug,或者找到更好的實現方式。一旦發現這些,他們就很快會去修改當前的 +接口。修改接口意味著,函數名可能會改變,結構體可能被擴充或者刪減,函數 +的參數也可能發生改變。一旦接口被修改,內核中使用這些接口的地方需要同時 +修正,這樣才能保證所有的東西繼續工作。 + +舉一個例子,內核的USB驅動程序接口在USB子系統的整個生命周期中,至少經歷 +了三次重寫。這些重寫解決以下問題: + + - 把數據流從同步模式改成非同步模式,這個改動減少了一些驅動程序的 + 複雜度,提高了所有USB驅動程序的吞吐率,這樣幾乎所有的USB設備都 + 能以最大速率工作了。 + - 修改了USB核心代碼中爲USB驅動分配數據包內存的方式,所有的驅動都 + 需要提供更多的參數給USB核心,以修正了很多已經被記錄在案的死鎖。 + +這和一些封閉原始碼的作業系統形成鮮明的對比,在那些作業系統上,不得不額 +外的維護舊的USB接口。這導致了一個可能性,新的開發者依然會不小心使用舊的 +接口,以不恰當的方式編寫代碼,進而影響到作業系統的穩定性。 +在上面的例子中,所有的開發者都同意這些重要的改動,在這樣的情況下修改代 +價很低。如果Linux保持一個穩定的內核原始碼接口,那麼就得創建一個新的接口 +;舊的,有問題的接口必須一直維護,給Linux USB開發者帶來額外的工作。既然 +所有的Linux USB驅動的作者都是利用自己的時間工作,那麼要求他們去做毫無意 +義的免費額外工作,是不可能的。 +安全問題對Linux來說十分重要。一個安全問題被發現,就會在短時間內得到修 +正。在很多情況下,這將導致Linux內核中的一些接口被重寫,以從根本上避免安 +全問題。一旦接口被重寫,所有使用這些接口的驅動程序,必須同時得到修正, +以確定安全問題已經得到修復並且不可能在未來還有同樣的安全問題。如果內核 +內部接口不允許改變,那麼就不可能修復這樣的安全問題,也不可能確認這樣的 +安全問題以後不會發生。 +開發者一直在清理內核接口。如果一個接口沒有人在使用了,它就會被刪除。這 +樣可以確保內核儘可能的小,而且所有潛在的接口都會得到儘可能完整的測試 +(沒有人使用的接口是不可能得到良好的測試的)。 + + +要做什麼 +-------- + +如果你寫了一個Linux內核驅動,但是它還不在Linux原始碼樹里,作爲一個開發 +者,你應該怎麼做?爲每個發布的每個版本提供一個二進位驅動,那簡直是一個 +噩夢,要跟上永遠處於變化之中的內核接口,也是一件辛苦活。 +很簡單,讓你的驅動進入內核原始碼樹(要記得我們在談論的是以GPL許可發行 +的驅動,如果你的代碼不符合GPL,那麼祝你好運,你只能自己解決這個問題了, +你這個吸血鬼<把Andrew和Linus對吸血鬼的定義連結到這裡>)。當你的代碼加入 +公版內核原始碼樹之後,如果一個內核接口改變,你的驅動會直接被修改接口的 +那個人修改。保證你的驅動永遠都可以編譯通過,並且一直工作,你幾乎不需要 +做什麼事情。 + +把驅動放到內核原始碼樹里會有很多的好處: + + - 驅動的質量會提升,而維護成本(對原始作者來說)會下降。 + - 其他人會給驅動添加新特性。 + - 其他人會找到驅動中的bug並修復。 + - 其他人會在驅動中找到性能優化的機會。 + - 當外部的接口的改變需要修改驅動程序的時候,其他人會修改驅動程序 + - 不需要聯繫任何發行商,這個驅動會自動的隨著所有的Linux發布一起發 + 布。 + +和別的作業系統相比,Linux爲更多不同的設備提供現成的驅動,而且能在更多不 +同體系結構的處理器上支持這些設備。這個經過考驗的開發模式,必然是錯不了 +的 :) + +感謝 +---- +感謝 Randy Dunlap, Andrew Morton, David Brownell, Hanna Linder, +Robert Love, and Nishanth Aravamudan 對於本文檔早期版本的評審和建議。 + +英文版維護者: Greg Kroah-Hartman + diff --git a/Documentation/translations/zh_TW/process/stable-kernel-rules.rst b/Documentation/translations/zh_TW/process/stable-kernel-rules.rst new file mode 100644 index 000000000000..9bb0d9b4f3ac --- /dev/null +++ b/Documentation/translations/zh_TW/process/stable-kernel-rules.rst @@ -0,0 +1,68 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_stable_kernel_rules: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/stable-kernel-rules.rst ` + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向中文版維護者求助。如果本翻譯更新不及時或者翻 +譯存在問題,請聯繫中文版維護者:: + + 中文版維護者: 鍾宇 TripleX Chung + 中文版翻譯者: 鍾宇 TripleX Chung + 中文版校譯者: + - 李陽 Li Yang + - Kangkai Yin + - 胡皓文 Hu Haowen + +所有你想知道的事情 - 關於linux穩定版發布 +======================================== + +關於Linux 2.6穩定版發布,所有你想知道的事情。 + +關於哪些類型的補丁可以被接收進入穩定版代碼樹,哪些不可以的規則: +---------------------------------------------------------------- + + - 必須是顯而易見的正確,並且經過測試的。 + - 連同上下文,不能大於100行。 + - 必須只修正一件事情。 + - 必須修正了一個給大家帶來麻煩的真正的bug(不是「這也許是一個問題...」 + 那樣的東西)。 + - 必須修正帶來如下後果的問題:編譯錯誤(對被標記爲CONFIG_BROKEN的例外), + 內核崩潰,掛起,數據損壞,真正的安全問題,或者一些類似「哦,這不 + 好」的問題。簡短的說,就是一些致命的問題。 + - 沒有「理論上的競爭條件」,除非能給出競爭條件如何被利用的解釋。 + - 不能存在任何的「瑣碎的」修正(拼寫修正,去掉多餘空格之類的)。 + - 必須被相關子系統的維護者接受。 + - 必須遵循Documentation/translations/zh_TW/process/submitting-patches.rst里的規則。 + +向穩定版代碼樹提交補丁的過程: +------------------------------ + + - 在確認了補丁符合以上的規則後,將補丁發送到stable@vger.kernel.org。 + - 如果補丁被接受到隊列里,發送者會收到一個ACK回復,如果沒有被接受,收 + 到的是NAK回復。回復需要幾天的時間,這取決於開發者的時間安排。 + - 被接受的補丁會被加到穩定版本隊列里,等待其他開發者的審查。 + - 安全方面的補丁不要發到這個列表,應該發送到security@kernel.org。 + +審查周期: +---------- + + - 當穩定版的維護者決定開始一個審查周期,補丁將被發送到審查委員會,以 + 及被補丁影響的領域的維護者(除非提交者就是該領域的維護者)並且抄送 + 到linux-kernel郵件列表。 + - 審查委員會有48小時的時間,用來決定給該補丁回復ACK還是NAK。 + - 如果委員會中有成員拒絕這個補丁,或者linux-kernel列表上有人反對這個 + 補丁,並提出維護者和審查委員會之前沒有意識到的問題,補丁會從隊列中 + 丟棄。 + - 在審查周期結束的時候,那些得到ACK回應的補丁將會被加入到最新的穩定版 + 發布中,一個新的穩定版發布就此產生。 + - 安全性補丁將從內核安全小組那裡直接接收到穩定版代碼樹中,而不是通過 + 通常的審查周期。請聯繫內核安全小組以獲得關於這個過程的更多細節。 + +審查委員會: +------------ + - 由一些自願承擔這項任務的內核開發者,和幾個非志願的組成。 + diff --git a/Documentation/translations/zh_TW/process/submit-checklist.rst b/Documentation/translations/zh_TW/process/submit-checklist.rst new file mode 100644 index 000000000000..ff2f89cba83f --- /dev/null +++ b/Documentation/translations/zh_TW/process/submit-checklist.rst @@ -0,0 +1,109 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/submit-checklist.rst ` +:Translator: Alex Shi + Hu Haowen + +.. _tw_submitchecklist: + +Linux內核補丁提交清單 +~~~~~~~~~~~~~~~~~~~~~ + +如果開發人員希望看到他們的內核補丁提交更快地被接受,那麼他們應該做一些基本 +的事情。 + +這些都是在 +:ref:`Documentation/translations/zh_TW/process/submitting-patches.rst ` +和其他有關提交Linux內核補丁的文檔中提供的。 + +1) 如果使用工具,則包括定義/聲明該工具的文件。不要依賴於其他頭文件拉入您使用 + 的頭文件。 + +2) 乾淨的編譯: + + a) 使用適用或修改的 ``CONFIG`` 選項 ``=y``、``=m`` 和 ``=n`` 。沒有GCC + 警告/錯誤,沒有連結器警告/錯誤。 + + b) 通過allnoconfig、allmodconfig + + c) 使用 ``O=builddir`` 時可以成功編譯 + +3) 通過使用本地交叉編譯工具或其他一些構建場在多個CPU體系結構上構建。 + +4) PPC64是一種很好的交叉編譯檢查體系結構,因爲它傾向於對64位的數使用無符號 + 長整型。 + +5) 如下所述 :ref:`Documentation/translations/zh_TW/process/coding-style.rst `. + 檢查您的補丁是否爲常規樣式。在提交( ``scripts/check patch.pl`` )之前, + 使用補丁樣式檢查器檢查是否有輕微的衝突。您應該能夠處理您的補丁中存在的所有 + 違規行爲。 + +6) 任何新的或修改過的 ``CONFIG`` 選項都不會弄髒配置菜單,並默認爲關閉,除非 + 它們符合 ``Documentation/kbuild/kconfig-language.rst`` 中記錄的異常條件, + 菜單屬性:默認值. + +7) 所有新的 ``kconfig`` 選項都有幫助文本。 + +8) 已仔細審查了相關的 ``Kconfig`` 組合。這很難用測試來糾正——腦力在這裡是有 + 回報的。 + +9) 用 sparse 檢查乾淨。 + +10) 使用 ``make checkstack`` 和 ``make namespacecheck`` 並修復他們發現的任何 + 問題。 + + .. note:: + + ``checkstack`` 並沒有明確指出問題,但是任何一個在堆棧上使用超過512 + 字節的函數都可以進行更改。 + +11) 包括 :ref:`kernel-doc ` 內核文檔以記錄全局內核API。(靜態函數 + 不需要,但也可以。)使用 ``make htmldocs`` 或 ``make pdfdocs`` 檢查 + :ref:`kernel-doc ` 並修復任何問題。 + +12) 通過以下選項同時啓用的測試 ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``, + ``CONFIG_DEBUG_SLAB``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``, + ``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``, + ``CONFIG_PROVE_RCU`` and ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` + +13) 已經過構建和運行時測試,包括有或沒有 ``CONFIG_SMP``, ``CONFIG_PREEMPT``. + +14) 如果補丁程序影響IO/磁碟等:使用或不使用 ``CONFIG_LBDAF`` 進行測試。 + +15) 所有代碼路徑都已在啓用所有lockdep功能的情況下運行。 + +16) 所有新的/proc條目都記錄在 ``Documentation/`` + +17) 所有新的內核引導參數都記錄在 + Documentation/admin-guide/kernel-parameters.rst 中。 + +18) 所有新的模塊參數都記錄在 ``MODULE_PARM_DESC()`` + +19) 所有新的用戶空間接口都記錄在 ``Documentation/ABI/`` 中。有關詳細信息, + 請參閱 ``Documentation/ABI/README`` 。更改用戶空間接口的補丁應該抄送 + linux-api@vger.kernel.org。 + +20) 已通過至少注入slab和page分配失敗進行檢查。請參閱 ``Documentation/fault-injection/`` + 如果新代碼是實質性的,那麼添加子系統特定的故障注入可能是合適的。 + +21) 新添加的代碼已經用 ``gcc -W`` 編譯(使用 ``make EXTRA-CFLAGS=-W`` )。這 + 將產生大量噪聲,但對於查找諸如「警告:有符號和無符號之間的比較」之類的錯誤 + 很有用。 + +22) 在它被合併到-mm補丁集中之後進行測試,以確保它仍然與所有其他排隊的補丁以 + 及VM、VFS和其他子系統中的各種更改一起工作。 + +23) 所有內存屏障例如 ``barrier()``, ``rmb()``, ``wmb()`` 都需要原始碼中的注 + 釋來解釋它們正在執行的操作及其原因的邏輯。 + +24) 如果補丁添加了任何ioctl,那麼也要更新 ``Documentation/userspace-api/ioctl/ioctl-number.rst`` + +25) 如果修改後的原始碼依賴或使用與以下 ``Kconfig`` 符號相關的任何內核API或 + 功能,則在禁用相關 ``Kconfig`` 符號和/或 ``=m`` (如果該選項可用)的情況 + 下測試以下多個構建[並非所有這些都同時存在,只是它們的各種/隨機組合]: + + ``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``, + ``CONFIG_NET``, ``CONFIG_INET=n`` (但是後者伴隨 ``CONFIG_NET=y``). + diff --git a/Documentation/translations/zh_TW/process/submitting-drivers.rst b/Documentation/translations/zh_TW/process/submitting-drivers.rst new file mode 100644 index 000000000000..2fdd742318ba --- /dev/null +++ b/Documentation/translations/zh_TW/process/submitting-drivers.rst @@ -0,0 +1,164 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_submittingdrivers: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/submitting-drivers.rst + ` + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向中文版維護者求助。如果本翻譯更新不及時或者翻 +譯存在問題,請聯繫中文版維護者:: + + 中文版維護者: 李陽 Li Yang + 中文版翻譯者: 李陽 Li Yang + 中文版校譯者: 陳琦 Maggie Chen + 王聰 Wang Cong + 張巍 Zhang Wei + 胡皓文 Hu Haowen + +如何向 Linux 內核提交驅動程序 +============================= + +這篇文檔將會解釋如何向不同的內核源碼樹提交設備驅動程序。請注意,如果你感 +興趣的是顯卡驅動程序,你也許應該訪問 XFree86 項目(https://www.xfree86.org/) +和/或 X.org 項目 (https://x.org)。 + +另請參閱 Documentation/translations/zh_TW/process/submitting-patches.rst 文檔。 + + +分配設備號 +---------- + +塊設備和字符設備的主設備號與從設備號是由 Linux 命名編號分配權威 LANANA( +現在是 Torben Mathiasen)負責分配。申請的網址是 https://www.lanana.org/。 +即使不準備提交到主流內核的設備驅動也需要在這裡分配設備號。有關詳細信息, +請參閱 Documentation/admin-guide/devices.rst。 + +如果你使用的不是已經分配的設備號,那麼當你提交設備驅動的時候,它將會被強 +制分配一個新的設備號,即便這個設備號和你之前發給客戶的截然不同。 + +設備驅動的提交對象 +------------------ + +Linux 2.0: + 此內核源碼樹不接受新的驅動程序。 + +Linux 2.2: + 此內核源碼樹不接受新的驅動程序。 + +Linux 2.4: + 如果所屬的代碼領域在內核的 MAINTAINERS 文件中列有一個總維護者, + 那麼請將驅動程序提交給他。如果此維護者沒有回應或者你找不到恰當的 + 維護者,那麼請聯繫 Willy Tarreau 。 + +Linux 2.6: + 除了遵循和 2.4 版內核同樣的規則外,你還需要在 linux-kernel 郵件 + 列表上跟蹤最新的 API 變化。向 Linux 2.6 內核提交驅動的頂級聯繫人 + 是 Andrew Morton 。 + +決定設備驅動能否被接受的條件 +---------------------------- + +許可: 代碼必須使用 GNU 通用公開許可證 (GPL) 提交給 Linux,但是 + 我們並不要求 GPL 是唯一的許可。你或許會希望同時使用多種 + 許可證發布,如果希望驅動程序可以被其他開源社區(比如BSD) + 使用。請參考 include/linux/module.h 文件中所列出的可被 + 接受共存的許可。 + +版權: 版權所有者必須同意使用 GPL 許可。最好提交者和版權所有者 + 是相同個人或實體。否則,必需列出授權使用 GPL 的版權所有 + 人或實體,以備驗證之需。 + +接口: 如果你的驅動程序使用現成的接口並且和其他同類的驅動程序行 + 爲相似,而不是去發明無謂的新接口,那麼它將會更容易被接受。 + 如果你需要一個 Linux 和 NT 的通用驅動接口,那麼請在用 + 戶空間實現它。 + +代碼: 請使用 Documentation/process/coding-style.rst 中所描述的 Linux 代碼風 + 格。如果你的某些代碼段(例如那些與 Windows 驅動程序包共 + 享的代碼段)需要使用其他格式,而你卻只希望維護一份代碼, + 那麼請將它們很好地區分出來,並且註明原因。 + +可移植性: 請注意,指針並不永遠是 32 位的,不是所有的計算機都使用小 + 尾模式 (little endian) 存儲數據,不是所有的人都擁有浮點 + 單元,不要隨便在你的驅動程序里嵌入 x86 彙編指令。只能在 + x86 上運行的驅動程序一般是不受歡迎的。雖然你可能只有 x86 + 硬體,很難測試驅動程序在其他平台上是否可用,但是確保代碼 + 可以被輕鬆地移植卻是很簡單的。 + +清晰度: 做到所有人都能修補這個驅動程序將會很有好處,因爲這樣你將 + 會直接收到修復的補丁而不是 bug 報告。如果你提交一個試圖 + 隱藏硬體工作機理的驅動程序,那麼它將會被扔進廢紙簍。 + +電源管理: 因爲 Linux 正在被很多行動裝置和桌面系統使用,所以你的驅 + 動程序也很有可能被使用在這些設備上。它應該支持最基本的電 + 源管理,即在需要的情況下實現系統級休眠和喚醒要用到的 + .suspend 和 .resume 函數。你應該檢查你的驅動程序是否能正 + 確地處理休眠與喚醒,如果實在無法確認,請至少把 .suspend + 函數定義成返回 -ENOSYS(功能未實現)錯誤。你還應該嘗試確 + 保你的驅動在什麼都不乾的情況下將耗電降到最低。要獲得驅動 + 程序測試的指導,請參閱 + Documentation/power/drivers-testing.rst。有關驅動程序電 + 源管理問題相對全面的概述,請參閱 + Documentation/driver-api/pm/devices.rst。 + +管理: 如果一個驅動程序的作者還在進行有效的維護,那麼通常除了那 + 些明顯正確且不需要任何檢查的補丁以外,其他所有的補丁都會 + 被轉發給作者。如果你希望成爲驅動程序的聯繫人和更新者,最 + 好在代碼注釋中寫明並且在 MAINTAINERS 文件中加入這個驅動 + 程序的條目。 + +不影響設備驅動能否被接受的條件 +------------------------------ + +供應商: 由硬體供應商來維護驅動程序通常是一件好事。不過,如果源碼 + 樹里已經有其他人提供了可穩定工作的驅動程序,那麼請不要期 + 望「我是供應商」會成爲內核改用你的驅動程序的理由。理想的情 + 況是:供應商與現有驅動程序的作者合作,構建一個統一完美的 + 驅動程序。 + +作者: 驅動程序是由大的 Linux 公司研發還是由你個人編寫,並不影 + 響其是否能被內核接受。沒有人對內核源碼樹享有特權。只要你 + 充分了解內核社區,你就會發現這一點。 + + +資源列表 +-------- + +Linux 內核主源碼樹: + ftp.??.kernel.org:/pub/linux/kernel/... + ?? == 你的國家代碼,例如 "cn"、"us"、"uk"、"fr" 等等 + +Linux 內核郵件列表: + linux-kernel@vger.kernel.org + [可通過向majordomo@vger.kernel.org發郵件來訂閱] + +Linux 設備驅動程序,第三版(探討 2.6.10 版內核): + https://lwn.net/Kernel/LDD3/ (免費版) + +LWN.net: + 每周內核開發活動摘要 - https://lwn.net/ + + 2.6 版中 API 的變更: + + https://lwn.net/Articles/2.6-kernel-api/ + + 將舊版內核的驅動程序移植到 2.6 版: + + https://lwn.net/Articles/driver-porting/ + +內核新手(KernelNewbies): + 爲新的內核開發者提供文檔和幫助 + https://kernelnewbies.org/ + +Linux USB項目: + http://www.linux-usb.org/ + +寫內核驅動的「不要」(Arjan van de Ven著): + http://www.fenrus.org/how-to-not-write-a-device-driver-paper.pdf + +內核清潔工 (Kernel Janitor): + https://kernelnewbies.org/KernelJanitors + diff --git a/Documentation/translations/zh_TW/process/submitting-patches.rst b/Documentation/translations/zh_TW/process/submitting-patches.rst new file mode 100644 index 000000000000..cdf0b52e4a98 --- /dev/null +++ b/Documentation/translations/zh_TW/process/submitting-patches.rst @@ -0,0 +1,686 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_submittingpatches: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/submitting-patches.rst ` + +譯者:: + + 中文版維護者: 鍾宇 TripleX Chung + 中文版翻譯者: 鍾宇 TripleX Chung + 時奎亮 Alex Shi + 中文版校譯者: 李陽 Li Yang + 王聰 Wang Cong + 胡皓文 Hu Haowen + + +如何讓你的改動進入內核 +====================== + +對於想要將改動提交到 Linux 內核的個人或者公司來說,如果不熟悉「規矩」, +提交的流程會讓人畏懼。本文檔收集了一系列建議,這些建議可以大大的提高你 +的改動被接受的機會. + +以下文檔含有大量簡潔的建議, 具體請見: +:ref:`Documentation/process ` +同樣,:ref:`Documentation/translations/zh_TW/process/submit-checklist.rst ` +給出在提交代碼前需要檢查的項目的列表。如果你在提交一個驅動程序,那麼 +同時閱讀一下: +:ref:`Documentation/process/submitting-drivers.rst ` + +其中許多步驟描述了Git版本控制系統的默認行爲;如果您使用Git來準備補丁, +您將發現它爲您完成的大部分機械工作,儘管您仍然需要準備和記錄一組合理的 +補丁。一般來說,使用git將使您作爲內核開發人員的生活更輕鬆。 + + +0) 獲取當前源碼樹 +----------------- + +如果您沒有一個可以使用當前內核原始碼的存儲庫,請使用git獲取一個。您將要 +從主線存儲庫開始,它可以通過以下方式獲取:: + + git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git + +但是,請注意,您可能不希望直接針對主線樹進行開發。大多數子系統維護人員運 +行自己的樹,並希望看到針對這些樹準備的補丁。請參見MAINTAINERS文件中子系 +統的 **T:** 項以查找該樹,或者簡單地詢問維護者該樹是否未在其中列出。 + +仍然可以通過tarballs下載內核版本(如下一節所述),但這是進行內核開發的 +一種困難的方式。 + +1) "diff -up" +------------- + +使用 "diff -up" 或者 "diff -uprN" 來創建補丁。 + +所有內核的改動,都是以補丁的形式呈現的,補丁由 diff(1) 生成。創建補丁的 +時候,要確認它是以 "unified diff" 格式創建的,這種格式由 diff(1) 的 '-u' +參數生成。而且,請使用 '-p' 參數,那樣會顯示每個改動所在的C函數,使得 +產生的補丁容易讀得多。補丁應該基於內核原始碼樹的根目錄,而不是裡邊的任 +何子目錄。 + +爲一個單獨的文件創建補丁,一般來說這樣做就夠了:: + + SRCTREE=linux + MYFILE=drivers/net/mydriver.c + + cd $SRCTREE + cp $MYFILE $MYFILE.orig + vi $MYFILE # make your change + cd .. + diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch + +爲多個文件創建補丁,你可以解開一個沒有修改過的內核原始碼樹,然後和你自 +己的代碼樹之間做 diff 。例如:: + + MYSRC=/devel/linux + + tar xvfz linux-3.19.tar.gz + mv linux-3.19 linux-3.19-vanilla + diff -uprN -X linux-3.19-vanilla/Documentation/dontdiff \ + linux-3.19-vanilla $MYSRC > /tmp/patch + +"dontdiff" 是內核在編譯的時候產生的文件的列表,列表中的文件在 diff(1) +產生的補丁里會被跳過。 + +確定你的補丁里沒有包含任何不屬於這次補丁提交的額外文件。記得在用diff(1) +生成補丁之後,審閱一次補丁,以確保準確。 + +如果你的改動很散亂,你應該研究一下如何將補丁分割成獨立的部分,將改動分 +割成一系列合乎邏輯的步驟。這樣更容易讓其他內核開發者審核,如果你想你的 +補丁被接受,這是很重要的。請參閱: +:ref:`tw_split_changes` + +如果你用 ``git`` , ``git rebase -i`` 可以幫助你這一點。如果你不用 ``git``, +``quilt`` 另外一個流行的選擇。 + +.. _tw_describe_changes: + +2) 描述你的改動 +--------------- + +描述你的問題。無論您的補丁是一行錯誤修復還是5000行新功能,都必須有一個潛在 +的問題激勵您完成這項工作。讓審稿人相信有一個問題值得解決,讓他們讀完第一段 +是有意義的。 + +描述用戶可見的影響。直接崩潰和鎖定是相當有說服力的,但並不是所有的錯誤都那麼 +明目張胆。即使在代碼審查期間發現了這個問題,也要描述一下您認爲它可能對用戶產 +生的影響。請記住,大多數Linux安裝運行的內核來自二級穩定樹或特定於供應商/產品 +的樹,只從上游精選特定的補丁,因此請包含任何可以幫助您將更改定位到下游的內容: +觸發的場景、DMESG的摘錄、崩潰描述、性能回歸、延遲尖峯、鎖定等。 + +量化優化和權衡。如果您聲稱在性能、內存消耗、堆棧占用空間或二進位大小方面有所 +改進,請包括支持它們的數字。但也要描述不明顯的成本。優化通常不是免費的,而是 +在CPU、內存和可讀性之間進行權衡;或者,探索性的工作,在不同的工作負載之間進 +行權衡。請描述優化的預期缺點,以便審閱者可以權衡成本和收益。 + +一旦問題建立起來,就要詳細地描述一下您實際在做什麼。對於審閱者來說,用簡單的 +英語描述代碼的變化是很重要的,以驗證代碼的行爲是否符合您的意願。 + +如果您將補丁描述寫在一個表單中,這個表單可以很容易地作爲「提交日誌」放入Linux +的原始碼管理系統git中,那麼維護人員將非常感謝您。見 :ref:`tw_explicit_in_reply_to`. + +每個補丁只解決一個問題。如果你的描述開始變長,這就表明你可能需要拆分你的補丁。 +請見 :ref:`tw_split_changes` + +提交或重新提交修補程序或修補程序系列時,請包括完整的修補程序說明和理由。不要 +只說這是補丁(系列)的第幾版。不要期望子系統維護人員引用更早的補丁版本或引用 +URL來查找補丁描述並將其放入補丁中。也就是說,補丁(系列)及其描述應該是獨立的。 +這對維護人員和審查人員都有好處。一些評審者可能甚至沒有收到補丁的早期版本。 + +描述你在命令語氣中的變化,例如「make xyzzy do frotz」而不是「[這個補丁]make +xyzzy do frotz」或「[我]changed xyzzy to do frotz」,就好像你在命令代碼庫改變 +它的行爲一樣。 + +如果修補程序修復了一個記錄的bug條目,請按編號和URL引用該bug條目。如果補丁來 +自郵件列表討論,請給出郵件列表存檔的URL;使用帶有 ``Message-ID`` 的 +https://lkml.kernel.org/ 重定向,以確保連結不會過時。 + +但是,在沒有外部資源的情況下,儘量讓你的解釋可理解。除了提供郵件列表存檔或 +bug的URL之外,還要總結需要提交補丁的相關討論要點。 + +如果您想要引用一個特定的提交,不要只引用提交的 SHA-1 ID。還請包括提交的一行 +摘要,以便於審閱者了解它是關於什麼的。例如:: + + Commit e21d2170f36602ae2708 ("video: remove unnecessary + platform_set_drvdata()") removed the unnecessary + platform_set_drvdata(), but left the variable "dev" unused, + delete it. + +您還應該確保至少使用前12位 SHA-1 ID. 內核存儲庫包含*許多*對象,使與較短的ID +發生衝突的可能性很大。記住,即使現在不會與您的六個字符ID發生衝突,這種情況 +可能五年後改變。 + +如果修補程序修復了特定提交中的錯誤,例如,使用 ``git bisct`` ,請使用帶有前 +12個字符SHA-1 ID 的"Fixes:"標記和單行摘要。爲了簡化不要將標記拆分爲多個, +行、標記不受分析腳本「75列換行」規則的限制。例如:: + + Fixes: 54a4f0239f2e ("KVM: MMU: make kvm_mmu_zap_page() return the number of pages it actually freed") + +下列 ``git config`` 設置可以添加讓 ``git log``, ``git show`` 漂亮的顯示格式:: + + [core] + abbrev = 12 + [pretty] + fixes = Fixes: %h (\"%s\") + +.. _tw_split_changes: + +3) 拆分你的改動 +--------------- + +將每個邏輯更改分隔成一個單獨的補丁。 + +例如,如果你的改動里同時有bug修正和性能優化,那麼把這些改動拆分到兩個或 +者更多的補丁文件中。如果你的改動包含對API的修改,並且修改了驅動程序來適 +應這些新的API,那麼把這些修改分成兩個補丁。 + +另一方面,如果你將一個單獨的改動做成多個補丁文件,那麼將它們合併成一個 +單獨的補丁文件。這樣一個邏輯上單獨的改動只被包含在一個補丁文件里。 + +如果有一個補丁依賴另外一個補丁來完成它的改動,那沒問題。簡單的在你的補 +丁描述里指出「這個補丁依賴某補丁」就好了。 + +在將您的更改劃分爲一系列補丁時,要特別注意確保內核在系列中的每個補丁之後 +都能正常構建和運行。使用 ``git bisect`` 來追蹤問題的開發者可能會在任何時 +候分割你的補丁系列;如果你在中間引入錯誤,他們不會感謝你。 + +如果你不能將補丁濃縮成更少的文件,那麼每次大約發送出15個,然後等待審查 +和集成。 + +4) 檢查你的更改風格 +------------------- + +檢查您的補丁是否存在基本樣式衝突,詳細信息可在 +:ref:`Documentation/translations/zh_TW/process/coding-style.rst ` +中找到。如果不這樣做,只會浪費審稿人的時間,並且會導致你的補丁被拒絕,甚至 +可能沒有被閱讀。 + +一個重要的例外是在將代碼從一個文件移動到另一個文件時——在這種情況下,您不應 +該在移動代碼的同一個補丁中修改移動的代碼。這清楚地描述了移動代碼和您的更改 +的行爲。這大大有助於審查實際差異,並允許工具更好地跟蹤代碼本身的歷史。 + +在提交之前,使用補丁樣式檢查程序檢查補丁(scripts/check patch.pl)。不過, +請注意,樣式檢查程序應該被視爲一個指南,而不是作爲人類判斷的替代品。如果您 +的代碼看起來更好,但有違規行爲,那麼最好不要使用它。 + +檢查者報告三個級別: + + - ERROR:很可能出錯的事情 + - WARNING:需要仔細審查的事項 + - CHECK:需要思考的事情 + +您應該能夠判斷您的補丁中存在的所有違規行爲。 + +5) 選擇補丁收件人 +----------------- + +您應該總是在任何補丁上複製相應的子系統維護人員,以獲得他們維護的代碼;查看 +維護人員文件和原始碼修訂歷史記錄,以了解這些維護人員是誰。腳本 +scripts/get_Maintainer.pl在這個步驟中非常有用。如果您找不到正在工作的子系統 +的維護人員,那麼Andrew Morton(akpm@linux-foundation.org)將充當最後的維護 +人員。 + +您通常還應該選擇至少一個郵件列表來接收補丁集的。linux-kernel@vger.kernel.org +作爲最後一個解決辦法的列表,但是這個列表上的體積已經引起了許多開發人員的拒絕。 +在MAINTAINERS文件中查找子系統特定的列表;您的補丁可能會在那裡得到更多的關注。 +不過,請不要發送垃圾郵件到無關的列表。 + +許多與內核相關的列表託管在vger.kernel.org上;您可以在 +http://vger.kernel.org/vger-lists.html 上找到它們的列表。不過,也有與內核相關 +的列表託管在其他地方。 + +不要一次發送超過15個補丁到vger郵件列表!!!! + +Linus Torvalds 是決定改動能否進入 Linux 內核的最終裁決者。他的 e-mail +地址是 。他收到的 e-mail 很多,所以一般 +的說,最好別給他發 e-mail。 + +如果您有修復可利用安全漏洞的補丁,請將該補丁發送到 security@kernel.org。對於 +嚴重的bug,可以考慮短期暫停以允許分銷商向用戶發布補丁;在這種情況下,顯然不應 +將補丁發送到任何公共列表。 + +修復已發布內核中嚴重錯誤的補丁程序應該指向穩定版維護人員,方法是放這樣的一行:: + + Cc: stable@vger.kernel.org + +進入補丁的簽准區(注意,不是電子郵件收件人)。除了這個文件之外,您還應該閱讀 +:ref:`Documentation/process/stable-kernel-rules.rst ` + +但是,請注意,一些子系統維護人員希望得出他們自己的結論,即哪些補丁應該被放到 +穩定的樹上。尤其是網絡維護人員,不希望看到單個開發人員在補丁中添加像上面這樣 +的行。 + +如果更改影響到用戶和內核接口,請向手冊頁維護人員(如維護人員文件中所列)發送 +手冊頁補丁,或至少發送更改通知,以便一些信息進入手冊頁。還應將用戶空間API +更改複製到 linux-api@vger.kernel.org。 + +對於小的補丁,你也許會CC到搜集瑣碎補丁的郵件列表(Trivial Patch Monkey) +trivial@kernel.org,那裡專門收集瑣碎的補丁。下面這樣的補丁會被看作「瑣碎的」 +補丁: + + - 文檔的拼寫修正。 + - 修正會影響到 grep(1) 的拼寫。 + - 警告信息修正(頻繁的列印無用的警告是不好的。) + - 編譯錯誤修正(代碼邏輯的確是對的,只是編譯有問題。) + - 運行時修正(只要真的修正了錯誤。) + - 移除使用了被廢棄的函數/宏的代碼(例如 check_region。) + - 聯繫方式和文檔修正。 + - 用可移植的代碼替換不可移植的代碼(即使在體系結構相關的代碼中,既然有 + - 人拷貝,只要它是瑣碎的) + - 任何文件的作者/維護者對該文件的改動(例如 patch monkey 在重傳模式下) + +(譯註,關於「瑣碎補丁」的一些說明:因爲原文的這一部分寫得比較簡單,所以不得不 +違例寫一下譯註。"trivial"這個英文單詞的本意是「瑣碎的,不重要的。」但是在這裡 +有稍微有一些變化,例如對一些明顯的NULL指針的修正,屬於運行時修正,會被歸類 +到瑣碎補丁里。雖然NULL指針的修正很重要,但是這樣的修正往往很小而且很容易得到 +檢驗,所以也被歸入瑣碎補丁。瑣碎補丁更精確的歸類應該是 +「simple, localized & easy to verify」,也就是說簡單的,局部的和易於檢驗的。 +trivial@kernel.org郵件列表的目的是針對這樣的補丁,爲提交者提供一個中心,來 +降低提交的門檻。) + +6) 沒有 MIME 編碼,沒有連結,沒有壓縮,沒有附件,只有純文本 +----------------------------------------------------------- + +Linus 和其他的內核開發者需要閱讀和評論你提交的改動。對於內核開發者來說 +,可以「引用」你的改動很重要,使用一般的 e-mail 工具,他們就可以在你的 +代碼的任何位置添加評論。 + +因爲這個原因,所有的提交的補丁都是 e-mail 中「內嵌」的。 + +.. warning:: + 如果你使用剪切-粘貼你的補丁,小心你的編輯器的自動換行功能破壞你的補丁 + +不要將補丁作爲 MIME 編碼的附件,不管是否壓縮。很多流行的 e-mail 軟體不 +是任何時候都將 MIME 編碼的附件當作純文本發送的,這會使得別人無法在你的 +代碼中加評論。另外,MIME 編碼的附件會讓 Linus 多花一點時間來處理,這就 +降低了你的改動被接受的可能性。 + +例外:如果你的郵遞員弄壞了補丁,那麼有人可能會要求你使用mime重新發送補丁 + +請參閱 :ref:`Documentation/translations/zh_TW/process/email-clients.rst ` +以獲取有關配置電子郵件客戶端以使其不受影響地發送修補程序的提示。 + +7) e-mail 的大小 +---------------- + +大的改動對郵件列表不合適,對某些維護者也不合適。如果你的補丁,在不壓縮 +的情況下,超過了300kB,那麼你最好將補丁放在一個能通過 internet 訪問的服 +務器上,然後用指向你的補丁的 URL 替代。但是請注意,如果您的補丁超過了 +300kb,那麼它幾乎肯定需要被破壞。 + +8)回複評審意見 +--------------- + +你的補丁幾乎肯定會得到評審者對補丁改進方法的評論。您必須對這些評論作出 +回應;讓補丁被忽略的一個好辦法就是忽略審閱者的意見。不會導致代碼更改的 +意見或問題幾乎肯定會帶來注釋或變更日誌的改變,以便下一個評審者更好地了解 +正在發生的事情。 + +一定要告訴審稿人你在做什麼改變,並感謝他們的時間。代碼審查是一個累人且 +耗時的過程,審查人員有時會變得暴躁。即使在這種情況下,也要禮貌地回應並 +解決他們指出的問題。 + +9)不要洩氣或不耐煩 +------------------- + +提交更改後,請耐心等待。審閱者是忙碌的人,可能無法立即訪問您的修補程序。 + +曾幾何時,補丁曾在沒有評論的情況下消失在空白中,但開發過程比現在更加順利。 +您應該在一周左右的時間內收到評論;如果沒有收到評論,請確保您已將補丁發送 +到正確的位置。在重新提交或聯繫審閱者之前至少等待一周-在諸如合併窗口之類的 +繁忙時間可能更長。 + +10)主題中包含 PATCH +-------------------- + +由於到linus和linux內核的電子郵件流量很高,通常會在主題行前面加上[PATCH] +前綴. 這使Linus和其他內核開發人員更容易將補丁與其他電子郵件討論區分開。 + +11)簽署你的作品-開發者原始認證 +------------------------------- + +爲了加強對誰做了何事的追蹤,尤其是對那些透過好幾層的維護者的補丁,我們 +建議在發送出去的補丁上加一個 「sign-off」 的過程。 + +"sign-off" 是在補丁的注釋的最後的簡單的一行文字,認證你編寫了它或者其他 +人有權力將它作爲開放原始碼的補丁傳遞。規則很簡單:如果你能認證如下信息: + +開發者來源證書 1.1 +^^^^^^^^^^^^^^^^^^ + +對於本項目的貢獻,我認證如下信息: + + (a)這些貢獻是完全或者部分的由我創建,我有權利以文件中指出 + 的開放原始碼許可證提交它;或者 + (b)這些貢獻基於以前的工作,據我所知,這些以前的工作受恰當的開放 + 原始碼許可證保護,而且,根據許可證,我有權提交修改後的貢獻, + 無論是完全還是部分由我創造,這些貢獻都使用同一個開放原始碼許可證 + (除非我被允許用其它的許可證),正如文件中指出的;或者 + (c)這些貢獻由認證(a),(b)或者(c)的人直接提供給我,而 + 且我沒有修改它。 + (d)我理解並同意這個項目和貢獻是公開的,貢獻的記錄(包括我 + 一起提交的個人記錄,包括 sign-off )被永久維護並且可以和這個項目 + 或者開放原始碼的許可證同步地再發行。 + +那麼加入這樣一行:: + + Signed-off-by: Random J Developer + +使用你的真名(抱歉,不能使用假名或者匿名。) + +有人在最後加上標籤。現在這些東西會被忽略,但是你可以這樣做,來標記公司 +內部的過程,或者只是指出關於 sign-off 的一些特殊細節。 + +如果您是子系統或分支維護人員,有時需要稍微修改收到的補丁,以便合併它們, +因爲樹和提交者中的代碼不完全相同。如果你嚴格遵守規則(c),你應該要求提交者 +重新發布,但這完全是在浪費時間和精力。規則(b)允許您調整代碼,但是更改一個 +提交者的代碼並讓他認可您的錯誤是非常不禮貌的。要解決此問題,建議在最後一個 +由簽名行和您的行之間添加一行,指示更改的性質。雖然這並不是強制性的,但似乎 +在描述前加上您的郵件和/或姓名(全部用方括號括起來),這足以讓人注意到您對最 +後一分鐘的更改負有責任。例如:: + + Signed-off-by: Random J Developer + [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h] + Signed-off-by: Lucky K Maintainer + +如果您維護一個穩定的分支機構,同時希望對作者進行致謝、跟蹤更改、合併修復並 +保護提交者不受投訴,那麼這種做法尤其有用。請注意,在任何情況下都不能更改作者 +的ID(From 頭),因爲它是出現在更改日誌中的標識。 + +對回合(back-porters)的特別說明:在提交消息的頂部(主題行之後)插入一個補丁 +的起源指示似乎是一種常見且有用的實踐,以便於跟蹤。例如,下面是我們在3.x穩定 +版本中看到的內容:: + + Date: Tue Oct 7 07:26:38 2014 -0400 + + libata: Un-break ATA blacklist + + commit 1c40279960bcd7d52dbdf1d466b20d24b99176c8 upstream. + +還有, 這裡是一個舊版內核中的一個回合補丁:: + + Date: Tue May 13 22:12:27 2008 +0200 + + wireless, airo: waitbusy() won't delay + + [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a] + +12)何時使用Acked-by:,CC:,和Co-Developed by: +---------------------------------------------- + +Singed-off-by: 標記表示簽名者參與了補丁的開發,或者他/她在補丁的傳遞路徑中。 + +如果一個人沒有直接參與補丁的準備或處理,但希望表示並記錄他們對補丁的批准, +那麼他們可以要求在補丁的變更日誌中添加一個 Acked-by: + +Acked-by:通常由受影響代碼的維護者使用,當該維護者既沒有貢獻也沒有轉發補丁時。 + +Acked-by: 不像簽字人那樣正式。這是一個記錄,確認人至少審查了補丁,並表示接受。 +因此,補丁合併有時會手動將Acker的「Yep,looks good to me」轉換爲 Acked-By:(但 +請注意,通常最好要求一個明確的Ack)。 + +Acked-by:不一定表示對整個補丁的確認。例如,如果一個補丁影響多個子系統,並且 +有一個:來自一個子系統維護者,那麼這通常表示只確認影響維護者代碼的部分。這裡 +應該仔細判斷。如有疑問,應參考郵件列表檔案中的原始討論。 + +如果某人有機會對補丁進行評論,但沒有提供此類評論,您可以選擇在補丁中添加 ``Cc:`` +這是唯一一個標籤,它可以在沒有被它命名的人顯式操作的情況下添加,但它應該表明 +這個人是在補丁上抄送的。討論中包含了潛在利益相關方。 + +Co-developed-by: 聲明補丁是由多個開發人員共同創建的;當幾個人在一個補丁上工 +作時,它用於將屬性賦予共同作者(除了 From: 所賦予的作者之外)。因爲 +Co-developed-by: 表示作者身份,所以每個共同開發人:必須緊跟在相關合作作者的 +簽名之後。標準的簽核程序要求:標記的簽核順序應儘可能反映補丁的時間歷史,而不 +管作者是通過 From :還是由 Co-developed-by: 共同開發的。值得注意的是,最後一 +個簽字人:必須始終是提交補丁的開發人員。 + +注意,當作者也是電子郵件標題「發件人:」行中列出的人時,「From: 」 標記是可選的。 + +作者提交的補丁程序示例:: + + + + Co-developed-by: First Co-Author + Signed-off-by: First Co-Author + Co-developed-by: Second Co-Author + Signed-off-by: Second Co-Author + Signed-off-by: From Author + +合作開發者提交的補丁示例:: + + From: From Author + + + + Co-developed-by: Random Co-Author + Signed-off-by: Random Co-Author + Signed-off-by: From Author + Co-developed-by: Submitting Co-Author + Signed-off-by: Submitting Co-Author + + +13)使用報告人:、測試人:、審核人:、建議人:、修復人: +-------------------------------------------------------- + +Reported-by: 給那些發現錯誤並報告錯誤的人致謝,它希望激勵他們在將來再次幫助 +我們。請注意,如果bug是以私有方式報告的,那麼在使用Reported-by標記之前,請 +先請求權限。 + +Tested-by: 標記表示補丁已由指定的人(在某些環境中)成功測試。這個標籤通知 +維護人員已經執行了一些測試,爲將來的補丁提供了一種定位測試人員的方法,並確 +保測試人員的信譽。 + +Reviewed-by:相反,根據審查人的聲明,表明該補丁已被審查並被認爲是可接受的: + + +審查人的監督聲明 +^^^^^^^^^^^^^^^^ + +通過提供我的 Reviewed-by,我聲明: + + (a) 我已經對這個補丁進行了一次技術審查,以評估它是否適合被包含到 + 主線內核中。 + + (b) 與補丁相關的任何問題、顧慮或問題都已反饋給提交者。我對提交者對 + 我的評論的回應感到滿意。 + + (c) 雖然這一提交可能會改進一些東西,但我相信,此時,(1)對內核 + 進行了有價值的修改,(2)沒有包含爭論中涉及的已知問題。 + + (d) 雖然我已經審查了補丁並認爲它是健全的,但我不會(除非另有明確 + 說明)作出任何保證或保證它將在任何給定情況下實現其規定的目的 + 或正常運行。 + +Reviewed-by 是一種觀點聲明,即補丁是對內核的適當修改,沒有任何遺留的嚴重技術 +問題。任何感興趣的審閱者(完成工作的人)都可以爲一個補丁提供一個 Review-by +標籤。此標籤用於向審閱者提供致謝,並通知維護者已在修補程序上完成的審閱程度。 +Reviewed-by: 當由已知了解主題區域並執行徹底檢查的審閱者提供時,通常會增加 +補丁進入內核的可能性。 + +Suggested-by: 表示補丁的想法是由指定的人提出的,並確保將此想法歸功於指定的 +人。請注意,未經許可,不得添加此標籤,特別是如果該想法未在公共論壇上發布。 +這就是說,如果我們勤快地致謝我們的創意者,他們很有希望在未來得到鼓舞,再次 +幫助我們。 + +Fixes: 指示補丁在以前的提交中修復了一個問題。它可以很容易地確定錯誤的來源, +這有助於檢查錯誤修復。這個標記還幫助穩定內核團隊確定應該接收修復的穩定內核 +版本。這是指示補丁修復的錯誤的首選方法。請參閱 :ref:`tw_describe_changes` +描述您的更改以了解更多詳細信息。 + +.. _tw_the_canonical_patch_format: + +12)標準補丁格式 +---------------- + +本節描述如何格式化補丁本身。請注意,如果您的補丁存儲在 ``Git`` 存儲庫中,則 +可以使用 ``git format-patch`` 進行正確的補丁格式設置。但是,這些工具無法創建 +必要的文本,因此請務必閱讀下面的說明。 + +標準的補丁,標題行是:: + + Subject: [PATCH 001/123] 子系統:一句話概述 + +標準補丁的信體存在如下部分: + + - 一個 "from" 行指出補丁作者。後跟空行(僅當發送修補程序的人不是作者時才需要)。 + + - 解釋的正文,行以75列包裝,這將被複製到永久變更日誌來描述這個補丁。 + + - 一個空行 + + - 上面描述的「Signed-off-by」 行,也將出現在更改日誌中。 + + - 只包含 ``---`` 的標記線。 + + - 任何其他不適合放在變更日誌的注釋。 + + - 實際補丁( ``diff`` 輸出)。 + +標題行的格式,使得對標題行按字母序排序非常的容易 - 很多 e-mail 客戶端都 +可以支持 - 因爲序列號是用零填充的,所以按數字排序和按字母排序是一樣的。 + +e-mail 標題中的「子系統」標識哪個內核子系統將被打補丁。 + +e-mail 標題中的「一句話概述」扼要的描述 e-mail 中的補丁。「一句話概述」 +不應該是一個文件名。對於一個補丁系列(「補丁系列」指一系列的多個相關補 +丁),不要對每個補丁都使用同樣的「一句話概述」。 + +記住 e-mail 的「一句話概述」會成爲該補丁的全局唯一標識。它會蔓延到 git +的改動記錄里。然後「一句話概述」會被用在開發者的討論里,用來指代這個補 +丁。用戶將希望通過 google 來搜索"一句話概述"來找到那些討論這個補丁的文 +章。當人們在兩三個月後使用諸如 ``gitk`` 或 ``git log --oneline`` 之類 +的工具查看數千個補丁時,也會很快看到它。 + +出於這些原因,概述必須不超過70-75個字符,並且必須描述補丁的更改以及爲 +什麼需要補丁。既要簡潔又要描述性很有挑戰性,但寫得好的概述應該這樣做。 + +概述的前綴可以用方括號括起來:「Subject: [PATCH ...] <概述>」。標記 +不被視爲概述的一部分,而是描述應該如何處理補丁。如果補丁的多個版本已發 +送出來以響應評審(即「v1,v2,v3」)或「rfc」,以指示評審請求,那麼通用標記 +可能包括版本描述符。如果一個補丁系列中有四個補丁,那麼各個補丁可以這樣 +編號:1/4、2/4、3/4、4/4。這可以確保開發人員了解補丁應用的順序,並且他們 +已經查看或應用了補丁系列中的所有補丁。 + +一些標題的例子:: + + Subject: [patch 2/5] ext2: improve scalability of bitmap searching + Subject: [PATCHv2 001/207] x86: fix eflags tracking + +"From" 行是信體裡的最上面一行,具有如下格式: + From: Patch Author + +"From" 行指明在永久改動日誌里,誰會被確認爲作者。如果沒有 "From" 行,那 +麼郵件頭裡的 "From: " 行會被用來決定改動日誌中的作者。 + +說明的主題將會被提交到永久的原始碼改動日誌里,因此對那些早已經不記得和 +這個補丁相關的討論細節的有能力的讀者來說,是有意義的。包括補丁程序定位 +錯誤的(內核日誌消息、OOPS消息等)症狀,對於搜索提交日誌以尋找適用補丁的人 +尤其有用。如果一個補丁修復了一個編譯失敗,那麼可能不需要包含所有編譯失敗; +只要足夠讓搜索補丁的人能夠找到它就行了。與概述一樣,既要簡潔又要描述性。 + +"---" 標記行對於補丁處理工具要找到哪裡是改動日誌信息的結束,是不可缺少 +的。 + +對於 "---" 標記之後的額外註解,一個好的用途就是用來寫 diffstat,用來顯 +示修改了什麼文件和每個文件都增加和刪除了多少行。diffstat 對於比較大的補 +丁特別有用。其餘那些只是和時刻或者開發者相關的註解,不合適放到永久的改 +動日誌里的,也應該放這裡。 +使用 diffstat的選項 "-p 1 -w 70" 這樣文件名就會從內核原始碼樹的目錄開始 +,不會占用太寬的空間(很容易適合80列的寬度,也許會有一些縮進。) + +在後面的參考資料中能看到適當的補丁格式的更多細節。 + +.. _tw_explicit_in_reply_to: + +15) 明確回覆郵件頭(In-Reply-To) +------------------------------- + +手動添加回復補丁的的標題頭(In-Reply_To:) 是有幫助的(例如,使用 ``git send-email`` ) +將補丁與以前的相關討論關聯起來,例如,將bug修復程序連結到電子郵件和bug報告。 +但是,對於多補丁系列,最好避免在回復時使用連結到該系列的舊版本。這樣, +補丁的多個版本就不會成爲電子郵件客戶端中無法管理的引用序列。如果連結有用, +可以使用 https://lkml.kernel.org/ 重定向器(例如,在封面電子郵件文本中) +連結到補丁系列的早期版本。 + +16) 發送git pull請求 +-------------------- + +如果您有一系列補丁,那麼讓維護人員通過git pull操作將它們直接拉入子系統存儲 +庫可能是最方便的。但是,請注意,從開發人員那裡獲取補丁比從郵件列表中獲取補 +丁需要更高的信任度。因此,許多子系統維護人員不願意接受請求,特別是來自新的 +未知開發人員的請求。如果有疑問,您可以在封面郵件中使用pull 請求作爲補丁系列 +正常發布的一個選項,讓維護人員可以選擇使用其中之一。 + +pull 請求的主題行中應該有[Git Pull]。請求本身應該在一行中包含存儲庫名稱和 +感興趣的分支;它應該看起來像:: + + Please pull from + + git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus + + to get these changes: + + +pull 請求還應該包含一條整體消息,說明請求中將包含什麼,一個補丁本身的 ``Git shortlog`` +以及一個顯示補丁系列整體效果的 ``diffstat`` 。當然,將所有這些信息收集在一起 +的最簡單方法是讓 ``git`` 使用 ``git request-pull`` 命令爲您完成這些工作。 + +一些維護人員(包括Linus)希望看到來自已簽名提交的請求;這增加了他們對你的 +請求信心。特別是,在沒有簽名標籤的情況下,Linus 不會從像 Github 這樣的公共 +託管站點拉請求。 + +創建此類簽名的第一步是生成一個 GNRPG 密鑰,並由一個或多個核心內核開發人員對 +其進行簽名。這一步對新開發人員來說可能很困難,但沒有辦法繞過它。參加會議是 +找到可以簽署您的密鑰的開發人員的好方法。 + +一旦您在Git 中準備了一個您希望有人拉的補丁系列,就用 ``git tag -s`` 創建一 +個簽名標記。這將創建一個新標記,標識該系列中的最後一次提交,並包含用您的私 +鑰創建的簽名。您還可以將changelog樣式的消息添加到標記中;這是一個描述拉請求 +整體效果的理想位置。 + +如果維護人員將要從中提取的樹不是您正在使用的存儲庫,請不要忘記將已簽名的標記 +顯式推送到公共樹。 + +生成拉請求時,請使用已簽名的標記作爲目標。這樣的命令可以實現:: + + git request-pull master git://my.public.tree/linux.git my-signed-tag + +參考文獻 +-------- + +Andrew Morton, "The perfect patch" (tpp). + + +Jeff Garzik, "Linux kernel patch submission format". + + +Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". + + + + + + + + + + + + +NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! + + +Kernel Documentation/process/coding-style.rst: + :ref:`Documentation/translations/zh_TW/process/coding-style.rst ` + +Linus Torvalds's mail on the canonical patch format: + + +Andi Kleen, "On submitting kernel patches" + Some strategies to get difficult or controversial changes in. + + http://halobates.de/on-submitting-patches.pdf + diff --git a/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst b/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst new file mode 100644 index 000000000000..097fe80352cb --- /dev/null +++ b/Documentation/translations/zh_TW/process/volatile-considered-harmful.rst @@ -0,0 +1,110 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. _tw_volatile_considered_harmful: + +.. include:: ../disclaimer-zh_TW.rst + +:Original: :ref:`Documentation/process/volatile-considered-harmful.rst + ` + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向中文版維護者求助。如果本翻譯更新不及時或者翻 +譯存在問題,請聯繫中文版維護者:: + + 英文版維護者: Jonathan Corbet + 中文版維護者: 伍鵬 Bryan Wu + 中文版翻譯者: 伍鵬 Bryan Wu + 中文版校譯者: 張漢輝 Eugene Teo + 楊瑞 Dave Young + 時奎亮 Alex Shi + 胡皓文 Hu Haowen + +爲什麼不應該使用「volatile」類型 +================================ + +C程式設計師通常認爲volatile表示某個變量可以在當前執行的線程之外被改變;因此,在內核 +中用到共享數據結構時,常常會有C程式設計師喜歡使用volatile這類變量。換句話說,他們經 +常會把volatile類型看成某種簡易的原子變量,當然它們不是。在內核中使用volatile幾 +乎總是錯誤的;本文檔將解釋爲什麼這樣。 + +理解volatile的關鍵是知道它的目的是用來消除優化,實際上很少有人真正需要這樣的應 +用。在內核中,程式設計師必須防止意外的並發訪問破壞共享的數據結構,這其實是一個完全 +不同的任務。用來防止意外並發訪問的保護措施,可以更加高效的避免大多數優化相關的 +問題。 + +像volatile一樣,內核提供了很多原語來保證並發訪問時的數據安全(自旋鎖, 互斥量,內 +存屏障等等),同樣可以防止意外的優化。如果可以正確使用這些內核原語,那麼就沒有 +必要再使用volatile。如果仍然必須使用volatile,那麼幾乎可以肯定在代碼的某處有一 +個bug。在正確設計的內核代碼中,volatile能帶來的僅僅是使事情變慢。 + +思考一下這段典型的內核代碼:: + + spin_lock(&the_lock); + do_something_on(&shared_data); + do_something_else_with(&shared_data); + spin_unlock(&the_lock); + +如果所有的代碼都遵循加鎖規則,當持有the_lock的時候,不可能意外的改變shared_data的 +值。任何可能訪問該數據的其他代碼都會在這個鎖上等待。自旋鎖原語跟內存屏障一樣—— 它 +們顯式的用來書寫成這樣 —— 意味著數據訪問不會跨越它們而被優化。所以本來編譯器認爲 +它知道在shared_data裡面將有什麼,但是因爲spin_lock()調用跟內存屏障一樣,會強制編 +譯器忘記它所知道的一切。那麼在訪問這些數據時不會有優化的問題。 + +如果shared_data被聲名爲volatile,鎖操作將仍然是必須的。就算我們知道沒有其他人正在 +使用它,編譯器也將被阻止優化對臨界區內shared_data的訪問。在鎖有效的同時, +shared_data不是volatile的。在處理共享數據的時候,適當的鎖操作可以不再需要 +volatile —— 並且是有潛在危害的。 + +volatile的存儲類型最初是爲那些內存映射的I/O寄存器而定義。在內核里,寄存器訪問也應 +該被鎖保護,但是人們也不希望編譯器「優化」臨界區內的寄存器訪問。內核里I/O的內存訪問 +是通過訪問函數完成的;不贊成通過指針對I/O內存的直接訪問,並且不是在所有體系架構上 +都能工作。那些訪問函數正是爲了防止意外優化而寫的,因此,再說一次,volatile類型不 +是必需的。 + +另一種引起用戶可能使用volatile的情況是當處理器正忙著等待一個變量的值。正確執行一 +個忙等待的方法是:: + + while (my_variable != what_i_want) + cpu_relax(); + +cpu_relax()調用會降低CPU的能量消耗或者讓位於超線程雙處理器;它也作爲內存屏障一樣出 +現,所以,再一次,volatile不是必需的。當然,忙等待一開始就是一種反常規的做法。 + +在內核中,一些稀少的情況下volatile仍然是有意義的: + + - 在一些體系架構的系統上,允許直接的I/0內存訪問,那麼前面提到的訪問函數可以使用 + volatile。基本上,每一個訪問函數調用它自己都是一個小的臨界區域並且保證了按照 + 程式設計師期望的那樣發生訪問操作。 + + - 某些會改變內存的內聯彙編代碼雖然沒有什麼其他明顯的附作用,但是有被GCC刪除的可 + 能性。在彙編聲明中加上volatile關鍵字可以防止這種刪除操作。 + + - Jiffies變量是一種特殊情況,雖然每次引用它的時候都可以有不同的值,但讀jiffies + 變量時不需要任何特殊的加鎖保護。所以jiffies變量可以使用volatile,但是不贊成 + 其他跟jiffies相同類型變量使用volatile。Jiffies被認爲是一種「愚蠢的遺留物" + (Linus的話)因爲解決這個問題比保持現狀要麻煩的多。 + + - 由於某些I/0設備可能會修改連續一致的內存,所以有時,指向連續一致內存的數據結構 + 的指針需要正確的使用volatile。網絡適配器使用的環狀緩存區正是這類情形的一個例 + 子,其中適配器用改變指針來表示哪些描述符已經處理過了。 + +對於大多代碼,上述幾種可以使用volatile的情況都不適用。所以,使用volatile是一種 +bug並且需要對這樣的代碼額外仔細檢查。那些試圖使用volatile的開發人員需要退一步想想 +他們真正想實現的是什麼。 + +非常歡迎刪除volatile變量的補丁 - 只要證明這些補丁完整的考慮了並發問題。 + +注釋 +---- + +[1] https://lwn.net/Articles/233481/ +[2] https://lwn.net/Articles/233482/ + +致謝 +---- + +最初由Randy Dunlap推動並作初步研究 +由Jonathan Corbet撰寫 +參考Satyam Sharma,Johannes Stezenbach,Jesper Juhl,Heikki Orsila, +H. Peter Anvin,Philipp Hahn和Stefan Richter的意見改善了本檔。 + -- cgit v1.2.3-70-g09d2 From 0c3b533cfdd5275fd556028ffe9121aa64e49778 Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Thu, 29 Jul 2021 23:56:27 +0800 Subject: MAINTAINERS: add entry for traditional Chinese documentation Add maintainer information for traditional Chinese documentation. Signed-off-by: Hu Haowen Reviewed-by: Pan Yunwang Link: https://lore.kernel.org/r/20210729155627.41744-3-src.res@email.cn Signed-off-by: Jonathan Corbet --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..1134e374a18e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18790,6 +18790,14 @@ F: arch/x86/mm/testmmiotrace.c F: include/linux/mmiotrace.h F: kernel/trace/trace_mmiotrace.c +TRADITIONAL CHINESE DOCUMENTATION +M: Hu Haowen +L: linux-doc-tw-discuss@lists.sourceforge.net +S: Maintained +W: https://github.com/srcres258/linux-doc +T: git git://github.com/srcres258/linux-doc.git doc-zh-tw +F: Documentation/translations/zh_TW/ + TRIVIAL PATCHES M: Jiri Kosina S: Maintained -- cgit v1.2.3-70-g09d2 From ba51bdafaafc065019c6f6a2cdae006d176cee48 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 5 Jul 2021 15:02:43 +0200 Subject: scsi: sr: cdrom: Move cdrom_read_cdda_bpc() into the sr driver cdrom_read_cdda_bpc() relies on sending SCSI command to the low level driver using a REQ_OP_SCSI_IN request. This isn't generic block layer functionality, so move the actual low-level code into the sr driver and call it through a new read_cdda_bpc method in the cdrom_device_ops structure. With this the CDROM code does not have to pull in scsi_normalize_sense() and depend on CONFIG_SCSI_COMMON. Link: https://lore.kernel.org/r/20210730072752.GB23847%40lst.de Tested-by: Anders Roxell Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/cdrom/cdrom.c | 71 ++++++--------------------------------------------- drivers/scsi/sr.c | 56 +++++++++++++++++++++++++++++++++++++++- include/linux/cdrom.h | 6 +++-- 3 files changed, 67 insertions(+), 66 deletions(-) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 8882b311bafd..bd2e5b1560f5 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -629,7 +629,7 @@ int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi) if (CDROM_CAN(CDC_MRW_W)) cdi->exit = cdrom_mrw_exit; - if (cdi->disk) + if (cdi->ops->read_cdda_bpc) cdi->cdda_method = CDDA_BPC_FULL; else cdi->cdda_method = CDDA_OLD; @@ -2159,81 +2159,26 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, int lba, int nframes) { - struct request_queue *q = cdi->disk->queue; - struct request *rq; - struct scsi_request *req; - struct bio *bio; - unsigned int len; + int max_frames = (queue_max_sectors(cdi->disk->queue) << 9) / + CD_FRAMESIZE_RAW; int nr, ret = 0; - if (!q) - return -ENXIO; - - if (!blk_queue_scsi_passthrough(q)) { - WARN_ONCE(true, - "Attempt read CDDA info through a non-SCSI queue\n"); - return -EINVAL; - } - cdi->last_sense = 0; while (nframes) { - nr = nframes; if (cdi->cdda_method == CDDA_BPC_SINGLE) nr = 1; - if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9)) - nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW; - - len = nr * CD_FRAMESIZE_RAW; - - rq = blk_get_request(q, REQ_OP_DRV_IN, 0); - if (IS_ERR(rq)) { - ret = PTR_ERR(rq); - break; - } - req = scsi_req(rq); - - ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL); - if (ret) { - blk_put_request(rq); - break; - } - - req->cmd[0] = GPCMD_READ_CD; - req->cmd[1] = 1 << 2; - req->cmd[2] = (lba >> 24) & 0xff; - req->cmd[3] = (lba >> 16) & 0xff; - req->cmd[4] = (lba >> 8) & 0xff; - req->cmd[5] = lba & 0xff; - req->cmd[6] = (nr >> 16) & 0xff; - req->cmd[7] = (nr >> 8) & 0xff; - req->cmd[8] = nr & 0xff; - req->cmd[9] = 0xf8; - - req->cmd_len = 12; - rq->timeout = 60 * HZ; - bio = rq->bio; - - blk_execute_rq(cdi->disk, rq, 0); - if (scsi_req(rq)->result) { - struct scsi_sense_hdr sshdr; - - ret = -EIO; - scsi_normalize_sense(req->sense, req->sense_len, - &sshdr); - cdi->last_sense = sshdr.sense_key; - } - - if (blk_rq_unmap_user(bio)) - ret = -EFAULT; - blk_put_request(rq); + else + nr = min(nframes, max_frames); + ret = cdi->ops->read_cdda_bpc(cdi, ubuf, lba, nr, + &cdi->last_sense); if (ret) break; nframes -= nr; lba += nr; - ubuf += len; + ubuf += (nr * CD_FRAMESIZE_RAW); } return ret; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index b98e77fe700b..6203a8b58d40 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -120,6 +120,8 @@ static void get_capabilities(struct scsi_cd *); static unsigned int sr_check_events(struct cdrom_device_info *cdi, unsigned int clearing, int slot); static int sr_packet(struct cdrom_device_info *, struct packet_command *); +static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf, + u32 lba, u32 nr, u8 *last_sense); static const struct cdrom_device_ops sr_dops = { .open = sr_open, @@ -133,8 +135,9 @@ static const struct cdrom_device_ops sr_dops = { .get_mcn = sr_get_mcn, .reset = sr_reset, .audio_ioctl = sr_audio_ioctl, - .capability = SR_CAPABILITIES, .generic_packet = sr_packet, + .read_cdda_bpc = sr_read_cdda_bpc, + .capability = SR_CAPABILITIES, }; static void sr_kref_release(struct kref *kref); @@ -951,6 +954,57 @@ static int sr_packet(struct cdrom_device_info *cdi, return cgc->stat; } +static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf, + u32 lba, u32 nr, u8 *last_sense) +{ + struct gendisk *disk = cdi->disk; + u32 len = nr * CD_FRAMESIZE_RAW; + struct scsi_request *req; + struct request *rq; + struct bio *bio; + int ret; + + rq = blk_get_request(disk->queue, REQ_OP_DRV_IN, 0); + if (IS_ERR(rq)) + return PTR_ERR(rq); + req = scsi_req(rq); + + ret = blk_rq_map_user(disk->queue, rq, NULL, ubuf, len, GFP_KERNEL); + if (ret) + goto out_put_request; + + req->cmd[0] = GPCMD_READ_CD; + req->cmd[1] = 1 << 2; + req->cmd[2] = (lba >> 24) & 0xff; + req->cmd[3] = (lba >> 16) & 0xff; + req->cmd[4] = (lba >> 8) & 0xff; + req->cmd[5] = lba & 0xff; + req->cmd[6] = (nr >> 16) & 0xff; + req->cmd[7] = (nr >> 8) & 0xff; + req->cmd[8] = nr & 0xff; + req->cmd[9] = 0xf8; + req->cmd_len = 12; + rq->timeout = 60 * HZ; + bio = rq->bio; + + blk_execute_rq(disk, rq, 0); + if (scsi_req(rq)->result) { + struct scsi_sense_hdr sshdr; + + scsi_normalize_sense(req->sense, req->sense_len, + &sshdr); + *last_sense = sshdr.sense_key; + ret = -EIO; + } + + if (blk_rq_unmap_user(bio)) + ret = -EFAULT; +out_put_request: + blk_put_request(rq); + return ret; +} + + /** * sr_kref_release - Called to free the scsi_cd structure * @kref: pointer to embedded kref diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index f48d0a31deae..c4fef00abdf3 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -86,11 +86,13 @@ struct cdrom_device_ops { /* play stuff */ int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); -/* driver specifications */ - const int capability; /* capability flags */ /* handle uniform packets for scsi type devices (scsi,atapi) */ int (*generic_packet) (struct cdrom_device_info *, struct packet_command *); + int (*read_cdda_bpc)(struct cdrom_device_info *cdi, void __user *ubuf, + u32 lba, u32 nframes, u8 *last_sense); +/* driver specifications */ + const int capability; /* capability flags */ }; int cdrom_multisession(struct cdrom_device_info *cdi, -- cgit v1.2.3-70-g09d2 From ead09dd3aed5cc6a6c6288a87a5bfa9bbc8d5ecf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 29 Jul 2021 08:48:42 +0200 Subject: scsi: bsg: Simplify device registration Use the per-device cdev_device_interface to store the bsg data in the char device inode, and thus remove the need to embedd the bsg_class_device structure in the request_queue. Link: https://lore.kernel.org/r/20210729064845.1044147-2-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/bsg-lib.c | 11 +- block/bsg.c | 304 +++++++++++---------------------------------- drivers/scsi/scsi_bsg.c | 5 +- drivers/scsi/scsi_priv.h | 11 +- drivers/scsi/scsi_sysfs.c | 24 ++-- include/linux/blkdev.h | 6 - include/linux/bsg-lib.h | 1 + include/linux/bsg.h | 21 +--- include/scsi/scsi_device.h | 2 + 9 files changed, 108 insertions(+), 277 deletions(-) diff --git a/block/bsg-lib.c b/block/bsg-lib.c index a89d80102304..fe43f5fda6e5 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -6,6 +6,7 @@ * Copyright (C) 2011 Red Hat, Inc. All rights reserved. * Copyright (C) 2011 Mike Christie */ +#include #include #include #include @@ -19,6 +20,7 @@ struct bsg_set { struct blk_mq_tag_set tag_set; + struct bsg_device *bd; bsg_job_fn *job_fn; bsg_timeout_fn *timeout_fn; }; @@ -327,7 +329,7 @@ void bsg_remove_queue(struct request_queue *q) struct bsg_set *bset = container_of(q->tag_set, struct bsg_set, tag_set); - bsg_unregister_queue(q); + bsg_unregister_queue(bset->bd); blk_cleanup_queue(q); blk_mq_free_tag_set(&bset->tag_set); kfree(bset); @@ -396,10 +398,9 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, q->queuedata = dev; blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); - ret = bsg_register_queue(q, dev, name, &bsg_transport_ops); - if (ret) { - printk(KERN_ERR "%s: bsg interface failed to " - "initialize - register queue\n", dev->kobj.name); + bset->bd = bsg_register_queue(q, dev, name, &bsg_transport_ops); + if (IS_ERR(bset->bd)) { + ret = PTR_ERR(bset->bd); goto out_cleanup_queue; } diff --git a/block/bsg.c b/block/bsg.c index 3dbfd2c6aef3..83a095185d33 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -20,38 +20,29 @@ #define BSG_DESCRIPTION "Block layer SCSI generic (bsg) driver" #define BSG_VERSION "0.4" -#define bsg_dbg(bd, fmt, ...) \ - pr_debug("%s: " fmt, (bd)->name, ##__VA_ARGS__) - struct bsg_device { struct request_queue *queue; - spinlock_t lock; - struct hlist_node dev_list; - refcount_t ref_count; - char name[20]; + const struct bsg_ops *ops; + struct device device; + struct cdev cdev; int max_queue; }; +static inline struct bsg_device *to_bsg_device(struct inode *inode) +{ + return container_of(inode->i_cdev, struct bsg_device, cdev); +} + #define BSG_DEFAULT_CMDS 64 #define BSG_MAX_DEVS 32768 -static DEFINE_MUTEX(bsg_mutex); -static DEFINE_IDR(bsg_minor_idr); - -#define BSG_LIST_ARRAY_SIZE 8 -static struct hlist_head bsg_device_list[BSG_LIST_ARRAY_SIZE]; - +static DEFINE_IDA(bsg_minor_ida); static struct class *bsg_class; static int bsg_major; -static inline struct hlist_head *bsg_dev_idx_hash(int index) -{ - return &bsg_device_list[index & (BSG_LIST_ARRAY_SIZE - 1)]; -} - #define uptr64(val) ((void __user *)(uintptr_t)(val)) -static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) +static int bsg_sg_io(struct bsg_device *bd, fmode_t mode, void __user *uarg) { struct request *rq; struct bio *bio; @@ -61,21 +52,18 @@ static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) if (copy_from_user(&hdr, uarg, sizeof(hdr))) return -EFAULT; - if (!q->bsg_dev.class_dev) - return -ENXIO; - if (hdr.guard != 'Q') return -EINVAL; - ret = q->bsg_dev.ops->check_proto(&hdr); + ret = bd->ops->check_proto(&hdr); if (ret) return ret; - rq = blk_get_request(q, hdr.dout_xfer_len ? + rq = blk_get_request(bd->queue, hdr.dout_xfer_len ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); - ret = q->bsg_dev.ops->fill_hdr(rq, &hdr, mode); + ret = bd->ops->fill_hdr(rq, &hdr, mode); if (ret) { blk_put_request(rq); return ret; @@ -83,17 +71,17 @@ static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) rq->timeout = msecs_to_jiffies(hdr.timeout); if (!rq->timeout) - rq->timeout = q->sg_timeout; + rq->timeout = rq->q->sg_timeout; if (!rq->timeout) rq->timeout = BLK_DEFAULT_SG_TIMEOUT; if (rq->timeout < BLK_MIN_SG_TIMEOUT) rq->timeout = BLK_MIN_SG_TIMEOUT; if (hdr.dout_xfer_len) { - ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr.dout_xferp), + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr.dout_xferp), hdr.dout_xfer_len, GFP_KERNEL); } else if (hdr.din_xfer_len) { - ret = blk_rq_map_user(q, rq, NULL, uptr64(hdr.din_xferp), + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr.din_xferp), hdr.din_xfer_len, GFP_KERNEL); } @@ -103,171 +91,50 @@ static int bsg_sg_io(struct request_queue *q, fmode_t mode, void __user *uarg) bio = rq->bio; blk_execute_rq(NULL, rq, !(hdr.flags & BSG_FLAG_Q_AT_TAIL)); - ret = rq->q->bsg_dev.ops->complete_rq(rq, &hdr); + ret = bd->ops->complete_rq(rq, &hdr); blk_rq_unmap_user(bio); out_free_rq: - rq->q->bsg_dev.ops->free_rq(rq); + bd->ops->free_rq(rq); blk_put_request(rq); if (!ret && copy_to_user(uarg, &hdr, sizeof(hdr))) return -EFAULT; return ret; } -static struct bsg_device *bsg_alloc_device(void) -{ - struct bsg_device *bd; - - bd = kzalloc(sizeof(struct bsg_device), GFP_KERNEL); - if (unlikely(!bd)) - return NULL; - - spin_lock_init(&bd->lock); - bd->max_queue = BSG_DEFAULT_CMDS; - INIT_HLIST_NODE(&bd->dev_list); - return bd; -} - -static int bsg_put_device(struct bsg_device *bd) -{ - struct request_queue *q = bd->queue; - - mutex_lock(&bsg_mutex); - - if (!refcount_dec_and_test(&bd->ref_count)) { - mutex_unlock(&bsg_mutex); - return 0; - } - - hlist_del(&bd->dev_list); - mutex_unlock(&bsg_mutex); - - bsg_dbg(bd, "tearing down\n"); - - /* - * close can always block - */ - kfree(bd); - blk_put_queue(q); - return 0; -} - -static struct bsg_device *bsg_add_device(struct inode *inode, - struct request_queue *rq, - struct file *file) -{ - struct bsg_device *bd; - unsigned char buf[32]; - - lockdep_assert_held(&bsg_mutex); - - if (!blk_get_queue(rq)) - return ERR_PTR(-ENXIO); - - bd = bsg_alloc_device(); - if (!bd) { - blk_put_queue(rq); - return ERR_PTR(-ENOMEM); - } - - bd->queue = rq; - - refcount_set(&bd->ref_count, 1); - hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode))); - - strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1); - bsg_dbg(bd, "bound to <%s>, max queue %d\n", - format_dev_t(buf, inode->i_rdev), bd->max_queue); - - return bd; -} - -static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q) -{ - struct bsg_device *bd; - - lockdep_assert_held(&bsg_mutex); - - hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) { - if (bd->queue == q) { - refcount_inc(&bd->ref_count); - goto found; - } - } - bd = NULL; -found: - return bd; -} - -static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) -{ - struct bsg_device *bd; - struct bsg_class_device *bcd; - - /* - * find the class device - */ - mutex_lock(&bsg_mutex); - bcd = idr_find(&bsg_minor_idr, iminor(inode)); - - if (!bcd) { - bd = ERR_PTR(-ENODEV); - goto out_unlock; - } - - bd = __bsg_get_device(iminor(inode), bcd->queue); - if (!bd) - bd = bsg_add_device(inode, bcd->queue, file); - -out_unlock: - mutex_unlock(&bsg_mutex); - return bd; -} - static int bsg_open(struct inode *inode, struct file *file) { - struct bsg_device *bd; - - bd = bsg_get_device(inode, file); - - if (IS_ERR(bd)) - return PTR_ERR(bd); - - file->private_data = bd; + if (!blk_get_queue(to_bsg_device(inode)->queue)) + return -ENXIO; return 0; } static int bsg_release(struct inode *inode, struct file *file) { - struct bsg_device *bd = file->private_data; - - file->private_data = NULL; - return bsg_put_device(bd); + blk_put_queue(to_bsg_device(inode)->queue); + return 0; } static int bsg_get_command_q(struct bsg_device *bd, int __user *uarg) { - return put_user(bd->max_queue, uarg); + return put_user(READ_ONCE(bd->max_queue), uarg); } static int bsg_set_command_q(struct bsg_device *bd, int __user *uarg) { - int queue; + int max_queue; - if (get_user(queue, uarg)) + if (get_user(max_queue, uarg)) return -EFAULT; - if (queue < 1) + if (max_queue < 1) return -EINVAL; - - spin_lock_irq(&bd->lock); - bd->max_queue = queue; - spin_unlock_irq(&bd->lock); + WRITE_ONCE(bd->max_queue, max_queue); return 0; } static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct bsg_device *bd = file->private_data; + struct bsg_device *bd = to_bsg_device(file_inode(file)); struct request_queue *q = bd->queue; void __user *uarg = (void __user *) arg; int __user *intp = uarg; @@ -312,7 +179,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_EMULATED_HOST: return put_user(1, intp); case SG_IO: - return bsg_sg_io(q, file->f_mode, uarg); + return bsg_sg_io(bd, file->f_mode, uarg); case SCSI_IOCTL_SEND_COMMAND: pr_warn_ratelimited("%s: calling unsupported SCSI_IOCTL_SEND_COMMAND\n", current->comm); @@ -331,83 +198,66 @@ static const struct file_operations bsg_fops = { .llseek = default_llseek, }; -void bsg_unregister_queue(struct request_queue *q) +void bsg_unregister_queue(struct bsg_device *bd) { - struct bsg_class_device *bcd = &q->bsg_dev; - - if (!bcd->class_dev) - return; - - mutex_lock(&bsg_mutex); - idr_remove(&bsg_minor_idr, bcd->minor); - if (q->kobj.sd) - sysfs_remove_link(&q->kobj, "bsg"); - device_unregister(bcd->class_dev); - bcd->class_dev = NULL; - mutex_unlock(&bsg_mutex); + if (bd->queue->kobj.sd) + sysfs_remove_link(&bd->queue->kobj, "bsg"); + cdev_device_del(&bd->cdev, &bd->device); + ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); + kfree(bd); } EXPORT_SYMBOL_GPL(bsg_unregister_queue); -int bsg_register_queue(struct request_queue *q, struct device *parent, - const char *name, const struct bsg_ops *ops) +struct bsg_device *bsg_register_queue(struct request_queue *q, + struct device *parent, const char *name, + const struct bsg_ops *ops) { - struct bsg_class_device *bcd; - dev_t dev; + struct bsg_device *bd; int ret; - struct device *class_dev = NULL; - - /* - * we need a proper transport to send commands, not a stacked device - */ - if (!queue_is_mq(q)) - return 0; - bcd = &q->bsg_dev; - memset(bcd, 0, sizeof(*bcd)); - - mutex_lock(&bsg_mutex); + bd = kzalloc(sizeof(*bd), GFP_KERNEL); + if (!bd) + return ERR_PTR(-ENOMEM); + bd->max_queue = BSG_DEFAULT_CMDS; + bd->queue = q; + bd->ops = ops; - ret = idr_alloc(&bsg_minor_idr, bcd, 0, BSG_MAX_DEVS, GFP_KERNEL); + ret = ida_simple_get(&bsg_minor_ida, 0, BSG_MAX_DEVS, GFP_KERNEL); if (ret < 0) { - if (ret == -ENOSPC) { - printk(KERN_ERR "bsg: too many bsg devices\n"); - ret = -EINVAL; - } - goto unlock; - } - - bcd->minor = ret; - bcd->queue = q; - bcd->ops = ops; - dev = MKDEV(bsg_major, bcd->minor); - class_dev = device_create(bsg_class, parent, dev, NULL, "%s", name); - if (IS_ERR(class_dev)) { - ret = PTR_ERR(class_dev); - goto idr_remove; + if (ret == -ENOSPC) + dev_err(parent, "bsg: too many bsg devices\n"); + goto out_kfree; } - bcd->class_dev = class_dev; + bd->device.devt = MKDEV(bsg_major, ret); + bd->device.class = bsg_class; + bd->device.parent = parent; + dev_set_name(&bd->device, "%s", name); + device_initialize(&bd->device); + + cdev_init(&bd->cdev, &bsg_fops); + bd->cdev.owner = THIS_MODULE; + ret = cdev_device_add(&bd->cdev, &bd->device); + if (ret) + goto out_ida_remove; if (q->kobj.sd) { - ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg"); + ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg"); if (ret) - goto unregister_class_dev; + goto out_device_del; } - mutex_unlock(&bsg_mutex); - return 0; + return bd; -unregister_class_dev: - device_unregister(class_dev); -idr_remove: - idr_remove(&bsg_minor_idr, bcd->minor); -unlock: - mutex_unlock(&bsg_mutex); - return ret; +out_device_del: + cdev_device_del(&bd->cdev, &bd->device); +out_ida_remove: + ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); +out_kfree: + kfree(bd); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(bsg_register_queue); -static struct cdev bsg_cdev; - static char *bsg_devnode(struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev)); @@ -415,11 +265,8 @@ static char *bsg_devnode(struct device *dev, umode_t *mode) static int __init bsg_init(void) { - int ret, i; dev_t devid; - - for (i = 0; i < BSG_LIST_ARRAY_SIZE; i++) - INIT_HLIST_HEAD(&bsg_device_list[i]); + int ret; bsg_class = class_create(THIS_MODULE, "bsg"); if (IS_ERR(bsg_class)) @@ -429,19 +276,12 @@ static int __init bsg_init(void) ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg"); if (ret) goto destroy_bsg_class; - bsg_major = MAJOR(devid); - cdev_init(&bsg_cdev, &bsg_fops); - ret = cdev_add(&bsg_cdev, MKDEV(bsg_major, 0), BSG_MAX_DEVS); - if (ret) - goto unregister_chrdev; - printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION " loaded (major %d)\n", bsg_major); return 0; -unregister_chrdev: - unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS); + destroy_bsg_class: class_destroy(bsg_class); return ret; diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index 68f60316adf1..c0d41c45c2be 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -89,7 +89,8 @@ static const struct bsg_ops scsi_bsg_ops = { .free_rq = scsi_bsg_free_rq, }; -int scsi_bsg_register_queue(struct request_queue *q, struct device *parent) +struct bsg_device *scsi_bsg_register_queue(struct scsi_device *sdev) { - return bsg_register_queue(q, parent, dev_name(parent), &scsi_bsg_ops); + return bsg_register_queue(sdev->request_queue, &sdev->sdev_gendev, + dev_name(&sdev->sdev_gendev), &scsi_bsg_ops); } diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 0a0db35bab04..6d9152031a40 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -7,6 +7,7 @@ #include #include +struct bsg_device; struct request_queue; struct request; struct scsi_cmnd; @@ -180,15 +181,7 @@ static inline void scsi_dh_add_device(struct scsi_device *sdev) { } static inline void scsi_dh_release_device(struct scsi_device *sdev) { } #endif -#ifdef CONFIG_BLK_DEV_BSG -int scsi_bsg_register_queue(struct request_queue *q, struct device *parent); -#else -static inline int scsi_bsg_register_queue(struct request_queue *q, - struct device *parent) -{ - return 0; -} -#endif +struct bsg_device *scsi_bsg_register_queue(struct scsi_device *sdev); extern int scsi_device_max_queue_depth(struct scsi_device *sdev); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 4ff9ac3296d8..07cee8dc4100 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -1327,7 +1328,6 @@ static int scsi_target_add(struct scsi_target *starget) int scsi_sysfs_add_sdev(struct scsi_device *sdev) { int error, i; - struct request_queue *rq = sdev->request_queue; struct scsi_target *starget = sdev->sdev_target; error = scsi_target_add(starget); @@ -1366,12 +1366,19 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) transport_add_device(&sdev->sdev_gendev); sdev->is_visible = 1; - error = scsi_bsg_register_queue(rq, &sdev->sdev_gendev); - if (error) - /* we're treating error on bsg register as non-fatal, - * so pretend nothing went wrong */ - sdev_printk(KERN_INFO, sdev, - "Failed to register bsg queue, errno=%d\n", error); + if (IS_ENABLED(CONFIG_BLK_DEV_BSG)) { + sdev->bsg_dev = scsi_bsg_register_queue(sdev); + if (IS_ERR(sdev->bsg_dev)) { + /* + * We're treating error on bsg register as non-fatal, so + * pretend nothing went wrong. + */ + sdev_printk(KERN_INFO, sdev, + "Failed to register bsg queue, errno=%d\n", + error); + sdev->bsg_dev = NULL; + } + } /* add additional host specific attributes */ if (sdev->host->hostt->sdev_attrs) { @@ -1433,7 +1440,8 @@ void __scsi_remove_device(struct scsi_device *sdev) sysfs_remove_groups(&sdev->sdev_gendev.kobj, sdev->host->hostt->sdev_groups); - bsg_unregister_queue(sdev->request_queue); + if (IS_ENABLED(CONFIG_BLK_DEV_BSG) && sdev->bsg_dev) + bsg_unregister_queue(sdev->bsg_dev); device_unregister(&sdev->sdev_dev); transport_remove_device(dev); device_del(dev); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 8c617a5a5d61..28957ccdd9c2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,6 @@ struct elevator_queue; struct blk_trace; struct request; struct sg_io_hdr; -struct bsg_job; struct blkcg_gq; struct blk_flush_queue; struct pr_ops; @@ -535,10 +533,6 @@ struct request_queue { int mq_freeze_depth; -#if IS_ENABLED(CONFIG_BLK_DEV_BSG_COMMON) - struct bsg_class_device bsg_dev; -#endif - #ifdef CONFIG_BLK_DEV_THROTTLING /* Throttle data */ struct throtl_data *td; diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h index 960988d42f77..6b211323a489 100644 --- a/include/linux/bsg-lib.h +++ b/include/linux/bsg-lib.h @@ -12,6 +12,7 @@ #include #include +struct bsg_job; struct request; struct device; struct scatterlist; diff --git a/include/linux/bsg.h b/include/linux/bsg.h index b887da20bd41..fa21f79beda2 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -4,10 +4,11 @@ #include +struct bsg_device; +struct device; struct request; struct request_queue; -#ifdef CONFIG_BLK_DEV_BSG_COMMON struct bsg_ops { int (*check_proto)(struct sg_io_v4 *hdr); int (*fill_hdr)(struct request *rq, struct sg_io_v4 *hdr, @@ -16,19 +17,9 @@ struct bsg_ops { void (*free_rq)(struct request *rq); }; -struct bsg_class_device { - struct device *class_dev; - int minor; - struct request_queue *queue; - const struct bsg_ops *ops; -}; +struct bsg_device *bsg_register_queue(struct request_queue *q, + struct device *parent, const char *name, + const struct bsg_ops *ops); +void bsg_unregister_queue(struct bsg_device *bcd); -int bsg_register_queue(struct request_queue *q, struct device *parent, - const char *name, const struct bsg_ops *ops); -void bsg_unregister_queue(struct request_queue *q); -#else -static inline void bsg_unregister_queue(struct request_queue *q) -{ -} -#endif /* CONFIG_BLK_DEV_BSG_COMMON */ #endif /* _LINUX_BSG_H */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index d1de21f799f4..99082da1b951 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -10,6 +10,7 @@ #include #include +struct bsg_device; struct device; struct request_queue; struct scsi_cmnd; @@ -235,6 +236,7 @@ struct scsi_device { size_t dma_drain_len; void *dma_drain_buf; + struct bsg_device *bsg_dev; unsigned char access_state; struct mutex state_mutex; enum scsi_device_state sdev_state; -- cgit v1.2.3-70-g09d2 From cf93a27446fe1a6e0acb9bbedf5fce1e98e4fc5b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 29 Jul 2021 08:48:43 +0200 Subject: scsi: block: Remove BLK_SCSI_MAX_CMDS This was used for the table based SCSI passthough permission checking that is gone now. Link: https://lore.kernel.org/r/20210729064845.1044147-3-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- include/linux/blkdev.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 28957ccdd9c2..e0bb14acb708 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -271,9 +271,6 @@ enum blk_queue_state { #define BLK_TAG_ALLOC_FIFO 0 /* allocate starting from 0 */ #define BLK_TAG_ALLOC_RR 1 /* allocate starting from last allocated tag */ -#define BLK_SCSI_MAX_CMDS (256) -#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) - /* * Zoned block device models (zoned limit). * -- cgit v1.2.3-70-g09d2 From 1e61c1a804d2a2a3c46add01cac3a6e9eca01080 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 29 Jul 2021 08:48:44 +0200 Subject: scsi: block: Remove the remaining SG_IO-related fields from struct request_queue Move the sg_timeout and sg_reserved_size fields into the bsg_device and scsi_device structures as they have nothing to do with generic block I/O. Note that these values are now separate for bsg vs. SCSI device node access, but that just matches how /dev/sg vs the other nodes has always behaved. Link: https://lore.kernel.org/r/20210729064845.1044147-4-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/blk-mq.c | 2 -- block/bsg.c | 13 ++++++---- drivers/scsi/scsi_ioctl.c | 63 ++++++++++++++++++++++------------------------ drivers/scsi/scsi_scan.c | 2 ++ include/linux/blkdev.h | 5 ---- include/scsi/scsi_device.h | 3 +++ 6 files changed, 43 insertions(+), 45 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 2c4ac51e54eb..495f508c6300 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3298,8 +3298,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, set->map[HCTX_TYPE_POLL].nr_queues) blk_queue_flag_set(QUEUE_FLAG_POLL, q); - q->sg_reserved_size = INT_MAX; - INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); INIT_LIST_HEAD(&q->requeue_list); spin_lock_init(&q->requeue_lock); diff --git a/block/bsg.c b/block/bsg.c index 83a095185d33..3ba74eec4ba2 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -26,6 +26,8 @@ struct bsg_device { struct device device; struct cdev cdev; int max_queue; + unsigned int timeout; + unsigned int reserved_size; }; static inline struct bsg_device *to_bsg_device(struct inode *inode) @@ -71,7 +73,7 @@ static int bsg_sg_io(struct bsg_device *bd, fmode_t mode, void __user *uarg) rq->timeout = msecs_to_jiffies(hdr.timeout); if (!rq->timeout) - rq->timeout = rq->q->sg_timeout; + rq->timeout = bd->timeout; if (!rq->timeout) rq->timeout = BLK_DEFAULT_SG_TIMEOUT; if (rq->timeout < BLK_MIN_SG_TIMEOUT) @@ -161,19 +163,19 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case SG_SET_TIMEOUT: if (get_user(val, intp)) return -EFAULT; - q->sg_timeout = clock_t_to_jiffies(val); + bd->timeout = clock_t_to_jiffies(val); return 0; case SG_GET_TIMEOUT: - return jiffies_to_clock_t(q->sg_timeout); + return jiffies_to_clock_t(bd->timeout); case SG_GET_RESERVED_SIZE: - return put_user(min(q->sg_reserved_size, queue_max_bytes(q)), + return put_user(min(bd->reserved_size, queue_max_bytes(q)), intp); case SG_SET_RESERVED_SIZE: if (get_user(val, intp)) return -EFAULT; if (val < 0) return -EINVAL; - q->sg_reserved_size = + bd->reserved_size = min_t(unsigned int, val, queue_max_bytes(q)); return 0; case SG_EMULATED_HOST: @@ -219,6 +221,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, if (!bd) return ERR_PTR(-ENOMEM); bd->max_queue = BSG_DEFAULT_CMDS; + bd->reserved_size = INT_MAX; bd->queue = q; bd->ops = ops; diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index 633f016c2bfe..7b2b0a1581f4 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -173,29 +173,25 @@ static int sg_get_version(int __user *p) return put_user(sg_version_num, p); } -static int sg_get_timeout(struct request_queue *q) -{ - return jiffies_to_clock_t(q->sg_timeout); -} - -static int sg_set_timeout(struct request_queue *q, int __user *p) +static int sg_set_timeout(struct scsi_device *sdev, int __user *p) { int timeout, err = get_user(timeout, p); if (!err) - q->sg_timeout = clock_t_to_jiffies(timeout); + sdev->sg_timeout = clock_t_to_jiffies(timeout); return err; } -static int sg_get_reserved_size(struct request_queue *q, int __user *p) +static int sg_get_reserved_size(struct scsi_device *sdev, int __user *p) { - int val = min(q->sg_reserved_size, queue_max_bytes(q)); + int val = min(sdev->sg_reserved_size, + queue_max_bytes(sdev->request_queue)); return put_user(val, p); } -static int sg_set_reserved_size(struct request_queue *q, int __user *p) +static int sg_set_reserved_size(struct scsi_device *sdev, int __user *p) { int size, err = get_user(size, p); @@ -205,7 +201,8 @@ static int sg_set_reserved_size(struct request_queue *q, int __user *p) if (size < 0) return -EINVAL; - q->sg_reserved_size = min_t(unsigned int, size, queue_max_bytes(q)); + sdev->sg_reserved_size = min_t(unsigned int, size, + queue_max_bytes(sdev->request_queue)); return 0; } @@ -345,7 +342,7 @@ bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode) } EXPORT_SYMBOL(scsi_cmd_allowed); -static int scsi_fill_sghdr_rq(struct request_queue *q, struct request *rq, +static int scsi_fill_sghdr_rq(struct scsi_device *sdev, struct request *rq, struct sg_io_hdr *hdr, fmode_t mode) { struct scsi_request *req = scsi_req(rq); @@ -362,7 +359,7 @@ static int scsi_fill_sghdr_rq(struct request_queue *q, struct request *rq, rq->timeout = msecs_to_jiffies(hdr->timeout); if (!rq->timeout) - rq->timeout = q->sg_timeout; + rq->timeout = sdev->sg_timeout; if (!rq->timeout) rq->timeout = BLK_DEFAULT_SG_TIMEOUT; if (rq->timeout < BLK_MIN_SG_TIMEOUT) @@ -409,7 +406,7 @@ static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, return ret; } -static int sg_io(struct request_queue *q, struct gendisk *bd_disk, +static int sg_io(struct scsi_device *sdev, struct gendisk *disk, struct sg_io_hdr *hdr, fmode_t mode) { unsigned long start_time; @@ -423,7 +420,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, if (hdr->interface_id != 'S') return -EINVAL; - if (hdr->dxfer_len > (queue_max_hw_sectors(q) << 9)) + if (hdr->dxfer_len > (queue_max_hw_sectors(sdev->request_queue) << 9)) return -EIO; if (hdr->dxfer_len) @@ -441,7 +438,8 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, at_head = 1; ret = -ENOMEM; - rq = blk_get_request(q, writing ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + rq = blk_get_request(sdev->request_queue, writing ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); if (IS_ERR(rq)) return PTR_ERR(rq); req = scsi_req(rq); @@ -452,7 +450,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, goto out_put_request; } - ret = scsi_fill_sghdr_rq(q, rq, hdr, mode); + ret = scsi_fill_sghdr_rq(sdev, rq, hdr, mode); if (ret < 0) goto out_free_cdb; @@ -469,11 +467,11 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, /* SG_IO howto says that the shorter of the two wins */ iov_iter_truncate(&i, hdr->dxfer_len); - ret = blk_rq_map_user_iov(q, rq, NULL, &i, GFP_KERNEL); + ret = blk_rq_map_user_iov(rq->q, rq, NULL, &i, GFP_KERNEL); kfree(iov); } else if (hdr->dxfer_len) - ret = blk_rq_map_user(q, rq, NULL, hdr->dxferp, hdr->dxfer_len, - GFP_KERNEL); + ret = blk_rq_map_user(rq->q, rq, NULL, hdr->dxferp, + hdr->dxfer_len, GFP_KERNEL); if (ret) goto out_free_cdb; @@ -483,7 +481,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk, start_time = jiffies; - blk_execute_rq(bd_disk, rq, at_head); + blk_execute_rq(disk, rq, at_head); hdr->duration = jiffies_to_msecs(jiffies - start_time); @@ -806,9 +804,8 @@ static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc, return 0; } -static int scsi_cdrom_send_packet(struct request_queue *q, - struct gendisk *bd_disk, - fmode_t mode, void __user *arg) +static int scsi_cdrom_send_packet(struct scsi_device *sdev, struct gendisk *disk, + fmode_t mode, void __user *arg) { struct cdrom_generic_command cgc; struct sg_io_hdr hdr; @@ -848,7 +845,7 @@ static int scsi_cdrom_send_packet(struct request_queue *q, hdr.cmdp = ((struct cdrom_generic_command __user *) arg)->cmd; hdr.cmd_len = sizeof(cgc.cmd); - err = sg_io(q, bd_disk, &hdr, mode); + err = sg_io(sdev, disk, &hdr, mode); if (err == -EFAULT) return -EFAULT; @@ -863,7 +860,7 @@ static int scsi_cdrom_send_packet(struct request_queue *q, return err; } -static int scsi_ioctl_sg_io(struct request_queue *q, struct gendisk *disk, +static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, void __user *argp) { struct sg_io_hdr hdr; @@ -872,7 +869,7 @@ static int scsi_ioctl_sg_io(struct request_queue *q, struct gendisk *disk, error = get_sg_io_hdr(&hdr, argp); if (error) return error; - error = sg_io(q, disk, &hdr, mode); + error = sg_io(sdev, disk, &hdr, mode); if (error == -EFAULT) return error; if (put_sg_io_hdr(&hdr, argp)) @@ -918,21 +915,21 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode, case SG_GET_VERSION_NUM: return sg_get_version(arg); case SG_SET_TIMEOUT: - return sg_set_timeout(q, arg); + return sg_set_timeout(sdev, arg); case SG_GET_TIMEOUT: - return sg_get_timeout(q); + return jiffies_to_clock_t(sdev->sg_timeout); case SG_GET_RESERVED_SIZE: - return sg_get_reserved_size(q, arg); + return sg_get_reserved_size(sdev, arg); case SG_SET_RESERVED_SIZE: - return sg_set_reserved_size(q, arg); + return sg_set_reserved_size(sdev, arg); case SG_EMULATED_HOST: return sg_emulated_host(q, arg); case SG_IO: - return scsi_ioctl_sg_io(q, disk, mode, arg); + return scsi_ioctl_sg_io(sdev, disk, mode, arg); case SCSI_IOCTL_SEND_COMMAND: return sg_scsi_ioctl(q, disk, mode, arg); case CDROM_SEND_PACKET: - return scsi_cdrom_send_packet(q, disk, mode, arg); + return scsi_cdrom_send_packet(sdev, disk, mode, arg); case CDROMCLOSETRAY: return scsi_send_start_stop(sdev, 3); case CDROMEJECT: diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3faedf4970ec..e06a2602fca4 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -267,6 +267,8 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, */ sdev->borken = 1; + sdev->sg_reserved_size = INT_MAX; + q = blk_mq_init_queue(&sdev->host->tag_set); if (IS_ERR(q)) { /* release fn is set up in scsi_sysfs_device_initialise, so diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e0bb14acb708..987f15089eeb 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -499,11 +499,6 @@ struct request_queue { unsigned int max_active_zones; #endif /* CONFIG_BLK_DEV_ZONED */ - /* - * sg stuff - */ - unsigned int sg_timeout; - unsigned int sg_reserved_size; int node; struct mutex debugfs_mutex; #ifdef CONFIG_BLK_DEV_IO_TRACE diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 99082da1b951..7137e7924913 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -236,6 +236,9 @@ struct scsi_device { size_t dma_drain_len; void *dma_drain_buf; + unsigned int sg_timeout; + unsigned int sg_reserved_size; + struct bsg_device *bsg_dev; unsigned char access_state; struct mutex state_mutex; -- cgit v1.2.3-70-g09d2 From 75ca56409e5b35aa6ceef94462f39ef4f533fc41 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 29 Jul 2021 08:48:45 +0200 Subject: scsi: bsg: Move the whole request execution into the SCSI/transport handlers Remove the amount of indirect calls by making the handler responsible for the entire execution of the request. Link: https://lore.kernel.org/r/20210729064845.1044147-5-hch@lst.de Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/bsg-lib.c | 80 ++++++++++++++++++++++++------------------------- block/bsg.c | 66 ++++++++++------------------------------ drivers/scsi/scsi_bsg.c | 69 +++++++++++++++++++++++------------------- include/linux/bsg.h | 12 ++------ 4 files changed, 96 insertions(+), 131 deletions(-) diff --git a/block/bsg-lib.c b/block/bsg-lib.c index fe43f5fda6e5..239ebf747141 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -25,32 +25,39 @@ struct bsg_set { bsg_timeout_fn *timeout_fn; }; -static int bsg_transport_check_proto(struct sg_io_v4 *hdr) +static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, + fmode_t mode, unsigned int timeout) { + struct bsg_job *job; + struct request *rq; + struct bio *bio; + int ret; + if (hdr->protocol != BSG_PROTOCOL_SCSI || hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_TRANSPORT) return -EINVAL; if (!capable(CAP_SYS_RAWIO)) return -EPERM; - return 0; -} -static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, - fmode_t mode) -{ - struct bsg_job *job = blk_mq_rq_to_pdu(rq); - int ret; + rq = blk_get_request(q, hdr->dout_xfer_len ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + if (IS_ERR(rq)) + return PTR_ERR(rq); + rq->timeout = timeout; + job = blk_mq_rq_to_pdu(rq); job->request_len = hdr->request_len; job->request = memdup_user(uptr64(hdr->request), hdr->request_len); - if (IS_ERR(job->request)) - return PTR_ERR(job->request); + if (IS_ERR(job->request)) { + ret = PTR_ERR(job->request); + goto out_put_request; + } if (hdr->dout_xfer_len && hdr->din_xfer_len) { job->bidi_rq = blk_get_request(rq->q, REQ_OP_DRV_IN, 0); if (IS_ERR(job->bidi_rq)) { ret = PTR_ERR(job->bidi_rq); - goto out; + goto out_free_job_request; } ret = blk_rq_map_user(rq->q, job->bidi_rq, NULL, @@ -65,20 +72,19 @@ static int bsg_transport_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, job->bidi_bio = NULL; } - return 0; + if (hdr->dout_xfer_len) { + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->dout_xferp), + hdr->dout_xfer_len, GFP_KERNEL); + } else if (hdr->din_xfer_len) { + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->din_xferp), + hdr->din_xfer_len, GFP_KERNEL); + } -out_free_bidi_rq: - if (job->bidi_rq) - blk_put_request(job->bidi_rq); -out: - kfree(job->request); - return ret; -} + if (ret) + goto out_unmap_bidi_rq; -static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr) -{ - struct bsg_job *job = blk_mq_rq_to_pdu(rq); - int ret = 0; + bio = rq->bio; + blk_execute_rq(NULL, rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL)); /* * The assignments below don't make much sense, but are kept for @@ -121,28 +127,20 @@ static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr) hdr->din_resid = 0; } - return ret; -} - -static void bsg_transport_free_rq(struct request *rq) -{ - struct bsg_job *job = blk_mq_rq_to_pdu(rq); - - if (job->bidi_rq) { + blk_rq_unmap_user(bio); +out_unmap_bidi_rq: + if (job->bidi_rq) blk_rq_unmap_user(job->bidi_bio); +out_free_bidi_rq: + if (job->bidi_rq) blk_put_request(job->bidi_rq); - } - +out_free_job_request: kfree(job->request); +out_put_request: + blk_put_request(rq); + return ret; } -static const struct bsg_ops bsg_transport_ops = { - .check_proto = bsg_transport_check_proto, - .fill_hdr = bsg_transport_fill_hdr, - .complete_rq = bsg_transport_complete_rq, - .free_rq = bsg_transport_free_rq, -}; - /** * bsg_teardown_job - routine to teardown a bsg job * @kref: kref inside bsg_job that is to be torn down @@ -398,7 +396,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, q->queuedata = dev; blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT); - bset->bd = bsg_register_queue(q, dev, name, &bsg_transport_ops); + bset->bd = bsg_register_queue(q, dev, name, bsg_transport_sg_io_fn); if (IS_ERR(bset->bd)) { ret = PTR_ERR(bset->bd); goto out_cleanup_queue; diff --git a/block/bsg.c b/block/bsg.c index 3ba74eec4ba2..351095193788 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -22,12 +22,12 @@ struct bsg_device { struct request_queue *queue; - const struct bsg_ops *ops; struct device device; struct cdev cdev; int max_queue; unsigned int timeout; unsigned int reserved_size; + bsg_sg_io_fn *sg_io_fn; }; static inline struct bsg_device *to_bsg_device(struct inode *inode) @@ -42,63 +42,28 @@ static DEFINE_IDA(bsg_minor_ida); static struct class *bsg_class; static int bsg_major; -#define uptr64(val) ((void __user *)(uintptr_t)(val)) +static unsigned int bsg_timeout(struct bsg_device *bd, struct sg_io_v4 *hdr) +{ + unsigned int timeout = BLK_DEFAULT_SG_TIMEOUT; + + if (hdr->timeout) + timeout = msecs_to_jiffies(hdr->timeout); + else if (bd->timeout) + timeout = bd->timeout; + + return max_t(unsigned int, timeout, BLK_MIN_SG_TIMEOUT); +} static int bsg_sg_io(struct bsg_device *bd, fmode_t mode, void __user *uarg) { - struct request *rq; - struct bio *bio; struct sg_io_v4 hdr; int ret; if (copy_from_user(&hdr, uarg, sizeof(hdr))) return -EFAULT; - if (hdr.guard != 'Q') return -EINVAL; - ret = bd->ops->check_proto(&hdr); - if (ret) - return ret; - - rq = blk_get_request(bd->queue, hdr.dout_xfer_len ? - REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); - if (IS_ERR(rq)) - return PTR_ERR(rq); - - ret = bd->ops->fill_hdr(rq, &hdr, mode); - if (ret) { - blk_put_request(rq); - return ret; - } - - rq->timeout = msecs_to_jiffies(hdr.timeout); - if (!rq->timeout) - rq->timeout = bd->timeout; - if (!rq->timeout) - rq->timeout = BLK_DEFAULT_SG_TIMEOUT; - if (rq->timeout < BLK_MIN_SG_TIMEOUT) - rq->timeout = BLK_MIN_SG_TIMEOUT; - - if (hdr.dout_xfer_len) { - ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr.dout_xferp), - hdr.dout_xfer_len, GFP_KERNEL); - } else if (hdr.din_xfer_len) { - ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr.din_xferp), - hdr.din_xfer_len, GFP_KERNEL); - } - - if (ret) - goto out_free_rq; - - bio = rq->bio; - - blk_execute_rq(NULL, rq, !(hdr.flags & BSG_FLAG_Q_AT_TAIL)); - ret = bd->ops->complete_rq(rq, &hdr); - blk_rq_unmap_user(bio); - -out_free_rq: - bd->ops->free_rq(rq); - blk_put_request(rq); + ret = bd->sg_io_fn(bd->queue, &hdr, mode, bsg_timeout(bd, &hdr)); if (!ret && copy_to_user(uarg, &hdr, sizeof(hdr))) return -EFAULT; return ret; @@ -211,8 +176,7 @@ void bsg_unregister_queue(struct bsg_device *bd) EXPORT_SYMBOL_GPL(bsg_unregister_queue); struct bsg_device *bsg_register_queue(struct request_queue *q, - struct device *parent, const char *name, - const struct bsg_ops *ops) + struct device *parent, const char *name, bsg_sg_io_fn *sg_io_fn) { struct bsg_device *bd; int ret; @@ -223,7 +187,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, bd->max_queue = BSG_DEFAULT_CMDS; bd->reserved_size = INT_MAX; bd->queue = q; - bd->ops = ops; + bd->sg_io_fn = sg_io_fn; ret = ida_simple_get(&bsg_minor_ida, 0, BSG_MAX_DEVS, GFP_KERNEL); if (ret < 0) { diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index c0d41c45c2be..d13a67b82429 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -9,42 +9,57 @@ #define uptr64(val) ((void __user *)(uintptr_t)(val)) -static int scsi_bsg_check_proto(struct sg_io_v4 *hdr) +static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, + fmode_t mode, unsigned int timeout) { + struct scsi_request *sreq; + struct request *rq; + struct bio *bio; + int ret; + if (hdr->protocol != BSG_PROTOCOL_SCSI || hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD) return -EINVAL; - return 0; -} - -static int scsi_bsg_fill_hdr(struct request *rq, struct sg_io_v4 *hdr, - fmode_t mode) -{ - struct scsi_request *sreq = scsi_req(rq); - if (hdr->dout_xfer_len && hdr->din_xfer_len) { pr_warn_once("BIDI support in bsg has been removed.\n"); return -EOPNOTSUPP; } + rq = blk_get_request(q, hdr->dout_xfer_len ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); + if (IS_ERR(rq)) + return PTR_ERR(rq); + rq->timeout = timeout; + + ret = -ENOMEM; + sreq = scsi_req(rq); sreq->cmd_len = hdr->request_len; if (sreq->cmd_len > BLK_MAX_CDB) { sreq->cmd = kzalloc(sreq->cmd_len, GFP_KERNEL); if (!sreq->cmd) - return -ENOMEM; + goto out_put_request; } + ret = -EFAULT; if (copy_from_user(sreq->cmd, uptr64(hdr->request), sreq->cmd_len)) - return -EFAULT; + goto out_free_cmd; + ret = -EPERM; if (!scsi_cmd_allowed(sreq->cmd, mode)) - return -EPERM; - return 0; -} + goto out_free_cmd; -static int scsi_bsg_complete_rq(struct request *rq, struct sg_io_v4 *hdr) -{ - struct scsi_request *sreq = scsi_req(rq); - int ret = 0; + if (hdr->dout_xfer_len) { + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->dout_xferp), + hdr->dout_xfer_len, GFP_KERNEL); + } else if (hdr->din_xfer_len) { + ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->din_xferp), + hdr->din_xfer_len, GFP_KERNEL); + } + + if (ret) + goto out_free_cmd; + + bio = rq->bio; + blk_execute_rq(NULL, rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL)); /* * fill in all the output members @@ -74,23 +89,17 @@ static int scsi_bsg_complete_rq(struct request *rq, struct sg_io_v4 *hdr) else hdr->dout_resid = sreq->resid_len; - return ret; -} + blk_rq_unmap_user(bio); -static void scsi_bsg_free_rq(struct request *rq) -{ +out_free_cmd: scsi_req_free_cmd(scsi_req(rq)); +out_put_request: + blk_put_request(rq); + return ret; } -static const struct bsg_ops scsi_bsg_ops = { - .check_proto = scsi_bsg_check_proto, - .fill_hdr = scsi_bsg_fill_hdr, - .complete_rq = scsi_bsg_complete_rq, - .free_rq = scsi_bsg_free_rq, -}; - struct bsg_device *scsi_bsg_register_queue(struct scsi_device *sdev) { return bsg_register_queue(sdev->request_queue, &sdev->sdev_gendev, - dev_name(&sdev->sdev_gendev), &scsi_bsg_ops); + dev_name(&sdev->sdev_gendev), scsi_bsg_sg_io_fn); } diff --git a/include/linux/bsg.h b/include/linux/bsg.h index fa21f79beda2..1ac81c809da9 100644 --- a/include/linux/bsg.h +++ b/include/linux/bsg.h @@ -6,20 +6,14 @@ struct bsg_device; struct device; -struct request; struct request_queue; -struct bsg_ops { - int (*check_proto)(struct sg_io_v4 *hdr); - int (*fill_hdr)(struct request *rq, struct sg_io_v4 *hdr, - fmode_t mode); - int (*complete_rq)(struct request *rq, struct sg_io_v4 *hdr); - void (*free_rq)(struct request *rq); -}; +typedef int (bsg_sg_io_fn)(struct request_queue *, struct sg_io_v4 *hdr, + fmode_t mode, unsigned int timeout); struct bsg_device *bsg_register_queue(struct request_queue *q, struct device *parent, const char *name, - const struct bsg_ops *ops); + bsg_sg_io_fn *sg_io_fn); void bsg_unregister_queue(struct bsg_device *bcd); #endif /* _LINUX_BSG_H */ -- cgit v1.2.3-70-g09d2 From 0f783c2d640ac03ad3bb3ba6b7a1287ddf18031d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 29 Jul 2021 09:24:13 +0100 Subject: scsi: qla2xxx: Fix spelling mistakes "allloc" -> "alloc" There are two spelling mistakes with the same triple l in alloc, one in a comment, the other in a ql_dbg() debug message. Fix them. Link: https://lore.kernel.org/r/20210729082413.4761-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_edif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index ccbe0e1bfcbc..fde410989c03 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -1886,7 +1886,7 @@ qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype) return node; } -/* adds a already alllocated enode to the linked list */ +/* adds a already allocated enode to the linked list */ static bool qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr) { @@ -2334,7 +2334,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) ptr = qla_enode_alloc(vha, N_PUREX); if (!ptr) { ql_dbg(ql_dbg_edif, vha, 0x09109, - "WARNING: enode allloc failed for sid=%x\n", + "WARNING: enode alloc failed for sid=%x\n", sid); qla_els_reject_iocb(vha, (*rsp)->qpair, &a); __qla_consume_iocb(vha, pkt, rsp); -- cgit v1.2.3-70-g09d2 From 7740b615b6665e47f162e261d805f1bbbac15876 Mon Sep 17 00:00:00 2001 From: James Smart Date: Fri, 30 Jul 2021 09:33:09 -0700 Subject: scsi: lpfc: Fix possible ABBA deadlock in nvmet_xri_aborted() The lpfc_sli4_nvmet_xri_aborted() routine takes out the abts_buf_list_lock and traverses the buffer contexts to match the xri. Upon match, it then takes the context lock before potentially removing the context from the associated buffer list. This violates the lock hierarchy used elsewhere in the driver of locking context, then the abts_buf_list_lock - thus a possible deadlock. Resolve by: after matching, release the abts_buf_list_lock, then take the context lock, and if to be deleted from the list, retake the abts_buf_list_lock, maintaining lock hierarchy. This matches same list lock hierarchy as elsewhere in the driver Link: https://lore.kernel.org/r/20210730163309.25809-1-jsmart2021@gmail.com Reported-by: Jia-Ju Bai Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvmet.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index f2d9a3580887..6e3dd0b9bcfa 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1797,19 +1797,22 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, if (ctxp->ctxbuf->sglq->sli4_xritag != xri) continue; - spin_lock(&ctxp->ctxlock); + spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, + iflag); + + spin_lock_irqsave(&ctxp->ctxlock, iflag); /* Check if we already received a free context call * and we have completed processing an abort situation. */ if (ctxp->flag & LPFC_NVME_CTX_RLS && !(ctxp->flag & LPFC_NVME_ABORT_OP)) { + spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); list_del_init(&ctxp->list); + spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); released = true; } ctxp->flag &= ~LPFC_NVME_XBUSY; - spin_unlock(&ctxp->ctxlock); - spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, - iflag); + spin_unlock_irqrestore(&ctxp->ctxlock, iflag); rrq_empty = list_empty(&phba->active_rrq_list); ndlp = lpfc_findnode_did(phba->pport, ctxp->sid); -- cgit v1.2.3-70-g09d2 From 1084514ca9aa5b3fcc485b378b92b632918237f4 Mon Sep 17 00:00:00 2001 From: Vincent Palomares Date: Tue, 27 Jul 2021 18:27:43 -0700 Subject: scsi: ufs: Allow async suspend/resume callbacks Allow UFS suspend/resume callbacks to run in parallel with other suspend/resume callbacks. This can recoup dozens of milliseconds on the resume path if UFS hardware needs to be powered back on. Suspending and resuming asynchronously is safe to do so long as the driver callbacks only depend on resources made available by either a) parent devices or b) devices explicitly marked as suppliers with device_link_add. Link: https://lore.kernel.org/r/20210728012743.1063928-1-paillon@google.com Cc: Bjorn Helgaas Cc: Jaegeuk Kim Cc: Bart Van Assche Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Cc: Martin K. Petersen Reviewed-by: Bart Van Assche Signed-off-by: Vincent Palomares Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 064a44e628d6..05495c34a2b7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -9626,6 +9626,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) async_schedule(ufshcd_async_scan, hba); ufs_sysfs_add_nodes(hba->dev); + device_enable_async_suspend(dev); return 0; free_tmf_queue: -- cgit v1.2.3-70-g09d2 From d1945f6c5bf82e9eb477565f3496396db4f4d6e5 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Fri, 23 Jul 2021 22:23:51 +0300 Subject: dt-bindings: pinctrl: qcom: Add SM6115 pinctrl bindings Add device tree binding Documentation details for Qualcomm SM6115 and SM4250 pinctrl. Signed-off-by: Iskren Chernev Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210723192352.546902-2-iskren.chernev@gmail.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,sm6115-pinctrl.yaml | 179 +++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml new file mode 100644 index 000000000000..8fc06f6a3ef4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6115-pinctrl.yaml @@ -0,0 +1,179 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,sm6115-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SM6115, SM4250 TLMM block + +maintainers: + - Iskren Chernev + +description: + This binding describes the Top Level Mode Multiplexer block found in the + SM4250/6115 platforms. + +properties: + compatible: + const: qcom,sm6115-tlmm + + reg: + minItems: 3 + maxItems: 3 + + reg-names: + items: + - const: west + - const: south + - const: east + + interrupts: + description: Specifies the TLMM summary IRQ + maxItems: 1 + + interrupt-controller: true + + '#interrupt-cells': + description: + Specifies the PIN numbers and Flags, as defined in defined in + include/dt-bindings/interrupt-controller/irq.h + const: 2 + + gpio-controller: true + + '#gpio-cells': + description: Specifying the pin number and flags, as defined in + include/dt-bindings/gpio/gpio.h + const: 2 + + gpio-ranges: + maxItems: 1 + + wakeup-parent: + maxItems: 1 + +#PIN CONFIGURATION NODES +patternProperties: + '-state$': + oneOf: + - $ref: "#/$defs/qcom-sm6115-tlmm-state" + - patternProperties: + ".*": + $ref: "#/$defs/qcom-sm6115-tlmm-state" + +'$defs': + qcom-sm6115-tlmm-state: + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + $ref: "qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state" + + properties: + pins: + description: + List of gpio pins affected by the properties specified in this + subnode. + items: + oneOf: + - pattern: "^gpio([0-9]|[1-9][0-9]|10[0-9]|11[0-2])$" + - enum: [ sdc1_rclk, sdc1_clk, sdc1_cmd, sdc1_data, + sdc2_clk, sdc2_cmd, sdc2_data, ufs_reset ] + minItems: 1 + maxItems: 36 + + function: + description: + Specify the alternative function to be configured for the specified + pins. + + enum: [ adsp_ext, agera_pll, atest, cam_mclk, cci_async, cci_i2c, + cci_timer, cri_trng, dac_calib, dbg_out, ddr_bist, ddr_pxi0, + ddr_pxi1, ddr_pxi2, ddr_pxi3, gcc_gp1, gcc_gp2, gcc_gp3, gpio, + gp_pdm0, gp_pdm1, gp_pdm2, gsm0_tx, gsm1_tx, jitter_bist, + mdp_vsync, mdp_vsync_out_0, mdp_vsync_out_1, mpm_pwr, mss_lte, + m_voc, nav_gpio, pa_indicator, pbs, pbs_out, phase_flag, + pll_bist, pll_bypassnl, pll_reset, prng_rosc, qdss_cti, + qdss_gpio, qup0, qup1, qup2, qup3, qup4, qup5, sdc1_tb, + sdc2_tb, sd_write, ssbi_wtr1, tgu, tsense_pwm, uim1_clk, + uim1_data, uim1_present, uim1_reset, uim2_clk, uim2_data, + uim2_present, uim2_reset, usb_phy, vfr_1, vsense_trigger, + wlan1_adc0, elan1_adc1 ] + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + default: 2 + description: + Selects the drive strength for the specified pins, in mA. + + bias-pull-down: true + + bias-pull-up: true + + bias-disable: true + + output-high: true + + output-low: true + + required: + - pins + + additionalProperties: false + +required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-controller + - '#interrupt-cells' + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +additionalProperties: false + +examples: + - | + #include + tlmm: pinctrl@500000 { + compatible = "qcom,sm6115-tlmm"; + reg = <0x500000 0x400000>, + <0x900000 0x400000>, + <0xd00000 0x400000>; + reg-names = "west", "south", "east"; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 114>; + + sdc2_on_state: sdc2-on-state { + clk { + pins = "sdc2_clk"; + bias-disable; + drive-strength = <16>; + }; + + cmd { + pins = "sdc2_cmd"; + bias-pull-up; + drive-strength = <10>; + }; + + data { + pins = "sdc2_data"; + bias-pull-up; + drive-strength = <10>; + }; + + sd-cd { + pins = "gpio88"; + function = "gpio"; + bias-pull-up; + drive-strength = <2>; + }; + }; + }; -- cgit v1.2.3-70-g09d2 From 4b77f1dff5a67bbae9ec44ab97c1e354d893d975 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Fri, 23 Jul 2021 22:23:52 +0300 Subject: drivers: qcom: pinctrl: Add pinctrl driver for sm6115 Based on CAF implementation with egpio/wake_reg support removed. Similar function names were merged to reduce total number of functions. Signed-off-by: Iskren Chernev Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210723192352.546902-3-iskren.chernev@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/qcom/Kconfig | 9 + drivers/pinctrl/qcom/Makefile | 1 + drivers/pinctrl/qcom/pinctrl-sm6115.c | 923 ++++++++++++++++++++++++++++++++++ 3 files changed, 933 insertions(+) create mode 100644 drivers/pinctrl/qcom/pinctrl-sm6115.c diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 6a151f3c1e3b..2bc620655550 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -264,6 +264,15 @@ config PINCTRL_SDX55 Qualcomm Technologies Inc TLMM block found on the Qualcomm Technologies Inc SDX55 platform. +config PINCTRL_SM6115 + tristate "Qualcomm Technologies Inc SM6115,SM4250 pin controller driver" + depends on GPIOLIB && OF + depends on PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm Technologies Inc TLMM block found on the Qualcomm + Technologies Inc SM6115 and SM4250 platforms. + config PINCTRL_SM6125 tristate "Qualcomm Technologies Inc SM6125 pin controller driver" depends on GPIOLIB && OF diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 3337860b4860..7a12e8cd2fba 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_PINCTRL_SC8180X) += pinctrl-sc8180x.o obj-$(CONFIG_PINCTRL_SDM660) += pinctrl-sdm660.o obj-$(CONFIG_PINCTRL_SDM845) += pinctrl-sdm845.o obj-$(CONFIG_PINCTRL_SDX55) += pinctrl-sdx55.o +obj-$(CONFIG_PINCTRL_SM6115) += pinctrl-sm6115.o obj-$(CONFIG_PINCTRL_SM6125) += pinctrl-sm6125.o obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o obj-$(CONFIG_PINCTRL_SM8250) += pinctrl-sm8250.o diff --git a/drivers/pinctrl/qcom/pinctrl-sm6115.c b/drivers/pinctrl/qcom/pinctrl-sm6115.c new file mode 100644 index 000000000000..b3a0161ca377 --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-sm6115.c @@ -0,0 +1,923 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include "pinctrl-msm.h" + +static const char * const sm6115_tiles[] = { + "south", + "east", + "west" +}; + +enum { + SOUTH, + EAST, + WEST +}; + +#define FUNCTION(fname) \ + [msm_mux_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define PINGROUP(id, _tile, f1, f2, f3, f4, f5, f6, f7, f8, f9) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + msm_mux_gpio, /* gpio mode */ \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9 \ + }, \ + .nfuncs = 10, \ + .ctl_reg = 0x1000 * id, \ + .io_reg = 0x4 + 0x1000 * id, \ + .intr_cfg_reg = 0x8 + 0x1000 * id, \ + .intr_status_reg = 0xc + 0x1000 * id, \ + .intr_target_reg = 0x8 + 0x1000 * id, \ + .tile = _tile, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_target_bit = 5, \ + .intr_target_kpss_val = 3, \ + .intr_raw_status_bit = 4, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 2, \ + } + +#define SDC_QDSD_PINGROUP(pg_name, _tile, ctl, pull, drv) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .tile = _tile, \ + .mux_bit = -1, \ + .pull_bit = pull, \ + .drv_bit = drv, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + +#define UFS_RESET(pg_name, offset) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \ + .ctl_reg = offset, \ + .io_reg = offset + 0x4, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .tile = WEST, \ + .mux_bit = -1, \ + .pull_bit = 3, \ + .drv_bit = 0, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = 0, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } +static const struct pinctrl_pin_desc sm6115_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "UFS_RESET"), + PINCTRL_PIN(114, "SDC1_RCLK"), + PINCTRL_PIN(115, "SDC1_CLK"), + PINCTRL_PIN(116, "SDC1_CMD"), + PINCTRL_PIN(117, "SDC1_DATA"), + PINCTRL_PIN(118, "SDC2_CLK"), + PINCTRL_PIN(119, "SDC2_CMD"), + PINCTRL_PIN(120, "SDC2_DATA"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); +DECLARE_MSM_GPIO_PINS(88); +DECLARE_MSM_GPIO_PINS(89); +DECLARE_MSM_GPIO_PINS(90); +DECLARE_MSM_GPIO_PINS(91); +DECLARE_MSM_GPIO_PINS(92); +DECLARE_MSM_GPIO_PINS(93); +DECLARE_MSM_GPIO_PINS(94); +DECLARE_MSM_GPIO_PINS(95); +DECLARE_MSM_GPIO_PINS(96); +DECLARE_MSM_GPIO_PINS(97); +DECLARE_MSM_GPIO_PINS(98); +DECLARE_MSM_GPIO_PINS(99); +DECLARE_MSM_GPIO_PINS(100); +DECLARE_MSM_GPIO_PINS(101); +DECLARE_MSM_GPIO_PINS(102); +DECLARE_MSM_GPIO_PINS(103); +DECLARE_MSM_GPIO_PINS(104); +DECLARE_MSM_GPIO_PINS(105); +DECLARE_MSM_GPIO_PINS(106); +DECLARE_MSM_GPIO_PINS(107); +DECLARE_MSM_GPIO_PINS(108); +DECLARE_MSM_GPIO_PINS(109); +DECLARE_MSM_GPIO_PINS(110); +DECLARE_MSM_GPIO_PINS(111); +DECLARE_MSM_GPIO_PINS(112); + +static const unsigned int ufs_reset_pins[] = { 113 }; +static const unsigned int sdc1_rclk_pins[] = { 114 }; +static const unsigned int sdc1_clk_pins[] = { 115 }; +static const unsigned int sdc1_cmd_pins[] = { 116 }; +static const unsigned int sdc1_data_pins[] = { 117 }; +static const unsigned int sdc2_clk_pins[] = { 118 }; +static const unsigned int sdc2_cmd_pins[] = { 119 }; +static const unsigned int sdc2_data_pins[] = { 120 }; + +enum sm6115_functions { + msm_mux_adsp_ext, + msm_mux_agera_pll, + msm_mux_atest, + msm_mux_cam_mclk, + msm_mux_cci_async, + msm_mux_cci_i2c, + msm_mux_cci_timer, + msm_mux_cri_trng, + msm_mux_dac_calib, + msm_mux_dbg_out, + msm_mux_ddr_bist, + msm_mux_ddr_pxi0, + msm_mux_ddr_pxi1, + msm_mux_ddr_pxi2, + msm_mux_ddr_pxi3, + msm_mux_gcc_gp1, + msm_mux_gcc_gp2, + msm_mux_gcc_gp3, + msm_mux_gpio, + msm_mux_gp_pdm0, + msm_mux_gp_pdm1, + msm_mux_gp_pdm2, + msm_mux_gsm0_tx, + msm_mux_gsm1_tx, + msm_mux_jitter_bist, + msm_mux_mdp_vsync, + msm_mux_mdp_vsync_out_0, + msm_mux_mdp_vsync_out_1, + msm_mux_mpm_pwr, + msm_mux_mss_lte, + msm_mux_m_voc, + msm_mux_nav_gpio, + msm_mux_pa_indicator, + msm_mux_pbs, + msm_mux_pbs_out, + msm_mux_phase_flag, + msm_mux_pll_bist, + msm_mux_pll_bypassnl, + msm_mux_pll_reset, + msm_mux_prng_rosc, + msm_mux_qdss_cti, + msm_mux_qdss_gpio, + msm_mux_qup0, + msm_mux_qup1, + msm_mux_qup2, + msm_mux_qup3, + msm_mux_qup4, + msm_mux_qup5, + msm_mux_sdc1_tb, + msm_mux_sdc2_tb, + msm_mux_sd_write, + msm_mux_ssbi_wtr1, + msm_mux_tgu, + msm_mux_tsense_pwm, + msm_mux_uim1_clk, + msm_mux_uim1_data, + msm_mux_uim1_present, + msm_mux_uim1_reset, + msm_mux_uim2_clk, + msm_mux_uim2_data, + msm_mux_uim2_present, + msm_mux_uim2_reset, + msm_mux_usb_phy, + msm_mux_vfr_1, + msm_mux_vsense_trigger, + msm_mux_wlan1_adc0, + msm_mux_wlan1_adc1, + msm_mux__, +}; + +static const char * const qup0_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio82", "gpio86", +}; +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110", + "gpio111", "gpio112", +}; +static const char * const ddr_bist_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", +}; +static const char * const phase_flag_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", + "gpio14", "gpio15", "gpio16", "gpio17", "gpio22", "gpio23", "gpio24", + "gpio25", "gpio26", "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", + "gpio35", "gpio36", "gpio43", "gpio44", "gpio45", "gpio63", "gpio64", + "gpio102", "gpio103", "gpio104", "gpio105", +}; +static const char * const qdss_gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio8", "gpio9", "gpio10", + "gpio11", "gpio14", "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio21", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", + "gpio47", "gpio48", "gpio69", "gpio70", "gpio87", "gpio90", "gpio91", + "gpio94", "gpio95", "gpio104", "gpio105", "gpio106", "gpio107", + "gpio109", "gpio110", +}; +static const char * const atest_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio29", "gpio30", + "gpio31", "gpio32", "gpio33", "gpio86", "gpio87", "gpio88", "gpio89", + "gpio100", "gpio101", +}; +static const char * const mpm_pwr_groups[] = { + "gpio1", +}; +static const char * const m_voc_groups[] = { + "gpio0", +}; +static const char * const dac_calib_groups[] = { + "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio14", "gpio15", + "gpio16", "gpio17", "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio80", "gpio81", + "gpio82", "gpio102", "gpio103", "gpio104", "gpio105" +}; +static const char * const qup1_groups[] = { + "gpio4", "gpio5", "gpio69", "gpio70", +}; +static const char * const cri_trng_groups[] = { + "gpio4", "gpio5", "gpio18", +}; +static const char * const qup2_groups[] = { + "gpio6", "gpio7", "gpio71", "gpio80", +}; +static const char * const qup3_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11", +}; +static const char * const pbs_out_groups[] = { + "gpio8", "gpio9", "gpio52", +}; +static const char * const pll_bist_groups[] = { + "gpio8", "gpio9", +}; +static const char * const tsense_pwm_groups[] = { + "gpio8", +}; +static const char * const agera_pll_groups[] = { + "gpio10", "gpio11", +}; +static const char * const pbs_groups[] = { + "gpio10", "gpio11", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", + "gpio23", "gpio24", "gpio25", "gpio26", "gpio47", "gpio48", "gpio87", + "gpio90", "gpio91", +}; +static const char * const qup4_groups[] = { + "gpio12", "gpio13", "gpio96", "gpio97", +}; +static const char * const tgu_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15", +}; +static const char * const qup5_groups[] = { + "gpio14", "gpio15", "gpio16", "gpio17", +}; +static const char * const sdc2_tb_groups[] = { + "gpio18", +}; +static const char * const sdc1_tb_groups[] = { + "gpio19", +}; +static const char * const cam_mclk_groups[] = { + "gpio20", "gpio21", "gpio27", "gpio28", +}; +static const char * const adsp_ext_groups[] = { + "gpio21", +}; +static const char * const cci_i2c_groups[] = { + "gpio22", "gpio23", "gpio29", "gpio30", +}; +static const char * const prng_rosc_groups[] = { + "gpio22", "gpio23", +}; +static const char * const cci_timer_groups[] = { + "gpio24", "gpio25", "gpio28", "gpio32", +}; +static const char * const gcc_gp1_groups[] = { + "gpio24", "gpio86", +}; +static const char * const cci_async_groups[] = { + "gpio25", +}; +static const char * const vsense_trigger_groups[] = { + "gpio26", +}; +static const char * const qdss_cti_groups[] = { + "gpio27", "gpio28", "gpio72", "gpio73", "gpio96", "gpio97", +}; +static const char * const gp_pdm0_groups[] = { + "gpio31", "gpio95", +}; +static const char * const gp_pdm1_groups[] = { + "gpio32", "gpio96", +}; +static const char * const gp_pdm2_groups[] = { + "gpio33", "gpio97", +}; +static const char * const nav_gpio_groups[] = { + "gpio42", "gpio47", "gpio52", "gpio95", "gpio96", "gpio97", "gpio106", + "gpio107", "gpio108", +}; +static const char * const vfr_1_groups[] = { + "gpio48", +}; +static const char * const pa_indicator_groups[] = { + "gpio49", +}; +static const char * const gsm1_tx_groups[] = { + "gpio53", +}; +static const char * const ssbi_wtr1_groups[] = { + "gpio59", "gpio60", +}; +static const char * const pll_bypassnl_groups[] = { + "gpio62", +}; +static const char * const pll_reset_groups[] = { + "gpio63", +}; +static const char * const ddr_pxi0_groups[] = { + "gpio63", "gpio64", +}; +static const char * const gsm0_tx_groups[] = { + "gpio64", +}; +static const char * const gcc_gp2_groups[] = { + "gpio69", "gpio107", +}; +static const char * const ddr_pxi1_groups[] = { + "gpio69", "gpio70", +}; +static const char * const gcc_gp3_groups[] = { + "gpio70", "gpio106", +}; +static const char * const dbg_out_groups[] = { + "gpio71", +}; +static const char * const uim2_data_groups[] = { + "gpio72", +}; +static const char * const uim2_clk_groups[] = { + "gpio73", +}; +static const char * const uim2_reset_groups[] = { + "gpio74", +}; +static const char * const uim2_present_groups[] = { + "gpio75", +}; +static const char * const uim1_data_groups[] = { + "gpio76", +}; +static const char * const uim1_clk_groups[] = { + "gpio77", +}; +static const char * const uim1_reset_groups[] = { + "gpio78", +}; +static const char * const uim1_present_groups[] = { + "gpio79", +}; +static const char * const mdp_vsync_groups[] = { + "gpio81", "gpio96", "gpio97", +}; +static const char * const mdp_vsync_out_0_groups[] = { + "gpio81", +}; +static const char * const mdp_vsync_out_1_groups[] = { + "gpio81", +}; +static const char * const usb_phy_groups[] = { + "gpio89", +}; +static const char * const mss_lte_groups[] = { + "gpio90", "gpio91", +}; +static const char * const wlan1_adc0_groups[] = { + "gpio94", +}; +static const char * const wlan1_adc1_groups[] = { + "gpio95", +}; +static const char * const sd_write_groups[] = { + "gpio96", +}; +static const char * const jitter_bist_groups[] = { + "gpio96", "gpio97", +}; +static const char * const ddr_pxi2_groups[] = { + "gpio102", "gpio103", +}; +static const char * const ddr_pxi3_groups[] = { + "gpio104", "gpio105", +}; + +static const struct msm_function sm6115_functions[] = { + FUNCTION(adsp_ext), + FUNCTION(agera_pll), + FUNCTION(atest), + FUNCTION(cam_mclk), + FUNCTION(cci_async), + FUNCTION(cci_i2c), + FUNCTION(cci_timer), + FUNCTION(cri_trng), + FUNCTION(dac_calib), + FUNCTION(dbg_out), + FUNCTION(ddr_bist), + FUNCTION(ddr_pxi0), + FUNCTION(ddr_pxi1), + FUNCTION(ddr_pxi2), + FUNCTION(ddr_pxi3), + FUNCTION(gcc_gp1), + FUNCTION(gcc_gp2), + FUNCTION(gcc_gp3), + FUNCTION(gpio), + FUNCTION(gp_pdm0), + FUNCTION(gp_pdm1), + FUNCTION(gp_pdm2), + FUNCTION(gsm0_tx), + FUNCTION(gsm1_tx), + FUNCTION(jitter_bist), + FUNCTION(mdp_vsync), + FUNCTION(mdp_vsync_out_0), + FUNCTION(mdp_vsync_out_1), + FUNCTION(mpm_pwr), + FUNCTION(mss_lte), + FUNCTION(m_voc), + FUNCTION(nav_gpio), + FUNCTION(pa_indicator), + FUNCTION(pbs), + FUNCTION(pbs_out), + FUNCTION(phase_flag), + FUNCTION(pll_bist), + FUNCTION(pll_bypassnl), + FUNCTION(pll_reset), + FUNCTION(prng_rosc), + FUNCTION(qdss_cti), + FUNCTION(qdss_gpio), + FUNCTION(qup0), + FUNCTION(qup1), + FUNCTION(qup2), + FUNCTION(qup3), + FUNCTION(qup4), + FUNCTION(qup5), + FUNCTION(sdc1_tb), + FUNCTION(sdc2_tb), + FUNCTION(sd_write), + FUNCTION(ssbi_wtr1), + FUNCTION(tgu), + FUNCTION(tsense_pwm), + FUNCTION(uim1_clk), + FUNCTION(uim1_data), + FUNCTION(uim1_present), + FUNCTION(uim1_reset), + FUNCTION(uim2_clk), + FUNCTION(uim2_data), + FUNCTION(uim2_present), + FUNCTION(uim2_reset), + FUNCTION(usb_phy), + FUNCTION(vfr_1), + FUNCTION(vsense_trigger), + FUNCTION(wlan1_adc0), + FUNCTION(wlan1_adc1), +}; + +/* Every pin is maintained as a single group, and missing or non-existing pin + * would be maintained as dummy group to synchronize pin group index with + * pin descriptor registered with pinctrl core. + * Clients would not be able to request these dummy pin groups. + */ +static const struct msm_pingroup sm6115_groups[] = { + [0] = PINGROUP(0, WEST, qup0, m_voc, ddr_bist, _, phase_flag, qdss_gpio, atest, _, _), + [1] = PINGROUP(1, WEST, qup0, mpm_pwr, ddr_bist, _, phase_flag, qdss_gpio, atest, _, _), + [2] = PINGROUP(2, WEST, qup0, ddr_bist, _, phase_flag, qdss_gpio, dac_calib, atest, _, _), + [3] = PINGROUP(3, WEST, qup0, ddr_bist, _, phase_flag, qdss_gpio, dac_calib, atest, _, _), + [4] = PINGROUP(4, WEST, qup1, cri_trng, _, phase_flag, dac_calib, atest, _, _, _), + [5] = PINGROUP(5, WEST, qup1, cri_trng, _, phase_flag, dac_calib, atest, _, _, _), + [6] = PINGROUP(6, WEST, qup2, _, phase_flag, dac_calib, atest, _, _, _, _), + [7] = PINGROUP(7, WEST, qup2, _, _, _, _, _, _, _, _), + [8] = PINGROUP(8, EAST, qup3, pbs_out, pll_bist, _, qdss_gpio, _, tsense_pwm, _, _), + [9] = PINGROUP(9, EAST, qup3, pbs_out, pll_bist, _, qdss_gpio, _, _, _, _), + [10] = PINGROUP(10, EAST, qup3, agera_pll, _, pbs, qdss_gpio, _, _, _, _), + [11] = PINGROUP(11, EAST, qup3, agera_pll, _, pbs, qdss_gpio, _, _, _, _), + [12] = PINGROUP(12, WEST, qup4, tgu, _, _, _, _, _, _, _), + [13] = PINGROUP(13, WEST, qup4, tgu, _, _, _, _, _, _, _), + [14] = PINGROUP(14, WEST, qup5, tgu, _, phase_flag, qdss_gpio, dac_calib, _, _, _), + [15] = PINGROUP(15, WEST, qup5, tgu, _, phase_flag, qdss_gpio, dac_calib, _, _, _), + [16] = PINGROUP(16, WEST, qup5, _, phase_flag, qdss_gpio, dac_calib, _, _, _, _), + [17] = PINGROUP(17, WEST, qup5, _, phase_flag, qdss_gpio, dac_calib, _, _, _, _), + [18] = PINGROUP(18, EAST, sdc2_tb, cri_trng, pbs, qdss_gpio, _, _, _, _, _), + [19] = PINGROUP(19, EAST, sdc1_tb, pbs, qdss_gpio, _, _, _, _, _, _), + [20] = PINGROUP(20, EAST, cam_mclk, pbs, qdss_gpio, _, _, _, _, _, _), + [21] = PINGROUP(21, EAST, cam_mclk, adsp_ext, pbs, qdss_gpio, _, _, _, _, _), + [22] = PINGROUP(22, EAST, cci_i2c, prng_rosc, _, pbs, phase_flag, qdss_gpio, dac_calib, atest, _), + [23] = PINGROUP(23, EAST, cci_i2c, prng_rosc, _, pbs, phase_flag, qdss_gpio, dac_calib, atest, _), + [24] = PINGROUP(24, EAST, cci_timer, gcc_gp1, _, pbs, phase_flag, qdss_gpio, dac_calib, atest, _), + [25] = PINGROUP(25, EAST, cci_async, cci_timer, _, pbs, phase_flag, qdss_gpio, dac_calib, atest, _), + [26] = PINGROUP(26, EAST, _, pbs, phase_flag, qdss_gpio, dac_calib, atest, vsense_trigger, _, _), + [27] = PINGROUP(27, EAST, cam_mclk, qdss_cti, _, _, _, _, _, _, _), + [28] = PINGROUP(28, EAST, cam_mclk, cci_timer, qdss_cti, _, _, _, _, _, _), + [29] = PINGROUP(29, EAST, cci_i2c, _, phase_flag, dac_calib, atest, _, _, _, _), + [30] = PINGROUP(30, EAST, cci_i2c, _, phase_flag, dac_calib, atest, _, _, _, _), + [31] = PINGROUP(31, EAST, gp_pdm0, _, phase_flag, dac_calib, atest, _, _, _, _), + [32] = PINGROUP(32, EAST, cci_timer, gp_pdm1, _, phase_flag, dac_calib, atest, _, _, _), + [33] = PINGROUP(33, EAST, gp_pdm2, _, phase_flag, dac_calib, atest, _, _, _, _), + [34] = PINGROUP(34, EAST, _, _, _, _, _, _, _, _, _), + [35] = PINGROUP(35, EAST, _, phase_flag, _, _, _, _, _, _, _), + [36] = PINGROUP(36, EAST, _, phase_flag, _, _, _, _, _, _, _), + [37] = PINGROUP(37, EAST, _, _, _, _, _, _, _, _, _), + [38] = PINGROUP(38, EAST, _, _, _, _, _, _, _, _, _), + [39] = PINGROUP(39, EAST, _, _, _, _, _, _, _, _, _), + [40] = PINGROUP(40, EAST, _, _, _, _, _, _, _, _, _), + [41] = PINGROUP(41, EAST, _, _, _, _, _, _, _, _, _), + [42] = PINGROUP(42, EAST, _, nav_gpio, _, _, _, _, _, _, _), + [43] = PINGROUP(43, EAST, _, _, phase_flag, _, _, _, _, _, _), + [44] = PINGROUP(44, EAST, _, _, phase_flag, _, _, _, _, _, _), + [45] = PINGROUP(45, EAST, _, _, phase_flag, _, _, _, _, _, _), + [46] = PINGROUP(46, EAST, _, _, _, _, _, _, _, _, _), + [47] = PINGROUP(47, EAST, _, nav_gpio, pbs, qdss_gpio, _, _, _, _, _), + [48] = PINGROUP(48, EAST, _, vfr_1, _, pbs, qdss_gpio, _, _, _, _), + [49] = PINGROUP(49, EAST, _, pa_indicator, _, _, _, _, _, _, _), + [50] = PINGROUP(50, EAST, _, _, _, _, _, _, _, _, _), + [51] = PINGROUP(51, EAST, _, _, _, _, _, _, _, _, _), + [52] = PINGROUP(52, EAST, _, nav_gpio, pbs_out, _, _, _, _, _, _), + [53] = PINGROUP(53, EAST, _, gsm1_tx, _, _, _, _, _, _, _), + [54] = PINGROUP(54, EAST, _, _, _, _, _, _, _, _, _), + [55] = PINGROUP(55, EAST, _, _, _, _, _, _, _, _, _), + [56] = PINGROUP(56, EAST, _, _, _, _, _, _, _, _, _), + [57] = PINGROUP(57, EAST, _, _, _, _, _, _, _, _, _), + [58] = PINGROUP(58, EAST, _, _, _, _, _, _, _, _, _), + [59] = PINGROUP(59, EAST, _, ssbi_wtr1, _, _, _, _, _, _, _), + [60] = PINGROUP(60, EAST, _, ssbi_wtr1, _, _, _, _, _, _, _), + [61] = PINGROUP(61, EAST, _, _, _, _, _, _, _, _, _), + [62] = PINGROUP(62, EAST, _, pll_bypassnl, _, _, _, _, _, _, _), + [63] = PINGROUP(63, EAST, pll_reset, _, phase_flag, ddr_pxi0, _, _, _, _, _), + [64] = PINGROUP(64, EAST, gsm0_tx, _, phase_flag, ddr_pxi0, _, _, _, _, _), + [65] = PINGROUP(65, WEST, _, _, _, _, _, _, _, _, _), + [66] = PINGROUP(66, WEST, _, _, _, _, _, _, _, _, _), + [67] = PINGROUP(67, WEST, _, _, _, _, _, _, _, _, _), + [68] = PINGROUP(68, WEST, _, _, _, _, _, _, _, _, _), + [69] = PINGROUP(69, WEST, qup1, gcc_gp2, qdss_gpio, ddr_pxi1, _, _, _, _, _), + [70] = PINGROUP(70, WEST, qup1, gcc_gp3, qdss_gpio, ddr_pxi1, _, _, _, _, _), + [71] = PINGROUP(71, WEST, qup2, dbg_out, _, _, _, _, _, _, _), + [72] = PINGROUP(72, SOUTH, uim2_data, qdss_cti, _, _, _, _, _, _, _), + [73] = PINGROUP(73, SOUTH, uim2_clk, _, qdss_cti, _, _, _, _, _, _), + [74] = PINGROUP(74, SOUTH, uim2_reset, _, _, _, _, _, _, _, _), + [75] = PINGROUP(75, SOUTH, uim2_present, _, _, _, _, _, _, _, _), + [76] = PINGROUP(76, SOUTH, uim1_data, _, _, _, _, _, _, _, _), + [77] = PINGROUP(77, SOUTH, uim1_clk, _, _, _, _, _, _, _, _), + [78] = PINGROUP(78, SOUTH, uim1_reset, _, _, _, _, _, _, _, _), + [79] = PINGROUP(79, SOUTH, uim1_present, _, _, _, _, _, _, _, _), + [80] = PINGROUP(80, WEST, qup2, dac_calib, _, _, _, _, _, _, _), + [81] = PINGROUP(81, WEST, mdp_vsync_out_0, mdp_vsync_out_1, mdp_vsync, dac_calib, _, _, _, _, _), + [82] = PINGROUP(82, WEST, qup0, dac_calib, _, _, _, _, _, _, _), + [83] = PINGROUP(83, WEST, _, _, _, _, _, _, _, _, _), + [84] = PINGROUP(84, WEST, _, _, _, _, _, _, _, _, _), + [85] = PINGROUP(85, WEST, _, _, _, _, _, _, _, _, _), + [86] = PINGROUP(86, WEST, qup0, gcc_gp1, atest, _, _, _, _, _, _), + [87] = PINGROUP(87, EAST, pbs, qdss_gpio, _, _, _, _, _, _, _), + [88] = PINGROUP(88, EAST, _, _, _, _, _, _, _, _, _), + [89] = PINGROUP(89, WEST, usb_phy, atest, _, _, _, _, _, _, _), + [90] = PINGROUP(90, EAST, mss_lte, pbs, qdss_gpio, _, _, _, _, _, _), + [91] = PINGROUP(91, EAST, mss_lte, pbs, qdss_gpio, _, _, _, _, _, _), + [92] = PINGROUP(92, WEST, _, _, _, _, _, _, _, _, _), + [93] = PINGROUP(93, WEST, _, _, _, _, _, _, _, _, _), + [94] = PINGROUP(94, WEST, _, qdss_gpio, wlan1_adc0, _, _, _, _, _, _), + [95] = PINGROUP(95, WEST, nav_gpio, gp_pdm0, qdss_gpio, wlan1_adc1, _, _, _, _, _), + [96] = PINGROUP(96, WEST, qup4, nav_gpio, mdp_vsync, gp_pdm1, sd_write, jitter_bist, qdss_cti, qdss_cti, _), + [97] = PINGROUP(97, WEST, qup4, nav_gpio, mdp_vsync, gp_pdm2, jitter_bist, qdss_cti, qdss_cti, _, _), + [98] = PINGROUP(98, SOUTH, _, _, _, _, _, _, _, _, _), + [99] = PINGROUP(99, SOUTH, _, _, _, _, _, _, _, _, _), + [100] = PINGROUP(100, SOUTH, atest, _, _, _, _, _, _, _, _), + [101] = PINGROUP(101, SOUTH, atest, _, _, _, _, _, _, _, _), + [102] = PINGROUP(102, SOUTH, _, phase_flag, dac_calib, ddr_pxi2, _, _, _, _, _), + [103] = PINGROUP(103, SOUTH, _, phase_flag, dac_calib, ddr_pxi2, _, _, _, _, _), + [104] = PINGROUP(104, SOUTH, _, phase_flag, qdss_gpio, dac_calib, ddr_pxi3, _, _, _, _), + [105] = PINGROUP(105, SOUTH, _, phase_flag, qdss_gpio, dac_calib, ddr_pxi3, _, _, _, _), + [106] = PINGROUP(106, SOUTH, nav_gpio, gcc_gp3, qdss_gpio, _, _, _, _, _, _), + [107] = PINGROUP(107, SOUTH, nav_gpio, gcc_gp2, qdss_gpio, _, _, _, _, _, _), + [108] = PINGROUP(108, SOUTH, nav_gpio, _, _, _, _, _, _, _, _), + [109] = PINGROUP(109, SOUTH, _, qdss_gpio, _, _, _, _, _, _, _), + [110] = PINGROUP(110, SOUTH, _, qdss_gpio, _, _, _, _, _, _, _), + [111] = PINGROUP(111, SOUTH, _, _, _, _, _, _, _, _, _), + [112] = PINGROUP(112, SOUTH, _, _, _, _, _, _, _, _, _), + [113] = UFS_RESET(ufs_reset, 0x78000), + [114] = SDC_QDSD_PINGROUP(sdc1_rclk, WEST, 0x75000, 15, 0), + [115] = SDC_QDSD_PINGROUP(sdc1_clk, WEST, 0x75000, 13, 6), + [116] = SDC_QDSD_PINGROUP(sdc1_cmd, WEST, 0x75000, 11, 3), + [117] = SDC_QDSD_PINGROUP(sdc1_data, WEST, 0x75000, 9, 0), + [118] = SDC_QDSD_PINGROUP(sdc2_clk, SOUTH, 0x73000, 14, 6), + [119] = SDC_QDSD_PINGROUP(sdc2_cmd, SOUTH, 0x73000, 11, 3), + [120] = SDC_QDSD_PINGROUP(sdc2_data, SOUTH, 0x73000, 9, 0), +}; + +static const struct msm_pinctrl_soc_data sm6115_tlmm = { + .pins = sm6115_pins, + .npins = ARRAY_SIZE(sm6115_pins), + .functions = sm6115_functions, + .nfunctions = ARRAY_SIZE(sm6115_functions), + .groups = sm6115_groups, + .ngroups = ARRAY_SIZE(sm6115_groups), + .ngpios = 114, + .tiles = sm6115_tiles, + .ntiles = ARRAY_SIZE(sm6115_tiles), +}; + +static int sm6115_tlmm_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &sm6115_tlmm); +} + +static const struct of_device_id sm6115_tlmm_of_match[] = { + { .compatible = "qcom,sm6115-tlmm", }, + { } +}; + +static struct platform_driver sm6115_tlmm_driver = { + .driver = { + .name = "sm6115-tlmm", + .of_match_table = sm6115_tlmm_of_match, + }, + .probe = sm6115_tlmm_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init sm6115_tlmm_init(void) +{ + return platform_driver_register(&sm6115_tlmm_driver); +} +arch_initcall(sm6115_tlmm_init); + +static void __exit sm6115_tlmm_exit(void) +{ + platform_driver_unregister(&sm6115_tlmm_driver); +} +module_exit(sm6115_tlmm_exit); + +MODULE_DESCRIPTION("QTI sm6115 tlmm driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, sm6115_tlmm_of_match); -- cgit v1.2.3-70-g09d2 From a449ffaf9181b5a2dc705d8a06b13e0068207fd4 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 30 Jul 2021 12:42:31 +0100 Subject: powerpc/svm: Don't issue ultracalls if !mem_encrypt_active() Commit ad6c00283163 ("swiotlb: Free tbl memory in swiotlb_exit()") introduced a set_memory_encrypted() call to swiotlb_exit() so that the buffer pages are returned to an encrypted state prior to being freed. Sachin reports that this leads to the following crash on a Power server: [ 0.010799] software IO TLB: tearing down default memory pool [ 0.010805] ------------[ cut here ]------------ [ 0.010808] kernel BUG at arch/powerpc/kernel/interrupt.c:98! Nick spotted that this is because set_memory_encrypted() is issuing an ultracall which doesn't exist for the processor, and should therefore be gated by mem_encrypt_active() to mirror the x86 implementation. Cc: Konrad Rzeszutek Wilk Cc: Claire Chang Cc: Christoph Hellwig Cc: Robin Murphy Fixes: ad6c00283163 ("swiotlb: Free tbl memory in swiotlb_exit()") Suggested-by: Nicholas Piggin Reported-by: Sachin Sant Tested-by: Sachin Sant Tested-by: Nathan Chancellor Link: https://lore.kernel.org/r/1905CD70-7656-42AE-99E2-A31FC3812EAC@linux.vnet.ibm.com/ Signed-off-by: Will Deacon Signed-off-by: Konrad Rzeszutek Wilk --- arch/powerpc/platforms/pseries/svm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c index 1d829e257996..87f001b4c4e4 100644 --- a/arch/powerpc/platforms/pseries/svm.c +++ b/arch/powerpc/platforms/pseries/svm.c @@ -63,6 +63,9 @@ void __init svm_swiotlb_init(void) int set_memory_encrypted(unsigned long addr, int numpages) { + if (!mem_encrypt_active()) + return 0; + if (!PAGE_ALIGNED(addr)) return -EINVAL; @@ -73,6 +76,9 @@ int set_memory_encrypted(unsigned long addr, int numpages) int set_memory_decrypted(unsigned long addr, int numpages) { + if (!mem_encrypt_active()) + return 0; + if (!PAGE_ALIGNED(addr)) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 5c0f61377b765e650b1bc85298b79add1148c97f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 31 Jul 2021 09:40:26 +0200 Subject: scsi: bsg: Fix commands without data transfer in scsi_bsg_sg_io_fn() Set ret to 0 after the initial permission checks to avoid leaking -EPERM for commands without data transfer. Link: https://lore.kernel.org/r/20210731074027.1185545-2-hch@lst.de Fixes: 75ca56409e5b ("scsi: bsg: Move the whole request execution into the SCSI/transport handlers") Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_bsg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c index d13a67b82429..81c3853a2a80 100644 --- a/drivers/scsi/scsi_bsg.c +++ b/drivers/scsi/scsi_bsg.c @@ -47,6 +47,7 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, if (!scsi_cmd_allowed(sreq->cmd, mode)) goto out_free_cmd; + ret = 0; if (hdr->dout_xfer_len) { ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->dout_xferp), hdr->dout_xfer_len, GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 659a37844abc00c3dc676bb1faed29c1dacbf59f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 31 Jul 2021 09:40:27 +0200 Subject: scsi: bsg-lib: Fix commands without data transfer in bsg_transport_sg_io_fn() Set ret to 0 after the initial permission checks to avoid leaking -EPERM for commands without data transfer. Link: https://lore.kernel.org/r/20210731074027.1185545-3-hch@lst.de Fixes: 75ca56409e5b ("scsi: bsg: Move the whole request execution into the SCSI/transport handlers") Signed-off-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- block/bsg-lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 239ebf747141..ccb98276c964 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -72,6 +72,7 @@ static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, job->bidi_bio = NULL; } + ret = 0; if (hdr->dout_xfer_len) { ret = blk_rq_map_user(rq->q, rq, NULL, uptr64(hdr->dout_xferp), hdr->dout_xfer_len, GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 44d01fc86d952f5a8b8b32bdb4841504d5833d95 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 20 Apr 2021 20:01:47 +0200 Subject: scsi: BusLogic: Fix missing pr_cont() use Update BusLogic driver's messaging system to use pr_cont() for continuation lines, bringing messy output: pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter scsi0: Firmware Version: 5.07B, I/O Address: 0x7000, IRQ Channel: 17/Level scsi0: PCI Bus: 0, Device: 19, Address: 0xE0012000, Host Adapter SCSI ID: 7 scsi0: Parity Checking: Enabled, Extended Translation: Enabled scsi0: Synchronous Negotiation: Ultra, Wide Negotiation: Enabled scsi0: Disconnect/Reconnect: Enabled, Tagged Queuing: Enabled scsi0: Scatter/Gather Limit: 128 of 8192 segments, Mailboxes: 211 scsi0: Driver Queue Depth: 211, Host Adapter Queue Depth: 192 scsi0: Tagged Queue Depth: Automatic , Untagged Queue Depth: 3 scsi0: SCSI Bus Termination: Both Enabled , SCAM: Disabled scsi0: *** BusLogic BT-958 Initialized Successfully *** scsi host0: BusLogic BT-958 back to order: pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter scsi0: Firmware Version: 5.07B, I/O Address: 0x7000, IRQ Channel: 17/Level scsi0: PCI Bus: 0, Device: 19, Address: 0xE0012000, Host Adapter SCSI ID: 7 scsi0: Parity Checking: Enabled, Extended Translation: Enabled scsi0: Synchronous Negotiation: Ultra, Wide Negotiation: Enabled scsi0: Disconnect/Reconnect: Enabled, Tagged Queuing: Enabled scsi0: Scatter/Gather Limit: 128 of 8192 segments, Mailboxes: 211 scsi0: Driver Queue Depth: 211, Host Adapter Queue Depth: 192 scsi0: Tagged Queue Depth: Automatic, Untagged Queue Depth: 3 scsi0: SCSI Bus Termination: Both Enabled, SCAM: Disabled scsi0: *** BusLogic BT-958 Initialized Successfully *** scsi host0: BusLogic BT-958 Also diagnostic output such as with the BusLogic=TraceConfiguration parameter is affected and becomes vertical and therefore hard to read. This has now been corrected, e.g.: pci 0000:00:13.0: PCI->APIC IRQ transform: INT A -> IRQ 17 blogic_cmd(86) Status = 30: 4 ==> 4: FF 05 93 00 blogic_cmd(95) Status = 28: (Modify I/O Address) blogic_cmd(91) Status = 30: 1 ==> 1: 01 blogic_cmd(04) Status = 30: 4 ==> 4: 41 41 35 30 blogic_cmd(8D) Status = 30: 14 ==> 14: 45 DC 00 20 00 00 00 00 00 40 30 37 42 1D scsi: ***** BusLogic SCSI Driver Version 2.1.17 of 12 September 2013 ***** scsi: Copyright 1995-1998 by Leonard N. Zubkoff blogic_cmd(04) Status = 30: 4 ==> 4: 41 41 35 30 blogic_cmd(0B) Status = 30: 3 ==> 3: 00 08 07 blogic_cmd(0D) Status = 30: 34 ==> 34: 03 01 07 04 00 00 00 00 00 00 00 00 00 00 00 00 FF 42 44 46 FF 00 00 00 00 00 00 00 00 00 FF 00 FF 00 blogic_cmd(8D) Status = 30: 14 ==> 14: 45 DC 00 20 00 00 00 00 00 40 30 37 42 1D blogic_cmd(84) Status = 30: 1 ==> 1: 37 blogic_cmd(8B) Status = 30: 5 ==> 5: 39 35 38 20 20 blogic_cmd(85) Status = 30: 1 ==> 1: 42 blogic_cmd(86) Status = 30: 4 ==> 4: FF 05 93 00 blogic_cmd(91) Status = 30: 64 ==> 64: 41 46 3E 20 39 35 38 20 20 00 C4 00 04 01 07 2F 07 04 35 FF FF FF FF FF FF FF FF FF FF 01 00 FE FF 08 FF FF 00 00 00 00 00 00 00 01 00 01 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 FC scsi0: Configuring BusLogic Model BT-958 PCI Wide Ultra SCSI Host Adapter etc. Link: https://lore.kernel.org/r/alpine.DEB.2.21.2104201940430.44318@angie.orcam.me.uk Fixes: 4bcc595ccd80 ("printk: reinstate KERN_CONT for printing continuation lines") Cc: stable@vger.kernel.org # v4.9+ Acked-by: Khalid Aziz Signed-off-by: Maciej W. Rozycki Signed-off-by: Martin K. Petersen --- drivers/scsi/BusLogic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index adddcd589941..4d8556fb5c68 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3451,7 +3451,7 @@ static void blogic_msg(enum blogic_msglevel msglevel, char *fmt, if (buf[0] != '\n' || len > 1) printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf); } else - printk("%s", buf); + pr_cont("%s", buf); } else { if (begin) { if (adapter != NULL && adapter->adapter_initd) @@ -3459,7 +3459,7 @@ static void blogic_msg(enum blogic_msglevel msglevel, char *fmt, else printk("%s%s", blogic_msglevelmap[msglevel], buf); } else - printk("%s", buf); + pr_cont("%s", buf); } begin = (buf[len - 1] == '\n'); } -- cgit v1.2.3-70-g09d2 From a40662c90d974a89d2f5d627542b63bed88e72f0 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 20 Apr 2021 20:01:52 +0200 Subject: scsi: BusLogic: Avoid unbounded vsprintf() use Existing blogic_msg() invocations do not appear to overrun its internal buffer of a fixed length of 100, which would cause stack corruption, but it's easy to miss with possible further updates and a fix is cheap in performance terms, so limit the output produced into the buffer by using vscnprintf() rather than vsprintf(). Link: https://lore.kernel.org/r/alpine.DEB.2.21.2104201939390.44318@angie.orcam.me.uk Acked-by: Khalid Aziz Signed-off-by: Maciej W. Rozycki Signed-off-by: Martin K. Petersen --- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 4d8556fb5c68..0bcedd9d8d26 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3436,7 +3436,7 @@ static void blogic_msg(enum blogic_msglevel msglevel, char *fmt, int len = 0; va_start(args, adapter); - len = vsprintf(buf, fmt, args); + len = vscnprintf(buf, sizeof(buf), fmt, args); va_end(args); if (msglevel == BLOGIC_ANNOUNCE_LEVEL) { static int msglines = 0; -- cgit v1.2.3-70-g09d2 From 2127cd21fb78c6e22d92944253afd967b0ff774d Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 30 Jul 2021 10:50:31 +0100 Subject: scsi: BusLogic: Use %X for u32 sized integer rather than %lX An earlier fix changed the print format specifier for adapter->bios_addr to use %lX. However, the integer is a u32 so the fix was wrong. Fix this by using the correct %X format specifier. Link: https://lore.kernel.org/r/20210730095031.26981-1-colin.king@canonical.com Fixes: 43622697117c ("scsi: BusLogic: use %lX for unsigned long rather than %X") Acked-by: Khalid Aziz Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Invalid type in argument") --- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 0bcedd9d8d26..40088dcb98cd 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -1711,7 +1711,7 @@ static bool __init blogic_reportconfig(struct blogic_adapter *adapter) if (adapter->adapter_bus_type != BLOGIC_PCI_BUS) { blogic_info(" DMA Channel: None, ", adapter); if (adapter->bios_addr > 0) - blogic_info("BIOS Address: 0x%lX, ", adapter, + blogic_info("BIOS Address: 0x%X, ", adapter, adapter->bios_addr); else blogic_info("BIOS Address: None, ", adapter); -- cgit v1.2.3-70-g09d2 From 33529018294f1eabc6b5bb2672941165e658e96a Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Fri, 16 Jul 2021 16:58:52 +0530 Subject: scsi: qla4xxx: Convert uses of __constant_cpu_to_ to cpu_to_ The macros cpu_to_le16() and cpu_to_le32() have special cases for constants. Their __constant_ versions are not required. On little endian systems, both cpu_to_le16() and __constant_cpu_to_le16() expand to the same expression. Same is the case with cpu_to_le32(). On big endian systems, cpu_to_le16() expands to __swab16() which has a __builtin_constant_p check. Similarly, cpu_to_le32() expands to __swab32(). Consequently these macros can be safely used with constants, and hence all those uses are converted. This was discovered as a part of a checkpatch evaluation, looking at all reports of WARNING:CONSTANT_CONVERSION error type. Link: https://lore.kernel.org/r/20210716112852.24598-1-dwaipayanray1@gmail.com Signed-off-by: Dwaipayan Ray Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_init.c | 4 ++-- drivers/scsi/qla4xxx/ql4_iocb.c | 2 +- drivers/scsi/qla4xxx/ql4_mbx.c | 30 +++++++++++++++--------------- drivers/scsi/qla4xxx/ql4_nx.c | 10 +++++----- drivers/scsi/qla4xxx/ql4_os.c | 10 +++++----- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index f786ac2f5548..301bc09c8365 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -119,8 +119,8 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha) * the interrupt_handler to think there are responses to be * processed when there aren't. */ - ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0); - ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0); + ha->shadow_regs->req_q_out = cpu_to_le32(0); + ha->shadow_regs->rsp_q_in = cpu_to_le32(0); wmb(); writel(0, &ha->reg->req_q_in); diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index cbd1e6ffcd67..c57cec6fff6d 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c @@ -160,7 +160,7 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb, if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { /* No data being transferred */ - cmd_entry->ttlByteCnt = __constant_cpu_to_le32(0); + cmd_entry->ttlByteCnt = cpu_to_le32(0); return; } diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 187d78aa4f67..cd71074f3abe 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -645,8 +645,8 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) /* Fill in the request and response queue information. */ init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out); init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in); - init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH); - init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH); + init_fw_cb->rqq_len = cpu_to_le16(REQUEST_QUEUE_DEPTH); + init_fw_cb->compq_len = cpu_to_le16(RESPONSE_QUEUE_DEPTH); init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma)); init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma)); init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma)); @@ -656,20 +656,20 @@ int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha) /* Set up required options. */ init_fw_cb->fw_options |= - __constant_cpu_to_le16(FWOPT_SESSION_MODE | - FWOPT_INITIATOR_MODE); + cpu_to_le16(FWOPT_SESSION_MODE | + FWOPT_INITIATOR_MODE); if (is_qla80XX(ha)) init_fw_cb->fw_options |= - __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB); + cpu_to_le16(FWOPT_ENABLE_CRBDB); - init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE); + init_fw_cb->fw_options &= cpu_to_le16(~FWOPT_TARGET_MODE); init_fw_cb->add_fw_options = 0; init_fw_cb->add_fw_options |= - __constant_cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT); + cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT); init_fw_cb->add_fw_options |= - __constant_cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE); + cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE); if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != QLA_SUCCESS) { @@ -1613,7 +1613,7 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, strlcpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN); strlcpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN); - chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); + chap_table->cookie = cpu_to_le16(CHAP_VALID_COOKIE); exit_get_chap: dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma); @@ -1655,7 +1655,7 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, chap_table->secret_len = strlen(password); strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN - 1); strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN - 1); - chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); + chap_table->cookie = cpu_to_le16(CHAP_VALID_COOKIE); if (is_qla40XX(ha)) { chap_size = MAX_CHAP_ENTRIES_40XX * sizeof(*chap_table); @@ -1721,7 +1721,7 @@ int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username, mutex_lock(&ha->chap_sem); chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index; - if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) { + if (chap_table->cookie != cpu_to_le16(CHAP_VALID_COOKIE)) { rval = QLA_ERROR; goto exit_unlock_uni_chap; } @@ -1784,7 +1784,7 @@ int qla4xxx_get_chap_index(struct scsi_qla_host *ha, char *username, for (i = 0; i < max_chap_entries; i++) { chap_table = (struct ql4_chap_table *)ha->chap_list + i; if (chap_table->cookie != - __constant_cpu_to_le16(CHAP_VALID_COOKIE)) { + cpu_to_le16(CHAP_VALID_COOKIE)) { if (i > MAX_RESRV_CHAP_IDX && free_index == -1) free_index = i; continue; @@ -2105,18 +2105,18 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha, if (conn->max_recv_dlength) fw_ddb_entry->iscsi_max_rcv_data_seg_len = - __constant_cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS)); + cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS)); if (sess->max_r2t) fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t); if (sess->first_burst) fw_ddb_entry->iscsi_first_burst_len = - __constant_cpu_to_le16((sess->first_burst / BYTE_UNITS)); + cpu_to_le16((sess->first_burst / BYTE_UNITS)); if (sess->max_burst) fw_ddb_entry->iscsi_max_burst_len = - __constant_cpu_to_le16((sess->max_burst / BYTE_UNITS)); + cpu_to_le16((sess->max_burst / BYTE_UNITS)); if (sess->time2wait) fw_ddb_entry->iscsi_def_time2wait = diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 66a487795c53..47adff9f0506 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -3658,7 +3658,7 @@ qla4_82xx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr, "Do ROM fast read failed\n"); goto done_read; } - dwptr[i] = __constant_cpu_to_le32(val); + dwptr[i] = cpu_to_le32(val); } done_read: @@ -3721,9 +3721,9 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr) goto no_flash_data; } - if (*wptr == __constant_cpu_to_le16(0xffff)) + if (*wptr == cpu_to_le16(0xffff)) goto no_flash_data; - if (flt->version != __constant_cpu_to_le16(1)) { + if (flt->version != cpu_to_le16(1)) { DEBUG2(ql4_printk(KERN_INFO, ha, "Unsupported FLT detected: " "version=0x%x length=0x%x checksum=0x%x.\n", le16_to_cpu(flt->version), le16_to_cpu(flt->length), @@ -3826,7 +3826,7 @@ qla4_82xx_get_fdt_info(struct scsi_qla_host *ha) qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring, hw->flt_region_fdt << 2, OPTROM_BURST_SIZE); - if (*wptr == __constant_cpu_to_le16(0xffff)) + if (*wptr == cpu_to_le16(0xffff)) goto no_flash_data; if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || @@ -3883,7 +3883,7 @@ qla4_82xx_get_idc_param(struct scsi_qla_host *ha) qla4_82xx_read_optrom_data(ha, (uint8_t *)ha->request_ring, QLA82XX_IDC_PARAM_ADDR , 8); - if (*wptr == __constant_cpu_to_le32(0xffffffff)) { + if (*wptr == cpu_to_le32(0xffffffff)) { ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT; ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT; } else { diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 6ee7ea4c27e0..3f7737386193 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -702,7 +702,7 @@ static int qla4xxx_get_chap_by_index(struct scsi_qla_host *ha, *chap_entry = (struct ql4_chap_table *)ha->chap_list + chap_index; if ((*chap_entry)->cookie != - __constant_cpu_to_le16(CHAP_VALID_COOKIE)) { + cpu_to_le16(CHAP_VALID_COOKIE)) { *chap_entry = NULL; } else { rval = QLA_SUCCESS; @@ -745,7 +745,7 @@ static int qla4xxx_find_free_chap_index(struct scsi_qla_host *ha, chap_table = (struct ql4_chap_table *)ha->chap_list + i; if ((chap_table->cookie != - __constant_cpu_to_le16(CHAP_VALID_COOKIE)) && + cpu_to_le16(CHAP_VALID_COOKIE)) && (i > MAX_RESRV_CHAP_IDX)) { free_index = i; break; @@ -794,7 +794,7 @@ static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx, for (i = chap_tbl_idx; i < max_chap_entries; i++) { chap_table = (struct ql4_chap_table *)ha->chap_list + i; if (chap_table->cookie != - __constant_cpu_to_le16(CHAP_VALID_COOKIE)) + cpu_to_le16(CHAP_VALID_COOKIE)) continue; chap_rec->chap_tbl_idx = i; @@ -923,7 +923,7 @@ static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx) goto exit_delete_chap; } - chap_table->cookie = __constant_cpu_to_le16(0xFFFF); + chap_table->cookie = cpu_to_le16(0xFFFF); offset = FLASH_CHAP_OFFSET | (chap_tbl_idx * sizeof(struct ql4_chap_table)); @@ -6043,7 +6043,7 @@ static int qla4xxx_get_bidi_chap(struct scsi_qla_host *ha, char *username, for (i = 0; i < max_chap_entries; i++) { chap_table = (struct ql4_chap_table *)ha->chap_list + i; if (chap_table->cookie != - __constant_cpu_to_le16(CHAP_VALID_COOKIE)) { + cpu_to_le16(CHAP_VALID_COOKIE)) { continue; } -- cgit v1.2.3-70-g09d2 From f02bc9754a6887bf5e286889265d24ce5e3b1952 Mon Sep 17 00:00:00 2001 From: Daejun Park Date: Mon, 12 Jul 2021 17:58:30 +0900 Subject: scsi: ufs: ufshpb: Introduce Host Performance Buffer feature Implement Host Performance Buffer (HPB) initialization and add function calls to UFS core driver. NAND flash-based storage devices, including UFS, have mechanisms to translate logical addresses of I/O requests to the corresponding physical addresses of the flash storage. In UFS, logical-to-physical-address (L2P) map data, which is required to identify the physical address for the requested I/Os, can only be partially stored in SRAM from NAND flash. Due to this partial loading, accessing the flash address area, where the L2P information for that address is not loaded in the SRAM, can result in serious performance degradation. The basic concept of HPB is to cache L2P mapping entries in host system memory so that both physical block address (PBA) and logical block address (LBA) can be delivered in HPB read command. The HPB read command allows to read data faster than a regular read command in UFS since it provides the physical address (HPB Entry) of the desired logical block in addition to its logical address. The UFS device can access the physical block in NAND directly without searching and uploading L2P mapping table. This improves read performance because the NAND read operation for uploading L2P mapping table is removed. In HPB initialization, the host checks if the UFS device supports HPB feature and retrieves related device capabilities. Then, HPB parameters are configured in the device. Total start-up time of popular applications was measured and the difference observed between HPB being enabled and disabled. Popular applications are 12 game apps and 24 non-game apps. Each test cycle consists of running 36 applications in sequence. We repeated the cycle for observing performance improvement by L2P mapping cache hit in HPB. The following is the test environment: - kernel version: 4.4.0 - RAM: 8GB - UFS 2.1 (64GB) Results: +-------+----------+----------+-------+ | cycle | baseline | with HPB | diff | +-------+----------+----------+-------+ | 1 | 272.4 | 264.9 | -7.5 | | 2 | 250.4 | 248.2 | -2.2 | | 3 | 226.2 | 215.6 | -10.6 | | 4 | 230.6 | 214.8 | -15.8 | | 5 | 232.0 | 218.1 | -13.9 | | 6 | 231.9 | 212.6 | -19.3 | +-------+----------+----------+-------+ We also measured HPB performance using iozone: $ iozone -r 4k -+n -i2 -ecI -t 16 -l 16 -u 16 -s $IO_RANGE/16 -F \ mnt/tmp_1 mnt/tmp_2 mnt/tmp_3 mnt/tmp_4 mnt/tmp_5 mnt/tmp_6 mnt/tmp_7 \ mnt/tmp_8 mnt/tmp_9 mnt/tmp_10 mnt/tmp_11 mnt/tmp_12 mnt/tmp_13 \ mnt/tmp_14 mnt/tmp_15 mnt/tmp_16 Results: +----------+--------+---------+ | IO range | HPB on | HPB off | +----------+--------+---------+ | 1 GB | 294.8 | 300.87 | | 4 GB | 293.51 | 179.35 | | 8 GB | 294.85 | 162.52 | | 16 GB | 293.45 | 156.26 | | 32 GB | 277.4 | 153.25 | +----------+--------+---------+ Link: https://lore.kernel.org/r/20210712085830epcms2p8c1288b7f7a81b044158a18232617b572@epcms2p8 Reported-by: kernel test robot Tested-by: Bean Huo Tested-by: Can Guo Tested-by: Stanley Chu Reviewed-by: Greg Kroah-Hartman Reviewed-by: Bart Van Assche Reviewed-by: Can Guo Reviewed-by: Bean Huo Reviewed-by: Stanley Chu Acked-by: Avri Altman Signed-off-by: Daejun Park Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 127 +++++++ drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-sysfs.c | 18 + drivers/scsi/ufs/ufs.h | 15 + drivers/scsi/ufs/ufshcd.c | 48 +++ drivers/scsi/ufs/ufshcd.h | 23 ++ drivers/scsi/ufs/ufshpb.c | 568 +++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshpb.h | 167 +++++++++ 9 files changed, 976 insertions(+) create mode 100644 drivers/scsi/ufs/ufshpb.c create mode 100644 drivers/scsi/ufs/ufshpb.h diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index b4a5d55fa19f..4c1a5d28408d 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -1298,3 +1298,130 @@ Description: This node is used to set or display whether UFS WriteBooster is (if the platform supports UFSHCD_CAP_CLK_SCALING). For a platform that doesn't support UFSHCD_CAP_CLK_SCALING, we can disable/enable WriteBooster through this sysfs node. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_version +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the HPB specification version. + The full information about the descriptor can be found in the UFS + HPB (Host Performance Booster) Extension specifications. + Example: version 1.2.3 = 0123h + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_control +Date: June 2021 +Contact: Daejun Park +Description: This entry shows an indication of the HPB control mode. + 00h: Host control mode + 01h: Device control mode + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_region_size +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the bHPBRegionSize which can be calculated + as in the following (in bytes): + HPB Region size = 512B * 2^bHPBRegionSize + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_number_lu +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of HPB LU supported by + the device. + 00h: HPB is not supported by the device. + 01h ~ 20h: Maximum number of HPB LU supported by the device + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_subregion_size +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the bHPBSubRegionSize, which can be + calculated as in the following (in bytes) and shall be a multiple of + logical block size: + HPB Sub-Region size = 512B x 2^bHPBSubRegionSize + bHPBSubRegionSize shall not exceed bHPBRegionSize. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_max_active_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of active HPB regions that + is supported by the device. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_lu_max_active_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of HPB regions assigned to + the HPB logical unit. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_pinned_region_start_offset +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the start offset of HPB pinned region. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_number_pinned_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of HPB pinned regions assigned to + the HPB logical unit. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/hit_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of reads that changed to HPB read. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/miss_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of reads that cannot be changed to + HPB read. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_noti_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of response UPIUs that has + recommendations for activating sub-regions and/or inactivating region. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_active_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of active sub-regions recommended by + response UPIUs. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_inactive_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of inactive regions recommended by + response UPIUs. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/map_req_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of read buffer commands for + activating sub-regions recommended by response UPIUs. + + The file is read only. diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 2d137953e7b4..ee650526c560 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -183,3 +183,12 @@ config SCSI_UFS_CRYPTO Enabling this makes it possible for the kernel to use the crypto capabilities of the UFS device (if present) to perform crypto operations on data being transferred to/from the device. + +config SCSI_UFS_HPB + bool "Support UFS Host Performance Booster" + depends on SCSI_UFSHCD + help + The UFS HPB feature improves random read performance. It caches + L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB + read command by piggybacking physical page number for bypassing FTL (flash + translation layer)'s L2P address translation. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 06f3a3fe4a44..cce9b3916f5b 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -8,6 +8,7 @@ ufshcd-core-y += ufshcd.o ufs-sysfs.o ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o +ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 52bd807f7940..639644817f36 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -604,6 +604,8 @@ UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2); UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1); UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4); UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1); +UFS_DEVICE_DESC_PARAM(hpb_version, _HPB_VER, 2); +UFS_DEVICE_DESC_PARAM(hpb_control, _HPB_CONTROL, 1); UFS_DEVICE_DESC_PARAM(ext_feature_sup, _EXT_UFS_FEATURE_SUP, 4); UFS_DEVICE_DESC_PARAM(wb_presv_us_en, _WB_PRESRV_USRSPC_EN, 1); UFS_DEVICE_DESC_PARAM(wb_type, _WB_TYPE, 1); @@ -636,6 +638,8 @@ static struct attribute *ufs_sysfs_device_descriptor[] = { &dev_attr_number_of_secure_wpa.attr, &dev_attr_psa_max_data_size.attr, &dev_attr_psa_state_timeout.attr, + &dev_attr_hpb_version.attr, + &dev_attr_hpb_control.attr, &dev_attr_ext_feature_sup.attr, &dev_attr_wb_presv_us_en.attr, &dev_attr_wb_type.attr, @@ -709,6 +713,10 @@ UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units, _ENM4_MAX_NUM_UNITS, 4); UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor, _ENM4_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(hpb_region_size, _HPB_REGION_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_number_lu, _HPB_NUMBER_LU, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_subregion_size, _HPB_SUBREGION_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_max_active_regions, _HPB_MAX_ACTIVE_REGS, 2); UFS_GEOMETRY_DESC_PARAM(wb_max_alloc_units, _WB_MAX_ALLOC_UNITS, 4); UFS_GEOMETRY_DESC_PARAM(wb_max_wb_luns, _WB_MAX_WB_LUNS, 1); UFS_GEOMETRY_DESC_PARAM(wb_buff_cap_adj, _WB_BUFF_CAP_ADJ, 1); @@ -746,6 +754,10 @@ static struct attribute *ufs_sysfs_geometry_descriptor[] = { &dev_attr_enh3_memory_capacity_adjustment_factor.attr, &dev_attr_enh4_memory_max_alloc_units.attr, &dev_attr_enh4_memory_capacity_adjustment_factor.attr, + &dev_attr_hpb_region_size.attr, + &dev_attr_hpb_number_lu.attr, + &dev_attr_hpb_subregion_size.attr, + &dev_attr_hpb_max_active_regions.attr, &dev_attr_wb_max_alloc_units.attr, &dev_attr_wb_max_wb_luns.attr, &dev_attr_wb_buff_cap_adj.attr, @@ -1160,6 +1172,9 @@ UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1); UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8); UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2); UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1); +UFS_UNIT_DESC_PARAM(hpb_lu_max_active_regions, _HPB_LU_MAX_ACTIVE_RGNS, 2); +UFS_UNIT_DESC_PARAM(hpb_pinned_region_start_offset, _HPB_PIN_RGN_START_OFF, 2); +UFS_UNIT_DESC_PARAM(hpb_number_pinned_regions, _HPB_NUM_PIN_RGNS, 2); UFS_UNIT_DESC_PARAM(wb_buf_alloc_units, _WB_BUF_ALLOC_UNITS, 4); @@ -1177,6 +1192,9 @@ static struct attribute *ufs_sysfs_unit_descriptor[] = { &dev_attr_physical_memory_resourse_count.attr, &dev_attr_context_capabilities.attr, &dev_attr_large_unit_granularity.attr, + &dev_attr_hpb_lu_max_active_regions.attr, + &dev_attr_hpb_pinned_region_start_offset.attr, + &dev_attr_hpb_number_pinned_regions.attr, &dev_attr_wb_buf_alloc_units.attr, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index cb80b9670bfe..4eee7e31d08d 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -122,6 +122,7 @@ enum flag_idn { QUERY_FLAG_IDN_WB_EN = 0x0E, QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F, QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10, + QUERY_FLAG_IDN_HPB_RESET = 0x11, }; /* Attribute idn for Query requests */ @@ -195,6 +196,9 @@ enum unit_desc_param { UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18, UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20, UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22, + UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS = 0x23, + UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF = 0x25, + UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS = 0x27, UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29, }; @@ -235,6 +239,8 @@ enum device_desc_param { DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25, DEVICE_DESC_PARAM_PSA_TMT = 0x29, DEVICE_DESC_PARAM_PRDCT_REV = 0x2A, + DEVICE_DESC_PARAM_HPB_VER = 0x40, + DEVICE_DESC_PARAM_HPB_CONTROL = 0x42, DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP = 0x4F, DEVICE_DESC_PARAM_WB_PRESRV_USRSPC_EN = 0x53, DEVICE_DESC_PARAM_WB_TYPE = 0x54, @@ -283,6 +289,10 @@ enum geometry_desc_param { GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E, GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42, GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, + GEOMETRY_DESC_PARAM_HPB_REGION_SIZE = 0x48, + GEOMETRY_DESC_PARAM_HPB_NUMBER_LU = 0x49, + GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE = 0x4A, + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS = 0x4B, GEOMETRY_DESC_PARAM_WB_MAX_ALLOC_UNITS = 0x4F, GEOMETRY_DESC_PARAM_WB_MAX_WB_LUNS = 0x53, GEOMETRY_DESC_PARAM_WB_BUFF_CAP_ADJ = 0x54, @@ -327,8 +337,10 @@ enum { /* Possible values for dExtendedUFSFeaturesSupport */ enum { + UFS_DEV_HPB_SUPPORT = BIT(7), UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), }; +#define UFS_DEV_HPB_SUPPORT_VERSION 0x310 #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 @@ -544,6 +556,9 @@ struct ufs_dev_info { u16 wspecversion; u32 clk_gating_wait_us; + /* UFS HPB related flag */ + bool hpb_enabled; + /* UFS WB related flags */ bool wb_enabled; bool wb_buf_flush_enabled; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 05495c34a2b7..0c54cf38913b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -24,6 +24,7 @@ #include "ufs-debugfs.h" #include "ufs_bsg.h" #include "ufshcd-crypto.h" +#include "ufshpb.h" #include #define CREATE_TRACE_POINTS @@ -4986,6 +4987,25 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth) return scsi_change_queue_depth(sdev, depth); } +static void ufshcd_hpb_destroy(struct ufs_hba *hba, struct scsi_device *sdev) +{ + /* skip well-known LU */ + if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || !ufshpb_is_allowed(hba)) + return; + + ufshpb_destroy_lu(hba, sdev); +} + +static void ufshcd_hpb_configure(struct ufs_hba *hba, struct scsi_device *sdev) +{ + /* skip well-known LU */ + if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || + !(hba->dev_info.hpb_enabled) || !ufshpb_is_allowed(hba)) + return; + + ufshpb_init_hpb_lu(hba, sdev); +} + /** * ufshcd_slave_configure - adjust SCSI device configurations * @sdev: pointer to SCSI device @@ -4995,6 +5015,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) struct ufs_hba *hba = shost_priv(sdev->host); struct request_queue *q = sdev->request_queue; + ufshcd_hpb_configure(hba, sdev); + blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); @@ -5021,6 +5043,9 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) struct ufs_hba *hba; hba = shost_priv(sdev->host); + + ufshcd_hpb_destroy(hba, sdev); + /* Drop the reference as it won't be needed anymore */ if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { unsigned long flags; @@ -7100,6 +7125,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) * Stop the host controller and complete the requests * cleared by h/w */ + ufshpb_reset_host(hba); ufshcd_hba_stop(hba); hba->silence_err_logs = true; ufshcd_complete_requests(hba); @@ -7498,6 +7524,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba) { int err; u8 model_index; + u8 b_ufs_feature_sup; u8 *desc_buf; struct ufs_dev_info *dev_info = &hba->dev_info; @@ -7525,9 +7552,16 @@ static int ufs_get_device_desc(struct ufs_hba *hba) /* getting Specification Version in big endian format */ dev_info->wspecversion = desc_buf[DEVICE_DESC_PARAM_SPEC_VER] << 8 | desc_buf[DEVICE_DESC_PARAM_SPEC_VER + 1]; + b_ufs_feature_sup = desc_buf[DEVICE_DESC_PARAM_UFS_FEAT]; model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; + if (dev_info->wspecversion >= UFS_DEV_HPB_SUPPORT_VERSION && + (b_ufs_feature_sup & UFS_DEV_HPB_SUPPORT)) { + dev_info->hpb_enabled = true; + ufshpb_get_dev_info(hba, desc_buf); + } + err = ufshcd_read_string_desc(hba, model_index, &dev_info->model, SD_ASCII_STD); if (err < 0) { @@ -7759,6 +7793,10 @@ static int ufshcd_device_geo_params_init(struct ufs_hba *hba) else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] == 0) hba->dev_info.max_lu_supported = 8; + if (hba->desc_size[QUERY_DESC_IDN_GEOMETRY] >= + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS) + ufshpb_get_geo_info(hba, desc_buf); + out: kfree(desc_buf); return err; @@ -7901,6 +7939,7 @@ static int ufshcd_add_lus(struct ufs_hba *hba) } ufs_bsg_probe(hba); + ufshpb_init(hba); scsi_scan_host(hba->host); pm_runtime_put_sync(hba->dev); @@ -8049,6 +8088,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + ufshpb_reset(hba); out: spin_lock_irqsave(hba->host->host_lock, flags); if (ret) @@ -8096,6 +8136,9 @@ out: static const struct attribute_group *ufshcd_driver_groups[] = { &ufs_sysfs_unit_descriptor_group, &ufs_sysfs_lun_attributes_group, +#ifdef CONFIG_SCSI_UFS_HPB + &ufs_sysfs_hpb_stat_group, +#endif NULL, }; @@ -8797,6 +8840,8 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) req_link_state = UIC_LINK_OFF_STATE; } + ufshpb_suspend(hba); + /* * If we can't transition into any of the low power modes * just gate the clocks. @@ -8920,6 +8965,7 @@ out: ufshcd_update_evt_hist(hba, UFS_EVT_WL_SUSP_ERR, (u32)ret); hba->clk_gating.is_suspended = false; ufshcd_release(hba); + ufshpb_resume(hba); } hba->pm_op_in_progress = false; return ret; @@ -8998,6 +9044,8 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + + ufshpb_resume(hba); goto out; set_old_link_state: diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 971cfabc4a1e..57d407be9e0a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -641,6 +641,25 @@ struct ufs_hba_variant_params { u32 wb_flush_threshold; }; +#ifdef CONFIG_SCSI_UFS_HPB +/** + * struct ufshpb_dev_info - UFSHPB device related info + * @num_lu: the number of user logical unit to check whether all lu finished + * initialization + * @rgn_size: device reported HPB region size + * @srgn_size: device reported HPB sub-region size + * @slave_conf_cnt: counter to check all lu finished initialization + * @hpb_disabled: flag to check if HPB is disabled + */ +struct ufshpb_dev_info { + int num_lu; + int rgn_size; + int srgn_size; + atomic_t slave_conf_cnt; + bool hpb_disabled; +}; +#endif + struct ufs_hba_monitor { unsigned long chunk_size; @@ -851,6 +870,10 @@ struct ufs_hba { struct request_queue *bsg_queue; struct delayed_work rpm_dev_flush_recheck_work; +#ifdef CONFIG_SCSI_UFS_HPB + struct ufshpb_dev_info ufshpb_dev; +#endif + struct ufs_hba_monitor monitor; #ifdef CONFIG_SCSI_UFS_CRYPTO diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c new file mode 100644 index 000000000000..91313c95e9b1 --- /dev/null +++ b/drivers/scsi/ufs/ufshpb.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Universal Flash Storage Host Performance Booster + * + * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd. + * + * Authors: + * Yongmyung Lee + * Jinyoung Choi + */ + +#include +#include + +#include "ufshcd.h" +#include "ufshpb.h" +#include "../sd.h" + +bool ufshpb_is_allowed(struct ufs_hba *hba) +{ + return !(hba->ufshpb_dev.hpb_disabled); +} + +static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev) +{ + return sdev->hostdata; +} + +static int ufshpb_get_state(struct ufshpb_lu *hpb) +{ + return atomic_read(&hpb->hpb_state); +} + +static void ufshpb_set_state(struct ufshpb_lu *hpb, int state) +{ + atomic_set(&hpb->hpb_state, state); +} + +static void ufshpb_init_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, bool last) +{ + int srgn_idx; + struct ufshpb_subregion *srgn; + + for (srgn_idx = 0; srgn_idx < rgn->srgn_cnt; srgn_idx++) { + srgn = rgn->srgn_tbl + srgn_idx; + + srgn->rgn_idx = rgn->rgn_idx; + srgn->srgn_idx = srgn_idx; + srgn->srgn_state = HPB_SRGN_UNUSED; + } + + if (unlikely(last && hpb->last_srgn_entries)) + srgn->is_last = true; +} + +static int ufshpb_alloc_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, int srgn_cnt) +{ + rgn->srgn_tbl = kvcalloc(srgn_cnt, sizeof(struct ufshpb_subregion), + GFP_KERNEL); + if (!rgn->srgn_tbl) + return -ENOMEM; + + rgn->srgn_cnt = srgn_cnt; + return 0; +} + +static void ufshpb_lu_parameter_init(struct ufs_hba *hba, + struct ufshpb_lu *hpb, + struct ufshpb_dev_info *hpb_dev_info, + struct ufshpb_lu_info *hpb_lu_info) +{ + u32 entries_per_rgn; + u64 rgn_mem_size, tmp; + + hpb->lu_pinned_start = hpb_lu_info->pinned_start; + hpb->lu_pinned_end = hpb_lu_info->num_pinned ? + (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1) + : PINNED_NOT_SET; + + rgn_mem_size = (1ULL << hpb_dev_info->rgn_size) * HPB_RGN_SIZE_UNIT + * HPB_ENTRY_SIZE; + do_div(rgn_mem_size, HPB_ENTRY_BLOCK_SIZE); + hpb->srgn_mem_size = (1ULL << hpb_dev_info->srgn_size) + * HPB_RGN_SIZE_UNIT / HPB_ENTRY_BLOCK_SIZE * HPB_ENTRY_SIZE; + + tmp = rgn_mem_size; + do_div(tmp, HPB_ENTRY_SIZE); + entries_per_rgn = (u32)tmp; + hpb->entries_per_rgn_shift = ilog2(entries_per_rgn); + hpb->entries_per_rgn_mask = entries_per_rgn - 1; + + hpb->entries_per_srgn = hpb->srgn_mem_size / HPB_ENTRY_SIZE; + hpb->entries_per_srgn_shift = ilog2(hpb->entries_per_srgn); + hpb->entries_per_srgn_mask = hpb->entries_per_srgn - 1; + + tmp = rgn_mem_size; + do_div(tmp, hpb->srgn_mem_size); + hpb->srgns_per_rgn = (int)tmp; + + hpb->rgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks, + entries_per_rgn); + hpb->srgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks, + (hpb->srgn_mem_size / HPB_ENTRY_SIZE)); + hpb->last_srgn_entries = hpb_lu_info->num_blocks + % (hpb->srgn_mem_size / HPB_ENTRY_SIZE); + + hpb->pages_per_srgn = DIV_ROUND_UP(hpb->srgn_mem_size, PAGE_SIZE); +} + +static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn_table, *rgn; + int rgn_idx, i; + int ret = 0; + + rgn_table = kvcalloc(hpb->rgns_per_lu, sizeof(struct ufshpb_region), + GFP_KERNEL); + if (!rgn_table) + return -ENOMEM; + + hpb->rgn_tbl = rgn_table; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + int srgn_cnt = hpb->srgns_per_rgn; + bool last_srgn = false; + + rgn = rgn_table + rgn_idx; + rgn->rgn_idx = rgn_idx; + + if (rgn_idx == hpb->rgns_per_lu - 1) { + srgn_cnt = ((hpb->srgns_per_lu - 1) % + hpb->srgns_per_rgn) + 1; + last_srgn = true; + } + + ret = ufshpb_alloc_subregion_tbl(hpb, rgn, srgn_cnt); + if (ret) + goto release_srgn_table; + ufshpb_init_subregion_tbl(hpb, rgn, last_srgn); + + rgn->rgn_state = HPB_RGN_INACTIVE; + } + + return 0; + +release_srgn_table: + for (i = 0; i < rgn_idx; i++) + kvfree(rgn_table[i].srgn_tbl); + + kvfree(rgn_table); + return ret; +} + +static void ufshpb_destroy_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + int srgn_idx; + + for (srgn_idx = 0; srgn_idx < rgn->srgn_cnt; srgn_idx++) { + struct ufshpb_subregion *srgn; + + srgn = rgn->srgn_tbl + srgn_idx; + srgn->srgn_state = HPB_SRGN_UNUSED; + } +} + +static void ufshpb_destroy_region_tbl(struct ufshpb_lu *hpb) +{ + int rgn_idx; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + struct ufshpb_region *rgn; + + rgn = hpb->rgn_tbl + rgn_idx; + if (rgn->rgn_state != HPB_RGN_INACTIVE) { + rgn->rgn_state = HPB_RGN_INACTIVE; + + ufshpb_destroy_subregion_tbl(hpb, rgn); + } + + kvfree(rgn->srgn_tbl); + } + + kvfree(hpb->rgn_tbl); +} + +/* SYSFS functions */ +#define ufshpb_sysfs_attr_show_func(__name) \ +static ssize_t __name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); \ + \ + if (!hpb) \ + return -ENODEV; \ + \ + return sysfs_emit(buf, "%llu\n", hpb->stats.__name); \ +} \ +\ +static DEVICE_ATTR_RO(__name) + +ufshpb_sysfs_attr_show_func(hit_cnt); +ufshpb_sysfs_attr_show_func(miss_cnt); +ufshpb_sysfs_attr_show_func(rb_noti_cnt); +ufshpb_sysfs_attr_show_func(rb_active_cnt); +ufshpb_sysfs_attr_show_func(rb_inactive_cnt); +ufshpb_sysfs_attr_show_func(map_req_cnt); + +static struct attribute *hpb_dev_attrs[] = { + &dev_attr_hit_cnt.attr, + &dev_attr_miss_cnt.attr, + &dev_attr_rb_noti_cnt.attr, + &dev_attr_rb_active_cnt.attr, + &dev_attr_rb_inactive_cnt.attr, + &dev_attr_map_req_cnt.attr, + NULL, +}; + +struct attribute_group ufs_sysfs_hpb_stat_group = { + .name = "hpb_stats", + .attrs = hpb_dev_attrs, +}; + +static void ufshpb_stat_init(struct ufshpb_lu *hpb) +{ + hpb->stats.hit_cnt = 0; + hpb->stats.miss_cnt = 0; + hpb->stats.rb_noti_cnt = 0; + hpb->stats.rb_active_cnt = 0; + hpb->stats.rb_inactive_cnt = 0; + hpb->stats.map_req_cnt = 0; +} + +static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) +{ + int ret; + + ret = ufshpb_alloc_region_tbl(hba, hpb); + + ufshpb_stat_init(hpb); + + return 0; +} + +static struct ufshpb_lu * +ufshpb_alloc_hpb_lu(struct ufs_hba *hba, int lun, + struct ufshpb_dev_info *hpb_dev_info, + struct ufshpb_lu_info *hpb_lu_info) +{ + struct ufshpb_lu *hpb; + int ret; + + hpb = kzalloc(sizeof(struct ufshpb_lu), GFP_KERNEL); + if (!hpb) + return NULL; + + hpb->lun = lun; + + ufshpb_lu_parameter_init(hba, hpb, hpb_dev_info, hpb_lu_info); + + ret = ufshpb_lu_hpb_init(hba, hpb); + if (ret) { + dev_err(hba->dev, "hpb lu init failed. ret %d", ret); + goto release_hpb; + } + + return hpb; + +release_hpb: + kfree(hpb); + return NULL; +} + +static bool ufshpb_check_hpb_reset_query(struct ufs_hba *hba) +{ + int err = 0; + bool flag_res = true; + int try; + + /* wait for the device to complete HPB reset query */ + for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) { + dev_dbg(hba->dev, + "%s start flag reset polling %d times\n", + __func__, try); + + /* Poll fHpbReset flag to be cleared */ + err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, + QUERY_FLAG_IDN_HPB_RESET, 0, &flag_res); + + if (err) { + dev_err(hba->dev, + "%s reading fHpbReset flag failed with error %d\n", + __func__, err); + return flag_res; + } + + if (!flag_res) + goto out; + + usleep_range(1000, 1100); + } + if (flag_res) { + dev_err(hba->dev, + "%s fHpbReset was not cleared by the device\n", + __func__); + } +out: + return flag_res; +} + +void ufshpb_reset(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = sdev->hostdata; + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_RESET) + continue; + + ufshpb_set_state(hpb, HPB_PRESENT); + } +} + +void ufshpb_reset_host(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = sdev->hostdata; + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + continue; + ufshpb_set_state(hpb, HPB_RESET); + } +} + +void ufshpb_suspend(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = sdev->hostdata; + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + continue; + ufshpb_set_state(hpb, HPB_SUSPEND); + } +} + +void ufshpb_resume(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = sdev->hostdata; + if (!hpb) + continue; + + if ((ufshpb_get_state(hpb) != HPB_PRESENT) && + (ufshpb_get_state(hpb) != HPB_SUSPEND)) + continue; + ufshpb_set_state(hpb, HPB_PRESENT); + } +} + +static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun, + struct ufshpb_lu_info *hpb_lu_info) +{ + u16 max_active_rgns; + u8 lu_enable; + int size; + int ret; + char desc_buf[QUERY_DESC_MAX_SIZE]; + + ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size); + + pm_runtime_get_sync(hba->dev); + ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, + QUERY_DESC_IDN_UNIT, lun, 0, + desc_buf, &size); + pm_runtime_put_sync(hba->dev); + + if (ret) { + dev_err(hba->dev, + "%s: idn: %d lun: %d query request failed", + __func__, QUERY_DESC_IDN_UNIT, lun); + return ret; + } + + lu_enable = desc_buf[UNIT_DESC_PARAM_LU_ENABLE]; + if (lu_enable != LU_ENABLED_HPB_FUNC) + return -ENODEV; + + max_active_rgns = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS); + if (!max_active_rgns) { + dev_err(hba->dev, + "lun %d wrong number of max active regions\n", lun); + return -ENODEV; + } + + hpb_lu_info->num_blocks = get_unaligned_be64( + desc_buf + UNIT_DESC_PARAM_LOGICAL_BLK_COUNT); + hpb_lu_info->pinned_start = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF); + hpb_lu_info->num_pinned = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS); + hpb_lu_info->max_active_rgns = max_active_rgns; + + return 0; +} + +void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) +{ + struct ufshpb_lu *hpb = sdev->hostdata; + + if (!hpb) + return; + + ufshpb_set_state(hpb, HPB_FAILED); + + sdev = hpb->sdev_ufs_lu; + sdev->hostdata = NULL; + + ufshpb_destroy_region_tbl(hpb); + + list_del_init(&hpb->list_hpb_lu); + + kfree(hpb); +} + +static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + bool init_success; + + init_success = !ufshpb_check_hpb_reset_query(hba); + + shost_for_each_device(sdev, hba->host) { + hpb = sdev->hostdata; + if (!hpb) + continue; + + if (init_success) { + ufshpb_set_state(hpb, HPB_PRESENT); + } else { + dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun); + ufshpb_destroy_lu(hba, sdev); + } + } +} + +void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) +{ + struct ufshpb_lu *hpb; + int ret; + struct ufshpb_lu_info hpb_lu_info = { 0 }; + int lun = sdev->lun; + + if (lun >= hba->dev_info.max_lu_supported) + goto out; + + ret = ufshpb_get_lu_info(hba, lun, &hpb_lu_info); + if (ret) + goto out; + + hpb = ufshpb_alloc_hpb_lu(hba, lun, &hba->ufshpb_dev, + &hpb_lu_info); + if (!hpb) + goto out; + + hpb->sdev_ufs_lu = sdev; + sdev->hostdata = hpb; + +out: + /* All LUs are initialized */ + if (atomic_dec_and_test(&hba->ufshpb_dev.slave_conf_cnt)) + ufshpb_hpb_lu_prepared(hba); +} + +void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) +{ + struct ufshpb_dev_info *hpb_info = &hba->ufshpb_dev; + int max_active_rgns = 0; + int hpb_num_lu; + + hpb_num_lu = geo_buf[GEOMETRY_DESC_PARAM_HPB_NUMBER_LU]; + if (hpb_num_lu == 0) { + dev_err(hba->dev, "No HPB LU supported\n"); + hpb_info->hpb_disabled = true; + return; + } + + hpb_info->rgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_REGION_SIZE]; + hpb_info->srgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE]; + max_active_rgns = get_unaligned_be16(geo_buf + + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS); + + if (hpb_info->rgn_size == 0 || hpb_info->srgn_size == 0 || + max_active_rgns == 0) { + dev_err(hba->dev, "No HPB supported device\n"); + hpb_info->hpb_disabled = true; + return; + } +} + +void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) +{ + struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; + int version; + u8 hpb_mode; + + hpb_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; + if (hpb_mode == HPB_HOST_CONTROL) { + dev_err(hba->dev, "%s: host control mode is not supported.\n", + __func__); + hpb_dev_info->hpb_disabled = true; + return; + } + + version = get_unaligned_be16(desc_buf + DEVICE_DESC_PARAM_HPB_VER); + if (version != HPB_SUPPORT_VERSION) { + dev_err(hba->dev, "%s: HPB %x version is not supported.\n", + __func__, version); + hpb_dev_info->hpb_disabled = true; + return; + } + + /* + * Get the number of user logical unit to check whether all + * scsi_device finish initialization + */ + hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU]; +} + +void ufshpb_init(struct ufs_hba *hba) +{ + struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; + int try; + int ret; + + if (!ufshpb_is_allowed(hba) || !hba->dev_info.hpb_enabled) + return; + + atomic_set(&hpb_dev_info->slave_conf_cnt, hpb_dev_info->num_lu); + /* issue HPB reset query */ + for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) { + ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG, + QUERY_FLAG_IDN_HPB_RESET, 0, NULL); + if (!ret) + break; + } +} diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h new file mode 100644 index 000000000000..fa311ed3fa94 --- /dev/null +++ b/drivers/scsi/ufs/ufshpb.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Universal Flash Storage Host Performance Booster + * + * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd. + * + * Authors: + * Yongmyung Lee + * Jinyoung Choi + */ + +#ifndef _UFSHPB_H_ +#define _UFSHPB_H_ + +/* hpb response UPIU macro */ +#define HPB_RSP_NONE 0x0 +#define HPB_RSP_REQ_REGION_UPDATE 0x1 +#define HPB_RSP_DEV_RESET 0x2 +#define MAX_ACTIVE_NUM 2 +#define MAX_INACTIVE_NUM 2 +#define DEV_DATA_SEG_LEN 0x14 +#define DEV_SENSE_SEG_LEN 0x12 +#define DEV_DES_TYPE 0x80 +#define DEV_ADDITIONAL_LEN 0x10 + +/* hpb map & entries macro */ +#define HPB_RGN_SIZE_UNIT 512 +#define HPB_ENTRY_BLOCK_SIZE 4096 +#define HPB_ENTRY_SIZE 0x8 +#define PINNED_NOT_SET U32_MAX + +/* hpb support chunk size */ +#define HPB_MULTI_CHUNK_HIGH 1 + +/* hpb vender defined opcode */ +#define UFSHPB_READ 0xF8 +#define UFSHPB_READ_BUFFER 0xF9 +#define UFSHPB_READ_BUFFER_ID 0x01 +#define HPB_READ_BUFFER_CMD_LENGTH 10 +#define LU_ENABLED_HPB_FUNC 0x02 + +#define HPB_RESET_REQ_RETRIES 10 + +#define HPB_SUPPORT_VERSION 0x100 + +enum UFSHPB_MODE { + HPB_HOST_CONTROL, + HPB_DEVICE_CONTROL, +}; + +enum UFSHPB_STATE { + HPB_INIT = 0, + HPB_PRESENT = 1, + HPB_SUSPEND, + HPB_FAILED, + HPB_RESET, +}; + +enum HPB_RGN_STATE { + HPB_RGN_INACTIVE, + HPB_RGN_ACTIVE, + /* pinned regions are always active */ + HPB_RGN_PINNED, +}; + +enum HPB_SRGN_STATE { + HPB_SRGN_UNUSED, + HPB_SRGN_INVALID, + HPB_SRGN_VALID, + HPB_SRGN_ISSUED, +}; + +/** + * struct ufshpb_lu_info - UFSHPB logical unit related info + * @num_blocks: the number of logical block + * @pinned_start: the start region number of pinned region + * @num_pinned: the number of pinned regions + * @max_active_rgns: maximum number of active regions + */ +struct ufshpb_lu_info { + int num_blocks; + int pinned_start; + int num_pinned; + int max_active_rgns; +}; + +struct ufshpb_subregion { + enum HPB_SRGN_STATE srgn_state; + int rgn_idx; + int srgn_idx; + bool is_last; +}; + +struct ufshpb_region { + struct ufshpb_subregion *srgn_tbl; + enum HPB_RGN_STATE rgn_state; + int rgn_idx; + int srgn_cnt; +}; + +struct ufshpb_stats { + u64 hit_cnt; + u64 miss_cnt; + u64 rb_noti_cnt; + u64 rb_active_cnt; + u64 rb_inactive_cnt; + u64 map_req_cnt; +}; + +struct ufshpb_lu { + int lun; + struct scsi_device *sdev_ufs_lu; + struct ufshpb_region *rgn_tbl; + + atomic_t hpb_state; + + /* pinned region information */ + u32 lu_pinned_start; + u32 lu_pinned_end; + + /* HPB related configuration */ + u32 rgns_per_lu; + u32 srgns_per_lu; + u32 last_srgn_entries; + int srgns_per_rgn; + u32 srgn_mem_size; + u32 entries_per_rgn_mask; + u32 entries_per_rgn_shift; + u32 entries_per_srgn; + u32 entries_per_srgn_mask; + u32 entries_per_srgn_shift; + u32 pages_per_srgn; + + struct ufshpb_stats stats; + + struct list_head list_hpb_lu; +}; + +struct ufs_hba; +struct ufshcd_lrb; + +#ifndef CONFIG_SCSI_UFS_HPB +static void ufshpb_resume(struct ufs_hba *hba) {} +static void ufshpb_suspend(struct ufs_hba *hba) {} +static void ufshpb_reset(struct ufs_hba *hba) {} +static void ufshpb_reset_host(struct ufs_hba *hba) {} +static void ufshpb_init(struct ufs_hba *hba) {} +static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} +static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} +static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; } +static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {} +static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {} +#else +void ufshpb_resume(struct ufs_hba *hba); +void ufshpb_suspend(struct ufs_hba *hba); +void ufshpb_reset(struct ufs_hba *hba); +void ufshpb_reset_host(struct ufs_hba *hba); +void ufshpb_init(struct ufs_hba *hba); +void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev); +void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev); +bool ufshpb_is_allowed(struct ufs_hba *hba); +void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf); +void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf); +extern struct attribute_group ufs_sysfs_hpb_stat_group; +#endif + +#endif /* End of Header */ -- cgit v1.2.3-70-g09d2 From 4b5f49079c52a7eadd2defbd8d2a270664a881d4 Mon Sep 17 00:00:00 2001 From: Daejun Park Date: Mon, 12 Jul 2021 17:58:59 +0900 Subject: scsi: ufs: ufshpb: L2P map management for HPB read Implement L2P map management in HPB. The HPB divides logical addresses into several regions. A region consists of several sub-regions. The sub-region is a basic unit where L2P mapping is managed. The driver loads L2P mapping data of each sub-region. The loaded sub-region is called active-state. The HPB driver unloads L2P mapping data as region unit. The unloaded region is called inactive-state. Sub-region/region candidates to be loaded and unloaded are delivered from the UFS device. The UFS device delivers the recommended active sub-region and inactivate region to the driver using sense data. The HPB module performs L2P mapping management on the host through the delivered information. A pinned region is a preset region on the UFS device that is always in activate-state. The data structures for map data requests and L2P mappings use the mempool API, minimizing allocation overhead while avoiding static allocation. The mininum size of the memory pool used in the HPB is implemented as a module parameter so that it can be configurable by the user. To guarantee a minimum memory pool size of 4MB: ufshpb_host_map_kbytes=4096. The map_work manages active/inactive via 2 "to-do" lists: - hpb->lh_inact_rgn: regions to be inactivated - hpb->lh_act_srgn: subregions to be activated These lists are maintained on I/O completion. [mkp: switch to REQ_OP_DRV_*] Link: https://lore.kernel.org/r/20210712085859epcms2p36e420f19564f6cd0c4a45d54949619eb@epcms2p3 Tested-by: Bean Huo Tested-by: Can Guo Tested-by: Stanley Chu Reviewed-by: Greg Kroah-Hartman Reviewed-by: Bart Van Assche Reviewed-by: Can Guo Reviewed-by: Bean Huo Reviewed-by: Stanley Chu Acked-by: Avri Altman Signed-off-by: Daejun Park Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs.h | 36 ++ drivers/scsi/ufs/ufshcd.c | 4 + drivers/scsi/ufs/ufshpb.c | 1088 ++++++++++++++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshpb.h | 65 +++ 4 files changed, 1178 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 4eee7e31d08d..bfb84d2ba990 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -478,6 +478,41 @@ struct utp_cmd_rsp { u8 sense_data[UFS_SENSE_SIZE]; }; +struct ufshpb_active_field { + __be16 active_rgn; + __be16 active_srgn; +}; +#define HPB_ACT_FIELD_SIZE 4 + +/** + * struct utp_hpb_rsp - Response UPIU structure + * @residual_transfer_count: Residual transfer count DW-3 + * @reserved1: Reserved double words DW-4 to DW-7 + * @sense_data_len: Sense data length DW-8 U16 + * @desc_type: Descriptor type of sense data + * @additional_len: Additional length of sense data + * @hpb_op: HPB operation type + * @lun: LUN of response UPIU + * @active_rgn_cnt: Active region count + * @inactive_rgn_cnt: Inactive region count + * @hpb_active_field: Recommended to read HPB region and subregion + * @hpb_inactive_field: To be inactivated HPB region and subregion + */ +struct utp_hpb_rsp { + __be32 residual_transfer_count; + __be32 reserved1[4]; + __be16 sense_data_len; + u8 desc_type; + u8 additional_len; + u8 hpb_op; + u8 lun; + u8 active_rgn_cnt; + u8 inactive_rgn_cnt; + struct ufshpb_active_field hpb_active_field[2]; + __be16 hpb_inactive_field[2]; +}; +#define UTP_HPB_RSP_SIZE 40 + /** * struct utp_upiu_rsp - general upiu response structure * @header: UPIU header structure DW-0 to DW-2 @@ -488,6 +523,7 @@ struct utp_upiu_rsp { struct utp_upiu_header header; union { struct utp_cmd_rsp sr; + struct utp_hpb_rsp hr; struct utp_upiu_query qr; }; }; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0c54cf38913b..c708e2b5b84d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5148,6 +5148,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) ufshcd_is_exception_event(lrbp->ucd_rsp_ptr)) /* Flushed in suspend */ schedule_work(&hba->eeh_work); + + if (scsi_status == SAM_STAT_GOOD) + ufshpb_rsp_upiu(hba, lrbp); break; case UPIU_TRANSACTION_REJECT_UPIU: /* TODO: handle Reject UPIU Response */ @@ -9390,6 +9393,7 @@ void ufshcd_remove(struct ufs_hba *hba) if (hba->sdev_ufs_device) ufshcd_rpm_get_sync(hba); ufs_bsg_remove(hba); + ufshpb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); blk_cleanup_queue(hba->tmf_queue); blk_mq_free_tag_set(&hba->tmf_tag_set); diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 91313c95e9b1..3a55f0543fe5 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -16,6 +16,16 @@ #include "ufshpb.h" #include "../sd.h" +/* memory management */ +static struct kmem_cache *ufshpb_mctx_cache; +static mempool_t *ufshpb_mctx_pool; +static mempool_t *ufshpb_page_pool; +/* A cache size of 2MB can cache ppn in the 1GB range. */ +static unsigned int ufshpb_host_map_kbytes = 2048; +static int tot_active_srgn_pages; + +static struct workqueue_struct *ufshpb_wq; + bool ufshpb_is_allowed(struct ufs_hba *hba) { return !(hba->ufshpb_dev.hpb_disabled); @@ -36,14 +46,889 @@ static void ufshpb_set_state(struct ufshpb_lu *hpb, int state) atomic_set(&hpb->hpb_state, state); } +static bool ufshpb_is_general_lun(int lun) +{ + return lun < UFS_UPIU_MAX_UNIT_NUM_ID; +} + +static bool +ufshpb_is_pinned_region(struct ufshpb_lu *hpb, int rgn_idx) +{ + if (hpb->lu_pinned_end != PINNED_NOT_SET && + rgn_idx >= hpb->lu_pinned_start && + rgn_idx <= hpb->lu_pinned_end) + return true; + + return false; +} + +static void ufshpb_kick_map_work(struct ufshpb_lu *hpb) +{ + bool ret = false; + unsigned long flags; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + return; + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + if (!list_empty(&hpb->lh_inact_rgn) || !list_empty(&hpb->lh_act_srgn)) + ret = true; + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + if (ret) + queue_work(ufshpb_wq, &hpb->map_work); +} + +static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp, + struct utp_hpb_rsp *rsp_field) +{ + /* Check HPB_UPDATE_ALERT */ + if (!(lrbp->ucd_rsp_ptr->header.dword_2 & + UPIU_HEADER_DWORD(0, 2, 0, 0))) + return false; + + if (be16_to_cpu(rsp_field->sense_data_len) != DEV_SENSE_SEG_LEN || + rsp_field->desc_type != DEV_DES_TYPE || + rsp_field->additional_len != DEV_ADDITIONAL_LEN || + rsp_field->active_rgn_cnt > MAX_ACTIVE_NUM || + rsp_field->inactive_rgn_cnt > MAX_INACTIVE_NUM || + rsp_field->hpb_op == HPB_RSP_NONE || + (rsp_field->hpb_op == HPB_RSP_REQ_REGION_UPDATE && + !rsp_field->active_rgn_cnt && !rsp_field->inactive_rgn_cnt)) + return false; + + if (!ufshpb_is_general_lun(rsp_field->lun)) { + dev_warn(hba->dev, "ufshpb: lun(%d) not supported\n", + lrbp->lun); + return false; + } + + return true; +} + +static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_req *map_req; + struct request *req; + struct bio *bio; + int retries = HPB_MAP_REQ_RETRIES; + + map_req = kmem_cache_alloc(hpb->map_req_cache, GFP_KERNEL); + if (!map_req) + return NULL; + +retry: + req = blk_get_request(hpb->sdev_ufs_lu->request_queue, + REQ_OP_DRV_IN, BLK_MQ_REQ_NOWAIT); + + if ((PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) { + usleep_range(3000, 3100); + goto retry; + } + + if (IS_ERR(req)) + goto free_map_req; + + bio = bio_alloc(GFP_KERNEL, hpb->pages_per_srgn); + if (!bio) { + blk_put_request(req); + goto free_map_req; + } + + map_req->hpb = hpb; + map_req->req = req; + map_req->bio = bio; + + map_req->rgn_idx = srgn->rgn_idx; + map_req->srgn_idx = srgn->srgn_idx; + map_req->mctx = srgn->mctx; + + return map_req; + +free_map_req: + kmem_cache_free(hpb->map_req_cache, map_req); + return NULL; +} + +static void ufshpb_put_map_req(struct ufshpb_lu *hpb, + struct ufshpb_req *map_req) +{ + bio_put(map_req->bio); + blk_put_request(map_req->req); + kmem_cache_free(hpb->map_req_cache, map_req); +} + +static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + u32 num_entries = hpb->entries_per_srgn; + + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + return -1; + } + + if (unlikely(srgn->is_last)) + num_entries = hpb->last_srgn_entries; + + bitmap_zero(srgn->mctx->ppn_dirty, num_entries); + return 0; +} + +static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + list_del_init(&rgn->list_inact_rgn); + + if (list_empty(&srgn->list_act_srgn)) + list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn); +} + +static void ufshpb_update_inactive_info(struct ufshpb_lu *hpb, int rgn_idx) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int srgn_idx; + + rgn = hpb->rgn_tbl + rgn_idx; + + for_each_sub_region(rgn, srgn_idx, srgn) + list_del_init(&srgn->list_act_srgn); + + if (list_empty(&rgn->list_inact_rgn)) + list_add_tail(&rgn->list_inact_rgn, &hpb->lh_inact_rgn); +} + +static void ufshpb_activate_subregion(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_region *rgn; + + /* + * If there is no mctx in subregion + * after I/O progress for HPB_READ_BUFFER, the region to which the + * subregion belongs was evicted. + * Make sure the region must not evict in I/O progress + */ + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + srgn->srgn_state = HPB_SRGN_INVALID; + return; + } + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + + if (unlikely(rgn->rgn_state == HPB_RGN_INACTIVE)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "region %d subregion %d evicted\n", + srgn->rgn_idx, srgn->srgn_idx); + srgn->srgn_state = HPB_SRGN_INVALID; + return; + } + srgn->srgn_state = HPB_SRGN_VALID; +} + +static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data; + struct ufshpb_lu *hpb = map_req->hpb; + struct ufshpb_subregion *srgn; + unsigned long flags; + + srgn = hpb->rgn_tbl[map_req->rgn_idx].srgn_tbl + + map_req->srgn_idx; + + ufshpb_clear_dirty_bitmap(hpb, srgn); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_activate_subregion(hpb, srgn); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + ufshpb_put_map_req(map_req->hpb, map_req); +} + +static void ufshpb_set_read_buf_cmd(unsigned char *cdb, int rgn_idx, + int srgn_idx, int srgn_mem_size) +{ + cdb[0] = UFSHPB_READ_BUFFER; + cdb[1] = UFSHPB_READ_BUFFER_ID; + + put_unaligned_be16(rgn_idx, &cdb[2]); + put_unaligned_be16(srgn_idx, &cdb[4]); + put_unaligned_be24(srgn_mem_size, &cdb[6]); + + cdb[9] = 0x00; +} + +static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, + struct ufshpb_req *map_req, bool last) +{ + struct request_queue *q; + struct request *req; + struct scsi_request *rq; + int mem_size = hpb->srgn_mem_size; + int ret = 0; + int i; + + q = hpb->sdev_ufs_lu->request_queue; + for (i = 0; i < hpb->pages_per_srgn; i++) { + ret = bio_add_pc_page(q, map_req->bio, map_req->mctx->m_page[i], + PAGE_SIZE, 0); + if (ret != PAGE_SIZE) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "bio_add_pc_page fail %d - %d\n", + map_req->rgn_idx, map_req->srgn_idx); + return ret; + } + } + + req = map_req->req; + + blk_rq_append_bio(req, map_req->bio); + + req->end_io_data = map_req; + + rq = scsi_req(req); + + if (unlikely(last)) + mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE; + + ufshpb_set_read_buf_cmd(rq->cmd, map_req->rgn_idx, + map_req->srgn_idx, mem_size); + rq->cmd_len = HPB_READ_BUFFER_CMD_LENGTH; + + blk_execute_rq_nowait(NULL, req, 1, ufshpb_map_req_compl_fn); + + hpb->stats.map_req_cnt++; + return 0; +} + +static struct ufshpb_map_ctx *ufshpb_get_map_ctx(struct ufshpb_lu *hpb, + bool last) +{ + struct ufshpb_map_ctx *mctx; + u32 num_entries = hpb->entries_per_srgn; + int i, j; + + mctx = mempool_alloc(ufshpb_mctx_pool, GFP_KERNEL); + if (!mctx) + return NULL; + + mctx->m_page = kmem_cache_alloc(hpb->m_page_cache, GFP_KERNEL); + if (!mctx->m_page) + goto release_mctx; + + if (unlikely(last)) + num_entries = hpb->last_srgn_entries; + + mctx->ppn_dirty = bitmap_zalloc(num_entries, GFP_KERNEL); + if (!mctx->ppn_dirty) + goto release_m_page; + + for (i = 0; i < hpb->pages_per_srgn; i++) { + mctx->m_page[i] = mempool_alloc(ufshpb_page_pool, GFP_KERNEL); + if (!mctx->m_page[i]) { + for (j = 0; j < i; j++) + mempool_free(mctx->m_page[j], ufshpb_page_pool); + goto release_ppn_dirty; + } + clear_page(page_address(mctx->m_page[i])); + } + + return mctx; + +release_ppn_dirty: + bitmap_free(mctx->ppn_dirty); +release_m_page: + kmem_cache_free(hpb->m_page_cache, mctx->m_page); +release_mctx: + mempool_free(mctx, ufshpb_mctx_pool); + return NULL; +} + +static void ufshpb_put_map_ctx(struct ufshpb_lu *hpb, + struct ufshpb_map_ctx *mctx) +{ + int i; + + for (i = 0; i < hpb->pages_per_srgn; i++) + mempool_free(mctx->m_page[i], ufshpb_page_pool); + + bitmap_free(mctx->ppn_dirty); + kmem_cache_free(hpb->m_page_cache, mctx->m_page); + mempool_free(mctx, ufshpb_mctx_pool); +} + +static int ufshpb_check_srgns_issue_state(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct ufshpb_subregion *srgn; + int srgn_idx; + + for_each_sub_region(rgn, srgn_idx, srgn) + if (srgn->srgn_state == HPB_SRGN_ISSUED) + return -EPERM; + + return 0; +} + +static void ufshpb_add_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + rgn->rgn_state = HPB_RGN_ACTIVE; + list_add_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); + atomic_inc(&lru_info->active_cnt); +} + +static void ufshpb_hit_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + list_move_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); +} + +static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb) +{ + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn, *victim_rgn = NULL; + + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) { + if (!rgn) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "%s: no region allocated\n", + __func__); + return NULL; + } + if (ufshpb_check_srgns_issue_state(hpb, rgn)) + continue; + + victim_rgn = rgn; + break; + } + + return victim_rgn; +} + +static void ufshpb_cleanup_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + list_del_init(&rgn->list_lru_rgn); + rgn->rgn_state = HPB_RGN_INACTIVE; + atomic_dec(&lru_info->active_cnt); +} + +static void ufshpb_purge_active_subregion(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + if (srgn->srgn_state != HPB_SRGN_UNUSED) { + ufshpb_put_map_ctx(hpb, srgn->mctx); + srgn->srgn_state = HPB_SRGN_UNUSED; + srgn->mctx = NULL; + } +} + +static void __ufshpb_evict_region(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct victim_select_info *lru_info; + struct ufshpb_subregion *srgn; + int srgn_idx; + + lru_info = &hpb->lru_info; + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", rgn->rgn_idx); + + ufshpb_cleanup_lru_info(lru_info, rgn); + + for_each_sub_region(rgn, srgn_idx, srgn) + ufshpb_purge_active_subregion(hpb, srgn); +} + +static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (rgn->rgn_state == HPB_RGN_PINNED) { + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "pinned region cannot drop-out. region %d\n", + rgn->rgn_idx); + goto out; + } + if (!list_empty(&rgn->list_lru_rgn)) { + if (ufshpb_check_srgns_issue_state(hpb, rgn)) { + ret = -EBUSY; + goto out; + } + + __ufshpb_evict_region(hpb, rgn); + } +out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return ret; +} + +static int ufshpb_issue_map_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_req *map_req; + unsigned long flags; + int ret; + int err = -EAGAIN; + bool alloc_required = false; + enum HPB_SRGN_STATE state = HPB_SRGN_INVALID; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT\n", __func__); + goto unlock_out; + } + + if ((rgn->rgn_state == HPB_RGN_INACTIVE) && + (srgn->srgn_state == HPB_SRGN_INVALID)) { + err = 0; + goto unlock_out; + } + + if (srgn->srgn_state == HPB_SRGN_UNUSED) + alloc_required = true; + + /* + * If the subregion is already ISSUED state, + * a specific event (e.g., GC or wear-leveling, etc.) occurs in + * the device and HPB response for map loading is received. + * In this case, after finishing the HPB_READ_BUFFER, + * the next HPB_READ_BUFFER is performed again to obtain the latest + * map data. + */ + if (srgn->srgn_state == HPB_SRGN_ISSUED) + goto unlock_out; + + srgn->srgn_state = HPB_SRGN_ISSUED; + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + if (alloc_required) { + srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last); + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "get map_ctx failed. region %d - %d\n", + rgn->rgn_idx, srgn->srgn_idx); + state = HPB_SRGN_UNUSED; + goto change_srgn_state; + } + } + + map_req = ufshpb_get_map_req(hpb, srgn); + if (!map_req) + goto change_srgn_state; + + + ret = ufshpb_execute_map_req(hpb, map_req, srgn->is_last); + if (ret) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "%s: issue map_req failed: %d, region %d - %d\n", + __func__, ret, srgn->rgn_idx, srgn->srgn_idx); + goto free_map_req; + } + return 0; + +free_map_req: + ufshpb_put_map_req(hpb, map_req); +change_srgn_state: + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + srgn->srgn_state = state; +unlock_out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return err; +} + +static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) +{ + struct ufshpb_region *victim_rgn; + struct victim_select_info *lru_info = &hpb->lru_info; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + /* + * If region belongs to lru_list, just move the region + * to the front of lru list because the state of the region + * is already active-state. + */ + if (!list_empty(&rgn->list_lru_rgn)) { + ufshpb_hit_lru_info(lru_info, rgn); + goto out; + } + + if (rgn->rgn_state == HPB_RGN_INACTIVE) { + if (atomic_read(&lru_info->active_cnt) == + lru_info->max_lru_active_cnt) { + /* + * If the maximum number of active regions + * is exceeded, evict the least recently used region. + * This case may occur when the device responds + * to the eviction information late. + * It is okay to evict the least recently used region, + * because the device could detect this region + * by not issuing HPB_READ + */ + victim_rgn = ufshpb_victim_lru_info(hpb); + if (!victim_rgn) { + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "cannot get victim region error\n"); + ret = -ENOMEM; + goto out; + } + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "LRU full (%d), choose victim %d\n", + atomic_read(&lru_info->active_cnt), + victim_rgn->rgn_idx); + __ufshpb_evict_region(hpb, victim_rgn); + } + + /* + * When a region is added to lru_info list_head, + * it is guaranteed that the subregion has been + * assigned all mctx. If failed, try to receive mctx again + * without being added to lru_info list_head + */ + ufshpb_add_lru_info(lru_info, rgn); + } +out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return ret; +} + +static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, + struct utp_hpb_rsp *rsp_field) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int i, rgn_i, srgn_i; + + BUILD_BUG_ON(sizeof(struct ufshpb_active_field) != HPB_ACT_FIELD_SIZE); + /* + * If the active region and the inactive region are the same, + * we will inactivate this region. + * The device could check this (region inactivated) and + * will response the proper active region information + */ + for (i = 0; i < rsp_field->active_rgn_cnt; i++) { + rgn_i = + be16_to_cpu(rsp_field->hpb_active_field[i].active_rgn); + srgn_i = + be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn); + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "activate(%d) region %d - %d\n", i, rgn_i, srgn_i); + + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_active_info(hpb, rgn_i, srgn_i); + spin_unlock(&hpb->rsp_list_lock); + + rgn = hpb->rgn_tbl + rgn_i; + srgn = rgn->srgn_tbl + srgn_i; + + /* blocking HPB_READ */ + spin_lock(&hpb->rgn_state_lock); + if (srgn->srgn_state == HPB_SRGN_VALID) + srgn->srgn_state = HPB_SRGN_INVALID; + spin_unlock(&hpb->rgn_state_lock); + hpb->stats.rb_active_cnt++; + } + + for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) { + rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]); + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "inactivate(%d) region %d\n", i, rgn_i); + + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_inactive_info(hpb, rgn_i); + spin_unlock(&hpb->rsp_list_lock); + + rgn = hpb->rgn_tbl + rgn_i; + + spin_lock(&hpb->rgn_state_lock); + if (rgn->rgn_state != HPB_RGN_INACTIVE) { + for (srgn_i = 0; srgn_i < rgn->srgn_cnt; srgn_i++) { + srgn = rgn->srgn_tbl + srgn_i; + if (srgn->srgn_state == HPB_SRGN_VALID) + srgn->srgn_state = HPB_SRGN_INVALID; + } + } + spin_unlock(&hpb->rgn_state_lock); + + hpb->stats.rb_inactive_cnt++; + } + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n", + rsp_field->active_rgn_cnt, rsp_field->inactive_rgn_cnt); + + if (ufshpb_get_state(hpb) == HPB_PRESENT) + queue_work(ufshpb_wq, &hpb->map_work); +} + +/* + * This function will parse recommended active subregion information in sense + * data field of response UPIU with SAM_STAT_GOOD state. + */ +void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(lrbp->cmd->device); + struct utp_hpb_rsp *rsp_field = &lrbp->ucd_rsp_ptr->hr; + int data_seg_len; + + if (unlikely(lrbp->lun != rsp_field->lun)) { + struct scsi_device *sdev; + bool found = false; + + __shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + + if (!hpb) + continue; + + if (rsp_field->lun == hpb->lun) { + found = true; + break; + } + } + + if (!found) + return; + } + + if (!hpb) + return; + + if (ufshpb_get_state(hpb) == HPB_INIT) + return; + + if ((ufshpb_get_state(hpb) != HPB_PRESENT) && + (ufshpb_get_state(hpb) != HPB_SUSPEND)) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT/SUSPEND\n", + __func__); + return; + } + + data_seg_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) + & MASK_RSP_UPIU_DATA_SEG_LEN; + + /* To flush remained rsp_list, we queue the map_work task */ + if (!data_seg_len) { + if (!ufshpb_is_general_lun(hpb->lun)) + return; + + ufshpb_kick_map_work(hpb); + return; + } + + BUILD_BUG_ON(sizeof(struct utp_hpb_rsp) != UTP_HPB_RSP_SIZE); + + if (!ufshpb_is_hpb_rsp_valid(hba, lrbp, rsp_field)) + return; + + hpb->stats.rb_noti_cnt++; + + switch (rsp_field->hpb_op) { + case HPB_RSP_REQ_REGION_UPDATE: + if (data_seg_len != DEV_DATA_SEG_LEN) + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "%s: data seg length is not same.\n", + __func__); + ufshpb_rsp_req_region_update(hpb, rsp_field); + break; + case HPB_RSP_DEV_RESET: + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "UFS device lost HPB information during PM.\n"); + break; + default: + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "hpb_op is not available: %d\n", + rsp_field->hpb_op); + break; + } +} + +static void ufshpb_add_active_list(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + if (!list_empty(&rgn->list_inact_rgn)) + return; + + if (!list_empty(&srgn->list_act_srgn)) { + list_move(&srgn->list_act_srgn, &hpb->lh_act_srgn); + return; + } + + list_add(&srgn->list_act_srgn, &hpb->lh_act_srgn); +} + +static void ufshpb_add_pending_evict_list(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct list_head *pending_list) +{ + struct ufshpb_subregion *srgn; + int srgn_idx; + + if (!list_empty(&rgn->list_inact_rgn)) + return; + + for_each_sub_region(rgn, srgn_idx, srgn) + if (!list_empty(&srgn->list_act_srgn)) + return; + + list_add_tail(&rgn->list_inact_rgn, pending_list); +} + +static void ufshpb_run_active_subregion_list(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + while ((srgn = list_first_entry_or_null(&hpb->lh_act_srgn, + struct ufshpb_subregion, + list_act_srgn))) { + if (ufshpb_get_state(hpb) == HPB_SUSPEND) + break; + + list_del_init(&srgn->list_act_srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + ret = ufshpb_add_region(hpb, rgn); + if (ret) + goto active_failed; + + ret = ufshpb_issue_map_req(hpb, rgn, srgn); + if (ret) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "issue map_req failed. ret %d, region %d - %d\n", + ret, rgn->rgn_idx, srgn->srgn_idx); + goto active_failed; + } + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + } + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + return; + +active_failed: + dev_err(&hpb->sdev_ufs_lu->sdev_dev, "failed to activate region %d - %d, will retry\n", + rgn->rgn_idx, srgn->srgn_idx); + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_add_active_list(hpb, rgn, srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_run_inactive_region_list(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn; + unsigned long flags; + int ret; + LIST_HEAD(pending_list); + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + while ((rgn = list_first_entry_or_null(&hpb->lh_inact_rgn, + struct ufshpb_region, + list_inact_rgn))) { + if (ufshpb_get_state(hpb) == HPB_SUSPEND) + break; + + list_del_init(&rgn->list_inact_rgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + ret = ufshpb_evict_region(hpb, rgn); + if (ret) { + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_add_pending_evict_list(hpb, rgn, &pending_list); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + } + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + } + + list_splice(&pending_list, &hpb->lh_inact_rgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_map_work_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, map_work); + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT\n", __func__); + return; + } + + ufshpb_run_inactive_region_list(hpb); + ufshpb_run_active_subregion_list(hpb); +} + +/* + * this function doesn't need to hold lock due to be called in init. + * (rgn_state_lock, rsp_list_lock, etc..) + */ +static int ufshpb_init_pinned_active_region(struct ufs_hba *hba, + struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct ufshpb_subregion *srgn; + int srgn_idx, i; + int err = 0; + + for_each_sub_region(rgn, srgn_idx, srgn) { + srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last); + srgn->srgn_state = HPB_SRGN_INVALID; + if (!srgn->mctx) { + err = -ENOMEM; + dev_err(hba->dev, + "alloc mctx for pinned region failed\n"); + goto release; + } + + list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn); + } + + rgn->rgn_state = HPB_RGN_PINNED; + return 0; + +release: + for (i = 0; i < srgn_idx; i++) { + srgn = rgn->srgn_tbl + i; + ufshpb_put_map_ctx(hpb, srgn->mctx); + } + return err; +} + static void ufshpb_init_subregion_tbl(struct ufshpb_lu *hpb, struct ufshpb_region *rgn, bool last) { int srgn_idx; struct ufshpb_subregion *srgn; - for (srgn_idx = 0; srgn_idx < rgn->srgn_cnt; srgn_idx++) { - srgn = rgn->srgn_tbl + srgn_idx; + for_each_sub_region(rgn, srgn_idx, srgn) { + INIT_LIST_HEAD(&srgn->list_act_srgn); srgn->rgn_idx = rgn->rgn_idx; srgn->srgn_idx = srgn_idx; @@ -78,6 +963,8 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba, hpb->lu_pinned_end = hpb_lu_info->num_pinned ? (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1) : PINNED_NOT_SET; + hpb->lru_info.max_lru_active_cnt = + hpb_lu_info->max_active_rgns - hpb_lu_info->num_pinned; rgn_mem_size = (1ULL << hpb_dev_info->rgn_size) * HPB_RGN_SIZE_UNIT * HPB_ENTRY_SIZE; @@ -129,6 +1016,9 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) rgn = rgn_table + rgn_idx; rgn->rgn_idx = rgn_idx; + INIT_LIST_HEAD(&rgn->list_inact_rgn); + INIT_LIST_HEAD(&rgn->list_lru_rgn); + if (rgn_idx == hpb->rgns_per_lu - 1) { srgn_cnt = ((hpb->srgns_per_lu - 1) % hpb->srgns_per_rgn) + 1; @@ -140,7 +1030,13 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) goto release_srgn_table; ufshpb_init_subregion_tbl(hpb, rgn, last_srgn); - rgn->rgn_state = HPB_RGN_INACTIVE; + if (ufshpb_is_pinned_region(hpb, rgn_idx)) { + ret = ufshpb_init_pinned_active_region(hba, hpb, rgn); + if (ret) + goto release_srgn_table; + } else { + rgn->rgn_state = HPB_RGN_INACTIVE; + } } return 0; @@ -157,13 +1053,13 @@ static void ufshpb_destroy_subregion_tbl(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) { int srgn_idx; + struct ufshpb_subregion *srgn; - for (srgn_idx = 0; srgn_idx < rgn->srgn_cnt; srgn_idx++) { - struct ufshpb_subregion *srgn; - - srgn = rgn->srgn_tbl + srgn_idx; - srgn->srgn_state = HPB_SRGN_UNUSED; - } + for_each_sub_region(rgn, srgn_idx, srgn) + if (srgn->srgn_state != HPB_SRGN_UNUSED) { + srgn->srgn_state = HPB_SRGN_UNUSED; + ufshpb_put_map_ctx(hpb, srgn->mctx); + } } static void ufshpb_destroy_region_tbl(struct ufshpb_lu *hpb) @@ -238,11 +1134,47 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) { int ret; + spin_lock_init(&hpb->rgn_state_lock); + spin_lock_init(&hpb->rsp_list_lock); + + INIT_LIST_HEAD(&hpb->lru_info.lh_lru_rgn); + INIT_LIST_HEAD(&hpb->lh_act_srgn); + INIT_LIST_HEAD(&hpb->lh_inact_rgn); + INIT_LIST_HEAD(&hpb->list_hpb_lu); + + INIT_WORK(&hpb->map_work, ufshpb_map_work_handler); + + hpb->map_req_cache = kmem_cache_create("ufshpb_req_cache", + sizeof(struct ufshpb_req), 0, 0, NULL); + if (!hpb->map_req_cache) { + dev_err(hba->dev, "ufshpb(%d) ufshpb_req_cache create fail", + hpb->lun); + return -ENOMEM; + } + + hpb->m_page_cache = kmem_cache_create("ufshpb_m_page_cache", + sizeof(struct page *) * hpb->pages_per_srgn, + 0, 0, NULL); + if (!hpb->m_page_cache) { + dev_err(hba->dev, "ufshpb(%d) ufshpb_m_page_cache create fail", + hpb->lun); + ret = -ENOMEM; + goto release_req_cache; + } + ret = ufshpb_alloc_region_tbl(hba, hpb); + if (ret) + goto release_m_page_cache; ufshpb_stat_init(hpb); return 0; + +release_m_page_cache: + kmem_cache_destroy(hpb->m_page_cache); +release_req_cache: + kmem_cache_destroy(hpb->map_req_cache); + return ret; } static struct ufshpb_lu * @@ -274,6 +1206,33 @@ release_hpb: return NULL; } +static void ufshpb_discard_rsp_lists(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn, *next_rgn; + struct ufshpb_subregion *srgn, *next_srgn; + unsigned long flags; + + /* + * If the device reset occurred, the remaining HPB region information + * may be stale. Therefore, by discarding the lists of HPB response + * that remained after reset, we prevent unnecessary work. + */ + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + list_for_each_entry_safe(rgn, next_rgn, &hpb->lh_inact_rgn, + list_inact_rgn) + list_del_init(&rgn->list_inact_rgn); + + list_for_each_entry_safe(srgn, next_srgn, &hpb->lh_act_srgn, + list_act_srgn) + list_del_init(&srgn->list_act_srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb) +{ + cancel_work_sync(&hpb->map_work); +} + static bool ufshpb_check_hpb_reset_query(struct ufs_hba *hba) { int err = 0; @@ -317,7 +1276,7 @@ void ufshpb_reset(struct ufs_hba *hba) struct scsi_device *sdev; shost_for_each_device(sdev, hba->host) { - hpb = sdev->hostdata; + hpb = ufshpb_get_hpb_data(sdev); if (!hpb) continue; @@ -334,13 +1293,15 @@ void ufshpb_reset_host(struct ufs_hba *hba) struct scsi_device *sdev; shost_for_each_device(sdev, hba->host) { - hpb = sdev->hostdata; + hpb = ufshpb_get_hpb_data(sdev); if (!hpb) continue; if (ufshpb_get_state(hpb) != HPB_PRESENT) continue; ufshpb_set_state(hpb, HPB_RESET); + ufshpb_cancel_jobs(hpb); + ufshpb_discard_rsp_lists(hpb); } } @@ -350,13 +1311,14 @@ void ufshpb_suspend(struct ufs_hba *hba) struct scsi_device *sdev; shost_for_each_device(sdev, hba->host) { - hpb = sdev->hostdata; + hpb = ufshpb_get_hpb_data(sdev); if (!hpb) continue; if (ufshpb_get_state(hpb) != HPB_PRESENT) continue; ufshpb_set_state(hpb, HPB_SUSPEND); + ufshpb_cancel_jobs(hpb); } } @@ -366,7 +1328,7 @@ void ufshpb_resume(struct ufs_hba *hba) struct scsi_device *sdev; shost_for_each_device(sdev, hba->host) { - hpb = sdev->hostdata; + hpb = ufshpb_get_hpb_data(sdev); if (!hpb) continue; @@ -374,6 +1336,7 @@ void ufshpb_resume(struct ufs_hba *hba) (ufshpb_get_state(hpb) != HPB_SUSPEND)) continue; ufshpb_set_state(hpb, HPB_PRESENT); + ufshpb_kick_map_work(hpb); } } @@ -426,7 +1389,7 @@ static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun, void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) { - struct ufshpb_lu *hpb = sdev->hostdata; + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); if (!hpb) return; @@ -436,8 +1399,13 @@ void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) sdev = hpb->sdev_ufs_lu; sdev->hostdata = NULL; + ufshpb_cancel_jobs(hpb); + ufshpb_destroy_region_tbl(hpb); + kmem_cache_destroy(hpb->map_req_cache); + kmem_cache_destroy(hpb->m_page_cache); + list_del_init(&hpb->list_hpb_lu); kfree(hpb); @@ -445,24 +1413,41 @@ void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba) { + int pool_size; struct ufshpb_lu *hpb; struct scsi_device *sdev; bool init_success; + if (tot_active_srgn_pages == 0) { + ufshpb_remove(hba); + return; + } + init_success = !ufshpb_check_hpb_reset_query(hba); + pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE; + if (pool_size > tot_active_srgn_pages) { + mempool_resize(ufshpb_mctx_pool, tot_active_srgn_pages); + mempool_resize(ufshpb_page_pool, tot_active_srgn_pages); + } + shost_for_each_device(sdev, hba->host) { - hpb = sdev->hostdata; + hpb = ufshpb_get_hpb_data(sdev); if (!hpb) continue; if (init_success) { ufshpb_set_state(hpb, HPB_PRESENT); + if ((hpb->lu_pinned_end - hpb->lu_pinned_start) > 0) + queue_work(ufshpb_wq, &hpb->map_work); } else { dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun); ufshpb_destroy_lu(hba, sdev); } } + + if (!init_success) + ufshpb_remove(hba); } void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) @@ -484,6 +1469,9 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) if (!hpb) goto out; + tot_active_srgn_pages += hpb_lu_info.max_active_rgns * + hpb->srgns_per_rgn * hpb->pages_per_srgn; + hpb->sdev_ufs_lu = sdev; sdev->hostdata = hpb; @@ -493,6 +1481,57 @@ out: ufshpb_hpb_lu_prepared(hba); } +static int ufshpb_init_mem_wq(struct ufs_hba *hba) +{ + int ret; + unsigned int pool_size; + + ufshpb_mctx_cache = kmem_cache_create("ufshpb_mctx_cache", + sizeof(struct ufshpb_map_ctx), + 0, 0, NULL); + if (!ufshpb_mctx_cache) { + dev_err(hba->dev, "ufshpb: cannot init mctx cache\n"); + return -ENOMEM; + } + + pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE; + dev_info(hba->dev, "%s:%d ufshpb_host_map_kbytes %u pool_size %u\n", + __func__, __LINE__, ufshpb_host_map_kbytes, pool_size); + + ufshpb_mctx_pool = mempool_create_slab_pool(pool_size, + ufshpb_mctx_cache); + if (!ufshpb_mctx_pool) { + dev_err(hba->dev, "ufshpb: cannot init mctx pool\n"); + ret = -ENOMEM; + goto release_mctx_cache; + } + + ufshpb_page_pool = mempool_create_page_pool(pool_size, 0); + if (!ufshpb_page_pool) { + dev_err(hba->dev, "ufshpb: cannot init page pool\n"); + ret = -ENOMEM; + goto release_mctx_pool; + } + + ufshpb_wq = alloc_workqueue("ufshpb-wq", + WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + if (!ufshpb_wq) { + dev_err(hba->dev, "ufshpb: alloc workqueue failed\n"); + ret = -ENOMEM; + goto release_page_pool; + } + + return 0; + +release_page_pool: + mempool_destroy(ufshpb_page_pool); +release_mctx_pool: + mempool_destroy(ufshpb_mctx_pool); +release_mctx_cache: + kmem_cache_destroy(ufshpb_mctx_cache); + return ret; +} + void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) { struct ufshpb_dev_info *hpb_info = &hba->ufshpb_dev; @@ -557,7 +1596,13 @@ void ufshpb_init(struct ufs_hba *hba) if (!ufshpb_is_allowed(hba) || !hba->dev_info.hpb_enabled) return; + if (ufshpb_init_mem_wq(hba)) { + hpb_dev_info->hpb_disabled = true; + return; + } + atomic_set(&hpb_dev_info->slave_conf_cnt, hpb_dev_info->num_lu); + tot_active_srgn_pages = 0; /* issue HPB reset query */ for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) { ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG, @@ -566,3 +1611,16 @@ void ufshpb_init(struct ufs_hba *hba) break; } } + +void ufshpb_remove(struct ufs_hba *hba) +{ + mempool_destroy(ufshpb_page_pool); + mempool_destroy(ufshpb_mctx_pool); + kmem_cache_destroy(ufshpb_mctx_cache); + + destroy_workqueue(ufshpb_wq); +} + +module_param(ufshpb_host_map_kbytes, uint, 0644); +MODULE_PARM_DESC(ufshpb_host_map_kbytes, + "ufshpb host mapping memory kilo-bytes for ufshpb memory-pool"); diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index fa311ed3fa94..dcc0ca3b8158 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -40,6 +40,7 @@ #define LU_ENABLED_HPB_FUNC 0x02 #define HPB_RESET_REQ_RETRIES 10 +#define HPB_MAP_REQ_RETRIES 5 #define HPB_SUPPORT_VERSION 0x100 @@ -84,11 +85,19 @@ struct ufshpb_lu_info { int max_active_rgns; }; +struct ufshpb_map_ctx { + struct page **m_page; + unsigned long *ppn_dirty; +}; + struct ufshpb_subregion { + struct ufshpb_map_ctx *mctx; enum HPB_SRGN_STATE srgn_state; int rgn_idx; int srgn_idx; bool is_last; + /* below information is used by rsp_list */ + struct list_head list_act_srgn; }; struct ufshpb_region { @@ -96,6 +105,43 @@ struct ufshpb_region { enum HPB_RGN_STATE rgn_state; int rgn_idx; int srgn_cnt; + + /* below information is used by rsp_list */ + struct list_head list_inact_rgn; + + /* below information is used by lru */ + struct list_head list_lru_rgn; +}; + +#define for_each_sub_region(rgn, i, srgn) \ + for ((i) = 0; \ + ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \ + (i)++) + +/** + * struct ufshpb_req - UFSHPB READ BUFFER (for caching map) request structure + * @req: block layer request for READ BUFFER + * @bio: bio for holding map page + * @hpb: ufshpb_lu structure that related to the L2P map + * @mctx: L2P map information + * @rgn_idx: target region index + * @srgn_idx: target sub-region index + * @lun: target logical unit number + */ +struct ufshpb_req { + struct request *req; + struct bio *bio; + struct ufshpb_lu *hpb; + struct ufshpb_map_ctx *mctx; + + unsigned int rgn_idx; + unsigned int srgn_idx; +}; + +struct victim_select_info { + struct list_head lh_lru_rgn; /* LRU list of regions */ + int max_lru_active_cnt; /* supported hpb #region - pinned #region */ + atomic_t active_cnt; }; struct ufshpb_stats { @@ -110,10 +156,22 @@ struct ufshpb_stats { struct ufshpb_lu { int lun; struct scsi_device *sdev_ufs_lu; + + spinlock_t rgn_state_lock; /* for protect rgn/srgn state */ struct ufshpb_region *rgn_tbl; atomic_t hpb_state; + spinlock_t rsp_list_lock; + struct list_head lh_act_srgn; /* hold rsp_list_lock */ + struct list_head lh_inact_rgn; /* hold rsp_list_lock */ + + /* cached L2P map management worker */ + struct work_struct map_work; + + /* for selecting victim */ + struct victim_select_info lru_info; + /* pinned region information */ u32 lu_pinned_start; u32 lu_pinned_end; @@ -133,6 +191,9 @@ struct ufshpb_lu { struct ufshpb_stats stats; + struct kmem_cache *map_req_cache; + struct kmem_cache *m_page_cache; + struct list_head list_hpb_lu; }; @@ -140,6 +201,7 @@ struct ufs_hba; struct ufshcd_lrb; #ifndef CONFIG_SCSI_UFS_HPB +static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} static void ufshpb_resume(struct ufs_hba *hba) {} static void ufshpb_suspend(struct ufs_hba *hba) {} static void ufshpb_reset(struct ufs_hba *hba) {} @@ -147,10 +209,12 @@ static void ufshpb_reset_host(struct ufs_hba *hba) {} static void ufshpb_init(struct ufs_hba *hba) {} static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} +static void ufshpb_remove(struct ufs_hba *hba) {} static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; } static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {} static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {} #else +void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); void ufshpb_resume(struct ufs_hba *hba); void ufshpb_suspend(struct ufs_hba *hba); void ufshpb_reset(struct ufs_hba *hba); @@ -158,6 +222,7 @@ void ufshpb_reset_host(struct ufs_hba *hba); void ufshpb_init(struct ufs_hba *hba); void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev); void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev); +void ufshpb_remove(struct ufs_hba *hba); bool ufshpb_is_allowed(struct ufs_hba *hba); void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf); void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf); -- cgit v1.2.3-70-g09d2 From 2fff76f87542fae2366448ec8b01dbff415a7d22 Mon Sep 17 00:00:00 2001 From: Daejun Park Date: Mon, 12 Jul 2021 17:59:36 +0900 Subject: scsi: ufs: ufshpb: Prepare HPB read for cached sub-region If the logical address of a read I/O belongs to an active sub-region, the HPB driver modifies the read I/O command to an HPB read. The driver modifies the UFS UPIU instead of modifying the existing SCSI command. In HPB version 1.0, the maximum read I/O size that can be converted to HPB read is 4KB. The dirty map of the active sub-region prevents an incorrect HPB read that has stale physical page number which is updated by previous write I/O. [mkp: REQ_OP_DRV_* and blk_rq_is_passthrough()] Link: https://lore.kernel.org/r/20210712085936epcms2p4b0ec5c8cecdeea6cc043d684363842b6@epcms2p4 Tested-by: Bean Huo Tested-by: Can Guo Tested-by: Stanley Chu Reviewed-by: Greg Kroah-Hartman Reviewed-by: Can Guo Reviewed-by: Bart Van Assche Reviewed-by: Bean Huo Reviewed-by: Stanley Chu Acked-by: Avri Altman Signed-off-by: Daejun Park Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 2 + drivers/scsi/ufs/ufshpb.c | 259 +++++++++++++++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshpb.h | 2 + 3 files changed, 260 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c708e2b5b84d..a5060f817125 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2788,6 +2788,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->req_abort_skip = false; + ufshpb_prep(hba, lrbp); + ufshcd_comp_scsi_upiu(hba, lrbp); err = ufshcd_map_sg(hba, lrbp); diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 3a55f0543fe5..3d2b8ca8bdb0 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -46,6 +46,29 @@ static void ufshpb_set_state(struct ufshpb_lu *hpb, int state) atomic_set(&hpb->hpb_state, state); } +static int ufshpb_is_valid_srgn(struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + return rgn->rgn_state != HPB_RGN_INACTIVE && + srgn->srgn_state == HPB_SRGN_VALID; +} + +static bool ufshpb_is_read_cmd(struct scsi_cmnd *cmd) +{ + return req_op(cmd->request) == REQ_OP_READ; +} + +static bool ufshpb_is_write_or_discard(struct scsi_cmnd *cmd) +{ + return op_is_write(req_op(cmd->request)) || + op_is_discard(req_op(cmd->request)); +} + +static bool ufshpb_is_supported_chunk(int transfer_len) +{ + return transfer_len <= HPB_MULTI_CHUNK_HIGH; +} + static bool ufshpb_is_general_lun(int lun) { return lun < UFS_UPIU_MAX_UNIT_NUM_ID; @@ -80,8 +103,8 @@ static void ufshpb_kick_map_work(struct ufshpb_lu *hpb) } static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba, - struct ufshcd_lrb *lrbp, - struct utp_hpb_rsp *rsp_field) + struct ufshcd_lrb *lrbp, + struct utp_hpb_rsp *rsp_field) { /* Check HPB_UPDATE_ALERT */ if (!(lrbp->ucd_rsp_ptr->header.dword_2 & @@ -107,6 +130,236 @@ static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba, return true; } +static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx, int srgn_offset, int cnt) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int set_bit_len; + int bitmap_len; + +next_srgn: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (likely(!srgn->is_last)) + bitmap_len = hpb->entries_per_srgn; + else + bitmap_len = hpb->last_srgn_entries; + + if ((srgn_offset + cnt) > bitmap_len) + set_bit_len = bitmap_len - srgn_offset; + else + set_bit_len = cnt; + + if (rgn->rgn_state != HPB_RGN_INACTIVE && + srgn->srgn_state == HPB_SRGN_VALID) + bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); + + srgn_offset = 0; + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + + cnt -= set_bit_len; + if (cnt > 0) + goto next_srgn; +} + +static bool ufshpb_test_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx, int srgn_offset, int cnt) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int bitmap_len; + int bit_len; + +next_srgn: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (likely(!srgn->is_last)) + bitmap_len = hpb->entries_per_srgn; + else + bitmap_len = hpb->last_srgn_entries; + + if (!ufshpb_is_valid_srgn(rgn, srgn)) + return true; + + /* + * If the region state is active, mctx must be allocated. + * In this case, check whether the region is evicted or + * mctx allcation fail. + */ + if (unlikely(!srgn->mctx)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + return true; + } + + if ((srgn_offset + cnt) > bitmap_len) + bit_len = bitmap_len - srgn_offset; + else + bit_len = cnt; + + if (find_next_bit(srgn->mctx->ppn_dirty, bit_len + srgn_offset, + srgn_offset) < bit_len + srgn_offset) + return true; + + srgn_offset = 0; + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + + cnt -= bit_len; + if (cnt > 0) + goto next_srgn; + + return false; +} + +static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb, + struct ufshpb_map_ctx *mctx, int pos, + int len, __be64 *ppn_buf) +{ + struct page *page; + int index, offset; + int copied; + + index = pos / (PAGE_SIZE / HPB_ENTRY_SIZE); + offset = pos % (PAGE_SIZE / HPB_ENTRY_SIZE); + + if ((offset + len) <= (PAGE_SIZE / HPB_ENTRY_SIZE)) + copied = len; + else + copied = (PAGE_SIZE / HPB_ENTRY_SIZE) - offset; + + page = mctx->m_page[index]; + if (unlikely(!page)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "error. cannot find page in mctx\n"); + return -ENOMEM; + } + + memcpy(ppn_buf, page_address(page) + (offset * HPB_ENTRY_SIZE), + copied * HPB_ENTRY_SIZE); + + return copied; +} + +static void +ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx, + int *srgn_idx, int *offset) +{ + int rgn_offset; + + *rgn_idx = lpn >> hpb->entries_per_rgn_shift; + rgn_offset = lpn & hpb->entries_per_rgn_mask; + *srgn_idx = rgn_offset >> hpb->entries_per_srgn_shift; + *offset = rgn_offset & hpb->entries_per_srgn_mask; +} + +static void +ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, + u32 lpn, __be64 ppn, u8 transfer_len) +{ + unsigned char *cdb = lrbp->cmd->cmnd; + + cdb[0] = UFSHPB_READ; + + /* ppn value is stored as big-endian in the host memory */ + memcpy(&cdb[6], &ppn, sizeof(__be64)); + cdb[14] = transfer_len; + + lrbp->cmd->cmd_len = UFS_CDB_SIZE; +} + +/* + * This function will set up HPB read command using host-side L2P map data. + * In HPB v1.0, maximum size of HPB read command is 4KB. + */ +void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct ufshpb_lu *hpb; + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + struct scsi_cmnd *cmd = lrbp->cmd; + u32 lpn; + __be64 ppn; + unsigned long flags; + int transfer_len, rgn_idx, srgn_idx, srgn_offset; + int err = 0; + + hpb = ufshpb_get_hpb_data(cmd->device); + if (!hpb) + return; + + if (ufshpb_get_state(hpb) == HPB_INIT) + return; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT", __func__); + return; + } + + if (blk_rq_is_passthrough(cmd->request) || + (!ufshpb_is_write_or_discard(cmd) && + !ufshpb_is_read_cmd(cmd))) + return; + + transfer_len = sectors_to_logical(cmd->device, + blk_rq_sectors(cmd->request)); + if (unlikely(!transfer_len)) + return; + + lpn = sectors_to_logical(cmd->device, blk_rq_pos(cmd->request)); + ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + /* If command type is WRITE or DISCARD, set bitmap as drity */ + if (ufshpb_is_write_or_discard(cmd)) { + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return; + } + + if (!ufshpb_is_supported_chunk(transfer_len)) + return; + + WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH); + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (ufshpb_test_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len)) { + hpb->stats.miss_cnt++; + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return; + } + + err = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, 1, &ppn); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + if (unlikely(err < 0)) { + /* + * In this case, the region state is active, + * but the ppn table is not allocated. + * Make sure that ppn table must be allocated on + * active state. + */ + dev_err(hba->dev, "get ppn failed. err %d\n", err); + return; + } + + ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len); + + hpb->stats.hit_cnt++; +} static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, struct ufshpb_subregion *srgn) { @@ -153,7 +406,7 @@ free_map_req: } static void ufshpb_put_map_req(struct ufshpb_lu *hpb, - struct ufshpb_req *map_req) + struct ufshpb_req *map_req) { bio_put(map_req->bio); blk_put_request(map_req->req); diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index dcc0ca3b8158..6e6a0252dc15 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -201,6 +201,7 @@ struct ufs_hba; struct ufshcd_lrb; #ifndef CONFIG_SCSI_UFS_HPB +static void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} static void ufshpb_resume(struct ufs_hba *hba) {} static void ufshpb_suspend(struct ufs_hba *hba) {} @@ -214,6 +215,7 @@ static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; } static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {} static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {} #else +void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); void ufshpb_resume(struct ufs_hba *hba); void ufshpb_suspend(struct ufs_hba *hba); -- cgit v1.2.3-70-g09d2 From 41d8a9333cc96f5ad4dd7a52786585338257d9f1 Mon Sep 17 00:00:00 2001 From: Daejun Park Date: Mon, 12 Jul 2021 18:00:25 +0900 Subject: scsi: ufs: ufshpb: Add HPB 2.0 support Version 2.0 of HBP supports reads of varying sizes from 4KB to 1MB. A read operation <= 32KB is supported as single HPB read. A read between 36KB and 1MB is supported by a combination of write buffer command and HPB read command to deliver more PPN. The write buffer commands may not be issued immediately due to busy tags. To use HPB read more aggressively, the driver can requeue the write buffer command. The requeue threshold is implemented as timeout and can be modified with requeue_timeout_ms entry in sysfs. [mkp: REQ_OP_DRV_* and blk_rq_is_passthrough()] Link: https://lore.kernel.org/r/20210712090025epcms2p3b3d94f6f1b2cfa394e3d9ba130ca0fa7@epcms2p3 Tested-by: Can Guo Tested-by: Stanley Chu Reviewed-by: Greg Kroah-Hartman Reviewed-by: Can Guo Reviewed-by: Bean Huo Reviewed-by: Stanley Chu Signed-off-by: Daejun Park Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 35 ++ drivers/scsi/ufs/ufs-sysfs.c | 4 + drivers/scsi/ufs/ufs.h | 3 +- drivers/scsi/ufs/ufshcd.c | 25 +- drivers/scsi/ufs/ufshcd.h | 7 + drivers/scsi/ufs/ufshpb.c | 615 ++++++++++++++++++++++++++--- drivers/scsi/ufs/ufshpb.h | 67 +++- 7 files changed, 682 insertions(+), 74 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 4c1a5d28408d..929460738651 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -1425,3 +1425,38 @@ Description: This entry shows the number of read buffer commands for activating sub-regions recommended by response UPIUs. The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_params/requeue_timeout_ms +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the requeue timeout threshold for write buffer + command in ms. The value can be changed by writing an integer to + this entry. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_size_hpb_single_cmd +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum HPB data size for using a single HPB + command. + + === ======== + 00h 4KB + 01h 8KB + 02h 12KB + ... + FFh 1024KB + === ======== + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the status of HPB. + + == ============================ + 0 HPB is not enabled. + 1 HPB is enabled + == ============================ + + The file is read only. diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 639644817f36..08fe037069bc 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -1018,6 +1018,7 @@ UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE); UFS_FLAG(wb_enable, _WB_EN); UFS_FLAG(wb_flush_en, _WB_BUFF_FLUSH_EN); UFS_FLAG(wb_flush_during_h8, _WB_BUFF_FLUSH_DURING_HIBERN8); +UFS_FLAG(hpb_enable, _HPB_EN); static struct attribute *ufs_sysfs_device_flags[] = { &dev_attr_device_init.attr, @@ -1031,6 +1032,7 @@ static struct attribute *ufs_sysfs_device_flags[] = { &dev_attr_wb_enable.attr, &dev_attr_wb_flush_en.attr, &dev_attr_wb_flush_during_h8.attr, + &dev_attr_hpb_enable.attr, NULL, }; @@ -1077,6 +1079,7 @@ out: \ static DEVICE_ATTR_RO(_name) UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN); +UFS_ATTRIBUTE(max_data_size_hpb_single_cmd, _MAX_HPB_SINGLE_CMD); UFS_ATTRIBUTE(current_power_mode, _POWER_MODE); UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL); UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN); @@ -1100,6 +1103,7 @@ UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE); static struct attribute *ufs_sysfs_attributes[] = { &dev_attr_boot_lun_enabled.attr, + &dev_attr_max_data_size_hpb_single_cmd.attr, &dev_attr_current_power_mode.attr, &dev_attr_active_icc_level.attr, &dev_attr_ooo_data_enabled.attr, diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index bfb84d2ba990..8c6b38b1b142 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -123,12 +123,13 @@ enum flag_idn { QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F, QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10, QUERY_FLAG_IDN_HPB_RESET = 0x11, + QUERY_FLAG_IDN_HPB_EN = 0x12, }; /* Attribute idn for Query requests */ enum attr_idn { QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, - QUERY_ATTR_IDN_RESERVED = 0x01, + QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01, QUERY_ATTR_IDN_POWER_MODE = 0x02, QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, QUERY_ATTR_IDN_OOO_DATA_EN = 0x04, diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a5060f817125..40d371f6e147 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2788,7 +2788,12 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->req_abort_skip = false; - ufshpb_prep(hba, lrbp); + err = ufshpb_prep(hba, lrbp); + if (err == -EAGAIN) { + lrbp->cmd = NULL; + ufshcd_release(hba); + goto out; + } ufshcd_comp_scsi_upiu(hba, lrbp); @@ -3196,7 +3201,7 @@ out_unlock: * * Returns 0 for success, non-zero in case of failure */ -static int ufshcd_query_attr_retry(struct ufs_hba *hba, +int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) { @@ -4992,7 +4997,8 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth) static void ufshcd_hpb_destroy(struct ufs_hba *hba, struct scsi_device *sdev) { /* skip well-known LU */ - if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || !ufshpb_is_allowed(hba)) + if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || + !(hba->dev_info.hpb_enabled) || !ufshpb_is_allowed(hba)) return; ufshpb_destroy_lu(hba, sdev); @@ -7563,8 +7569,18 @@ static int ufs_get_device_desc(struct ufs_hba *hba) if (dev_info->wspecversion >= UFS_DEV_HPB_SUPPORT_VERSION && (b_ufs_feature_sup & UFS_DEV_HPB_SUPPORT)) { - dev_info->hpb_enabled = true; + bool hpb_en = false; + ufshpb_get_dev_info(hba, desc_buf); + + if (!ufshpb_is_legacy(hba)) + err = ufshcd_query_flag_retry(hba, + UPIU_QUERY_OPCODE_READ_FLAG, + QUERY_FLAG_IDN_HPB_EN, 0, + &hpb_en); + + if (ufshpb_is_legacy(hba) || (!err && hpb_en)) + dev_info->hpb_enabled = true; } err = ufshcd_read_string_desc(hba, model_index, @@ -8143,6 +8159,7 @@ static const struct attribute_group *ufshcd_driver_groups[] = { &ufs_sysfs_lun_attributes_group, #ifdef CONFIG_SCSI_UFS_HPB &ufs_sysfs_hpb_stat_group, + &ufs_sysfs_hpb_param_group, #endif NULL, }; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 57d407be9e0a..84570501c3ac 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -650,6 +650,8 @@ struct ufs_hba_variant_params { * @srgn_size: device reported HPB sub-region size * @slave_conf_cnt: counter to check all lu finished initialization * @hpb_disabled: flag to check if HPB is disabled + * @max_hpb_single_cmd: device reported bMAX_DATA_SIZE_FOR_SINGLE_CMD value + * @is_legacy: flag to check HPB 1.0 */ struct ufshpb_dev_info { int num_lu; @@ -657,6 +659,8 @@ struct ufshpb_dev_info { int srgn_size; atomic_t slave_conf_cnt; bool hpb_disabled; + u8 max_hpb_single_cmd; + bool is_legacy; }; #endif @@ -1111,6 +1115,9 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, u8 param_offset, u8 *param_read_buf, u8 param_size); +int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, + enum attr_idn idn, u8 index, u8 selector, + u32 *attr_val); int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 3d2b8ca8bdb0..9333b670b33f 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -31,6 +31,12 @@ bool ufshpb_is_allowed(struct ufs_hba *hba) return !(hba->ufshpb_dev.hpb_disabled); } +/* HPB version 1.0 is called as legacy version. */ +bool ufshpb_is_legacy(struct ufs_hba *hba) +{ + return hba->ufshpb_dev.is_legacy; +} + static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev) { return sdev->hostdata; @@ -64,9 +70,19 @@ static bool ufshpb_is_write_or_discard(struct scsi_cmnd *cmd) op_is_discard(req_op(cmd->request)); } -static bool ufshpb_is_supported_chunk(int transfer_len) +static bool ufshpb_is_supported_chunk(struct ufshpb_lu *hpb, int transfer_len) { - return transfer_len <= HPB_MULTI_CHUNK_HIGH; + return transfer_len <= hpb->pre_req_max_tr_len; +} + +/* + * In this driver, WRITE_BUFFER CMD support 36KB (len=9) ~ 1MB (len=256) as + * default. It is possible to change range of transfer_len through sysfs. + */ +static inline bool ufshpb_is_required_wb(struct ufshpb_lu *hpb, int len) +{ + return len > hpb->pre_req_min_tr_len && + len <= hpb->pre_req_max_tr_len; } static bool ufshpb_is_general_lun(int lun) @@ -74,8 +90,7 @@ static bool ufshpb_is_general_lun(int lun) return lun < UFS_UPIU_MAX_UNIT_NUM_ID; } -static bool -ufshpb_is_pinned_region(struct ufshpb_lu *hpb, int rgn_idx) +static bool ufshpb_is_pinned_region(struct ufshpb_lu *hpb, int rgn_idx) { if (hpb->lu_pinned_end != PINNED_NOT_SET && rgn_idx >= hpb->lu_pinned_start && @@ -264,7 +279,7 @@ ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx, static void ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, - u32 lpn, __be64 ppn, u8 transfer_len) + u32 lpn, __be64 ppn, u8 transfer_len, int read_id) { unsigned char *cdb = lrbp->cmd->cmnd; @@ -273,15 +288,260 @@ ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, /* ppn value is stored as big-endian in the host memory */ memcpy(&cdb[6], &ppn, sizeof(__be64)); cdb[14] = transfer_len; + cdb[15] = read_id; lrbp->cmd->cmd_len = UFS_CDB_SIZE; } +static inline void ufshpb_set_write_buf_cmd(unsigned char *cdb, + unsigned long lpn, unsigned int len, + int read_id) +{ + cdb[0] = UFSHPB_WRITE_BUFFER; + cdb[1] = UFSHPB_WRITE_BUFFER_PREFETCH_ID; + + put_unaligned_be32(lpn, &cdb[2]); + cdb[6] = read_id; + put_unaligned_be16(len * HPB_ENTRY_SIZE, &cdb[7]); + + cdb[9] = 0x00; /* Control = 0x00 */ +} + +static struct ufshpb_req *ufshpb_get_pre_req(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req; + + if (hpb->num_inflight_pre_req >= hpb->throttle_pre_req) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, + "pre_req throttle. inflight %d throttle %d", + hpb->num_inflight_pre_req, hpb->throttle_pre_req); + return NULL; + } + + pre_req = list_first_entry_or_null(&hpb->lh_pre_req_free, + struct ufshpb_req, list_req); + if (!pre_req) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, "There is no pre_req"); + return NULL; + } + + list_del_init(&pre_req->list_req); + hpb->num_inflight_pre_req++; + + return pre_req; +} + +static inline void ufshpb_put_pre_req(struct ufshpb_lu *hpb, + struct ufshpb_req *pre_req) +{ + pre_req->req = NULL; + bio_reset(pre_req->bio); + list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free); + hpb->num_inflight_pre_req--; +} + +static void ufshpb_pre_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *pre_req = (struct ufshpb_req *)req->end_io_data; + struct ufshpb_lu *hpb = pre_req->hpb; + unsigned long flags; + + if (error) { + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + struct scsi_sense_hdr sshdr; + + dev_err(&hpb->sdev_ufs_lu->sdev_dev, "block status %d", error); + scsi_command_normalize_sense(cmd, &sshdr); + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "code %x sense_key %x asc %x ascq %x", + sshdr.response_code, + sshdr.sense_key, sshdr.asc, sshdr.ascq); + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "byte4 %x byte5 %x byte6 %x additional_len %x", + sshdr.byte4, sshdr.byte5, + sshdr.byte6, sshdr.additional_length); + } + + blk_mq_free_request(req); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_put_pre_req(pre_req->hpb, pre_req); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); +} + +static int ufshpb_prep_entry(struct ufshpb_req *pre_req, struct page *page) +{ + struct ufshpb_lu *hpb = pre_req->hpb; + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + __be64 *addr; + int offset = 0; + int copied; + unsigned long lpn = pre_req->wb.lpn; + int rgn_idx, srgn_idx, srgn_offset; + unsigned long flags; + + addr = page_address(page); + ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + +next_offset: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (!ufshpb_is_valid_srgn(rgn, srgn)) + goto mctx_error; + + if (!srgn->mctx) + goto mctx_error; + + copied = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, + pre_req->wb.len - offset, + &addr[offset]); + + if (copied < 0) + goto mctx_error; + + offset += copied; + srgn_offset += copied; + + if (srgn_offset == hpb->entries_per_srgn) { + srgn_offset = 0; + + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + } + + if (offset < pre_req->wb.len) + goto next_offset; + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return 0; +mctx_error: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return -ENOMEM; +} + +static int ufshpb_pre_req_add_bio_page(struct ufshpb_lu *hpb, + struct request_queue *q, + struct ufshpb_req *pre_req) +{ + struct page *page = pre_req->wb.m_page; + struct bio *bio = pre_req->bio; + int entries_bytes, ret; + + if (!page) + return -ENOMEM; + + if (ufshpb_prep_entry(pre_req, page)) + return -ENOMEM; + + entries_bytes = pre_req->wb.len * sizeof(__be64); + + ret = bio_add_pc_page(q, bio, page, entries_bytes, 0); + if (ret != entries_bytes) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "bio_add_pc_page fail: %d", ret); + return -ENOMEM; + } + return 0; +} + +static inline int ufshpb_get_read_id(struct ufshpb_lu *hpb) +{ + if (++hpb->cur_read_id >= MAX_HPB_READ_ID) + hpb->cur_read_id = 1; + return hpb->cur_read_id; +} + +static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd, + struct ufshpb_req *pre_req, int read_id) +{ + struct scsi_device *sdev = cmd->device; + struct request_queue *q = sdev->request_queue; + struct request *req; + struct scsi_request *rq; + struct bio *bio = pre_req->bio; + + pre_req->hpb = hpb; + pre_req->wb.lpn = sectors_to_logical(cmd->device, + blk_rq_pos(cmd->request)); + pre_req->wb.len = sectors_to_logical(cmd->device, + blk_rq_sectors(cmd->request)); + if (ufshpb_pre_req_add_bio_page(hpb, q, pre_req)) + return -ENOMEM; + + req = pre_req->req; + + /* 1. request setup */ + blk_rq_append_bio(req, bio); + req->rq_disk = NULL; + req->end_io_data = (void *)pre_req; + req->end_io = ufshpb_pre_req_compl_fn; + + /* 2. scsi_request setup */ + rq = scsi_req(req); + rq->retries = 1; + + ufshpb_set_write_buf_cmd(rq->cmd, pre_req->wb.lpn, pre_req->wb.len, + read_id); + rq->cmd_len = scsi_command_size(rq->cmd); + + if (blk_insert_cloned_request(q, req) != BLK_STS_OK) + return -EAGAIN; + + hpb->stats.pre_req_cnt++; + + return 0; +} + +static int ufshpb_issue_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd, + int *read_id) +{ + struct ufshpb_req *pre_req; + struct request *req = NULL; + unsigned long flags; + int _read_id; + int ret = 0; + + req = blk_get_request(cmd->device->request_queue, + REQ_OP_DRV_OUT | REQ_SYNC, BLK_MQ_REQ_NOWAIT); + if (IS_ERR(req)) + return -EAGAIN; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + pre_req = ufshpb_get_pre_req(hpb); + if (!pre_req) { + ret = -EAGAIN; + goto unlock_out; + } + _read_id = ufshpb_get_read_id(hpb); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + pre_req->req = req; + + ret = ufshpb_execute_pre_req(hpb, cmd, pre_req, _read_id); + if (ret) + goto free_pre_req; + + *read_id = _read_id; + + return ret; +free_pre_req: + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_put_pre_req(hpb, pre_req); +unlock_out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + blk_put_request(req); + return ret; +} + /* * This function will set up HPB read command using host-side L2P map data. - * In HPB v1.0, maximum size of HPB read command is 4KB. */ -void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { struct ufshpb_lu *hpb; struct ufshpb_region *rgn; @@ -291,30 +551,31 @@ void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) __be64 ppn; unsigned long flags; int transfer_len, rgn_idx, srgn_idx, srgn_offset; + int read_id = 0; int err = 0; hpb = ufshpb_get_hpb_data(cmd->device); if (!hpb) - return; + return -ENODEV; if (ufshpb_get_state(hpb) == HPB_INIT) - return; + return -ENODEV; if (ufshpb_get_state(hpb) != HPB_PRESENT) { dev_notice(&hpb->sdev_ufs_lu->sdev_dev, "%s: ufshpb state is not PRESENT", __func__); - return; + return -ENODEV; } if (blk_rq_is_passthrough(cmd->request) || (!ufshpb_is_write_or_discard(cmd) && !ufshpb_is_read_cmd(cmd))) - return; + return 0; transfer_len = sectors_to_logical(cmd->device, blk_rq_sectors(cmd->request)); if (unlikely(!transfer_len)) - return; + return 0; lpn = sectors_to_logical(cmd->device, blk_rq_pos(cmd->request)); ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); @@ -327,11 +588,11 @@ void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, transfer_len); spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); - return; + return 0; } - if (!ufshpb_is_supported_chunk(transfer_len)) - return; + if (!ufshpb_is_supported_chunk(hpb, transfer_len)) + return 0; WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH); @@ -340,7 +601,7 @@ void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) transfer_len)) { hpb->stats.miss_cnt++; spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); - return; + return 0; } err = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, 1, &ppn); @@ -353,28 +614,45 @@ void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) * active state. */ dev_err(hba->dev, "get ppn failed. err %d\n", err); - return; + return err; } + if (!ufshpb_is_legacy(hba) && + ufshpb_is_required_wb(hpb, transfer_len)) { + err = ufshpb_issue_pre_req(hpb, cmd, &read_id); + if (err) { + unsigned long timeout; + + timeout = cmd->jiffies_at_alloc + msecs_to_jiffies( + hpb->params.requeue_timeout_ms); - ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len); + if (time_before(jiffies, timeout)) + return -EAGAIN; + + hpb->stats.miss_cnt++; + return 0; + } + } + + ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len, read_id); hpb->stats.hit_cnt++; + return 0; } -static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, - struct ufshpb_subregion *srgn) + +static struct ufshpb_req *ufshpb_get_req(struct ufshpb_lu *hpb, + int rgn_idx, enum req_opf dir) { - struct ufshpb_req *map_req; + struct ufshpb_req *rq; struct request *req; - struct bio *bio; int retries = HPB_MAP_REQ_RETRIES; - map_req = kmem_cache_alloc(hpb->map_req_cache, GFP_KERNEL); - if (!map_req) + rq = kmem_cache_alloc(hpb->map_req_cache, GFP_KERNEL); + if (!rq) return NULL; retry: - req = blk_get_request(hpb->sdev_ufs_lu->request_queue, - REQ_OP_DRV_IN, BLK_MQ_REQ_NOWAIT); + req = blk_get_request(hpb->sdev_ufs_lu->request_queue, dir, + BLK_MQ_REQ_NOWAIT); if ((PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) { usleep_range(3000, 3100); @@ -382,35 +660,54 @@ retry: } if (IS_ERR(req)) - goto free_map_req; + goto free_rq; + + rq->hpb = hpb; + rq->req = req; + rq->rb.rgn_idx = rgn_idx; + + return rq; + +free_rq: + kmem_cache_free(hpb->map_req_cache, rq); + return NULL; +} + +static void ufshpb_put_req(struct ufshpb_lu *hpb, struct ufshpb_req *rq) +{ + blk_put_request(rq->req); + kmem_cache_free(hpb->map_req_cache, rq); +} + +static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_req *map_req; + struct bio *bio; + + map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_DRV_IN); + if (!map_req) + return NULL; bio = bio_alloc(GFP_KERNEL, hpb->pages_per_srgn); if (!bio) { - blk_put_request(req); - goto free_map_req; + ufshpb_put_req(hpb, map_req); + return NULL; } - map_req->hpb = hpb; - map_req->req = req; map_req->bio = bio; - map_req->rgn_idx = srgn->rgn_idx; - map_req->srgn_idx = srgn->srgn_idx; - map_req->mctx = srgn->mctx; + map_req->rb.srgn_idx = srgn->srgn_idx; + map_req->rb.mctx = srgn->mctx; return map_req; - -free_map_req: - kmem_cache_free(hpb->map_req_cache, map_req); - return NULL; } static void ufshpb_put_map_req(struct ufshpb_lu *hpb, struct ufshpb_req *map_req) { bio_put(map_req->bio); - blk_put_request(map_req->req); - kmem_cache_free(hpb->map_req_cache, map_req); + ufshpb_put_req(hpb, map_req); } static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, @@ -493,6 +790,13 @@ static void ufshpb_activate_subregion(struct ufshpb_lu *hpb, srgn->srgn_state = HPB_SRGN_VALID; } +static void ufshpb_umap_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *umap_req = (struct ufshpb_req *)req->end_io_data; + + ufshpb_put_req(umap_req->hpb, umap_req); +} + static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) { struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data; @@ -500,8 +804,8 @@ static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) struct ufshpb_subregion *srgn; unsigned long flags; - srgn = hpb->rgn_tbl[map_req->rgn_idx].srgn_tbl + - map_req->srgn_idx; + srgn = hpb->rgn_tbl[map_req->rb.rgn_idx].srgn_tbl + + map_req->rb.srgn_idx; ufshpb_clear_dirty_bitmap(hpb, srgn); spin_lock_irqsave(&hpb->rgn_state_lock, flags); @@ -511,6 +815,16 @@ static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) ufshpb_put_map_req(map_req->hpb, map_req); } +static void ufshpb_set_unmap_cmd(unsigned char *cdb, struct ufshpb_region *rgn) +{ + cdb[0] = UFSHPB_WRITE_BUFFER; + cdb[1] = rgn ? UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID : + UFSHPB_WRITE_BUFFER_INACT_ALL_ID; + if (rgn) + put_unaligned_be16(rgn->rgn_idx, &cdb[2]); + cdb[9] = 0x00; +} + static void ufshpb_set_read_buf_cmd(unsigned char *cdb, int rgn_idx, int srgn_idx, int srgn_mem_size) { @@ -524,6 +838,23 @@ static void ufshpb_set_read_buf_cmd(unsigned char *cdb, int rgn_idx, cdb[9] = 0x00; } +static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb, + struct ufshpb_req *umap_req, + struct ufshpb_region *rgn) +{ + struct request *req; + struct scsi_request *rq; + + req = umap_req->req; + req->timeout = 0; + req->end_io_data = (void *)umap_req; + rq = scsi_req(req); + ufshpb_set_unmap_cmd(rq->cmd, rgn); + rq->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH; + + blk_execute_rq_nowait(NULL, req, 1, ufshpb_umap_req_compl_fn); +} + static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, struct ufshpb_req *map_req, bool last) { @@ -536,12 +867,12 @@ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, q = hpb->sdev_ufs_lu->request_queue; for (i = 0; i < hpb->pages_per_srgn; i++) { - ret = bio_add_pc_page(q, map_req->bio, map_req->mctx->m_page[i], + ret = bio_add_pc_page(q, map_req->bio, map_req->rb.mctx->m_page[i], PAGE_SIZE, 0); if (ret != PAGE_SIZE) { dev_err(&hpb->sdev_ufs_lu->sdev_dev, "bio_add_pc_page fail %d - %d\n", - map_req->rgn_idx, map_req->srgn_idx); + map_req->rb.rgn_idx, map_req->rb.srgn_idx); return ret; } } @@ -557,8 +888,8 @@ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, if (unlikely(last)) mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE; - ufshpb_set_read_buf_cmd(rq->cmd, map_req->rgn_idx, - map_req->srgn_idx, mem_size); + ufshpb_set_read_buf_cmd(rq->cmd, map_req->rb.rgn_idx, + map_req->rb.srgn_idx, mem_size); rq->cmd_len = HPB_READ_BUFFER_CMD_LENGTH; blk_execute_rq_nowait(NULL, req, 1, ufshpb_map_req_compl_fn); @@ -690,6 +1021,26 @@ static void ufshpb_purge_active_subregion(struct ufshpb_lu *hpb, } } +static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct ufshpb_req *umap_req; + int rgn_idx = rgn ? rgn->rgn_idx : 0; + + umap_req = ufshpb_get_req(hpb, rgn_idx, REQ_OP_DRV_OUT); + if (!umap_req) + return -ENOMEM; + + ufshpb_execute_umap_req(hpb, umap_req, rgn); + + return 0; +} + +static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb) +{ + return ufshpb_issue_umap_req(hpb, NULL); +} + static void __ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) { @@ -1212,6 +1563,16 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba, u32 entries_per_rgn; u64 rgn_mem_size, tmp; + /* for pre_req */ + hpb->pre_req_min_tr_len = hpb_dev_info->max_hpb_single_cmd + 1; + + if (ufshpb_is_legacy(hba)) + hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH; + else + hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH; + + hpb->cur_read_id = 0; + hpb->lu_pinned_start = hpb_lu_info->pinned_start; hpb->lu_pinned_end = hpb_lu_info->num_pinned ? (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1) @@ -1358,7 +1719,7 @@ ufshpb_sysfs_attr_show_func(rb_active_cnt); ufshpb_sysfs_attr_show_func(rb_inactive_cnt); ufshpb_sysfs_attr_show_func(map_req_cnt); -static struct attribute *hpb_dev_attrs[] = { +static struct attribute *hpb_dev_stat_attrs[] = { &dev_attr_hit_cnt.attr, &dev_attr_miss_cnt.attr, &dev_attr_rb_noti_cnt.attr, @@ -1370,9 +1731,118 @@ static struct attribute *hpb_dev_attrs[] = { struct attribute_group ufs_sysfs_hpb_stat_group = { .name = "hpb_stats", - .attrs = hpb_dev_attrs, + .attrs = hpb_dev_stat_attrs, +}; + +/* SYSFS functions */ +#define ufshpb_sysfs_param_show_func(__name) \ +static ssize_t __name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); \ + \ + if (!hpb) \ + return -ENODEV; \ + \ + return sysfs_emit(buf, "%d\n", hpb->params.__name); \ +} + +ufshpb_sysfs_param_show_func(requeue_timeout_ms); +static ssize_t +requeue_timeout_ms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val < 0) + return -EINVAL; + + hpb->params.requeue_timeout_ms = val; + + return count; +} +static DEVICE_ATTR_RW(requeue_timeout_ms); + +static struct attribute *hpb_dev_param_attrs[] = { + &dev_attr_requeue_timeout_ms.attr, + NULL, }; +struct attribute_group ufs_sysfs_hpb_param_group = { + .name = "hpb_params", + .attrs = hpb_dev_param_attrs, +}; + +static int ufshpb_pre_req_mempool_init(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req = NULL, *t; + int qd = hpb->sdev_ufs_lu->queue_depth / 2; + int i; + + INIT_LIST_HEAD(&hpb->lh_pre_req_free); + + hpb->pre_req = kcalloc(qd, sizeof(struct ufshpb_req), GFP_KERNEL); + hpb->throttle_pre_req = qd; + hpb->num_inflight_pre_req = 0; + + if (!hpb->pre_req) + goto release_mem; + + for (i = 0; i < qd; i++) { + pre_req = hpb->pre_req + i; + INIT_LIST_HEAD(&pre_req->list_req); + pre_req->req = NULL; + + pre_req->bio = bio_alloc(GFP_KERNEL, 1); + if (!pre_req->bio) + goto release_mem; + + pre_req->wb.m_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!pre_req->wb.m_page) { + bio_put(pre_req->bio); + goto release_mem; + } + + list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free); + } + + return 0; +release_mem: + list_for_each_entry_safe(pre_req, t, &hpb->lh_pre_req_free, list_req) { + list_del_init(&pre_req->list_req); + bio_put(pre_req->bio); + __free_page(pre_req->wb.m_page); + } + + kfree(hpb->pre_req); + return -ENOMEM; +} + +static void ufshpb_pre_req_mempool_destroy(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req = NULL; + int i; + + for (i = 0; i < hpb->throttle_pre_req; i++) { + pre_req = hpb->pre_req + i; + bio_put(hpb->pre_req[i].bio); + if (!pre_req->wb.m_page) + __free_page(hpb->pre_req[i].wb.m_page); + list_del_init(&pre_req->list_req); + } + + kfree(hpb->pre_req); +} + static void ufshpb_stat_init(struct ufshpb_lu *hpb) { hpb->stats.hit_cnt = 0; @@ -1383,6 +1853,11 @@ static void ufshpb_stat_init(struct ufshpb_lu *hpb) hpb->stats.map_req_cnt = 0; } +static void ufshpb_param_init(struct ufshpb_lu *hpb) +{ + hpb->params.requeue_timeout_ms = HPB_REQUEUE_TIME_MS; +} + static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) { int ret; @@ -1415,14 +1890,24 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) goto release_req_cache; } + ret = ufshpb_pre_req_mempool_init(hpb); + if (ret) { + dev_err(hba->dev, "ufshpb(%d) pre_req_mempool init fail", + hpb->lun); + goto release_m_page_cache; + } + ret = ufshpb_alloc_region_tbl(hba, hpb); if (ret) - goto release_m_page_cache; + goto release_pre_req_mempool; ufshpb_stat_init(hpb); + ufshpb_param_init(hpb); return 0; +release_pre_req_mempool: + ufshpb_pre_req_mempool_destroy(hpb); release_m_page_cache: kmem_cache_destroy(hpb->m_page_cache); release_req_cache: @@ -1431,7 +1916,7 @@ release_req_cache: } static struct ufshpb_lu * -ufshpb_alloc_hpb_lu(struct ufs_hba *hba, int lun, +ufshpb_alloc_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev, struct ufshpb_dev_info *hpb_dev_info, struct ufshpb_lu_info *hpb_lu_info) { @@ -1442,7 +1927,8 @@ ufshpb_alloc_hpb_lu(struct ufs_hba *hba, int lun, if (!hpb) return NULL; - hpb->lun = lun; + hpb->lun = sdev->lun; + hpb->sdev_ufs_lu = sdev; ufshpb_lu_parameter_init(hba, hpb, hpb_dev_info, hpb_lu_info); @@ -1452,6 +1938,7 @@ ufshpb_alloc_hpb_lu(struct ufs_hba *hba, int lun, goto release_hpb; } + sdev->hostdata = hpb; return hpb; release_hpb: @@ -1654,6 +2141,7 @@ void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) ufshpb_cancel_jobs(hpb); + ufshpb_pre_req_mempool_destroy(hpb); ufshpb_destroy_region_tbl(hpb); kmem_cache_destroy(hpb->map_req_cache); @@ -1693,6 +2181,7 @@ static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba) ufshpb_set_state(hpb, HPB_PRESENT); if ((hpb->lu_pinned_end - hpb->lu_pinned_start) > 0) queue_work(ufshpb_wq, &hpb->map_work); + ufshpb_issue_umap_all_req(hpb); } else { dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun); ufshpb_destroy_lu(hba, sdev); @@ -1717,7 +2206,7 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) if (ret) goto out; - hpb = ufshpb_alloc_hpb_lu(hba, lun, &hba->ufshpb_dev, + hpb = ufshpb_alloc_hpb_lu(hba, sdev, &hba->ufshpb_dev, &hpb_lu_info); if (!hpb) goto out; @@ -1725,9 +2214,6 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) tot_active_srgn_pages += hpb_lu_info.max_active_rgns * hpb->srgns_per_rgn * hpb->pages_per_srgn; - hpb->sdev_ufs_lu = sdev; - sdev->hostdata = hpb; - out: /* All LUs are initialized */ if (atomic_dec_and_test(&hba->ufshpb_dev.slave_conf_cnt)) @@ -1814,8 +2300,9 @@ void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) { struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; - int version; + int version, ret; u8 hpb_mode; + u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; hpb_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; if (hpb_mode == HPB_HOST_CONTROL) { @@ -1826,13 +2313,27 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) } version = get_unaligned_be16(desc_buf + DEVICE_DESC_PARAM_HPB_VER); - if (version != HPB_SUPPORT_VERSION) { + if ((version != HPB_SUPPORT_VERSION) && + (version != HPB_SUPPORT_LEGACY_VERSION)) { dev_err(hba->dev, "%s: HPB %x version is not supported.\n", __func__, version); hpb_dev_info->hpb_disabled = true; return; } + if (version == HPB_SUPPORT_LEGACY_VERSION) + hpb_dev_info->is_legacy = true; + + pm_runtime_get_sync(hba->dev); + ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); + pm_runtime_put_sync(hba->dev); + + if (ret) + dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", + __func__); + hpb_dev_info->max_hpb_single_cmd = max_hpb_single_cmd; + /* * Get the number of user logical unit to check whether all * scsi_device finish initialization diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 6e6a0252dc15..1e8d6e1d909e 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -30,19 +30,29 @@ #define PINNED_NOT_SET U32_MAX /* hpb support chunk size */ -#define HPB_MULTI_CHUNK_HIGH 1 +#define HPB_LEGACY_CHUNK_HIGH 1 +#define HPB_MULTI_CHUNK_LOW 7 +#define HPB_MULTI_CHUNK_HIGH 256 /* hpb vender defined opcode */ #define UFSHPB_READ 0xF8 #define UFSHPB_READ_BUFFER 0xF9 #define UFSHPB_READ_BUFFER_ID 0x01 +#define UFSHPB_WRITE_BUFFER 0xFA +#define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID 0x01 +#define UFSHPB_WRITE_BUFFER_PREFETCH_ID 0x02 +#define UFSHPB_WRITE_BUFFER_INACT_ALL_ID 0x03 +#define HPB_WRITE_BUFFER_CMD_LENGTH 10 +#define MAX_HPB_READ_ID 0x7F #define HPB_READ_BUFFER_CMD_LENGTH 10 #define LU_ENABLED_HPB_FUNC 0x02 #define HPB_RESET_REQ_RETRIES 10 #define HPB_MAP_REQ_RETRIES 5 +#define HPB_REQUEUE_TIME_MS 0 -#define HPB_SUPPORT_VERSION 0x100 +#define HPB_SUPPORT_VERSION 0x200 +#define HPB_SUPPORT_LEGACY_VERSION 0x100 enum UFSHPB_MODE { HPB_HOST_CONTROL, @@ -119,23 +129,38 @@ struct ufshpb_region { (i)++) /** - * struct ufshpb_req - UFSHPB READ BUFFER (for caching map) request structure - * @req: block layer request for READ BUFFER - * @bio: bio for holding map page - * @hpb: ufshpb_lu structure that related to the L2P map + * struct ufshpb_req - HPB related request structure (write/read buffer) + * @req: block layer request structure + * @bio: bio for this request + * @hpb: ufshpb_lu structure that related to + * @list_req: ufshpb_req mempool list + * @sense: store its sense data * @mctx: L2P map information * @rgn_idx: target region index * @srgn_idx: target sub-region index * @lun: target logical unit number + * @m_page: L2P map information data for pre-request + * @len: length of host-side cached L2P map in m_page + * @lpn: start LPN of L2P map in m_page */ struct ufshpb_req { struct request *req; struct bio *bio; struct ufshpb_lu *hpb; - struct ufshpb_map_ctx *mctx; - - unsigned int rgn_idx; - unsigned int srgn_idx; + struct list_head list_req; + union { + struct { + struct ufshpb_map_ctx *mctx; + unsigned int rgn_idx; + unsigned int srgn_idx; + unsigned int lun; + } rb; + struct { + struct page *m_page; + unsigned int len; + unsigned long lpn; + } wb; + }; }; struct victim_select_info { @@ -144,6 +169,10 @@ struct victim_select_info { atomic_t active_cnt; }; +struct ufshpb_params { + unsigned int requeue_timeout_ms; +}; + struct ufshpb_stats { u64 hit_cnt; u64 miss_cnt; @@ -151,6 +180,7 @@ struct ufshpb_stats { u64 rb_active_cnt; u64 rb_inactive_cnt; u64 map_req_cnt; + u64 pre_req_cnt; }; struct ufshpb_lu { @@ -166,6 +196,15 @@ struct ufshpb_lu { struct list_head lh_act_srgn; /* hold rsp_list_lock */ struct list_head lh_inact_rgn; /* hold rsp_list_lock */ + /* pre request information */ + struct ufshpb_req *pre_req; + int num_inflight_pre_req; + int throttle_pre_req; + struct list_head lh_pre_req_free; + int cur_read_id; + int pre_req_min_tr_len; + int pre_req_max_tr_len; + /* cached L2P map management worker */ struct work_struct map_work; @@ -190,6 +229,7 @@ struct ufshpb_lu { u32 pages_per_srgn; struct ufshpb_stats stats; + struct ufshpb_params params; struct kmem_cache *map_req_cache; struct kmem_cache *m_page_cache; @@ -201,7 +241,7 @@ struct ufs_hba; struct ufshcd_lrb; #ifndef CONFIG_SCSI_UFS_HPB -static void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} +static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; } static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} static void ufshpb_resume(struct ufs_hba *hba) {} static void ufshpb_suspend(struct ufs_hba *hba) {} @@ -214,8 +254,9 @@ static void ufshpb_remove(struct ufs_hba *hba) {} static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; } static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {} static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {} +static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; } #else -void ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); +int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); void ufshpb_resume(struct ufs_hba *hba); void ufshpb_suspend(struct ufs_hba *hba); @@ -228,7 +269,9 @@ void ufshpb_remove(struct ufs_hba *hba); bool ufshpb_is_allowed(struct ufs_hba *hba); void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf); void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf); +bool ufshpb_is_legacy(struct ufs_hba *hba); extern struct attribute_group ufs_sysfs_hpb_stat_group; +extern struct attribute_group ufs_sysfs_hpb_param_group; #endif #endif /* End of Header */ -- cgit v1.2.3-70-g09d2 From 119ee38c10fa34f37f2880af20b957ce55943ed2 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:28 +0300 Subject: scsi: ufs: ufshpb: Cache HPB Control mode on init We will use control_mode later when we need to differentiate between device and host control modes. Link: https://lore.kernel.org/r/20210712095039.8093-2-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 2 ++ drivers/scsi/ufs/ufshpb.c | 8 +++++--- drivers/scsi/ufs/ufshpb.h | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 84570501c3ac..b4322ce11d58 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -652,6 +652,7 @@ struct ufs_hba_variant_params { * @hpb_disabled: flag to check if HPB is disabled * @max_hpb_single_cmd: device reported bMAX_DATA_SIZE_FOR_SINGLE_CMD value * @is_legacy: flag to check HPB 1.0 + * @control_mode: either host or device */ struct ufshpb_dev_info { int num_lu; @@ -661,6 +662,7 @@ struct ufshpb_dev_info { bool hpb_disabled; u8 max_hpb_single_cmd; bool is_legacy; + u8 control_mode; }; #endif diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 9333b670b33f..26353ccc143f 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -1608,6 +1608,9 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba, % (hpb->srgn_mem_size / HPB_ENTRY_SIZE); hpb->pages_per_srgn = DIV_ROUND_UP(hpb->srgn_mem_size, PAGE_SIZE); + + if (hpb_dev_info->control_mode == HPB_HOST_CONTROL) + hpb->is_hcm = true; } static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) @@ -2301,11 +2304,10 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) { struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; int version, ret; - u8 hpb_mode; u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; - hpb_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; - if (hpb_mode == HPB_HOST_CONTROL) { + hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; + if (hpb_dev_info->control_mode == HPB_HOST_CONTROL) { dev_err(hba->dev, "%s: host control mode is not supported.\n", __func__); hpb_dev_info->hpb_disabled = true; diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 1e8d6e1d909e..dc168ba08a09 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -228,6 +228,8 @@ struct ufshpb_lu { u32 entries_per_srgn_shift; u32 pages_per_srgn; + bool is_hcm; + struct ufshpb_stats stats; struct ufshpb_params params; -- cgit v1.2.3-70-g09d2 From 3a2c1f6803298c0a8784444cf66645163dd8e61b Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:29 +0300 Subject: scsi: ufs: ufshpb: Add host control mode support to rsp_upiu In device control mode, the device may recommend the host to either activate or inactivate a region, and the host should follow. Meaning those are not actually recommendations, but more of instructions. Conversely, in host control mode, the recommendation protocol is slightly changed: a) The device may only recommend the host to update a subregion of an already-active region. And, b) The device may *not* recommend to inactivate a region. Furthermore, in host control mode, the host may choose not to follow any of the device's recommendations. However, in case of a recommendation to update an active and clean subregion, it is better to follow those recommendation because otherwise the host has no other way to know that some internal relocation took place. Link: https://lore.kernel.org/r/20210712095039.8093-3-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 34 +++++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshpb.h | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 26353ccc143f..9d46d02f6b97 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -167,6 +167,8 @@ next_srgn: else set_bit_len = cnt; + set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + if (rgn->rgn_state != HPB_RGN_INACTIVE && srgn->srgn_state == HPB_SRGN_VALID) bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); @@ -236,6 +238,11 @@ next_srgn: return false; } +static inline bool is_rgn_dirty(struct ufshpb_region *rgn) +{ + return test_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); +} + static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb, struct ufshpb_map_ctx *mctx, int pos, int len, __be64 *ppn_buf) @@ -713,6 +720,7 @@ static void ufshpb_put_map_req(struct ufshpb_lu *hpb, static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, struct ufshpb_subregion *srgn) { + struct ufshpb_region *rgn; u32 num_entries = hpb->entries_per_srgn; if (!srgn->mctx) { @@ -726,6 +734,10 @@ static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, num_entries = hpb->last_srgn_entries; bitmap_zero(srgn->mctx->ppn_dirty, num_entries); + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + clear_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + return 0; } @@ -1238,6 +1250,18 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, srgn_i = be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn); + rgn = hpb->rgn_tbl + rgn_i; + if (hpb->is_hcm && + (rgn->rgn_state != HPB_RGN_ACTIVE || is_rgn_dirty(rgn))) { + /* + * in host control mode, subregion activation + * recommendations are only allowed to active regions. + * Also, ignore recommendations for dirty regions - the + * host will make decisions concerning those by himself + */ + continue; + } + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "activate(%d) region %d - %d\n", i, rgn_i, srgn_i); @@ -1245,7 +1269,6 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, ufshpb_update_active_info(hpb, rgn_i, srgn_i); spin_unlock(&hpb->rsp_list_lock); - rgn = hpb->rgn_tbl + rgn_i; srgn = rgn->srgn_tbl + srgn_i; /* blocking HPB_READ */ @@ -1256,6 +1279,14 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, hpb->stats.rb_active_cnt++; } + if (hpb->is_hcm) { + /* + * in host control mode the device is not allowed to inactivate + * regions + */ + goto out; + } + for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) { rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]); dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, @@ -1280,6 +1311,7 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, hpb->stats.rb_inactive_cnt++; } +out: dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n", rsp_field->active_rgn_cnt, rsp_field->inactive_rgn_cnt); diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index dc168ba08a09..9ab502f82835 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -121,6 +121,8 @@ struct ufshpb_region { /* below information is used by lru */ struct list_head list_lru_rgn; + unsigned long rgn_flags; +#define RGN_FLAG_DIRTY 0 }; #define for_each_sub_region(rgn, i, srgn) \ -- cgit v1.2.3-70-g09d2 From 8becf4db1e01d6ae2bb9f9877537dffee89b8308 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:30 +0300 Subject: scsi: ufs: ufshpb: Transform set_dirty to iterate_rgn Given a transfer length, set_dirty meticulously iterates over all the entries, across subregions and regions if needed. Currently its only use is to mark dirty blocks, but HCM may benefit from it as well to manage its read counters. Link: https://lore.kernel.org/r/20210712095039.8093-4-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 9d46d02f6b97..8b4029b9da2e 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -145,13 +145,14 @@ static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba, return true; } -static void ufshpb_set_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx, - int srgn_idx, int srgn_offset, int cnt) +static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx, + int srgn_offset, int cnt, bool set_dirty) { struct ufshpb_region *rgn; struct ufshpb_subregion *srgn; int set_bit_len; int bitmap_len; + unsigned long flags; next_srgn: rgn = hpb->rgn_tbl + rgn_idx; @@ -167,11 +168,14 @@ next_srgn: else set_bit_len = cnt; - set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + if (set_dirty) + set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); - if (rgn->rgn_state != HPB_RGN_INACTIVE && + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (set_dirty && rgn->rgn_state != HPB_RGN_INACTIVE && srgn->srgn_state == HPB_SRGN_VALID) bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); srgn_offset = 0; if (++srgn_idx == hpb->srgns_per_rgn) { @@ -591,10 +595,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) /* If command type is WRITE or DISCARD, set bitmap as drity */ if (ufshpb_is_write_or_discard(cmd)) { - spin_lock_irqsave(&hpb->rgn_state_lock, flags); - ufshpb_set_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, - transfer_len); - spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len, true); return 0; } -- cgit v1.2.3-70-g09d2 From c76a188856413f0a40585a7bc6801c755a4c0c8d Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:31 +0300 Subject: scsi: ufs: ufshpb: Add reads counter In host control mode, reads are the major source of activation trials. Keep track of those reads counters, for both active as well inactive regions. We reset the read counter upon write - we are only interested in "clean" reads. Keep those counters normalized, as we are using those reads as a comparative score, to make various decisions. If during consecutive normalizations an active region has exhaust its reads - inactivate it. While at it, protect the {active,inactive}_count stats by adding them into the applicable handler. Link: https://lore.kernel.org/r/20210712095039.8093-5-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 94 ++++++++++++++++++++++++++++++++++++++++++++--- drivers/scsi/ufs/ufshpb.h | 9 +++++ 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 8b4029b9da2e..a330c4922965 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -16,6 +16,8 @@ #include "ufshpb.h" #include "../sd.h" +#define ACTIVATION_THRESHOLD 8 /* 8 IOs */ + /* memory management */ static struct kmem_cache *ufshpb_mctx_cache; static mempool_t *ufshpb_mctx_pool; @@ -26,6 +28,9 @@ static int tot_active_srgn_pages; static struct workqueue_struct *ufshpb_wq; +static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx); + bool ufshpb_is_allowed(struct ufs_hba *hba) { return !(hba->ufshpb_dev.hpb_disabled); @@ -149,7 +154,7 @@ static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx, int srgn_offset, int cnt, bool set_dirty) { struct ufshpb_region *rgn; - struct ufshpb_subregion *srgn; + struct ufshpb_subregion *srgn, *prev_srgn = NULL; int set_bit_len; int bitmap_len; unsigned long flags; @@ -168,15 +173,39 @@ next_srgn: else set_bit_len = cnt; - if (set_dirty) - set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); - spin_lock_irqsave(&hpb->rgn_state_lock, flags); if (set_dirty && rgn->rgn_state != HPB_RGN_INACTIVE && srgn->srgn_state == HPB_SRGN_VALID) bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + if (hpb->is_hcm && prev_srgn != srgn) { + bool activate = false; + + spin_lock(&rgn->rgn_lock); + if (set_dirty) { + rgn->reads -= srgn->reads; + srgn->reads = 0; + set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + } else { + srgn->reads++; + rgn->reads++; + if (srgn->reads == ACTIVATION_THRESHOLD) + activate = true; + } + spin_unlock(&rgn->rgn_lock); + + if (activate) { + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_update_active_info(hpb, rgn_idx, srgn_idx); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "activate region %d-%d\n", rgn_idx, srgn_idx); + } + + prev_srgn = srgn; + } + srgn_offset = 0; if (++srgn_idx == hpb->srgns_per_rgn) { srgn_idx = 0; @@ -605,6 +634,19 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH); + if (hpb->is_hcm) { + /* + * in host control mode, reads are the main source for + * activation trials. + */ + ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len, false); + + /* keep those counters normalized */ + if (rgn->reads > hpb->entries_per_srgn) + schedule_work(&hpb->ufshpb_normalization_work); + } + spin_lock_irqsave(&hpb->rgn_state_lock, flags); if (ufshpb_test_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, transfer_len)) { @@ -756,6 +798,8 @@ static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, if (list_empty(&srgn->list_act_srgn)) list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn); + + hpb->stats.rb_active_cnt++; } static void ufshpb_update_inactive_info(struct ufshpb_lu *hpb, int rgn_idx) @@ -771,6 +815,8 @@ static void ufshpb_update_inactive_info(struct ufshpb_lu *hpb, int rgn_idx) if (list_empty(&rgn->list_inact_rgn)) list_add_tail(&rgn->list_inact_rgn, &hpb->lh_inact_rgn); + + hpb->stats.rb_inactive_cnt++; } static void ufshpb_activate_subregion(struct ufshpb_lu *hpb, @@ -1084,6 +1130,7 @@ static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) rgn->rgn_idx); goto out; } + if (!list_empty(&rgn->list_lru_rgn)) { if (ufshpb_check_srgns_issue_state(hpb, rgn)) { ret = -EBUSY; @@ -1278,7 +1325,6 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, if (srgn->srgn_state == HPB_SRGN_VALID) srgn->srgn_state = HPB_SRGN_INVALID; spin_unlock(&hpb->rgn_state_lock); - hpb->stats.rb_active_cnt++; } if (hpb->is_hcm) { @@ -1310,7 +1356,6 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, } spin_unlock(&hpb->rgn_state_lock); - hpb->stats.rb_inactive_cnt++; } out: @@ -1509,6 +1554,36 @@ static void ufshpb_run_inactive_region_list(struct ufshpb_lu *hpb) spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); } +static void ufshpb_normalization_work_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, + ufshpb_normalization_work); + int rgn_idx; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + struct ufshpb_region *rgn = hpb->rgn_tbl + rgn_idx; + int srgn_idx; + + spin_lock(&rgn->rgn_lock); + rgn->reads = 0; + for (srgn_idx = 0; srgn_idx < hpb->srgns_per_rgn; srgn_idx++) { + struct ufshpb_subregion *srgn = rgn->srgn_tbl + srgn_idx; + + srgn->reads >>= 1; + rgn->reads += srgn->reads; + } + spin_unlock(&rgn->rgn_lock); + + if (rgn->rgn_state != HPB_RGN_ACTIVE || rgn->reads) + continue; + + /* if region is active but has no reads - inactivate it */ + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_inactive_info(hpb, rgn->rgn_idx); + spin_unlock(&hpb->rsp_list_lock); + } +} + static void ufshpb_map_work_handler(struct work_struct *work) { struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, map_work); @@ -1667,6 +1742,8 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) rgn = rgn_table + rgn_idx; rgn->rgn_idx = rgn_idx; + spin_lock_init(&rgn->rgn_lock); + INIT_LIST_HEAD(&rgn->list_inact_rgn); INIT_LIST_HEAD(&rgn->list_lru_rgn); @@ -1908,6 +1985,9 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) INIT_LIST_HEAD(&hpb->list_hpb_lu); INIT_WORK(&hpb->map_work, ufshpb_map_work_handler); + if (hpb->is_hcm) + INIT_WORK(&hpb->ufshpb_normalization_work, + ufshpb_normalization_work_handler); hpb->map_req_cache = kmem_cache_create("ufshpb_req_cache", sizeof(struct ufshpb_req), 0, 0, NULL); @@ -2007,6 +2087,8 @@ static void ufshpb_discard_rsp_lists(struct ufshpb_lu *hpb) static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb) { + if (hpb->is_hcm) + cancel_work_sync(&hpb->ufshpb_normalization_work); cancel_work_sync(&hpb->map_work); } diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 9ab502f82835..33d163e76d41 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -106,6 +106,10 @@ struct ufshpb_subregion { int rgn_idx; int srgn_idx; bool is_last; + + /* subregion reads - for host mode */ + unsigned int reads; + /* below information is used by rsp_list */ struct list_head list_act_srgn; }; @@ -123,6 +127,10 @@ struct ufshpb_region { struct list_head list_lru_rgn; unsigned long rgn_flags; #define RGN_FLAG_DIRTY 0 + + /* region reads - for host mode */ + spinlock_t rgn_lock; + unsigned int reads; }; #define for_each_sub_region(rgn, i, srgn) \ @@ -212,6 +220,7 @@ struct ufshpb_lu { /* for selecting victim */ struct victim_select_info lru_info; + struct work_struct ufshpb_normalization_work; /* pinned region information */ u32 lu_pinned_start; -- cgit v1.2.3-70-g09d2 From 6c59cb501b86f8cddc486d6846732375f7baef24 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:32 +0300 Subject: scsi: ufs: ufshpb: Make eviction depend on region's reads In host mode, eviction is considered an extreme measure. Verify that the entering region has enough reads, and the exiting region has fewer reads. Link: https://lore.kernel.org/r/20210712095039.8093-6-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index a330c4922965..912bc6e5f3f8 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -17,6 +17,7 @@ #include "../sd.h" #define ACTIVATION_THRESHOLD 8 /* 8 IOs */ +#define EVICTION_THRESHOLD (ACTIVATION_THRESHOLD << 5) /* 256 IOs */ /* memory management */ static struct kmem_cache *ufshpb_mctx_cache; @@ -1056,6 +1057,13 @@ static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb) if (ufshpb_check_srgns_issue_state(hpb, rgn)) continue; + /* + * in host control mode, verify that the exiting region + * has fewer reads + */ + if (hpb->is_hcm && rgn->reads > (EVICTION_THRESHOLD >> 1)) + continue; + victim_rgn = rgn; break; } @@ -1223,7 +1231,7 @@ unlock_out: static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) { - struct ufshpb_region *victim_rgn; + struct ufshpb_region *victim_rgn = NULL; struct victim_select_info *lru_info = &hpb->lru_info; unsigned long flags; int ret = 0; @@ -1250,7 +1258,15 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) * It is okay to evict the least recently used region, * because the device could detect this region * by not issuing HPB_READ + * + * in host control mode, verify that the entering + * region has enough reads */ + if (hpb->is_hcm && rgn->reads < EVICTION_THRESHOLD) { + ret = -EACCES; + goto out; + } + victim_rgn = ufshpb_victim_lru_info(hpb); if (!victim_rgn) { dev_warn(&hpb->sdev_ufs_lu->sdev_dev, -- cgit v1.2.3-70-g09d2 From 6f4ad14f0fb9f0e6809057a46489ef3ad3a274ab Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:33 +0300 Subject: scsi: ufs: ufshpb: Region inactivation in host mode In host mode, the host is expected to send HPB WRITE BUFFER with buffer-id = 0x1 when it inactivates a region. Use the map-requests pool as there is no point in assigning a designated cache for umap-requests. [mkp: REQ_OP_DRV_*] Link: https://lore.kernel.org/r/20210712095039.8093-7-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 47 ++++++++++++++++++++++++++++++++++++++++------- drivers/scsi/ufs/ufshpb.h | 1 + 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 912bc6e5f3f8..e71fe6e31366 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -692,7 +692,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } static struct ufshpb_req *ufshpb_get_req(struct ufshpb_lu *hpb, - int rgn_idx, enum req_opf dir) + int rgn_idx, enum req_opf dir, + bool atomic) { struct ufshpb_req *rq; struct request *req; @@ -706,7 +707,7 @@ retry: req = blk_get_request(hpb->sdev_ufs_lu->request_queue, dir, BLK_MQ_REQ_NOWAIT); - if ((PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) { + if (!atomic && (PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) { usleep_range(3000, 3100); goto retry; } @@ -737,7 +738,7 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, struct ufshpb_req *map_req; struct bio *bio; - map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_DRV_IN); + map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_DRV_IN, false); if (!map_req) return NULL; @@ -914,6 +915,8 @@ static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb, rq->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH; blk_execute_rq_nowait(NULL, req, 1, ufshpb_umap_req_compl_fn); + + hpb->stats.umap_req_cnt++; } static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, @@ -1090,12 +1093,13 @@ static void ufshpb_purge_active_subregion(struct ufshpb_lu *hpb, } static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb, - struct ufshpb_region *rgn) + struct ufshpb_region *rgn, + bool atomic) { struct ufshpb_req *umap_req; int rgn_idx = rgn ? rgn->rgn_idx : 0; - umap_req = ufshpb_get_req(hpb, rgn_idx, REQ_OP_DRV_OUT); + umap_req = ufshpb_get_req(hpb, rgn_idx, REQ_OP_DRV_OUT, atomic); if (!umap_req) return -ENOMEM; @@ -1104,13 +1108,19 @@ static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb, return 0; } +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + return ufshpb_issue_umap_req(hpb, rgn, true); +} + static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb) { - return ufshpb_issue_umap_req(hpb, NULL); + return ufshpb_issue_umap_req(hpb, NULL, false); } static void __ufshpb_evict_region(struct ufshpb_lu *hpb, - struct ufshpb_region *rgn) + struct ufshpb_region *rgn) { struct victim_select_info *lru_info; struct ufshpb_subregion *srgn; @@ -1145,6 +1155,14 @@ static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) goto out; } + if (hpb->is_hcm) { + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + ret = ufshpb_issue_umap_single_req(hpb, rgn); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (ret) + goto out; + } + __ufshpb_evict_region(hpb, rgn); } out: @@ -1279,6 +1297,18 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) "LRU full (%d), choose victim %d\n", atomic_read(&lru_info->active_cnt), victim_rgn->rgn_idx); + + if (hpb->is_hcm) { + spin_unlock_irqrestore(&hpb->rgn_state_lock, + flags); + ret = ufshpb_issue_umap_single_req(hpb, + victim_rgn); + spin_lock_irqsave(&hpb->rgn_state_lock, + flags); + if (ret) + goto out; + } + __ufshpb_evict_region(hpb, victim_rgn); } @@ -1848,6 +1878,7 @@ ufshpb_sysfs_attr_show_func(rb_noti_cnt); ufshpb_sysfs_attr_show_func(rb_active_cnt); ufshpb_sysfs_attr_show_func(rb_inactive_cnt); ufshpb_sysfs_attr_show_func(map_req_cnt); +ufshpb_sysfs_attr_show_func(umap_req_cnt); static struct attribute *hpb_dev_stat_attrs[] = { &dev_attr_hit_cnt.attr, @@ -1856,6 +1887,7 @@ static struct attribute *hpb_dev_stat_attrs[] = { &dev_attr_rb_active_cnt.attr, &dev_attr_rb_inactive_cnt.attr, &dev_attr_map_req_cnt.attr, + &dev_attr_umap_req_cnt.attr, NULL, }; @@ -1981,6 +2013,7 @@ static void ufshpb_stat_init(struct ufshpb_lu *hpb) hpb->stats.rb_active_cnt = 0; hpb->stats.rb_inactive_cnt = 0; hpb->stats.map_req_cnt = 0; + hpb->stats.umap_req_cnt = 0; } static void ufshpb_param_init(struct ufshpb_lu *hpb) diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 33d163e76d41..0204e4fec6bc 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -191,6 +191,7 @@ struct ufshpb_stats { u64 rb_inactive_cnt; u64 map_req_cnt; u64 pre_req_cnt; + u64 umap_req_cnt; }; struct ufshpb_lu { -- cgit v1.2.3-70-g09d2 From 67001ff171cb4ae79774cdd13dc1d00cbfdbab66 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:34 +0300 Subject: scsi: ufs: ufshpb: Add HPB dev reset response The spec does not define what the host's recommended response is when the device sends HPB dev reset response (oper 0x2). Update all active HPB regions. Link: https://lore.kernel.org/r/20210712095039.8093-8-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 32 +++++++++++++++++++++++++++++++- drivers/scsi/ufs/ufshpb.h | 1 + 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index e71fe6e31366..8b03f34897b2 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -196,7 +196,8 @@ next_srgn: } spin_unlock(&rgn->rgn_lock); - if (activate) { + if (activate || + test_and_clear_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags)) { spin_lock_irqsave(&hpb->rsp_list_lock, flags); ufshpb_update_active_info(hpb, rgn_idx, srgn_idx); spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); @@ -1412,6 +1413,20 @@ out: queue_work(ufshpb_wq, &hpb->map_work); } +static void ufshpb_dev_reset_handler(struct ufshpb_lu *hpb) +{ + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn; + unsigned long flags; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) + set_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags); + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); +} + /* * This function will parse recommended active subregion information in sense * data field of response UPIU with SAM_STAT_GOOD state. @@ -1486,6 +1501,18 @@ void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) case HPB_RSP_DEV_RESET: dev_warn(&hpb->sdev_ufs_lu->sdev_dev, "UFS device lost HPB information during PM.\n"); + + if (hpb->is_hcm) { + struct scsi_device *sdev; + + __shost_for_each_device(sdev, hba->host) { + struct ufshpb_lu *h = sdev->hostdata; + + if (h) + ufshpb_dev_reset_handler(h); + } + } + break; default: dev_notice(&hpb->sdev_ufs_lu->sdev_dev, @@ -1811,6 +1838,8 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) } else { rgn->rgn_state = HPB_RGN_INACTIVE; } + + rgn->rgn_flags = 0; } return 0; @@ -2138,6 +2167,7 @@ static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb) { if (hpb->is_hcm) cancel_work_sync(&hpb->ufshpb_normalization_work); + cancel_work_sync(&hpb->map_work); } diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 0204e4fec6bc..43a95c670763 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -127,6 +127,7 @@ struct ufshpb_region { struct list_head list_lru_rgn; unsigned long rgn_flags; #define RGN_FLAG_DIRTY 0 +#define RGN_FLAG_UPDATE 1 /* region reads - for host mode */ spinlock_t rgn_lock; -- cgit v1.2.3-70-g09d2 From 13c044e91678d6ef099285705261418bb7b0c748 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:35 +0300 Subject: scsi: ufs: ufshpb: Add "cold" regions timer In order not to hang on to "cold" regions, we inactivate a region that has had no READ access for a predefined amount of time - READ_TO_MS. For that purpose monitor the active regions list, polling it on every POLLING_INTERVAL_MS. On timeout expiry add the region to the "to-be-inactivated" list unless it is clean and did not exhaust its READ_TO_EXPIRIES - another parameter. None of this applies to pinned regions. Link: https://lore.kernel.org/r/20210712095039.8093-9-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufshpb.h | 8 +++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 8b03f34897b2..2d8c7bc12713 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -18,6 +18,9 @@ #define ACTIVATION_THRESHOLD 8 /* 8 IOs */ #define EVICTION_THRESHOLD (ACTIVATION_THRESHOLD << 5) /* 256 IOs */ +#define READ_TO_MS 1000 +#define READ_TO_EXPIRIES 100 +#define POLLING_INTERVAL_MS 200 /* memory management */ static struct kmem_cache *ufshpb_mctx_cache; @@ -1032,12 +1035,63 @@ static int ufshpb_check_srgns_issue_state(struct ufshpb_lu *hpb, return 0; } +static void ufshpb_read_to_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, + ufshpb_read_to_work.work); + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn, *next_rgn; + unsigned long flags; + LIST_HEAD(expired_list); + + if (test_and_set_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits)) + return; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + list_for_each_entry_safe(rgn, next_rgn, &lru_info->lh_lru_rgn, + list_lru_rgn) { + bool timedout = ktime_after(ktime_get(), rgn->read_timeout); + + if (timedout) { + rgn->read_timeout_expiries--; + if (is_rgn_dirty(rgn) || + rgn->read_timeout_expiries == 0) + list_add(&rgn->list_expired_rgn, &expired_list); + else + rgn->read_timeout = ktime_add_ms(ktime_get(), + READ_TO_MS); + } + } + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + list_for_each_entry_safe(rgn, next_rgn, &expired_list, + list_expired_rgn) { + list_del_init(&rgn->list_expired_rgn); + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_update_inactive_info(hpb, rgn->rgn_idx); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + } + + ufshpb_kick_map_work(hpb); + + clear_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits); + + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(POLLING_INTERVAL_MS)); +} + static void ufshpb_add_lru_info(struct victim_select_info *lru_info, struct ufshpb_region *rgn) { rgn->rgn_state = HPB_RGN_ACTIVE; list_add_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); atomic_inc(&lru_info->active_cnt); + if (rgn->hpb->is_hcm) { + rgn->read_timeout = ktime_add_ms(ktime_get(), READ_TO_MS); + rgn->read_timeout_expiries = READ_TO_EXPIRIES; + } } static void ufshpb_hit_lru_info(struct victim_select_info *lru_info, @@ -1819,6 +1873,7 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) INIT_LIST_HEAD(&rgn->list_inact_rgn); INIT_LIST_HEAD(&rgn->list_lru_rgn); + INIT_LIST_HEAD(&rgn->list_expired_rgn); if (rgn_idx == hpb->rgns_per_lu - 1) { srgn_cnt = ((hpb->srgns_per_lu - 1) % @@ -1840,6 +1895,7 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) } rgn->rgn_flags = 0; + rgn->hpb = hpb; } return 0; @@ -2063,9 +2119,12 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) INIT_LIST_HEAD(&hpb->list_hpb_lu); INIT_WORK(&hpb->map_work, ufshpb_map_work_handler); - if (hpb->is_hcm) + if (hpb->is_hcm) { INIT_WORK(&hpb->ufshpb_normalization_work, ufshpb_normalization_work_handler); + INIT_DELAYED_WORK(&hpb->ufshpb_read_to_work, + ufshpb_read_to_handler); + } hpb->map_req_cache = kmem_cache_create("ufshpb_req_cache", sizeof(struct ufshpb_req), 0, 0, NULL); @@ -2099,6 +2158,10 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) ufshpb_stat_init(hpb); ufshpb_param_init(hpb); + if (hpb->is_hcm) + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(POLLING_INTERVAL_MS)); + return 0; release_pre_req_mempool: @@ -2165,9 +2228,10 @@ static void ufshpb_discard_rsp_lists(struct ufshpb_lu *hpb) static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb) { - if (hpb->is_hcm) + if (hpb->is_hcm) { + cancel_delayed_work_sync(&hpb->ufshpb_read_to_work); cancel_work_sync(&hpb->ufshpb_normalization_work); - + } cancel_work_sync(&hpb->map_work); } @@ -2275,6 +2339,10 @@ void ufshpb_resume(struct ufs_hba *hba) continue; ufshpb_set_state(hpb, HPB_PRESENT); ufshpb_kick_map_work(hpb); + if (hpb->is_hcm) + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(POLLING_INTERVAL_MS)); + } } diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 43a95c670763..8309b59c7819 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -115,6 +115,7 @@ struct ufshpb_subregion { }; struct ufshpb_region { + struct ufshpb_lu *hpb; struct ufshpb_subregion *srgn_tbl; enum HPB_RGN_STATE rgn_state; int rgn_idx; @@ -132,6 +133,10 @@ struct ufshpb_region { /* region reads - for host mode */ spinlock_t rgn_lock; unsigned int reads; + /* region "cold" timer - for host mode */ + ktime_t read_timeout; + unsigned int read_timeout_expiries; + struct list_head list_expired_rgn; }; #define for_each_sub_region(rgn, i, srgn) \ @@ -223,6 +228,9 @@ struct ufshpb_lu { /* for selecting victim */ struct victim_select_info lru_info; struct work_struct ufshpb_normalization_work; + struct delayed_work ufshpb_read_to_work; + unsigned long work_data_bits; +#define TIMEOUT_WORK_RUNNING 0 /* pinned region information */ u32 lu_pinned_start; -- cgit v1.2.3-70-g09d2 From 33845a2d844be6157914cf81b7170e4b12a5bf17 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:36 +0300 Subject: scsi: ufs: ufshpb: Limit the number of in-flight map requests In host control mode the host is the originator of map requests. To not flood the device with map requests, use a simple throttling mechanism that limits the number of in-flight map requests. Link: https://lore.kernel.org/r/20210712095039.8093-10-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 11 +++++++++++ drivers/scsi/ufs/ufshpb.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 2d8c7bc12713..2a463b755808 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -21,6 +21,7 @@ #define READ_TO_MS 1000 #define READ_TO_EXPIRIES 100 #define POLLING_INTERVAL_MS 200 +#define THROTTLE_MAP_REQ_DEFAULT 1 /* memory management */ static struct kmem_cache *ufshpb_mctx_cache; @@ -742,6 +743,14 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, struct ufshpb_req *map_req; struct bio *bio; + if (hpb->is_hcm && + hpb->num_inflight_map_req >= THROTTLE_MAP_REQ_DEFAULT) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, + "map_req throttle. inflight %d throttle %d", + hpb->num_inflight_map_req, THROTTLE_MAP_REQ_DEFAULT); + return NULL; + } + map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_DRV_IN, false); if (!map_req) return NULL; @@ -756,6 +765,7 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, map_req->rb.srgn_idx = srgn->srgn_idx; map_req->rb.mctx = srgn->mctx; + hpb->num_inflight_map_req++; return map_req; } @@ -765,6 +775,7 @@ static void ufshpb_put_map_req(struct ufshpb_lu *hpb, { bio_put(map_req->bio); ufshpb_put_req(hpb, map_req); + hpb->num_inflight_map_req--; } static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 8309b59c7819..edf565e9036f 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -217,6 +217,7 @@ struct ufshpb_lu { struct ufshpb_req *pre_req; int num_inflight_pre_req; int throttle_pre_req; + int num_inflight_map_req; struct list_head lh_pre_req_free; int cur_read_id; int pre_req_min_tr_len; -- cgit v1.2.3-70-g09d2 From 1afb7ddadcadb3f45b34a434ea32457050ba2119 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:37 +0300 Subject: scsi: ufs: ufshpb: Do not send umap_all in host control mode HPB WRITE BUFFER with buffer-id = 0x3h is supported in device control mode only. Link: https://lore.kernel.org/r/20210712095039.8093-11-avri.altman@wdc.com Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 2a463b755808..cb55a0864073 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2458,7 +2458,8 @@ static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba) ufshpb_set_state(hpb, HPB_PRESENT); if ((hpb->lu_pinned_end - hpb->lu_pinned_start) > 0) queue_work(ufshpb_wq, &hpb->map_work); - ufshpb_issue_umap_all_req(hpb); + if (!hpb->is_hcm) + ufshpb_issue_umap_all_req(hpb); } else { dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun); ufshpb_destroy_lu(hba, sdev); -- cgit v1.2.3-70-g09d2 From 5dea655a09e6395f461ba0f9d38914c2c0d772e4 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:38 +0300 Subject: scsi: ufs: ufshpb: Add support for host control mode Support devices that report they are using host control mode. Link: https://lore.kernel.org/r/20210712095039.8093-12-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index cb55a0864073..49f58598dba7 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2582,12 +2582,6 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; - if (hpb_dev_info->control_mode == HPB_HOST_CONTROL) { - dev_err(hba->dev, "%s: host control mode is not supported.\n", - __func__); - hpb_dev_info->hpb_disabled = true; - return; - } version = get_unaligned_be16(desc_buf + DEVICE_DESC_PARAM_HPB_VER); if ((version != HPB_SUPPORT_VERSION) && -- cgit v1.2.3-70-g09d2 From f95f59a2bb60f917faf516f2f0a679dc4e58f490 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 12 Jul 2021 12:50:39 +0300 Subject: scsi: ufs: ufshpb: Make host mode parameters configurable Elaborate some more on the host control mode logic parameters, explaining what they do and how to configure them. Link: https://lore.kernel.org/r/20210712095039.8093-13-avri.altman@wdc.com Reviewed-by: Daejun Park Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- Documentation/ABI/testing/sysfs-driver-ufs | 76 +++++++- drivers/scsi/ufs/ufshpb.c | 288 +++++++++++++++++++++++++++-- drivers/scsi/ufs/ufshpb.h | 20 ++ 3 files changed, 367 insertions(+), 17 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index 929460738651..ec3a7149ced5 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -1449,7 +1449,7 @@ Description: This entry shows the maximum HPB data size for using a single HPB The file is read only. -What: /sys/bus/platform/drivers/ufshcd/*/flags/wb_enable +What: /sys/bus/platform/drivers/ufshcd/*/flags/hpb_enable Date: June 2021 Contact: Daejun Park Description: This entry shows the status of HPB. @@ -1460,3 +1460,77 @@ Description: This entry shows the status of HPB. == ============================ The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/activation_thld +Date: February 2021 +Contact: Avri Altman +Description: In host control mode, reads are the major source of activation + trials. Once this threshold hs met, the region is added to the + "to-be-activated" list. Since we reset the read counter upon + write, this include sending a rb command updating the region + ppn as well. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/normalization_factor +Date: February 2021 +Contact: Avri Altman +Description: In host control mode, we think of the regions as "buckets". + Those buckets are being filled with reads, and emptied on write. + We use entries_per_srgn - the amount of blocks in a subregion as + our bucket size. This applies because HPB1.0 only handles + single-block reads. Once the bucket size is crossed, we trigger + a normalization work - not only to avoid overflow, but mainly + because we want to keep those counters normalized, as we are + using those reads as a comparative score, to make various decisions. + The normalization is dividing (shift right) the read counter by + the normalization_factor. If during consecutive normalizations + an active region has exhausted its reads - inactivate it. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/eviction_thld_enter +Date: February 2021 +Contact: Avri Altman +Description: Region deactivation is often due to the fact that eviction took + place: A region becomes active at the expense of another. This is + happening when the max-active-regions limit has been crossed. + In host mode, eviction is considered an extreme measure. We + want to verify that the entering region has enough reads, and + the exiting region has much fewer reads. eviction_thld_enter is + the min reads that a region must have in order to be considered + a candidate for evicting another region. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/eviction_thld_exit +Date: February 2021 +Contact: Avri Altman +Description: Same as above for the exiting region. A region is considered to + be a candidate for eviction only if it has fewer reads than + eviction_thld_exit. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/read_timeout_ms +Date: February 2021 +Contact: Avri Altman +Description: In order not to hang on to "cold" regions, we inactivate + a region that has no READ access for a predefined amount of + time - read_timeout_ms. If read_timeout_ms has expired, and the + region is dirty, it is less likely that we can make any use of + HPB reading it so we inactivate it. Still, deactivation has + its overhead, and we may still benefit from HPB reading this + region if it is clean - see read_timeout_expiries. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/read_timeout_expiries +Date: February 2021 +Contact: Avri Altman +Description: If the region read timeout has expired, but the region is clean, + just re-wind its timer for another spin. Do that as long as it + is clean and did not exhaust its read_timeout_expiries threshold. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/timeout_polling_interval_ms +Date: February 2021 +Contact: Avri Altman +Description: The frequency with which the delayed worker that checks the + read_timeouts is awakened. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/inflight_map_req +Date: February 2021 +Contact: Avri Altman +Description: In host control mode the host is the originator of map requests. + To avoid flooding the device with map requests, use a simple throttling + mechanism that limits the number of inflight map requests. diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 49f58598dba7..54e8e019bdbe 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -17,7 +17,6 @@ #include "../sd.h" #define ACTIVATION_THRESHOLD 8 /* 8 IOs */ -#define EVICTION_THRESHOLD (ACTIVATION_THRESHOLD << 5) /* 256 IOs */ #define READ_TO_MS 1000 #define READ_TO_EXPIRIES 100 #define POLLING_INTERVAL_MS 200 @@ -195,7 +194,7 @@ next_srgn: } else { srgn->reads++; rgn->reads++; - if (srgn->reads == ACTIVATION_THRESHOLD) + if (srgn->reads == hpb->params.activation_thld) activate = true; } spin_unlock(&rgn->rgn_lock); @@ -744,10 +743,11 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, struct bio *bio; if (hpb->is_hcm && - hpb->num_inflight_map_req >= THROTTLE_MAP_REQ_DEFAULT) { + hpb->num_inflight_map_req >= hpb->params.inflight_map_req) { dev_info(&hpb->sdev_ufs_lu->sdev_dev, "map_req throttle. inflight %d throttle %d", - hpb->num_inflight_map_req, THROTTLE_MAP_REQ_DEFAULT); + hpb->num_inflight_map_req, + hpb->params.inflight_map_req); return NULL; } @@ -1053,6 +1053,7 @@ static void ufshpb_read_to_handler(struct work_struct *work) struct victim_select_info *lru_info = &hpb->lru_info; struct ufshpb_region *rgn, *next_rgn; unsigned long flags; + unsigned int poll; LIST_HEAD(expired_list); if (test_and_set_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits)) @@ -1071,7 +1072,7 @@ static void ufshpb_read_to_handler(struct work_struct *work) list_add(&rgn->list_expired_rgn, &expired_list); else rgn->read_timeout = ktime_add_ms(ktime_get(), - READ_TO_MS); + hpb->params.read_timeout_ms); } } @@ -1089,8 +1090,9 @@ static void ufshpb_read_to_handler(struct work_struct *work) clear_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits); + poll = hpb->params.timeout_polling_interval_ms; schedule_delayed_work(&hpb->ufshpb_read_to_work, - msecs_to_jiffies(POLLING_INTERVAL_MS)); + msecs_to_jiffies(poll)); } static void ufshpb_add_lru_info(struct victim_select_info *lru_info, @@ -1100,8 +1102,11 @@ static void ufshpb_add_lru_info(struct victim_select_info *lru_info, list_add_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); atomic_inc(&lru_info->active_cnt); if (rgn->hpb->is_hcm) { - rgn->read_timeout = ktime_add_ms(ktime_get(), READ_TO_MS); - rgn->read_timeout_expiries = READ_TO_EXPIRIES; + rgn->read_timeout = + ktime_add_ms(ktime_get(), + rgn->hpb->params.read_timeout_ms); + rgn->read_timeout_expiries = + rgn->hpb->params.read_timeout_expiries; } } @@ -1130,7 +1135,8 @@ static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb) * in host control mode, verify that the exiting region * has fewer reads */ - if (hpb->is_hcm && rgn->reads > (EVICTION_THRESHOLD >> 1)) + if (hpb->is_hcm && + rgn->reads > hpb->params.eviction_thld_exit) continue; victim_rgn = rgn; @@ -1346,7 +1352,8 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) * in host control mode, verify that the entering * region has enough reads */ - if (hpb->is_hcm && rgn->reads < EVICTION_THRESHOLD) { + if (hpb->is_hcm && + rgn->reads < hpb->params.eviction_thld_enter) { ret = -EACCES; goto out; } @@ -1697,6 +1704,7 @@ static void ufshpb_normalization_work_handler(struct work_struct *work) struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, ufshpb_normalization_work); int rgn_idx; + u8 factor = hpb->params.normalization_factor; for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { struct ufshpb_region *rgn = hpb->rgn_tbl + rgn_idx; @@ -1707,7 +1715,7 @@ static void ufshpb_normalization_work_handler(struct work_struct *work) for (srgn_idx = 0; srgn_idx < hpb->srgns_per_rgn; srgn_idx++) { struct ufshpb_subregion *srgn = rgn->srgn_tbl + srgn_idx; - srgn->reads >>= 1; + srgn->reads >>= factor; rgn->reads += srgn->reads; } spin_unlock(&rgn->rgn_lock); @@ -2030,8 +2038,247 @@ requeue_timeout_ms_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(requeue_timeout_ms); +ufshpb_sysfs_param_show_func(activation_thld); +static ssize_t +activation_thld_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0) + return -EINVAL; + + hpb->params.activation_thld = val; + + return count; +} +static DEVICE_ATTR_RW(activation_thld); + +ufshpb_sysfs_param_show_func(normalization_factor); +static ssize_t +normalization_factor_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0 || val > ilog2(hpb->entries_per_srgn)) + return -EINVAL; + + hpb->params.normalization_factor = val; + + return count; +} +static DEVICE_ATTR_RW(normalization_factor); + +ufshpb_sysfs_param_show_func(eviction_thld_enter); +static ssize_t +eviction_thld_enter_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= hpb->params.eviction_thld_exit) + return -EINVAL; + + hpb->params.eviction_thld_enter = val; + + return count; +} +static DEVICE_ATTR_RW(eviction_thld_enter); + +ufshpb_sysfs_param_show_func(eviction_thld_exit); +static ssize_t +eviction_thld_exit_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= hpb->params.activation_thld) + return -EINVAL; + + hpb->params.eviction_thld_exit = val; + + return count; +} +static DEVICE_ATTR_RW(eviction_thld_exit); + +ufshpb_sysfs_param_show_func(read_timeout_ms); +static ssize_t +read_timeout_ms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + /* read_timeout >> timeout_polling_interval */ + if (val < hpb->params.timeout_polling_interval_ms * 2) + return -EINVAL; + + hpb->params.read_timeout_ms = val; + + return count; +} +static DEVICE_ATTR_RW(read_timeout_ms); + +ufshpb_sysfs_param_show_func(read_timeout_expiries); +static ssize_t +read_timeout_expiries_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0) + return -EINVAL; + + hpb->params.read_timeout_expiries = val; + + return count; +} +static DEVICE_ATTR_RW(read_timeout_expiries); + +ufshpb_sysfs_param_show_func(timeout_polling_interval_ms); +static ssize_t +timeout_polling_interval_ms_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + /* timeout_polling_interval << read_timeout */ + if (val <= 0 || val > hpb->params.read_timeout_ms / 2) + return -EINVAL; + + hpb->params.timeout_polling_interval_ms = val; + + return count; +} +static DEVICE_ATTR_RW(timeout_polling_interval_ms); + +ufshpb_sysfs_param_show_func(inflight_map_req); +static ssize_t inflight_map_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0 || val > hpb->sdev_ufs_lu->queue_depth - 1) + return -EINVAL; + + hpb->params.inflight_map_req = val; + + return count; +} +static DEVICE_ATTR_RW(inflight_map_req); + +static void ufshpb_hcm_param_init(struct ufshpb_lu *hpb) +{ + hpb->params.activation_thld = ACTIVATION_THRESHOLD; + hpb->params.normalization_factor = 1; + hpb->params.eviction_thld_enter = (ACTIVATION_THRESHOLD << 5); + hpb->params.eviction_thld_exit = (ACTIVATION_THRESHOLD << 4); + hpb->params.read_timeout_ms = READ_TO_MS; + hpb->params.read_timeout_expiries = READ_TO_EXPIRIES; + hpb->params.timeout_polling_interval_ms = POLLING_INTERVAL_MS; + hpb->params.inflight_map_req = THROTTLE_MAP_REQ_DEFAULT; +} + static struct attribute *hpb_dev_param_attrs[] = { &dev_attr_requeue_timeout_ms.attr, + &dev_attr_activation_thld.attr, + &dev_attr_normalization_factor.attr, + &dev_attr_eviction_thld_enter.attr, + &dev_attr_eviction_thld_exit.attr, + &dev_attr_read_timeout_ms.attr, + &dev_attr_read_timeout_expiries.attr, + &dev_attr_timeout_polling_interval_ms.attr, + &dev_attr_inflight_map_req.attr, NULL, }; @@ -2115,6 +2362,8 @@ static void ufshpb_stat_init(struct ufshpb_lu *hpb) static void ufshpb_param_init(struct ufshpb_lu *hpb) { hpb->params.requeue_timeout_ms = HPB_REQUEUE_TIME_MS; + if (hpb->is_hcm) + ufshpb_hcm_param_init(hpb); } static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) @@ -2169,9 +2418,13 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) ufshpb_stat_init(hpb); ufshpb_param_init(hpb); - if (hpb->is_hcm) + if (hpb->is_hcm) { + unsigned int poll; + + poll = hpb->params.timeout_polling_interval_ms; schedule_delayed_work(&hpb->ufshpb_read_to_work, - msecs_to_jiffies(POLLING_INTERVAL_MS)); + msecs_to_jiffies(poll)); + } return 0; @@ -2350,10 +2603,13 @@ void ufshpb_resume(struct ufs_hba *hba) continue; ufshpb_set_state(hpb, HPB_PRESENT); ufshpb_kick_map_work(hpb); - if (hpb->is_hcm) - schedule_delayed_work(&hpb->ufshpb_read_to_work, - msecs_to_jiffies(POLLING_INTERVAL_MS)); + if (hpb->is_hcm) { + unsigned int poll = + hpb->params.timeout_polling_interval_ms; + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(poll)); + } } } diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index edf565e9036f..c74a6c35a446 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -185,8 +185,28 @@ struct victim_select_info { atomic_t active_cnt; }; +/** + * ufshpb_params - ufs hpb parameters + * @requeue_timeout_ms - requeue threshold of wb command (0x2) + * @activation_thld - min reads [IOs] to activate/update a region + * @normalization_factor - shift right the region's reads + * @eviction_thld_enter - min reads [IOs] for the entering region in eviction + * @eviction_thld_exit - max reads [IOs] for the exiting region in eviction + * @read_timeout_ms - timeout [ms] from the last read IO to the region + * @read_timeout_expiries - amount of allowable timeout expireis + * @timeout_polling_interval_ms - frequency in which timeouts are checked + * @inflight_map_req - number of inflight map requests + */ struct ufshpb_params { unsigned int requeue_timeout_ms; + unsigned int activation_thld; + unsigned int normalization_factor; + unsigned int eviction_thld_enter; + unsigned int eviction_thld_exit; + unsigned int read_timeout_ms; + unsigned int read_timeout_expiries; + unsigned int timeout_polling_interval_ms; + unsigned int inflight_map_req; }; struct ufshpb_stats { -- cgit v1.2.3-70-g09d2 From 5eea6c9712bd2a707216d7b923090510d60f9663 Mon Sep 17 00:00:00 2001 From: Jordy Zomer Date: Sat, 31 Jul 2021 11:19:38 +0200 Subject: dmaengine: usb-dmac: make usb_dmac_get_current_residue unsigned The usb_dmac_get_current_residue function used to take a signed integer as a pos parameter. The only callers of this function passes an unsigned integer to it. Therefore to make it obviously safe, let's just make this an unsgined integer as this is used in pointer arithmetics. Signed-off-by: Jordy Zomer Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20210731091939.510816-1-jordy@pwning.systems Signed-off-by: Vinod Koul --- drivers/dma/sh/usb-dmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 1cc06900153e..5edaeb89d1e6 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -466,7 +466,7 @@ static int usb_dmac_chan_terminate_all(struct dma_chan *chan) static unsigned int usb_dmac_get_current_residue(struct usb_dmac_chan *chan, struct usb_dmac_desc *desc, - int sg_index) + unsigned int sg_index) { struct usb_dmac_sg *sg = desc->sg + sg_index; u32 mem_addr = sg->mem_addr & 0xffffffff; -- cgit v1.2.3-70-g09d2 From 32286e2793858a8491c2276b2754e9850467bb6b Mon Sep 17 00:00:00 2001 From: Pandith N Date: Mon, 2 Aug 2021 11:24:52 +0530 Subject: dmaengine: dw-axi-dmac: Remove free slot check algorithm in dw_axi_dma_set_hw_channel Removed free slot check algorithm in dw_axi_dma_set_hw_channel. For 8 DMA channels, use respective handshake slot in DMA_HS_SEL APB register. For every channel, an dedicated slot is provided in hardware handshake register AXIDMA_CTRL_DMA_HS_SEL_n. Peripheral source number is programmed in respective channel slots. Signed-off-by: Pandith N Tested-by: Pan Kris Link: https://lore.kernel.org/r/20210802055454.15192-2-pandith.n@intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 49 ++++++++++---------------- drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 ++ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index d9e4ac3edb4e..c3bb2b4820a3 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -470,18 +470,13 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) pm_runtime_put(chan->chip->dev); } -static void dw_axi_dma_set_hw_channel(struct axi_dma_chip *chip, - u32 handshake_num, bool set) +static void dw_axi_dma_set_hw_channel(struct axi_dma_chan *chan, bool set) { - unsigned long start = 0; - unsigned long reg_value; - unsigned long reg_mask; - unsigned long reg_set; - unsigned long mask; - unsigned long val; + struct axi_dma_chip *chip = chan->chip; + unsigned long reg_value, val; if (!chip->apb_regs) { - dev_dbg(chip->dev, "apb_regs not initialized\n"); + dev_err(chip->dev, "apb_regs not initialized\n"); return; } @@ -490,26 +485,22 @@ static void dw_axi_dma_set_hw_channel(struct axi_dma_chip *chip, * Lock the DMA channel by assign a handshake number to the channel. * Unlock the DMA channel by assign 0x3F to the channel. */ - if (set) { - reg_set = UNUSED_CHANNEL; - val = handshake_num; - } else { - reg_set = handshake_num; + if (set) + val = chan->hw_handshake_num; + else val = UNUSED_CHANNEL; - } reg_value = lo_hi_readq(chip->apb_regs + DMAC_APB_HW_HS_SEL_0); - for_each_set_clump8(start, reg_mask, ®_value, 64) { - if (reg_mask == reg_set) { - mask = GENMASK_ULL(start + 7, start); - reg_value &= ~mask; - reg_value |= rol64(val, start); - lo_hi_writeq(reg_value, - chip->apb_regs + DMAC_APB_HW_HS_SEL_0); - break; - } - } + /* Channel is already allocated, set handshake as per channel ID */ + /* 64 bit write should handle for 8 channels */ + + reg_value &= ~(DMA_APB_HS_SEL_MASK << + (chan->id * DMA_APB_HS_SEL_BIT_SIZE)); + reg_value |= (val << (chan->id * DMA_APB_HS_SEL_BIT_SIZE)); + lo_hi_writeq(reg_value, chip->apb_regs + DMAC_APB_HW_HS_SEL_0); + + return; } /* @@ -742,7 +733,7 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr, llp = hw_desc->llp; } while (total_segments); - dw_axi_dma_set_hw_channel(chan->chip, chan->hw_handshake_num, true); + dw_axi_dma_set_hw_channel(chan, true); return vchan_tx_prep(&chan->vc, &desc->vd, flags); @@ -822,7 +813,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, llp = hw_desc->llp; } while (num_sgs); - dw_axi_dma_set_hw_channel(chan->chip, chan->hw_handshake_num, true); + dw_axi_dma_set_hw_channel(chan, true); return vchan_tx_prep(&chan->vc, &desc->vd, flags); @@ -1098,8 +1089,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) "%s failed to stop\n", axi_chan_name(chan)); if (chan->direction != DMA_MEM_TO_MEM) - dw_axi_dma_set_hw_channel(chan->chip, - chan->hw_handshake_num, false); + dw_axi_dma_set_hw_channel(chan, false); if (chan->direction == DMA_MEM_TO_DEV) dw_axi_dma_set_byte_halfword(chan, false); @@ -1365,7 +1355,6 @@ static int dw_probe(struct platform_device *pdev) if (ret) return ret; - INIT_LIST_HEAD(&dw->dma.channels); for (i = 0; i < hdata->nr_channels; i++) { struct axi_dma_chan *chan = &dw->chan[i]; diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index b69897887c76..358f553cafe9 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -184,6 +184,8 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan) #define DMAC_APB_HALFWORD_WR_CH_EN 0x020 /* DMAC Halfword write enables */ #define UNUSED_CHANNEL 0x3F /* Set unused DMA channel to 0x3F */ +#define DMA_APB_HS_SEL_BIT_SIZE 0x08 /* HW handshake bits per channel */ +#define DMA_APB_HS_SEL_MASK 0xFF /* HW handshake select masks */ #define MAX_BLOCK_SIZE 0x1000 /* 1024 blocks * 4 bytes data width */ /* DMAC_CFG */ -- cgit v1.2.3-70-g09d2 From f95f3b53513d4bd846169fc42705548609494cce Mon Sep 17 00:00:00 2001 From: Pandith N Date: Mon, 2 Aug 2021 11:24:53 +0530 Subject: dmaengine: dw-axi-dmac: support parallel memory <--> peripheral transfers Added support for multiple DMA_MEM_TO_DEV, DMA_DEV_TO_MEM transfers in parallel. This is required for peripherals using DMA for transmit and receive operations at the same time. APB slot number needs to be programmed in channel hardware handshaking interface Signed-off-by: Pandith N Tested-by: Pan Kris Link: https://lore.kernel.org/r/20210802055454.15192-3-pandith.n@intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 ++++ drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index c3bb2b4820a3..3edc647271b4 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -363,12 +363,16 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, DWAXIDMAC_TT_FC_MEM_TO_PER_DST : DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC) << CH_CFG_H_TT_FC_POS; + if (chan->chip->apb_regs) + reg |= (chan->id << CH_CFG_H_DST_PER_POS); break; case DMA_DEV_TO_MEM: reg |= (chan->config.device_fc ? DWAXIDMAC_TT_FC_PER_TO_MEM_SRC : DWAXIDMAC_TT_FC_PER_TO_MEM_DMAC) << CH_CFG_H_TT_FC_POS; + if (chan->chip->apb_regs) + reg |= (chan->id << CH_CFG_H_SRC_PER_POS); break; default: break; diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 358f553cafe9..380005afde16 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -258,6 +258,8 @@ enum { /* CH_CFG_H */ #define CH_CFG_H_PRIORITY_POS 17 +#define CH_CFG_H_DST_PER_POS 12 +#define CH_CFG_H_SRC_PER_POS 7 #define CH_CFG_H_HS_SEL_DST_POS 4 #define CH_CFG_H_HS_SEL_SRC_POS 3 enum { -- cgit v1.2.3-70-g09d2 From c454d16a7d5a9af88b844d98bec50d2363c19941 Mon Sep 17 00:00:00 2001 From: Pandith N Date: Mon, 2 Aug 2021 11:24:54 +0530 Subject: dmaengine: dw-axi-dmac: Burst length settings Burst length, DMA HW capability set in dt-binding is now used in driver. Signed-off-by: Pandith N Tested-by: Pan Kris Link: https://lore.kernel.org/r/20210802055454.15192-4-pandith.n@intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index 3edc647271b4..35993ab92154 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -1290,7 +1290,7 @@ static int parse_device_properties(struct axi_dma_chip *chip) return -EINVAL; chip->dw->hdata->restrict_axi_burst_len = true; - chip->dw->hdata->axi_rw_burst_len = tmp - 1; + chip->dw->hdata->axi_rw_burst_len = tmp; } return 0; @@ -1379,6 +1379,7 @@ static int dw_probe(struct platform_device *pdev) /* DMA capabilities */ dw->dma.chancnt = hdata->nr_channels; + dw->dma.max_burst = hdata->axi_rw_burst_len; dw->dma.src_addr_widths = AXI_DMA_BUSWIDTHS; dw->dma.dst_addr_widths = AXI_DMA_BUSWIDTHS; dw->dma.directions = BIT(DMA_MEM_TO_MEM); -- cgit v1.2.3-70-g09d2 From b92e83f7c4f0e5dea11fd9aef1039d3121897391 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Mon, 26 Jul 2021 16:59:53 +0300 Subject: dmaengine: ep93xx: Prepare clock before using it Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch to Common Clock Framework, otherwise the following is visible: WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc Enabling unprepared m2p0 ... Hardware name: Cirrus Logic EDB9302 Evaluation Board ... clk_core_enable clk_core_enable_lock ep93xx_dma_alloc_chan_resources dma_chan_get find_candidate __dma_request_channel snd_dmaengine_pcm_request_channel dmaengine_pcm_new snd_soc_pcm_component_new soc_new_pcm snd_soc_bind_card edb93xx_probe ... ep93xx-i2s ep93xx-i2s: Missing dma channel for stream: 0 ep93xx-i2s ep93xx-i2s: ASoC: error at snd_soc_pcm_component_new on ep93xx-i2s: -22 edb93xx-audio edb93xx-audio: ASoC: can't create pcm CS4271 HiFi :-22 edb93xx-audio edb93xx-audio: snd_soc_register_card() failed: -22 edb93xx-audio: probe of edb93xx-audio failed with error -22 Signed-off-by: Alexander Sverdlin Signed-off-by: Nikita Shubin Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210726140001.24820-6-nikita.shubin@maquefel.me Signed-off-by: Vinod Koul --- drivers/dma/ep93xx_dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index 01027779beb8..98f9ee70362e 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -897,7 +897,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan) if (data && data->name) name = data->name; - ret = clk_enable(edmac->clk); + ret = clk_prepare_enable(edmac->clk); if (ret) return ret; @@ -936,7 +936,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan) fail_free_irq: free_irq(edmac->irq, edmac); fail_clk_disable: - clk_disable(edmac->clk); + clk_disable_unprepare(edmac->clk); return ret; } @@ -969,7 +969,7 @@ static void ep93xx_dma_free_chan_resources(struct dma_chan *chan) list_for_each_entry_safe(desc, d, &list, node) kfree(desc); - clk_disable(edmac->clk); + clk_disable_unprepare(edmac->clk); free_irq(edmac->irq, edmac); } -- cgit v1.2.3-70-g09d2 From dd861267bfecc49df5232c33d3566a334ff5e9f6 Mon Sep 17 00:00:00 2001 From: Juergen Borleis Date: Thu, 29 Jul 2021 09:18:21 +0200 Subject: dma: imx-dma: configure the generic DMA type to make it work Commit dea7a9f dmaengine: imx-dma: remove dma_slave_config direction usage changes the method from a "configuration when called" to an "configuration when used". Due to this, only the cyclic DMA type gets configured correctly, while the generic DMA type is left non-configured. Without this additional call, the struct imxdma_channel::word_size member is stuck at DMA_SLAVE_BUSWIDTH_UNDEFINED and imxdma_prep_slave_sg() always returns NULL. Signed-off-by: Juergen Borleis Link: https://lore.kernel.org/r/20210729071821.9857-1-jbe@pengutronix.de Signed-off-by: Vinod Koul --- drivers/dma/imx-dma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 7f116bbcfad2..2ddc31e64db0 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -812,6 +812,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( dma_length += sg_dma_len(sg); } + imxdma_config_write(chan, &imxdmac->config, direction); + switch (imxdmac->word_size) { case DMA_SLAVE_BUSWIDTH_4_BYTES: if (sg_dma_len(sgl) & 3 || sgl->dma_address & 3) -- cgit v1.2.3-70-g09d2 From e9c5b0b53ccca81dd0a35c62309e243a57c7959d Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Thu, 29 Jul 2021 14:04:01 +0200 Subject: dmaengine: idxd: Fix a possible NULL pointer dereference 'device_driver_attach()' dereferences its first argument (i.e. 'alt_drv') so it must not be NULL. Simplify the error handling logic about NULL 'alt_drv' in order to be more robust and future-proof. Fixes: 568b2126466f ("dmaengine: idxd: fix uninit var for alt_drv") Fixes: 6e7f3ee97bbe ("dmaengine: idxd: move dsa_drv support to compatible mode") Signed-off-by: Christophe JAILLET Acked-by: Dave Jiang Link: https://lore.kernel.org/r/77f0dc4f3966591d1f0cffb614a94085f8895a85.1627560174.git.christophe.jaillet@wanadoo.fr Signed-off-by: Vinod Koul --- drivers/dma/idxd/compat.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/dma/idxd/compat.c b/drivers/dma/idxd/compat.c index d7616c240dcd..3df21615f888 100644 --- a/drivers/dma/idxd/compat.c +++ b/drivers/dma/idxd/compat.c @@ -45,23 +45,16 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t cou idxd_dev = confdev_to_idxd_dev(dev); if (is_idxd_dev(idxd_dev)) { alt_drv = driver_find("idxd", bus); - if (!alt_drv) - return -ENODEV; } else if (is_idxd_wq_dev(idxd_dev)) { struct idxd_wq *wq = confdev_to_wq(dev); - if (is_idxd_wq_kernel(wq)) { + if (is_idxd_wq_kernel(wq)) alt_drv = driver_find("dmaengine", bus); - if (!alt_drv) - return -ENODEV; - } else if (is_idxd_wq_user(wq)) { + else if (is_idxd_wq_user(wq)) alt_drv = driver_find("user", bus); - if (!alt_drv) - return -ENODEV; - } else { - return -ENODEV; - } } + if (!alt_drv) + return -ENODEV; rc = device_driver_attach(alt_drv, dev); if (rc < 0) -- cgit v1.2.3-70-g09d2 From 614e1bb5305e82f968306bcf63be01693ac82a1f Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 2 Aug 2021 01:39:42 +0100 Subject: dt-bindings: mfd: axp20x: Add AXP305 compatible (plus optional IRQ) The AXP305 PMIC used on many boards with the H616 SoC seems to be fully compatible to the AXP805 PMIC, so add the proper chain of compatible strings. Also at least on one board (Orangepi Zero2) there is no interrupt line connected to the CPU, so make the "interrupts" property optional. Signed-off-by: Andre Przywara Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/axp20x.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index 4991a6415796..2b53dcc0ea61 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -26,10 +26,10 @@ Required properties: * "x-powers,axp803" * "x-powers,axp806" * "x-powers,axp805", "x-powers,axp806" + * "x-powers,axp305", "x-powers,axp805", "x-powers,axp806" * "x-powers,axp809" * "x-powers,axp813" - reg: The I2C slave address or RSB hardware address for the AXP chip -- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin - interrupt-controller: The PMIC has its own internal IRQs - #interrupt-cells: Should be set to 1 @@ -43,6 +43,7 @@ more information: AXP20x/LDO3: software-based implementation Optional properties: +- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin - x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz AXP152/20X: range: 750-1875, Default: 1.5 MHz AXP22X/8XX: range: 1800-4050, Default: 3 MHz -- cgit v1.2.3-70-g09d2 From ec343111c056ec3847800302f6dbc57281f833fa Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 2 Aug 2021 01:33:13 +0200 Subject: mfd: db8500-prcmu: Adjust map to reality These are the actual frequencies reported by the PLL, so let's report these. The roundoffs are inappropriate, we should round to the frequency that the clock will later report. Drop some whitespace at the same time. Cc: phone-devel@vger.kernel.org Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/db8500-prcmu.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 3bde7fda755f..dea4e4e8bed5 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -1622,22 +1622,20 @@ static long round_clock_rate(u8 clock, unsigned long rate) } static const unsigned long db8500_armss_freqs[] = { - 200000000, - 400000000, - 800000000, + 199680000, + 399360000, + 798720000, 998400000 }; /* The DB8520 has slightly higher ARMSS max frequency */ static const unsigned long db8520_armss_freqs[] = { - 200000000, - 400000000, - 800000000, + 199680000, + 399360000, + 798720000, 1152000000 }; - - static long round_armss_rate(unsigned long rate) { unsigned long freq = 0; -- cgit v1.2.3-70-g09d2 From fc65d0acaf23179b94de399c204328fa259acb90 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:03 -0700 Subject: iommu/amd: Selective flush on unmap Recent patch attempted to enable selective page flushes on AMD IOMMU but neglected to adapt amd_iommu_iotlb_sync() to use the selective flushes. Adapt amd_iommu_iotlb_sync() to use selective flushes and change amd_iommu_unmap() to collect the flushes. As a defensive measure, to avoid potential issues as those that the Intel IOMMU driver encountered recently, flush the page-walk caches by always setting the "pde" parameter. This can be removed later. Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Robin Murphy Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-2-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index a7d6d78147b7..5e4b0ee98f64 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2060,12 +2060,17 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, { struct protection_domain *domain = to_pdomain(dom); struct io_pgtable_ops *ops = &domain->iop.iop.ops; + size_t r; if ((amd_iommu_pgtable == AMD_IOMMU_V1) && (domain->iop.mode == PAGE_MODE_NONE)) return 0; - return (ops->unmap) ? ops->unmap(ops, iova, page_size, gather) : 0; + r = (ops->unmap) ? ops->unmap(ops, iova, page_size, gather) : 0; + + iommu_iotlb_gather_add_page(dom, gather, iova, page_size); + + return r; } static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, @@ -2168,7 +2173,13 @@ static void amd_iommu_flush_iotlb_all(struct iommu_domain *domain) static void amd_iommu_iotlb_sync(struct iommu_domain *domain, struct iommu_iotlb_gather *gather) { - amd_iommu_flush_iotlb_all(domain); + struct protection_domain *dom = to_pdomain(domain); + unsigned long flags; + + spin_lock_irqsave(&dom->lock, flags); + __domain_flush_pages(dom, gather->start, gather->end - gather->start, 1); + amd_iommu_domain_flush_complete(dom); + spin_unlock_irqrestore(&dom->lock, flags); } static int amd_iommu_def_domain_type(struct device *dev) -- cgit v1.2.3-70-g09d2 From 6664340cf1d541c2a44d588002893f795ab4143f Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:04 -0700 Subject: iommu/amd: Do not use flush-queue when NpCache is on Do not use flush-queue on virtualized environments, where the NpCache capability of the IOMMU is set. This is required to reduce virtualization overheads. This change follows a similar change to Intel's VT-d and a detailed explanation as for the rationale is described in commit 29b32839725f ("iommu/vt-d: Do not use flush-queue when caching-mode is on"). Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Robin Murphy Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-3-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/init.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 46280e6e1535..1c7ae7d3c55d 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -1850,8 +1850,13 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) if (ret) return ret; - if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) + if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) { + if (!amd_iommu_unmap_flush) + pr_info("IOMMU batching is disabled due to virtualization\n"); + amd_iommu_np_cache = true; + amd_iommu_unmap_flush = true; + } init_iommu_perf_ctr(iommu); -- cgit v1.2.3-70-g09d2 From 3136895cc5b665c1ab406d78f90c0700a3551e74 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 23 Jul 2021 02:32:05 -0700 Subject: iommu: Improve iommu_iotlb_gather helpers The Mediatek driver is not the only one which might want a basic address-based gathering behaviour, so although it's arguably simple enough to open-code, let's factor it out for the sake of cleanliness. Let's also take this opportunity to document the intent of these helpers for clarity. Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Robin Murphy Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Robin Murphy Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-4-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/mtk_iommu.c | 6 +----- include/linux/iommu.h | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 6f7c69688ce2..d9939e4af35c 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -520,12 +520,8 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain, struct iommu_iotlb_gather *gather) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); - unsigned long end = iova + size - 1; - if (gather->start > iova) - gather->start = iova; - if (gather->end < end) - gather->end = end; + iommu_iotlb_gather_add_range(gather, iova, size); return dom->iop->unmap(dom->iop, iova, size, gather); } diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 32d448050bf7..e554871db46f 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -497,6 +497,38 @@ static inline void iommu_iotlb_sync(struct iommu_domain *domain, iommu_iotlb_gather_init(iotlb_gather); } +/** + * iommu_iotlb_gather_add_range - Gather for address-based TLB invalidation + * @gather: TLB gather data + * @iova: start of page to invalidate + * @size: size of page to invalidate + * + * Helper for IOMMU drivers to build arbitrarily-sized invalidation commands + * where only the address range matters, and simply minimising intermediate + * syncs is preferred. + */ +static inline void iommu_iotlb_gather_add_range(struct iommu_iotlb_gather *gather, + unsigned long iova, size_t size) +{ + unsigned long end = iova + size - 1; + + if (gather->start > iova) + gather->start = iova; + if (gather->end < end) + gather->end = end; +} + +/** + * iommu_iotlb_gather_add_page - Gather for page-based TLB invalidation + * @domain: IOMMU domain to be invalidated + * @gather: TLB gather data + * @iova: start of page to invalidate + * @size: size of page to invalidate + * + * Helper for IOMMU drivers to build invalidation commands based on individual + * pages, or with page size/table level hints which cannot be gathered if they + * differ. + */ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain, struct iommu_iotlb_gather *gather, unsigned long iova, size_t size) @@ -515,11 +547,7 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain, gather->pgsize = size; } - if (gather->end < end) - gather->end = end; - - if (gather->start > start) - gather->start = start; + iommu_iotlb_gather_add_range(gather, iova, size); } /* PCI device grouping function */ -- cgit v1.2.3-70-g09d2 From febb82c208e481eee057c70fa3176bb48712a111 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:06 -0700 Subject: iommu: Factor iommu_iotlb_gather_is_disjoint() out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor iommu_iotlb_gather_add_page() and factor out the logic that detects whether IOTLB gather range and a new range are disjoint. To be used by the next patch that implements different gathering logic for AMD. Note that updating gather->pgsize unconditionally does not affect correctness as the function had (and has) an invariant, in which gather->pgsize always represents the flushing granularity of its range. Arguably, “size" should never be zero, but lets assume for the matter of discussion that it might. If "size" equals to "gather->pgsize", then the assignment in question has no impact. Otherwise, if "size" is non-zero, then iommu_iotlb_sync() would initialize the size and range (see iommu_iotlb_gather_init()), and the invariant is kept. Otherwise, "size" is zero, and "gather" already holds a range, so gather->pgsize is non-zero and (gather->pgsize && gather->pgsize != size) is true. Therefore, again, iommu_iotlb_sync() would be called and initialize the size. Cc: Joerg Roedel Cc: Jiajun Cao Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org> Reviewed-by: Robin Murphy Acked-by: Will Deacon Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-5-namit@vmware.com Signed-off-by: Joerg Roedel --- include/linux/iommu.h | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e554871db46f..979a5ceeea55 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -497,6 +497,28 @@ static inline void iommu_iotlb_sync(struct iommu_domain *domain, iommu_iotlb_gather_init(iotlb_gather); } +/** + * iommu_iotlb_gather_is_disjoint - Checks whether a new range is disjoint + * + * @gather: TLB gather data + * @iova: start of page to invalidate + * @size: size of page to invalidate + * + * Helper for IOMMU drivers to check whether a new range and the gathered range + * are disjoint. For many IOMMUs, flushing the IOMMU in this case is better + * than merging the two, which might lead to unnecessary invalidations. + */ +static inline +bool iommu_iotlb_gather_is_disjoint(struct iommu_iotlb_gather *gather, + unsigned long iova, size_t size) +{ + unsigned long start = iova, end = start + size - 1; + + return gather->end != 0 && + (end + 1 < gather->start || start > gather->end + 1); +} + + /** * iommu_iotlb_gather_add_range - Gather for address-based TLB invalidation * @gather: TLB gather data @@ -533,20 +555,16 @@ static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain, struct iommu_iotlb_gather *gather, unsigned long iova, size_t size) { - unsigned long start = iova, end = start + size - 1; - /* * If the new page is disjoint from the current range or is mapped at * a different granularity, then sync the TLB so that the gather * structure can be rewritten. */ - if (gather->pgsize != size || - end + 1 < gather->start || start > gather->end + 1) { - if (gather->pgsize) - iommu_iotlb_sync(domain, gather); - gather->pgsize = size; - } + if ((gather->pgsize && gather->pgsize != size) || + iommu_iotlb_gather_is_disjoint(gather, iova, size)) + iommu_iotlb_sync(domain, gather); + gather->pgsize = size; iommu_iotlb_gather_add_range(gather, iova, size); } -- cgit v1.2.3-70-g09d2 From fe6d269d0e9b05fa5233f810a3cb7cce4077b261 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:07 -0700 Subject: iommu/amd: Tailored gather logic for AMD AMD's IOMMU can flush efficiently (i.e., in a single flush) any range. This is in contrast, for instnace, to Intel IOMMUs that have a limit on the number of pages that can be flushed in a single flush. In addition, AMD's IOMMU do not care about the page-size, so changes of the page size do not need to trigger a TLB flush. So in most cases, a TLB flush due to disjoint range is not needed for AMD. Yet, vIOMMUs require the hypervisor to synchronize the virtualized IOMMU's PTEs with the physical ones. This process induce overheads, so it is better not to cause unnecessary flushes, i.e., flushes of PTEs that were not modified. Implement and use amd_iommu_iotlb_gather_add_page() and use it instead of the generic iommu_iotlb_gather_add_page(). Ignore disjoint regions unless "non-present cache" feature is reported by the IOMMU capabilities, as this is an indication we are running on a physical IOMMU. A similar indication is used by VT-d (see "caching mode"). The new logic retains the same flushing behavior that we had before the introduction of page-selective IOTLB flushes for AMD. On virtualized environments, check if the newly flushed region and the gathered one are disjoint and flush if it is. Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org> Reviewed-by: Robin Murphy Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-6-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 5e4b0ee98f64..0957be3b6274 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2054,6 +2054,27 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, return ret; } +static void amd_iommu_iotlb_gather_add_page(struct iommu_domain *domain, + struct iommu_iotlb_gather *gather, + unsigned long iova, size_t size) +{ + /* + * AMD's IOMMU can flush as many pages as necessary in a single flush. + * Unless we run in a virtual machine, which can be inferred according + * to whether "non-present cache" is on, it is probably best to prefer + * (potentially) too extensive TLB flushing (i.e., more misses) over + * mutliple TLB flushes (i.e., more flushes). For virtual machines the + * hypervisor needs to synchronize the host IOMMU PTEs with those of + * the guest, and the trade-off is different: unnecessary TLB flushes + * should be avoided. + */ + if (amd_iommu_np_cache && + iommu_iotlb_gather_is_disjoint(gather, iova, size)) + iommu_iotlb_sync(domain, gather); + + iommu_iotlb_gather_add_range(gather, iova, size); +} + static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, size_t page_size, struct iommu_iotlb_gather *gather) @@ -2068,7 +2089,7 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, r = (ops->unmap) ? ops->unmap(ops, iova, page_size, gather) : 0; - iommu_iotlb_gather_add_page(dom, gather, iova, page_size); + amd_iommu_iotlb_gather_add_page(dom, gather, iova, page_size); return r; } -- cgit v1.2.3-70-g09d2 From 3b122a5666cb7c0bb9a439fba0c9a6cf59f999c3 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:08 -0700 Subject: iommu/amd: Sync once for scatter-gather operations On virtual machines, software must flush the IOTLB after each page table entry update. The iommu_map_sg() code iterates through the given scatter-gather list and invokes iommu_map() for each element in the scatter-gather list, which calls into the vendor IOMMU driver through iommu_ops callback. As the result, a single sg mapping may lead to multiple IOTLB flushes. Fix this by adding amd_iotlb_sync_map() callback and flushing at this point after all sg mappings we set. This commit is followed and inspired by commit 933fcd01e97e2 ("iommu/vt-d: Add iotlb_sync_map callback"). Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Robin Murphy Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-7-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 0957be3b6274..cee91cdf0016 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -2028,6 +2028,16 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, return ret; } +static void amd_iommu_iotlb_sync_map(struct iommu_domain *dom, + unsigned long iova, size_t size) +{ + struct protection_domain *domain = to_pdomain(dom); + struct io_pgtable_ops *ops = &domain->iop.iop.ops; + + if (ops->map) + domain_flush_np_cache(domain, iova, size); +} + static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, phys_addr_t paddr, size_t page_size, int iommu_prot, gfp_t gfp) @@ -2046,10 +2056,8 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, if (iommu_prot & IOMMU_WRITE) prot |= IOMMU_PROT_IW; - if (ops->map) { + if (ops->map) ret = ops->map(ops, iova, paddr, page_size, prot, gfp); - domain_flush_np_cache(domain, iova, page_size); - } return ret; } @@ -2229,6 +2237,7 @@ const struct iommu_ops amd_iommu_ops = { .attach_dev = amd_iommu_attach_device, .detach_dev = amd_iommu_detach_device, .map = amd_iommu_map, + .iotlb_sync_map = amd_iommu_iotlb_sync_map, .unmap = amd_iommu_unmap, .iova_to_phys = amd_iommu_iova_to_phys, .probe_device = amd_iommu_probe_device, -- cgit v1.2.3-70-g09d2 From a270be1b3fdfb6940dd692c859fdf9a7407047be Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Fri, 23 Jul 2021 02:32:09 -0700 Subject: iommu/amd: Use only natural aligned flushes in a VM When running on an AMD vIOMMU, it is better to avoid TLB flushes of unmodified PTEs. vIOMMUs require the hypervisor to synchronize the virtualized IOMMU's PTEs with the physical ones. This process induce overheads. AMD IOMMU allows us to flush any range that is aligned to the power of 2. So when running on top of a vIOMMU, break the range into sub-ranges that are naturally aligned, and flush each one separately. This apporach is better when running with a vIOMMU, but on physical IOMMUs, the penalty of IOTLB misses due to unnecessary flushed entries is likely to be low. Repurpose (i.e., keeping the name, changing the logic) domain_flush_pages() so it is used to choose whether to perform one flush of the whole range or multiple ones to avoid flushing unnecessary ranges. Use NpCache, as usual, to infer whether the IOMMU is physical or virtual. Cc: Joerg Roedel Cc: Will Deacon Cc: Jiajun Cao Cc: Lu Baolu Cc: iommu@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Suggested-by: Robin Murphy Signed-off-by: Nadav Amit Link: https://lore.kernel.org/r/20210723093209.714328-8-namit@vmware.com Signed-off-by: Joerg Roedel --- drivers/iommu/amd/iommu.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index cee91cdf0016..fb5c40715d10 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1267,15 +1267,52 @@ static void __domain_flush_pages(struct protection_domain *domain, } static void domain_flush_pages(struct protection_domain *domain, - u64 address, size_t size) + u64 address, size_t size, int pde) { - __domain_flush_pages(domain, address, size, 0); + if (likely(!amd_iommu_np_cache)) { + __domain_flush_pages(domain, address, size, pde); + return; + } + + /* + * When NpCache is on, we infer that we run in a VM and use a vIOMMU. + * In such setups it is best to avoid flushes of ranges which are not + * naturally aligned, since it would lead to flushes of unmodified + * PTEs. Such flushes would require the hypervisor to do more work than + * necessary. Therefore, perform repeated flushes of aligned ranges + * until you cover the range. Each iteration flushes the smaller + * between the natural alignment of the address that we flush and the + * greatest naturally aligned region that fits in the range. + */ + while (size != 0) { + int addr_alignment = __ffs(address); + int size_alignment = __fls(size); + int min_alignment; + size_t flush_size; + + /* + * size is always non-zero, but address might be zero, causing + * addr_alignment to be negative. As the casting of the + * argument in __ffs(address) to long might trim the high bits + * of the address on x86-32, cast to long when doing the check. + */ + if (likely((unsigned long)address != 0)) + min_alignment = min(addr_alignment, size_alignment); + else + min_alignment = size_alignment; + + flush_size = 1ul << min_alignment; + + __domain_flush_pages(domain, address, flush_size, pde); + address += flush_size; + size -= flush_size; + } } /* Flush the whole IO/TLB for a given protection domain - including PDE */ void amd_iommu_domain_flush_tlb_pde(struct protection_domain *domain) { - __domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1); + domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1); } void amd_iommu_domain_flush_complete(struct protection_domain *domain) @@ -1302,7 +1339,7 @@ static void domain_flush_np_cache(struct protection_domain *domain, unsigned long flags; spin_lock_irqsave(&domain->lock, flags); - domain_flush_pages(domain, iova, size); + domain_flush_pages(domain, iova, size, 1); amd_iommu_domain_flush_complete(domain); spin_unlock_irqrestore(&domain->lock, flags); } @@ -2206,7 +2243,7 @@ static void amd_iommu_iotlb_sync(struct iommu_domain *domain, unsigned long flags; spin_lock_irqsave(&dom->lock, flags); - __domain_flush_pages(dom, gather->start, gather->end - gather->start, 1); + domain_flush_pages(dom, gather->start, gather->end - gather->start, 1); amd_iommu_domain_flush_complete(dom); spin_unlock_irqrestore(&dom->lock, flags); } -- cgit v1.2.3-70-g09d2 From 5c08c5acdc6ce46296a0f98d06896c818b8b34e0 Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 22 Jun 2021 00:36:34 +0800 Subject: iommu/arm-smmu-v3: Remove some unneeded init in arm_smmu_cmdq_issue_cmdlist() Members of struct "llq" will be zero-inited, apart from member max_n_shift. But we write llq.val straight after the init, so it was pointless to zero init those other members. As such, separately init member max_n_shift only. In addition, struct "head" is initialised to "llq" only so that member max_n_shift is set. But that member is never referenced for "head", so remove any init there. Removing these initializations is seen as a small performance optimisation, as this code is (very) hot path. Signed-off-by: John Garry Link: https://lore.kernel.org/r/1624293394-202509-1-git-send-email-john.garry@huawei.com Signed-off-by: Will Deacon --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 235f9bdaeaf2..952291840c76 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -733,11 +733,11 @@ static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu, unsigned long flags; bool owner; struct arm_smmu_cmdq *cmdq = &smmu->cmdq; - struct arm_smmu_ll_queue llq = { - .max_n_shift = cmdq->q.llq.max_n_shift, - }, head = llq; + struct arm_smmu_ll_queue llq, head; int ret = 0; + llq.max_n_shift = cmdq->q.llq.max_n_shift; + /* 1. Allocate some space in the queue */ local_irq_save(flags); llq.val = READ_ONCE(cmdq->q.llq.val); -- cgit v1.2.3-70-g09d2 From ea0056f09a74d96ddad11b0c484961c011baba08 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Wed, 14 Jul 2021 09:50:00 +0800 Subject: perf trace: Update cmd string table to decode sys_bpf first arg As 'enum bpf_cmd' has been extended a lot, update the cmd string table to decode sys_bpf first arg clearly in perf-trace. Signed-off-by: Wei Li Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andrii Nakryiko Cc: Daniel Borkmann Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Li Bin Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Song Liu Cc: Yonghong Song Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20210714015000.2844867-1-liwei391@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9c265fa96011..8f3582eb5254 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -707,7 +707,15 @@ static size_t syscall_arg__scnprintf_char_array(char *bf, size_t size, struct sy static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", - "MAP_GET_NEXT_KEY", "PROG_LOAD", + "MAP_GET_NEXT_KEY", "PROG_LOAD", "OBJ_PIN", "OBJ_GET", "PROG_ATTACH", + "PROG_DETACH", "PROG_TEST_RUN", "PROG_GET_NEXT_ID", "MAP_GET_NEXT_ID", + "PROG_GET_FD_BY_ID", "MAP_GET_FD_BY_ID", "OBJ_GET_INFO_BY_FD", + "PROG_QUERY", "RAW_TRACEPOINT_OPEN", "BTF_LOAD", "BTF_GET_FD_BY_ID", + "TASK_FD_QUERY", "MAP_LOOKUP_AND_DELETE_ELEM", "MAP_FREEZE", + "BTF_GET_NEXT_ID", "MAP_LOOKUP_BATCH", "MAP_LOOKUP_AND_DELETE_BATCH", + "MAP_UPDATE_BATCH", "MAP_DELETE_BATCH", "LINK_CREATE", "LINK_UPDATE", + "LINK_GET_FD_BY_ID", "LINK_GET_NEXT_ID", "ENABLE_STATS", "ITER_CREATE", + "LINK_DETACH", "PROG_BIND_MAP", }; static DEFINE_STRARRAY(bpf_cmd, "BPF_"); -- cgit v1.2.3-70-g09d2 From 6f38e1158bba17c5e45236ac7eedb0a6cbbc2ded Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:01:57 +0100 Subject: perf cs-etm: Refactor initialisation of kernel start address The kernel start address is already cached in the machine struct once it is initialised, so storing it in the cs_etm struct is unnecessary. It also depends on kernel maps being available to be initialised. Therefore cs_etm__setup_queues() isn't an appropriate place to call it because it could be called before processing starts. It would be better to initialise it at the point when it is needed, then we can be sure that all the necessary maps are available. Also by calling machine__kernel_start() multiple times it can be initialised at some point, even if it failed to initialise previously due to missing maps. In a later commit cs_etm__setup_queues() will be moved which is the motivation for this change. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Al Grant Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Cc: coresight@lists.linaro.org Link: https://lore.kernel.org/r/20210721150202.32065-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index bc1f64873c8f..4c69ef391f60 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -62,7 +62,6 @@ struct cs_etm_auxtrace { u64 instructions_sample_period; u64 instructions_id; u64 **metadata; - u64 kernel_start; unsigned int pmu_type; }; @@ -691,7 +690,7 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address) machine = etmq->etm->machine; - if (address >= etmq->etm->kernel_start) { + if (address >= machine__kernel_start(machine)) { if (machine__is_host(machine)) return PERF_RECORD_MISC_KERNEL; else @@ -901,9 +900,6 @@ static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm) unsigned int i; int ret; - if (!etm->kernel_start) - etm->kernel_start = machine__kernel_start(etm->machine); - for (i = 0; i < etm->queues.nr_queues; i++) { ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i); if (ret) -- cgit v1.2.3-70-g09d2 From 9ac8afd500e4597edd52b9469368c0126bb42124 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:01:58 +0100 Subject: perf cs-etm: Split setup and timestamp search functions This refactoring has some benefits: * Decoding is done to find the timestamp. If we want to print errors when maps aren't available, then doing it from cs_etm__setup_queue() may cause warnings to be printed. * The cs_etm__setup_queue() flow is shared between timed and timeless modes, so it needs to be guarded by an if statement which can now be removed. * Allows moving the setup queues function earlier. * If data was piped in, then not all queues would be filled so it wouldn't have worked properly anyway. Now it waits for flush so data in all queues will be available. The motivation for this is to decouple setup functions with ones that involve decoding. That way we can move the setup function earlier when the formatted/unformatted trace information is available. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https //lore.kernel.org/r/20210721150202.32065-3-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 4c69ef391f60..426e99c07ca9 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -809,29 +809,32 @@ static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue, unsigned int queue_nr) { - int ret = 0; - unsigned int cs_queue_nr; - u8 trace_chan_id; - u64 cs_timestamp; struct cs_etm_queue *etmq = queue->priv; if (list_empty(&queue->head) || etmq) - goto out; + return 0; etmq = cs_etm__alloc_queue(etm); - if (!etmq) { - ret = -ENOMEM; - goto out; - } + if (!etmq) + return -ENOMEM; queue->priv = etmq; etmq->etm = etm; etmq->queue_nr = queue_nr; etmq->offset = 0; - if (etm->timeless_decoding) - goto out; + return 0; +} + +static int cs_etm__queue_first_cs_timestamp(struct cs_etm_auxtrace *etm, + struct cs_etm_queue *etmq, + unsigned int queue_nr) +{ + int ret = 0; + unsigned int cs_queue_nr; + u8 trace_chan_id; + u64 cs_timestamp; /* * We are under a CPU-wide trace scenario. As such we need to know @@ -2218,13 +2221,27 @@ static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, static int cs_etm__process_queues(struct cs_etm_auxtrace *etm) { int ret = 0; - unsigned int cs_queue_nr, queue_nr; + unsigned int cs_queue_nr, queue_nr, i; u8 trace_chan_id; u64 cs_timestamp; struct auxtrace_queue *queue; struct cs_etm_queue *etmq; struct cs_etm_traceid_queue *tidq; + /* + * Pre-populate the heap with one entry from each queue so that we can + * start processing in time order across all queues. + */ + for (i = 0; i < etm->queues.nr_queues; i++) { + etmq = etm->queues.queue_array[i].priv; + if (!etmq) + continue; + + ret = cs_etm__queue_first_cs_timestamp(etm, etmq, i); + if (ret) + return ret; + } + while (1) { if (!etm->heap.heap_cnt) goto out; -- cgit v1.2.3-70-g09d2 From ca50db5917cbb963e87c925422bee5851f55bd7f Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:01:59 +0100 Subject: perf cs-etm: Only setup queues when they are modified Continually creating queues in cs_etm__process_event() is unnecessary. They only need to be created when a buffer for a new CPU or thread is encountered. This can be in two places, when building the queues in advance in cs_etm__process_auxtrace_info(), or in cs_etm__process_auxtrace_event() when data_queued is false and the index wasn't available (pipe mode). This change will allow the 'formatted' decoder setting to applied when iterating over aux records in a later commit. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https //lore.kernel.org/r/20210721150202.32065-4-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 54 +++++++++++++----------------------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 426e99c07ca9..2d07e52ffd3c 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -96,7 +96,6 @@ struct cs_etm_queue { /* RB tree for quick conversion between traceID and metadata pointers */ static struct intlist *traceid_list; -static int cs_etm__update_queues(struct cs_etm_auxtrace *etm); static int cs_etm__process_queues(struct cs_etm_auxtrace *etm); static int cs_etm__process_timeless_queues(struct cs_etm_auxtrace *etm, pid_t tid); @@ -564,7 +563,6 @@ out_free: static int cs_etm__flush_events(struct perf_session *session, struct perf_tool *tool) { - int ret; struct cs_etm_auxtrace *etm = container_of(session->auxtrace, struct cs_etm_auxtrace, auxtrace); @@ -574,11 +572,6 @@ static int cs_etm__flush_events(struct perf_session *session, if (!tool->ordered_events) return -EINVAL; - ret = cs_etm__update_queues(etm); - - if (ret < 0) - return ret; - if (etm->timeless_decoding) return cs_etm__process_timeless_queues(etm, -1); @@ -898,30 +891,6 @@ out: return ret; } -static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm) -{ - unsigned int i; - int ret; - - for (i = 0; i < etm->queues.nr_queues; i++) { - ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i); - if (ret) - return ret; - } - - return 0; -} - -static int cs_etm__update_queues(struct cs_etm_auxtrace *etm) -{ - if (etm->queues.new_data) { - etm->queues.new_data = false; - return cs_etm__setup_queues(etm); - } - - return 0; -} - static inline void cs_etm__copy_last_branch_rb(struct cs_etm_queue *etmq, struct cs_etm_traceid_queue *tidq) @@ -2395,7 +2364,6 @@ static int cs_etm__process_event(struct perf_session *session, struct perf_sample *sample, struct perf_tool *tool) { - int err = 0; u64 sample_kernel_timestamp; struct cs_etm_auxtrace *etm = container_of(session->auxtrace, struct cs_etm_auxtrace, @@ -2414,12 +2382,6 @@ static int cs_etm__process_event(struct perf_session *session, else sample_kernel_timestamp = 0; - if (sample_kernel_timestamp || etm->timeless_decoding) { - err = cs_etm__update_queues(etm); - if (err) - return err; - } - /* * Don't wait for cs_etm__flush_events() in per-thread/timeless mode to start the decode. We * need the tid of the PERF_RECORD_EXIT event to assign to the synthesised samples because @@ -2476,6 +2438,7 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, int fd = perf_data__fd(session->data); bool is_pipe = perf_data__is_pipe(session->data); int err; + int idx = event->auxtrace.idx; if (is_pipe) data_offset = 0; @@ -2490,6 +2453,11 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, if (err) return err; + err = cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], + idx); + if (err) + return err; + if (dump_trace) if (auxtrace_buffer__get_data(buffer, fd)) { cs_etm__dump_event(etm, buffer); @@ -2732,6 +2700,7 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o struct perf_record_auxtrace *auxtrace_event; union perf_event auxtrace_fragment; __u64 aux_offset, aux_size; + __u32 idx; struct cs_etm_auxtrace *etm = container_of(session->auxtrace, struct cs_etm_auxtrace, @@ -2793,8 +2762,13 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64 " tid: %d cpu: %d\n", aux_size, aux_offset, sample->tid, sample->cpu); - return auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment, - file_offset, NULL); + err = auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment, + file_offset, NULL); + if (err) + return err; + + idx = auxtrace_event->idx; + return cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], idx); } /* Wasn't inside this buffer, but there were no parse errors. 1 == 'not found' */ -- cgit v1.2.3-70-g09d2 From b8324f490be886b0e9026f1258fc2db3c9556d86 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:02:00 +0100 Subject: perf cs-etm: Suppress printing when resetting decoder The decoder is quite noisy when being reset. In a future commit, dump-raw-trace will use a code path that resets the decoder rather than creating a new one, so printing has to be suppressed to not flood the output. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https //lore.kernel.org/r/20210721150202.32065-5-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 3e1a05bc82cc..ed1f0326f859 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -35,6 +35,7 @@ struct cs_etm_decoder { void *data; void (*packet_printer)(const char *msg); + bool suppress_printing; dcd_tree_handle_t dcd_tree; cs_etm_mem_cb_type mem_access; ocsd_datapath_resp_t prev_return; @@ -74,9 +75,10 @@ int cs_etm_decoder__reset(struct cs_etm_decoder *decoder) ocsd_datapath_resp_t dp_ret; decoder->prev_return = OCSD_RESP_CONT; - + decoder->suppress_printing = true; dp_ret = ocsd_dt_process_data(decoder->dcd_tree, OCSD_OP_RESET, 0, 0, NULL, NULL); + decoder->suppress_printing = false; if (OCSD_DATA_RESP_IS_FATAL(dp_ret)) return -1; @@ -146,8 +148,10 @@ static void cs_etm_decoder__print_str_cb(const void *p_context, const char *msg, const int str_len) { - if (p_context && str_len) - ((struct cs_etm_decoder *)p_context)->packet_printer(msg); + const struct cs_etm_decoder *decoder = p_context; + + if (p_context && str_len && !decoder->suppress_printing) + decoder->packet_printer(msg); } static int -- cgit v1.2.3-70-g09d2 From 04aaad262c9aae822c9f108bf6b0ac131e0ec690 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:02:01 +0100 Subject: perf cs-etm: Use existing decoder instead of resetting it When dumping trace, the decoder is continually deleted and recreated to decode each buffer. To support both formatted and unformatted trace in a later commit, the decoder will be configured in advance. This commit removes the deletion of the decoder and allows the formatted/unformatted setting to persist. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https //lore.kernel.org/r/20210721150202.32065-6-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 2d07e52ffd3c..760050ea936d 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -508,14 +508,11 @@ out: return ret; } -static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, +static void cs_etm__dump_event(struct cs_etm_queue *etmq, struct auxtrace_buffer *buffer) { int ret; const char *color = PERF_COLOR_BLUE; - struct cs_etm_decoder_params d_params; - struct cs_etm_trace_params *t_params; - struct cs_etm_decoder *decoder; size_t buffer_used = 0; fprintf(stdout, "\n"); @@ -523,29 +520,11 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, ". ... CoreSight ETM Trace data: size %zu bytes\n", buffer->size); - /* Use metadata to fill in trace parameters for trace decoder */ - t_params = zalloc(sizeof(*t_params) * etm->num_cpu); - - if (!t_params) - return; - - if (cs_etm__init_trace_params(t_params, etm)) - goto out_free; - - /* Set decoder parameters to simply print the trace packets */ - if (cs_etm__init_decoder_params(&d_params, NULL, - CS_ETM_OPERATION_PRINT)) - goto out_free; - - decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params); - - if (!decoder) - goto out_free; do { size_t consumed; ret = cs_etm_decoder__process_data_block( - decoder, buffer->offset, + etmq->decoder, buffer->offset, &((u8 *)buffer->data)[buffer_used], buffer->size - buffer_used, &consumed); if (ret) @@ -554,10 +533,7 @@ static void cs_etm__dump_event(struct cs_etm_auxtrace *etm, buffer_used += consumed; } while (buffer_used < buffer->size); - cs_etm_decoder__free(decoder); - -out_free: - zfree(&t_params); + cs_etm_decoder__reset(etmq->decoder); } static int cs_etm__flush_events(struct perf_session *session, @@ -769,7 +745,8 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm) /* Set decoder parameters to decode trace packets */ if (cs_etm__init_decoder_params(&d_params, etmq, - CS_ETM_OPERATION_DECODE)) + dump_trace ? CS_ETM_OPERATION_PRINT : + CS_ETM_OPERATION_DECODE)) goto out_free; etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params); @@ -2422,7 +2399,7 @@ static void dump_queued_data(struct cs_etm_auxtrace *etm, for (i = 0; i < etm->queues.nr_queues; ++i) list_for_each_entry(buf, &etm->queues.queue_array[i].head, list) if (buf->reference == event->reference) - cs_etm__dump_event(etm, buf); + cs_etm__dump_event(etm->queues.queue_array[i].priv, buf); } static int cs_etm__process_auxtrace_event(struct perf_session *session, @@ -2460,7 +2437,7 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, if (dump_trace) if (auxtrace_buffer__get_data(buffer, fd)) { - cs_etm__dump_event(etm, buffer); + cs_etm__dump_event(etm->queues.queue_array[idx].priv, buffer); auxtrace_buffer__put_data(buffer); } } else if (dump_trace) -- cgit v1.2.3-70-g09d2 From 9182f04a85b2c2062bbf4f8e53bec9ce698d55f0 Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 21 Jul 2021 16:02:02 +0100 Subject: perf cs-etm: Pass unformatted flag to decoder The TRBE (Trace Buffer Extension) feature allows a separate trace buffer for each trace source, therefore the trace wouldn't need to be formatted. The driver was introduced in commit 3fbf7f011f24 ("coresight: sink: Add TRBE driver"). The formatted/unformatted mode is encoded in one of the flags of the AUX record. The first AUX record encountered for each event is used to determine the mode, and this will persist for the remaining trace that is either decoded or dumped. Reviewed-by: Mathieu Poirier Signed-off-by: James Clark Cc: Al Grant Cc: Alexander Shishkin Cc: Anshuman Khandual Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https //lore.kernel.org/r/20210721150202.32065-7-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 4 +- tools/perf/util/cs-etm.c | 53 +++++++++++++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index ed1f0326f859..9c9039ae6989 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -687,7 +687,7 @@ cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params *d_params, } struct cs_etm_decoder * -cs_etm_decoder__new(int num_cpu, struct cs_etm_decoder_params *d_params, +cs_etm_decoder__new(int decoders, struct cs_etm_decoder_params *d_params, struct cs_etm_trace_params t_params[]) { struct cs_etm_decoder *decoder; @@ -732,7 +732,7 @@ cs_etm_decoder__new(int num_cpu, struct cs_etm_decoder_params *d_params, /* init raw frame logging if required */ cs_etm_decoder__init_raw_frame_logging(d_params, decoder); - for (i = 0; i < num_cpu; i++) { + for (i = 0; i < decoders; i++) { ret = cs_etm_decoder__create_etm_decoder(d_params, &t_params[i], decoder); diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 760050ea936d..f4b2bff533f3 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -461,13 +461,14 @@ static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params, } static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params, - struct cs_etm_auxtrace *etm) + struct cs_etm_auxtrace *etm, + int decoders) { int i; u32 etmidr; u64 architecture; - for (i = 0; i < etm->num_cpu; i++) { + for (i = 0; i < decoders; i++) { architecture = etm->metadata[i][CS_ETM_MAGIC]; switch (architecture) { @@ -488,7 +489,8 @@ static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params, static int cs_etm__init_decoder_params(struct cs_etm_decoder_params *d_params, struct cs_etm_queue *etmq, - enum cs_etm_decoder_operation mode) + enum cs_etm_decoder_operation mode, + bool formatted) { int ret = -EINVAL; @@ -498,7 +500,7 @@ static int cs_etm__init_decoder_params(struct cs_etm_decoder_params *d_params, d_params->packet_printer = cs_etm__packet_dump; d_params->operation = mode; d_params->data = etmq; - d_params->formatted = true; + d_params->formatted = formatted; d_params->fsyncs = false; d_params->hsyncs = false; d_params->frame_aligned = true; @@ -720,11 +722,17 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, return len; } -static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm) +static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, + bool formatted) { struct cs_etm_decoder_params d_params; struct cs_etm_trace_params *t_params = NULL; struct cs_etm_queue *etmq; + /* + * Each queue can only contain data from one CPU when unformatted, so only one decoder is + * needed. + */ + int decoders = formatted ? etm->num_cpu : 1; etmq = zalloc(sizeof(*etmq)); if (!etmq) @@ -735,21 +743,23 @@ static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm) goto out_free; /* Use metadata to fill in trace parameters for trace decoder */ - t_params = zalloc(sizeof(*t_params) * etm->num_cpu); + t_params = zalloc(sizeof(*t_params) * decoders); if (!t_params) goto out_free; - if (cs_etm__init_trace_params(t_params, etm)) + if (cs_etm__init_trace_params(t_params, etm, decoders)) goto out_free; /* Set decoder parameters to decode trace packets */ if (cs_etm__init_decoder_params(&d_params, etmq, dump_trace ? CS_ETM_OPERATION_PRINT : - CS_ETM_OPERATION_DECODE)) + CS_ETM_OPERATION_DECODE, + formatted)) goto out_free; - etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params); + etmq->decoder = cs_etm_decoder__new(decoders, &d_params, + t_params); if (!etmq->decoder) goto out_free; @@ -777,14 +787,15 @@ out_free: static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue, - unsigned int queue_nr) + unsigned int queue_nr, + bool formatted) { struct cs_etm_queue *etmq = queue->priv; if (list_empty(&queue->head) || etmq) return 0; - etmq = cs_etm__alloc_queue(etm); + etmq = cs_etm__alloc_queue(etm, formatted); if (!etmq) return -ENOMEM; @@ -2430,8 +2441,14 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, if (err) return err; + /* + * Knowing if the trace is formatted or not requires a lookup of + * the aux record so only works in non-piped mode where data is + * queued in cs_etm__queue_aux_records(). Always assume + * formatted in piped mode (true). + */ err = cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], - idx); + idx, true); if (err) return err; @@ -2678,6 +2695,7 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o union perf_event auxtrace_fragment; __u64 aux_offset, aux_size; __u32 idx; + bool formatted; struct cs_etm_auxtrace *etm = container_of(session->auxtrace, struct cs_etm_auxtrace, @@ -2745,7 +2763,9 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o return err; idx = auxtrace_event->idx; - return cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], idx); + formatted = !(aux_event->flags & PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW); + return cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], + idx, formatted); } /* Wasn't inside this buffer, but there were no parse errors. 1 == 'not found' */ @@ -3034,6 +3054,13 @@ int cs_etm__process_auxtrace_info(union perf_event *event, goto err_delete_thread; etm->data_queued = etm->queues.populated; + /* + * Print warning in pipe mode, see cs_etm__process_auxtrace_event() and + * cs_etm__queue_aux_fragment() for details relating to limitations. + */ + if (!etm->data_queued) + pr_warning("CS ETM warning: Coresight decode and TRBE support requires random file access.\n" + "Continuing with best effort decoding in piped mode.\n\n"); return 0; -- cgit v1.2.3-70-g09d2 From 6f6e7f065c8414c5dffa8b4a6b427062007035c3 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:37 -0700 Subject: perf doc: Fix perfman.info build Before this change 'make perfman.info' fails as cat-texi.perl is missing. It also fails as the makeinfo output isn't written into the appropriate file. Add cat-texi.perl from git. Add missing output file flag for makeinfo. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 2 +- tools/perf/Documentation/cat-texi.perl | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100755 tools/perf/Documentation/cat-texi.perl diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 6e54979c2124..859ec1496716 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -331,7 +331,7 @@ $(OUTPUT)perfman.texi: $(MAN_XML) cat-texi.perl mv $@+ $@ $(OUTPUT)perfman.info: $(OUTPUT)perfman.texi - $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi + $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate -o $@ $*.texi $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ diff --git a/tools/perf/Documentation/cat-texi.perl b/tools/perf/Documentation/cat-texi.perl new file mode 100755 index 000000000000..14d2f8341517 --- /dev/null +++ b/tools/perf/Documentation/cat-texi.perl @@ -0,0 +1,46 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +my @menu = (); +my $output = $ARGV[0]; + +open my $tmp, '>', "$output.tmp"; + +while () { + next if (/^\\input texinfo/../\@node Top/); + next if (/^\@bye/ || /^\.ft/); + if (s/^\@top (.*)/\@node $1,,,Top/) { + push @menu, $1; + } + s/\(\@pxref\{\[(URLS|REMOTES)\]}\)//; + s/\@anchor\{[^{}]*\}//g; + print $tmp $_; +} +close $tmp; + +print '\input texinfo +@setfilename gitman.info +@documentencoding UTF-8 +@dircategory Development +@direntry +* Git Man Pages: (gitman). Manual pages for Git revision control system +@end direntry +@node Top,,, (dir) +@top Git Manual Pages +@documentlanguage en +@menu +'; + +for (@menu) { + print "* ${_}::\n"; +} +print "\@end menu\n"; +open $tmp, '<', "$output.tmp"; +while (<$tmp>) { + print; +} +close $tmp; +print "\@bye\n"; +unlink "$output.tmp"; -- cgit v1.2.3-70-g09d2 From a81df63a5df3e195868236f2f77cfccf298950a2 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:38 -0700 Subject: perf doc: Fix doc.dep The doc.dep dependencies for the Makefile fail to build as build-docdep.perl is missing. Add this file from git. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-3-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/build-docdep.perl | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 tools/perf/Documentation/build-docdep.perl diff --git a/tools/perf/Documentation/build-docdep.perl b/tools/perf/Documentation/build-docdep.perl new file mode 100755 index 000000000000..ba4205e0302a --- /dev/null +++ b/tools/perf/Documentation/build-docdep.perl @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +my %include = (); +my %included = (); + +for my $text (<*.txt>) { + open I, '<', $text || die "cannot read: $text"; + while () { + if (/^include::/) { + chomp; + s/^include::\s*//; + s/\[\]//; + $include{$text}{$_} = 1; + $included{$_} = 1; + } + } + close I; +} + +# Do we care about chained includes??? +my $changed = 1; +while ($changed) { + $changed = 0; + while (my ($text, $included) = each %include) { + for my $i (keys %$included) { + # $text has include::$i; if $i includes $j + # $text indirectly includes $j. + if (exists $include{$i}) { + for my $j (keys %{$include{$i}}) { + if (!exists $include{$text}{$j}) { + $include{$text}{$j} = 1; + $included{$j} = 1; + $changed = 1; + } + } + } + } + } +} + +while (my ($text, $included) = each %include) { + if (! exists $included{$text} && + (my $base = $text) =~ s/\.txt$//) { + print "$base.html $base.xml : ", join(" ", keys %$included), "\n"; + } +} -- cgit v1.2.3-70-g09d2 From 33e536103f227c41d00d91056b3f936dac513f14 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:39 -0700 Subject: perf doc: Remove references to user-manual Perf doesn't have a user-manual.txt, but git does and this explains why there are references here. Having these references breaks 'make info' as user-manual.info can't be created given the missing dependency. Remove all references to user-manual so that 'make info' can succeed. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-4-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 859ec1496716..03300c151858 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -186,8 +186,6 @@ man7: $(DOC_MAN7) info: $(OUTPUT)perf.info $(OUTPUT)perfman.info -pdf: $(OUTPUT)user-manual.pdf - install: install-man check-man-tools: @@ -225,11 +223,6 @@ install-info: info echo "No directory found in $(DESTDIR)$(infodir)" >&2 ; \ fi -install-pdf: pdf - $(call QUIET_INSTALL, Documentation-pdf) \ - $(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir); \ - $(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir) - #install-html: html # '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir) @@ -304,24 +297,6 @@ $(OUTPUT)%.xml : %.txt XSLT = docbook.xsl XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css -$(OUTPUT)user-manual.html: $(OUTPUT)user-manual.xml - $(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $< - -$(OUTPUT)perf.info: $(OUTPUT)user-manual.texi - $(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ $(OUTPUT)user-manual.texi - -$(OUTPUT)user-manual.texi: $(OUTPUT)user-manual.xml - $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ - $(DOCBOOK2X_TEXI) $(OUTPUT)user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \ - $(PERL_PATH) fix-texi.perl <$@++ >$@+ && \ - rm $@++ && \ - mv $@+ $@ - -$(OUTPUT)user-manual.pdf: $(OUTPUT)user-manual.xml - $(QUIET_DBLATEX)$(RM) $@+ $@ && \ - $(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $< && \ - mv $@+ $@ - $(OUTPUT)perfman.texi: $(MAN_XML) cat-texi.perl $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ ($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \ -- cgit v1.2.3-70-g09d2 From 361ac7b462d3efacad5c70e15441dcbf914e2b4a Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:40 -0700 Subject: perf doc: Add info pages to all target. Enabled to ensure that info pages build. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-5-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 03300c151858..85a796c112a2 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -173,7 +173,7 @@ ifneq ($(V),1) endif endif -all: html man +all: html man info html: $(DOC_HTML) -- cgit v1.2.3-70-g09d2 From e30b992f0854d45bd192cfbfa2afcdb14fa4ec44 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:41 -0700 Subject: perf doc: Remove cmd-list.perl references cmd-list.perl exists in git but not in perf. As such these targets fail with missing dependencies. Remove them. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-6-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 85a796c112a2..c5ec17ee5bb0 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -237,24 +237,6 @@ $(OUTPUT)doc.dep : $(wildcard *.txt) build-docdep.perl -include $(OUTPUT)doc.dep -_cmds_txt = cmds-ancillaryinterrogators.txt \ - cmds-ancillarymanipulators.txt \ - cmds-mainporcelain.txt \ - cmds-plumbinginterrogators.txt \ - cmds-plumbingmanipulators.txt \ - cmds-synchingrepositories.txt \ - cmds-synchelpers.txt \ - cmds-purehelpers.txt \ - cmds-foreignscminterface.txt -cmds_txt=$(addprefix $(OUTPUT),$(_cmds_txt)) - -$(cmds_txt): $(OUTPUT)cmd-list.made - -$(OUTPUT)cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) - $(QUIET_GEN)$(RM) $@ && \ - $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \ - date >$@ - CLEAN_FILES = \ $(MAN_XML) $(addsuffix +,$(MAN_XML)) \ $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ @@ -262,8 +244,7 @@ CLEAN_FILES = \ $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++ \ $(OUTPUT)perf.info $(OUTPUT)perfman.info \ $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep \ - $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt \ - $(cmds_txt) $(OUTPUT)*.made + $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt clean: $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) -- cgit v1.2.3-70-g09d2 From 17ef1f14f62bc17bffadd1d7844bee6220934e20 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:42 -0700 Subject: perf doc: Remove howto-index.sh related references. howto-index.sh exists in git but not in perf, as such targets that depend upon it fail. Remove such failing targets. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-7-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index c5ec17ee5bb0..9d991b14ac4b 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -242,8 +242,7 @@ CLEAN_FILES = \ $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \ $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7) \ $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++ \ - $(OUTPUT)perf.info $(OUTPUT)perfman.info \ - $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep \ + $(OUTPUT)perf.info $(OUTPUT)perfman.info $(OUTPUT)doc.dep \ $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt clean: $(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES) @@ -294,21 +293,11 @@ $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml $(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+ && \ mv $@+ $@ -howto-index.txt: howto-index.sh $(wildcard howto/*.txt) - $(QUIET_GEN)$(RM) $@+ $@ && \ - '$(SHELL_PATH_SQ)' ./howto-index.sh $(wildcard howto/*.txt) >$@+ && \ - mv $@+ $@ - $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt $(QUIET_ASCIIDOC)$(ASCIIDOC) -b $(ASCIIDOC_HTML) $*.txt WEBDOC_DEST = /pub/software/tools/perf/docs -$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - sed -e '1,/^$$/d' $< | $(ASCIIDOC) -b $(ASCIIDOC_HTML) - >$@+ && \ - mv $@+ $@ - # UNIMPLEMENTED #install-webdoc : html # '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(WEBDOC_DEST) -- cgit v1.2.3-70-g09d2 From c44fc5af3cdcd7e414b793903054e4e9b0999306 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 14 Jul 2021 18:33:43 -0700 Subject: perf doc: Reorganize ARTICLES variables. Place early, as they are in the git Makefile. Remove references to a 'technical` directory that doesn't exist in perf. Signed-off-by: Ian Rogers Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mark Rutland Cc: Peter Zijlstra Cc: Stephane Eranian Link: https //lore.kernel.org/r/20210715013343.2286699-8-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 9d991b14ac4b..6e7b88917ca0 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -2,6 +2,10 @@ include ../../scripts/Makefile.include include ../../scripts/utilities.mak +ARTICLES = +# with their own formatting rules. +SP_ARTICLES = + MAN1_TXT= \ $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ $(wildcard perf-*.txt)) \ @@ -16,13 +20,6 @@ _MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML)) MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML)) -ARTICLES = -# with their own formatting rules. -SP_ARTICLES = -API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) -SP_ARTICLES += $(API_DOCS) -SP_ARTICLES += technical/api-index - _DOC_HTML = $(_MAN_HTML) _DOC_HTML+=$(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES)) DOC_HTML=$(addprefix $(OUTPUT),$(_DOC_HTML)) -- cgit v1.2.3-70-g09d2 From f463ad7f41d3a042653f55959c77e28db56cb312 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Wed, 12 May 2021 23:04:41 -0700 Subject: perf beauty: Reuse the generic arch errno switch Previously the code would see if, for example, tools/perf/arch/arm/include/uapi/asm/errno.h exists and if not generate a "generic" switch statement using the asm-generic/errno.h. This creates multiple identical "generic" switch statements before the default generic switch statement for an unknown architecture. By simplifying the archlist to be only for architectures that are not "generic" the amount of generated code can be reduced from 14 down to 6 functions. Remove the special case of x86, instead reverse the architecture names so that it comes first. Committer testing: $ tools/perf/trace/beauty/arch_errno_names.sh gcc tools > before Apply this patch and: $ tools/perf/trace/beauty/arch_errno_names.sh gcc tools > after 14 arches down to 6, that are the ones with an explicit errno.h file: $ ls -1 tools/arch/*/include/uapi/asm/errno.h tools/arch/alpha/include/uapi/asm/errno.h tools/arch/mips/include/uapi/asm/errno.h tools/arch/parisc/include/uapi/asm/errno.h tools/arch/powerpc/include/uapi/asm/errno.h tools/arch/sparc/include/uapi/asm/errno.h tools/arch/x86/include/uapi/asm/errno.h $ $ diff -u4 before after @@ -2099,32 +987,16 @@ const char *arch_syscalls__strerrno(const char *arch, int err) { if (!strcmp(arch, "x86")) return errno_to_name__x86(err); - if (!strcmp(arch, "alpha")) - return errno_to_name__alpha(err); - if (!strcmp(arch, "arc")) - return errno_to_name__arc(err); - if (!strcmp(arch, "arm")) - return errno_to_name__arm(err); - if (!strcmp(arch, "arm64")) - return errno_to_name__arm64(err); - if (!strcmp(arch, "csky")) - return errno_to_name__csky(err); - if (!strcmp(arch, "mips")) - return errno_to_name__mips(err); - if (!strcmp(arch, "parisc")) - return errno_to_name__parisc(err); - if (!strcmp(arch, "powerpc")) - return errno_to_name__powerpc(err); - if (!strcmp(arch, "riscv")) - return errno_to_name__riscv(err); - if (!strcmp(arch, "s390")) - return errno_to_name__s390(err); - if (!strcmp(arch, "sh")) - return errno_to_name__sh(err); if (!strcmp(arch, "sparc")) return errno_to_name__sparc(err); - if (!strcmp(arch, "xtensa")) - return errno_to_name__xtensa(err); + if (!strcmp(arch, "powerpc")) + return errno_to_name__powerpc(err); + if (!strcmp(arch, "parisc")) + return errno_to_name__parisc(err); + if (!strcmp(arch, "mips")) + return errno_to_name__mips(err); + if (!strcmp(arch, "alpha")) + return errno_to_name__alpha(err); return errno_to_name__generic(err); } The rest of the patch is the removal of the errno_to_name__generic() unneeded clones. Signed-off-by: Ian Rogers Tested-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210513060441.408507-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/arch_errno_names.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/perf/trace/beauty/arch_errno_names.sh b/tools/perf/trace/beauty/arch_errno_names.sh index 9f9ea45cddc4..2c5f72fa8108 100755 --- a/tools/perf/trace/beauty/arch_errno_names.sh +++ b/tools/perf/trace/beauty/arch_errno_names.sh @@ -87,14 +87,13 @@ cat < Date: Mon, 26 Jul 2021 20:38:53 +0800 Subject: perf env: Normalize aarch64.* and arm64.* to arm64 in normalize_arch() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my aarch64 big endian machine, the perf annotate does not work. # perf annotate Percent | Source code & Disassembly of [kernel.kallsyms] for cycles (253 samples, percent: local period) -------------------------------------------------------------------------------------------------------------- Percent | Source code & Disassembly of [kernel.kallsyms] for cycles (1 samples, percent: local period) ------------------------------------------------------------------------------------------------------------ Percent | Source code & Disassembly of [kernel.kallsyms] for cycles (47 samples, percent: local period) ------------------------------------------------------------------------------------------------------------- ... This is because the arch_find() function uses the normalized architecture name provided by normalize_arch(), and my machine's architecture name aarch64_be is not normalized to arm64. Like other architectures such as arm and powerpc, we can fuzzy match the architecture names associated with aarch64.* and normalize them. It seems that there is also arm64_be architecture name, which we also normalize to arm64. Signed-off-by: Li Huafei Reviewed-by: James Clark Cc: Alexander Shishkin Cc: Dengcheng Zhu Cc: Ian Rogers Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Martin Liška Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Zhang Jinhao Link: http //lore.kernel.org/lkml/20210726123854.13463-1-lihuafei1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/env.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index cec2e6cad8aa..ab341050be46 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -349,7 +349,7 @@ static const char *normalize_arch(char *arch) return "x86"; if (!strcmp(arch, "sun4u") || !strncmp(arch, "sparc", 5)) return "sparc"; - if (!strcmp(arch, "aarch64") || !strcmp(arch, "arm64")) + if (!strncmp(arch, "aarch64", 7) || !strncmp(arch, "arm64", 5)) return "arm64"; if (!strncmp(arch, "arm", 3) || !strcmp(arch, "sa110")) return "arm"; -- cgit v1.2.3-70-g09d2 From c4db54be9bc00f9f6883de798de99744b30ed461 Mon Sep 17 00:00:00 2001 From: Li Huafei Date: Mon, 26 Jul 2021 20:38:54 +0800 Subject: perf annotate: Add error log in symbol__annotate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When users use 'perf annotate' on unsupported machines, error logs should be printed for user feedback. Signed-off-by: Li Huafei Reviewed-by: James Clark Cc: Alexander Shishkin Cc: Dengcheng Zhu Cc: Ian Rogers Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Martin Liška Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Zhang Jinhao Link: http://lore.kernel.org/lkml/20210726123854.13463-2-lihuafei1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index aa04a3655236..cb280de3369f 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2192,8 +2192,10 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, return errno; args.arch = arch = arch__find(arch_name); - if (arch == NULL) + if (arch == NULL) { + pr_err("%s: unsupported arch %s\n", __func__, arch_name); return ENOTSUP; + } if (parch) *parch = arch; -- cgit v1.2.3-70-g09d2 From 4babba5572e6adf99039beef8408f700dc45f464 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 16 Jul 2021 11:03:40 +0800 Subject: perf vendor events intel: Add core event list for Tigerlake Add JSON core events for Tigerlake to perf. Based on JSON list v1.03: https://download.01.org/perfmon/TGL/ Reviewed-by: Andi Kleen Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719070058.4159-1-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/arch/x86/mapfile.csv | 2 +- .../perf/pmu-events/arch/x86/tigerlake/cache.json | 595 +++++++++++++ .../arch/x86/tigerlake/floating-point.json | 94 ++ .../pmu-events/arch/x86/tigerlake/frontend.json | 463 ++++++++++ .../perf/pmu-events/arch/x86/tigerlake/memory.json | 295 +++++++ .../perf/pmu-events/arch/x86/tigerlake/other.json | 189 ++++ .../pmu-events/arch/x86/tigerlake/pipeline.json | 982 +++++++++++++++++++++ .../arch/x86/tigerlake/virtual-memory.json | 225 +++++ 8 files changed, 2844 insertions(+), 1 deletion(-) create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/cache.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/floating-point.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/frontend.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/memory.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/other.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/pipeline.json create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/virtual-memory.json diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 5f5df6560202..37382343d25f 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -36,7 +36,7 @@ GenuineIntel-6-55-[01234],v1,skylakex,core GenuineIntel-6-55-[56789ABCDEF],v1,cascadelakex,core GenuineIntel-6-7D,v1,icelake,core GenuineIntel-6-7E,v1,icelake,core -GenuineIntel-6-8[CD],v1,icelake,core +GenuineIntel-6-8[CD],v1,tigerlake,core GenuineIntel-6-A7,v1,icelake,core GenuineIntel-6-6A,v1,icelakex,core GenuineIntel-6-6C,v1,icelakex,core diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/cache.json b/tools/perf/pmu-events/arch/x86/tigerlake/cache.json new file mode 100644 index 000000000000..8d767b8932b0 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/cache.json @@ -0,0 +1,595 @@ +[ + { + "BriefDescription": "Counts the number of cache lines replaced in L1 data cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x51", + "EventName": "L1D.REPLACEMENT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailability.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.FB_FULL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D Fill Buffer (FB) unavailablability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailablability.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.FB_FULL_PERIODS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of phases a demand request has waited due to L1D Fill Buffer (FB) unavailablability. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of cycles a demand request has waited due to L1D due to lack of L2 resources.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.L2_STALL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of cycles a demand request has waited due to L1D due to lack of L2 resources. Demand requests include cacheable/uncacheable demand load, store, lock or SW prefetch accesses.", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of L1D misses that are outstanding", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts number of L1D misses that are outstanding in each cycle, that is each cycle the number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch. Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles with L1D load Misses outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "L2 cache lines filling L2", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xf1", + "EventName": "L2_LINES_IN.ALL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", + "SampleAfterValue": "100003", + "UMask": "0x1f" + }, + { + "BriefDescription": "Modified cache lines that are evicted by L2 cache when triggered by an L2 cache fill.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xf2", + "EventName": "L2_LINES_OUT.NON_SILENT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines are in Modified state. Modified lines are written back to L3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Non-modified cache lines that are silently dropped by L2 cache when triggered by an L2 cache fill.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xf2", + "EventName": "L2_LINES_OUT.SILENT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared or Exclusive state. A non-threaded event.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "L2 code requests", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of L2 code requests.", + "SampleAfterValue": "200003", + "UMask": "0xe4" + }, + { + "BriefDescription": "RFO requests to L2 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_RFO", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "SampleAfterValue": "200003", + "UMask": "0xe2" + }, + { + "BriefDescription": "L2 cache hits when fetching instructions, code reads.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "SampleAfterValue": "200003", + "UMask": "0xc4" + }, + { + "BriefDescription": "L2 cache misses when fetching instructions", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "SampleAfterValue": "200003", + "UMask": "0x24" + }, + { + "BriefDescription": "All requests that miss L2 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.MISS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x3f" + }, + { + "BriefDescription": "RFO requests that hit L2 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xc2" + }, + { + "BriefDescription": "RFO requests that miss L2 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_MISS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x22" + }, + { + "BriefDescription": "SW prefetch requests that hit L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.SWPF_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts Software prefetch requests that hit the L2 cache. This event accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions.", + "SampleAfterValue": "200003", + "UMask": "0xc8" + }, + { + "BriefDescription": "SW prefetch requests that miss L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "L2_RQSTS.SWPF_MISS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts Software prefetch requests that miss the L2 cache. This event accounts for PREFETCHNTA and PREFETCHT0/1/2 instructions.", + "SampleAfterValue": "200003", + "UMask": "0x28" + }, + { + "BriefDescription": "L2 writebacks that access L2 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xf0", + "EventName": "L2_TRANS.L2_WB", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts L2 writebacks that access L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x40" + }, + { + "BriefDescription": "Cycles when L1D is locked", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x63", + "EventName": "LOCK_CYCLES.CACHE_LOCK_DURATION", + "PEBScounters": "0,1,2,3", + "PublicDescription": "This event counts the number of cycles when the L1D is locked. It is a superset of the 0x1 mask (BUS_LOCK_CLOCKS.BUS_LOCK_DURATION).", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "All retired load instructions.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all retired load instructions. This event accounts for SW prefetch instructions for loads.", + "SampleAfterValue": "1000003", + "UMask": "0x81" + }, + { + "BriefDescription": "All retired store instructions.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all retired store instructions. This event account for SW prefetch instructions and PREFETCHW instruction for stores.", + "SampleAfterValue": "1000003", + "UMask": "0x82" + }, + { + "BriefDescription": "Retired load instructions with locked access.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with locked access.", + "SampleAfterValue": "100007", + "UMask": "0x21" + }, + { + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x41" + }, + { + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x42" + }, + { + "BriefDescription": "Retired load instructions that miss the STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions that true miss the STLB.", + "SampleAfterValue": "100003", + "UMask": "0x11" + }, + { + "BriefDescription": "Retired store instructions that miss the STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired store instructions that true miss the STLB.", + "SampleAfterValue": "100003", + "UMask": "0x12" + }, + { + "BriefDescription": "TBD", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_FWD", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "20011", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the retired load instructions whose data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "SampleAfterValue": "20011", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions whose data sources were hits in L3 without snoops required", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions whose data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "TBD", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NO_FWD", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "20011", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of completed demand load requests that missed the L1, but hit the FB(fill buffer), because a preceding miss to the same cacheline initiated the line to be brought into L1, but data is not yet ready in L1.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", + "SampleAfterValue": "100007", + "UMask": "0x40" + }, + { + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "200003", + "UMask": "0x8" + }, + { + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "100021", + "UMask": "0x10" + }, + { + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", + "SampleAfterValue": "100021", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", + "SampleAfterValue": "50021", + "UMask": "0x20" + }, + { + "BriefDescription": "Demand and prefetch data reads", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xb0", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Any memory transaction that reached the SQ.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xb0", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Demand Data Read requests sent to uncore", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xb0", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xb0", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Demand Data Read transactions pending for off-core. Highly correlated.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of off-core outstanding Demand Data Read transactions every cycle. A transaction is considered to be in the Off-core outstanding state between L2 cache miss and data-return to the core.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "6", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Store Read transactions pending for off-core. Highly correlated.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of off-core outstanding read-for-ownership (RFO) store transactions every cycle. An RFO transaction is considered to be in the Off-core outstanding state between L2 cache miss and transaction completion.", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles the superQ cannot take any more entries.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xf4", + "EventName": "SQ_MISC.SQ_FULL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the cycles for which the thread is active and the superQ cannot take any more entries.", + "SampleAfterValue": "100003", + "UMask": "0x4" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/floating-point.json b/tools/perf/pmu-events/arch/x86/tigerlake/floating-point.json new file mode 100644 index 000000000000..402f01851313 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/floating-point.json @@ -0,0 +1,94 @@ +[ + { + "BriefDescription": "Counts all microcode FP assists.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc1", + "EventName": "ASSISTS.FP", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all microcode Floating Point assists.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT RCP DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT14 RCP14 FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computational operation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT RSQRT RCP FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc7", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x2" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/frontend.json b/tools/perf/pmu-events/arch/x86/tigerlake/frontend.json new file mode 100644 index 000000000000..24c736ac8f8e --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/frontend.json @@ -0,0 +1,463 @@ +[ + { + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.ANY", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE transitions count.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0xab", + "EventName": "DSB2MITE_SWITCHES.COUNT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of Decode Stream Buffer (DSB a.k.a. Uop Cache)-to-MITE speculative transitions.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "DSB-to-MITE switch true penalty cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xab", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Decode Stream Buffer (DSB) is a Uop-cache that holds translations of previously fetched instructions that were decoded by the legacy x86 decode pipeline (MITE). This event counts fetch penalty cycles when a transition occurs from DSB to MITE.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired Instructions who experienced DSB miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.DSB_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x11", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x14", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.L1I_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x12", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions who experienced Instruction L1 Cache true miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.L2_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x13", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions who experienced Instruction L2 Cache true miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x500106", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "MSRIndex": "0x3F7", + "MSRValue": "0x508006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", + "MSRIndex": "0x3F7", + "MSRValue": "0x501006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions after front-end starvation of at least 2 cycles", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", + "MSRIndex": "0x3F7", + "MSRValue": "0x500206", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 2 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "MSRIndex": "0x3F7", + "MSRValue": "0x510006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x100206", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "MSRValue": "0x502006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", + "MSRIndex": "0x3F7", + "MSRValue": "0x500406", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "MSRValue": "0x520006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_64", + "MSRIndex": "0x3F7", + "MSRValue": "0x504006", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "MSRIndex": "0x3F7", + "MSRValue": "0x500806", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.STLB_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x15", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x80", + "EventName": "ICACHE_16B.IFDATA_STALL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", + "SampleAfterValue": "500009", + "UMask": "0x4" + }, + { + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity. Accounts for both cacheable and uncacheable accesses.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_MISS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity. Accounts for both cacheable and uncacheable accesses.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_STALL", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.DSB_CYCLES_ANY", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles DSB is delivering optimal number of Uops", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "5", + "EventCode": "0x79", + "EventName": "IDQ.DSB_CYCLES_OK", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x79", + "EventName": "IDQ.DSB_UOPS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles MITE is delivering any Uop", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MITE_CYCLES_ANY", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles MITE is delivering optimal number of Uops", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "5", + "EventCode": "0x79", + "EventName": "IDQ.MITE_CYCLES_OK", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles where optimal number of uops was delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x79", + "EventName": "IDQ.MITE_UOPS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles when uops are being delivered to IDQ while MS is busy", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MS_CYCLES_ANY", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", + "SampleAfterValue": "2000003", + "UMask": "0x30" + }, + { + "BriefDescription": "Number of switches from DSB or MITE to the MS", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x79", + "EventName": "IDQ.MS_SWITCHES", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", + "SampleAfterValue": "100003", + "UMask": "0x30" + }, + { + "BriefDescription": "Uops delivered to IDQ while MS is busy", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x79", + "EventName": "IDQ.MS_UOPS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "SampleAfterValue": "100003", + "UMask": "0x30" + }, + { + "BriefDescription": "Uops not delivered by IDQ when backend of the machine is not stalled", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x9c", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of uops not delivered to by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles when no uops are not delivered by the IDQ when backend of the machine is not stalled", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "5", + "EventCode": "0x9c", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of cycles when no uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles when optimal number of uops was delivered to the back-end when the back-end is not stalled", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x9c", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of cycles when the optimal number of uops were delivered by the Instruction Decode Queue (IDQ) to the back-end of the pipeline when there was no back-end stalls. This event counts for one SMT thread in a given cycle.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/memory.json b/tools/perf/pmu-events/arch/x86/tigerlake/memory.json new file mode 100644 index 000000000000..0948de0b160c --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/memory.json @@ -0,0 +1,295 @@ +[ + { + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "6", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x6" + }, + { + "BriefDescription": "Number of machine clears due to memory ordering conflicts.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of Machine Clears detected dye to memory ordering. Memory Ordering Machine Clears may apply when a memory read may not conform to the memory ordering rules of the x86 architecture", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "MSRValue": "0x80", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "1009", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "MSRValue": "0x10", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "20011", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "MSRValue": "0x100", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "503", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "MSRValue": "0x20", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "MSRValue": "0x4", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "100003", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "MSRValue": "0x200", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "101", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "MSRValue": "0x40", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "2003", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "MSRValue": "0x8", + "PEBS": "2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "50021", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Demand Data Read requests who miss L3 cache", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xb0", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an RTM execution aborted.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.ABORTED", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times RTM abort was triggered.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.ABORTED_EVENTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times an RTM execution aborted due to incompatible memory type.", + "SampleAfterValue": "100003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times an RTM execution successfully committed", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.COMMIT", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times RTM commit succeeded.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an RTM execution started.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc9", + "EventName": "RTM_RETIRED.START", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of times we entered an RTM region. Does not count nested transactions.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed inside a transactional region", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts Unfriendly TSX abort triggered by a vzeroupper instruction.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an instruction execution caused the transactional nest count supported to be exceeded", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC3", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts Unfriendly TSX abort triggered by a nest count that is too deep.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Speculatively counts the number of TSX aborts due to a data capacity limitation for transactional reads", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CAPACITY_READ", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Speculatively counts the number of Transactional Synchronization Extensions (TSX) aborts due to a data capacity limitation for transactional reads", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Speculatively counts the number of TSX aborts due to a data capacity limitation for transactional writes.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CAPACITY_WRITE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Speculatively counts the number of Transactional Synchronization Extensions (TSX) aborts due to a data capacity limitation for transactional writes.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CONFLICT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times a TSX line had a cache conflict.", + "SampleAfterValue": "100003", + "UMask": "0x1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/other.json b/tools/perf/pmu-events/arch/x86/tigerlake/other.json new file mode 100644 index 000000000000..b1143fe74246 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/other.json @@ -0,0 +1,189 @@ +[ + { + "BriefDescription": "Number of occurrences where a microcode assist is invoked by hardware.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc1", + "EventName": "ASSISTS.ANY", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of occurrences where a microcode assist is invoked by hardware Examples include AD (page Access Dirty), FP and AVX related assists.", + "SampleAfterValue": "100003", + "UMask": "0x7" + }, + { + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", + "SampleAfterValue": "200003", + "UMask": "0x7" + }, + { + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "UMask": "0x18" + }, + { + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server microarchtecture). This includes high current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts demand data reads that hit a cacheline in the L3 where a snoop hit in another cores caches, data forwarding is required as the data is modified.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0001", + "Offcore": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x8003C0001", + "Offcore": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) requests and software prefetches for exclusive ownership (PREFETCHW) that hit a cacheline in the L3 where a snoop hit in another cores caches, data forwarding is required as the data is modified.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0002", + "Offcore": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts streaming stores that have any type of response.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.STREAMING_WR.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10800", + "Offcore": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of PREFETCHNTA instructions executed.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.NTA", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHNTA instructions executed.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of PREFETCHW instructions executed.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHW instructions executed.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of PREFETCHT0 instructions executed.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T0", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHT0 instructions executed.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T1_T2", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of PREFETCHT1 or PREFETCHT2 instructions executed.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "TMA slots where no uops were being issued due to lack of back-end resources.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa4", + "EventName": "TOPDOWN.BACKEND_BOUND_SLOTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of Top-down Microarchitecture Analysis (TMA) method's slots where no micro-operations were being issued from front-end to back-end of the machine due to lack of back-end resources.", + "SampleAfterValue": "10000003", + "UMask": "0x2" + }, + { + "BriefDescription": "TMA slots wasted due to incorrect speculation by branch mispredictions", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa4", + "EventName": "TOPDOWN.BR_MISPREDICT_SLOTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Number of TMA slots that were wasted due to incorrect speculation by branch mispredictions. This event estimates number of operations that were issued but not retired from the specualtive path as well as the out-of-order engine recovery past a branch misprediction.", + "SampleAfterValue": "10000003", + "UMask": "0x8" + }, + { + "BriefDescription": "TMA slots available for an unhalted logical processor. Fixed counter - architectural event", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 3", + "EventName": "TOPDOWN.SLOTS", + "PEBScounters": "35", + "PublicDescription": "Number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method (TMA). The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core. Software can use this event as the denominator for the top-level metrics of the TMA method. This architectural event is counted on a designated fixed counter (Fixed Counter 3).", + "SampleAfterValue": "10000003", + "UMask": "0x4" + }, + { + "BriefDescription": "TMA slots available for an unhalted logical processor. General counter - architectural event", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa4", + "EventName": "TOPDOWN.SLOTS_P", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of available slots for an unhalted logical processor. The event increments by machine-width of the narrowest pipeline as employed by the Top-down Microarchitecture Analysis method. The count is distributed among unhalted logical processors (hyper-threads) who share the same physical core.", + "SampleAfterValue": "10000003", + "UMask": "0x1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/pipeline.json b/tools/perf/pmu-events/arch/x86/tigerlake/pipeline.json new file mode 100644 index 000000000000..d0d8a09bc470 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/pipeline.json @@ -0,0 +1,982 @@ +[ + { + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x14", + "EventName": "ARITH.DIVIDER_ACTIVE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "SampleAfterValue": "1000003", + "UMask": "0x9" + }, + { + "BriefDescription": "All branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all branch instructions retired.", + "SampleAfterValue": "400009" + }, + { + "BriefDescription": "Conditional branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts conditional branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x11" + }, + { + "BriefDescription": "Not taken branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_NTAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x10" + }, + { + "BriefDescription": "Taken conditional branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_TAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken conditional branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x1" + }, + { + "BriefDescription": "Far branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts far branch instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x40" + }, + { + "BriefDescription": "All indirect branch instructions retired (excluding RETs. TSX aborts are considered indirect branch).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.INDIRECT", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Direct and indirect near call instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts both direct and indirect near call instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x2" + }, + { + "BriefDescription": "Return instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts return instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x8" + }, + { + "BriefDescription": "Taken branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x20" + }, + { + "BriefDescription": "All mispredicted branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "SampleAfterValue": "50021" + }, + { + "BriefDescription": "Mispredicted conditional branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts mispredicted conditional branch instructions retired.", + "SampleAfterValue": "50021", + "UMask": "0x11" + }, + { + "BriefDescription": "Mispredicted non-taken conditional branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND_NTAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of conditional branch instructions retired that were mispredicted and the branch direction was not taken.", + "SampleAfterValue": "50021", + "UMask": "0x10" + }, + { + "BriefDescription": "number of branch instructions retired that were mispredicted and taken. Non PEBS", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.COND_TAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts taken conditional mispredicted branch instructions retired.", + "SampleAfterValue": "50021", + "UMask": "0x1" + }, + { + "BriefDescription": "All miss-predicted indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts all miss-predicted indirect branch instructions retired (excluding RETs. TSX aborts is considered indirect branch).", + "SampleAfterValue": "50021", + "UMask": "0x80" + }, + { + "BriefDescription": "Mispredicted indirect CALL instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.INDIRECT_CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts retired mispredicted indirect (near taken) CALL instructions, including both register and memory indirect.", + "SampleAfterValue": "50021", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts number of near branch instructions retired that were mispredicted and taken.", + "SampleAfterValue": "50021", + "UMask": "0x20" + }, + { + "BriefDescription": "Cycle counts are evenly distributed between active threads in the Core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xec", + "EventName": "CPU_CLK_UNHALTED.DISTRIBUTED", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event distributes cycle counts between active hyperthreads, i.e., those in C0. A hyperthread becomes inactive when it executes the HLT or MWAIT instructions. If all other hyperthreads are inactive (or disabled or do not exist), all counts are attributed to this hyperthread. To obtain the full count when the Core is active, sum the counts from each hyperthread.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts Core crystal clock cycles when current thread is unhalted and the other thread is halted.", + "SampleAfterValue": "25003", + "UMask": "0x2" + }, + { + "BriefDescription": "Core crystal clock cycles. Cycle counts are evenly distributed between active threads in the Core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF_DISTRIBUTED", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event distributes Core crystal clock cycle counts between active hyperthreads, i.e., those in C0 sleep-state. A hyperthread becomes inactive when it executes the HLT or MWAIT instructions. If one thread is active in a core, all counts are attributed to this hyperthread. To obtain the full count when the Core is active, sum the counts from each hyperthread.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Reference cycles when the core is not in halt state.", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PEBScounters": "34", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the eight programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", + "SampleAfterValue": "2000003", + "UMask": "0x3" + }, + { + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core crystal clock cycles when the thread is unhalted.", + "SampleAfterValue": "25003", + "UMask": "0x1" + }, + { + "BriefDescription": "Core cycles when the thread is not in halt state", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PEBScounters": "33", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the eight programmable counters available for other events.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Thread cycles when thread is not in halt state", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "8", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "16", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "12", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0xc" + }, + { + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "5", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x5" + }, + { + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "20", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "1000003", + "UMask": "0x14" + }, + { + "BriefDescription": "Total execution stalls.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0xa3", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.3_PORTS_UTIL", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Cycles when the memory subsystem has an outstanding load. Increments by 4 for every such cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "5", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.BOUND_ON_LOADS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when the memory subsystem has an outstanding load. Increments by 4 for every such cycle.", + "SampleAfterValue": "2000003", + "UMask": "0x21" + }, + { + "BriefDescription": "Cycles where the Store Buffer was full and no loads caused an execution stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles where the Store Buffer was full and no loads caused an execution stall.", + "SampleAfterValue": "1000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa6", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "1000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Stalls caused by changing prefix length of the instruction.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x87", + "EventName": "ILD_STALL.LCP", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", + "SampleAfterValue": "500009", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of instructions retired. Fixed Counter - architectural event", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 0", + "EventName": "INST_RETIRED.ANY", + "PEBS": "1", + "PEBScounters": "32", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of instructions retired. General Counter - architectural event", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc0", + "EventName": "INST_RETIRED.ANY_P", + "PEBS": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of X86 instructions retired - an Architectural PerfMon event. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter freeing up programmable counters to count other events. INST_RETIRED.ANY_P is counted by a programmable counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Precise instruction retired event with a reduced effect of PEBS shadow in IP distribution", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 0", + "EventName": "INST_RETIRED.PREC_DIST", + "PEBS": "1", + "PEBScounters": "32", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled. Use on Fixed Counter 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles the Backend cluster is recovering after a miss-speculation or a Store Buffer or Load Buffer drain stall.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x0d", + "EventName": "INT_MISC.ALL_RECOVERY_CYCLES", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles the Backend cluster is recovering after a miss-speculation or a Store Buffer or Load Buffer drain stall.", + "SampleAfterValue": "2000003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x0d", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles after recovery from a branch misprediction or machine clear till the first uop is issued from the resteered path.", + "SampleAfterValue": "500009", + "UMask": "0x80" + }, + { + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x0d", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts core cycles when the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "SampleAfterValue": "500009", + "UMask": "0x1" + }, + { + "BriefDescription": "TMA slots where uops got dropped", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x0d", + "EventName": "INT_MISC.UOP_DROPPING", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Estimated number of Top-down Microarchitecture Analysis slots that got dropped due to non front-end reasons", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.NO_SR", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "False dependencies in MOB due to partial compare on address.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x07", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times a load got blocked due to false dependencies in MOB due to partial compare on address.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x4c", + "EventName": "LOAD_HIT_PREFETCH.SWPF", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0xa8", + "EventName": "LSD.CYCLES_ACTIVE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles optimal number of Uops delivered by the LSD, but did not come from the decoder.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "5", + "EventCode": "0xa8", + "EventName": "LSD.CYCLES_OK", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the cycles when optimal number of uops is delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of Uops delivered by the LSD.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xa8", + "EventName": "LSD.UOPS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of machine clears (nukes) of any type.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.COUNT", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of machine clears (nukes) of any type.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Self-modifying code (SMC) detected.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.SMC", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Increments whenever there is an update to the LBR array.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xcc", + "EventName": "MISC_RETIRED.LBR_INSERTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of retired PAUSE instructions. This event is not supported on first SKL and KBL products.", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xcc", + "EventName": "MISC_RETIRED.PAUSE_INST", + "PublicDescription": "Counts number of retired PAUSE instructions. This event is not supported on first SKL and KBL products.", + "SampleAfterValue": "100003", + "UMask": "0x40" + }, + { + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa2", + "EventName": "RESOURCE_STALLS.SB", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts cycles where the pipeline is stalled due to serializing operations.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa2", + "EventName": "RESOURCE_STALLS.SCOREBOARD", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x5e", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for this logical processor. This is usually caused when the front-end pipeline runs into stravation periods (e.g. branch mispredictions or i-cache misses)", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x5e", + "EventName": "RS_EVENTS.EMPTY_END", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to closely sample on front-end latency issues (see the FRONTEND_RETIRED event of designated precise events)", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of uops executed on port 0", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_0", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of uops executed on port 1", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of uops executed on port 2 and 3", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_2_3", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 2 and 3.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of uops executed on port 4 and 9", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_4_9", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 5 and 9.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of uops executed on port 5", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_5", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of uops executed on port 6", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_6", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "SampleAfterValue": "2000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of uops executed on port 7 and 8", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xa1", + "EventName": "UOPS_DISPATCHED.PORT_7_8", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to ports 7 and 8.", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Number of uops executed on the core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CORE", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of uops executed from any thread.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 1 micro-op is executed from any thread on physical core.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 2 micro-ops are executed from any thread on physical core.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "3", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 3 micro-ops are executed from any thread on physical core.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles when at least 4 micro-ops are executed from any thread on physical core.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "3", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.THREAD", + "PEBScounters": "0,1,2,3,4,5,6,7", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of x87 uops dispatched.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xb1", + "EventName": "UOPS_EXECUTED.X87", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of x87 uops executed.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Uops that RAT issues to RS", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x0e", + "EventName": "UOPS_ISSUED.ANY", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles when RAT does not issue Uops to RS for the thread", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x0e", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0x0e", + "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to Mixing Intel AVX and Intel SSE Code section of the Optimization Guide.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retirement slots used.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.SLOTS", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the retirement slots used each cycle.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles without actually retired uops.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.STALL_CYCLES", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "This event counts cycles without actually retired uops.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles with less than 10 actually retired uops.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3,4,5,6,7", + "CounterMask": "10", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "Invert": "1", + "PEBScounters": "0,1,2,3,4,5,6,7", + "PublicDescription": "Counts the number of cycles using always true condition (uops_ret &lt; 16) applied to non PEBS uops retired event.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/virtual-memory.json b/tools/perf/pmu-events/arch/x86/tigerlake/virtual-memory.json new file mode 100644 index 000000000000..3ebec78969b0 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/virtual-memory.json @@ -0,0 +1,225 @@ +[ + { + "BriefDescription": "Loads that miss the DTLB and hit the STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a demand load.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a demand load.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data loads. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0xe" + }, + { + "BriefDescription": "Page walks completed due to a demand data load to a 2M/4M page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Page walks completed due to a demand data load to a 4K page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of page walks outstanding for a demand load in the PMH each cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for a demand load in the PMH (Page Miss Handler) each cycle.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Stores that miss the DTLB and hit the STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.STLB_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data stores. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0xe" + }, + { + "BriefDescription": "Page walks completed due to a demand data store to a 2M/4M page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Page walks completed due to a demand data store to a 4K page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of page walks outstanding for a store in the PMH each cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for a store in the PMH (Page Miss Handler) each cycle.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.STLB_HIT", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts instruction fetch requests that miss the ITLB (Instruction TLB) and hit the STLB (Second-level TLB).", + "SampleAfterValue": "100003", + "UMask": "0x20" + }, + { + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "CounterMask": "1", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a code (instruction fetch) request.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (all page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0xe" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (2M/4M page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts completed page walks (4K page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of page walks outstanding for an outstanding code request in the PMH each cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding for an outstanding code (instruction fetch) request in the PMH (Page Miss Handler) each cycle.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "DTLB flush attempts of the thread-specific entries", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xbd", + "EventName": "TLB_FLUSH.DTLB_THREAD", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", + "SampleAfterValue": "100007", + "UMask": "0x1" + }, + { + "BriefDescription": "STLB flush attempts", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xbd", + "EventName": "TLB_FLUSH.STLB_ANY", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "SampleAfterValue": "100007", + "UMask": "0x20" + } +] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From b9efd75b6ec966f50b3db7fd9b2598d32e8f2f8b Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 16 Jul 2021 12:01:37 +0800 Subject: perf vendor events: Add metrics for Tigerlake Add JSON metrics for Tigerlake to perf. Based on TMA metrics 4.21 at 01.org. https://download.01.org/perfmon/ Reviewed-by: Andi Kleen Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719070058.4159-2-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/x86/tigerlake/tgl-metrics.json | 231 +++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/tigerlake/tgl-metrics.json diff --git a/tools/perf/pmu-events/arch/x86/tigerlake/tgl-metrics.json b/tools/perf/pmu-events/arch/x86/tigerlake/tgl-metrics.json new file mode 100644 index 000000000000..00a16f1a0f44 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/tigerlake/tgl-metrics.json @@ -0,0 +1,231 @@ +[ + { + "BriefDescription": "Instructions Per Cycle (per Logical Processor)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Summary", + "MetricName": "IPC" + }, + { + "BriefDescription": "Instruction per taken branch", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_TAKEN", + "MetricGroup": "Branches;FetchBW;PGO", + "MetricName": "IpTB" + }, + { + "BriefDescription": "Cycles Per Instruction (per Logical Processor)", + "MetricExpr": "1 / IPC", + "MetricGroup": "Pipeline", + "MetricName": "CPI" + }, + { + "BriefDescription": "Per-Logical Processor actual clocks when the Logical Processor is active.", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Pipeline", + "MetricName": "CLKS" + }, + { + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "Flops", + "MetricName": "FLOPc" + }, + { + "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", + "MetricExpr": "UOPS_EXECUTED.THREAD / ( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 )", + "MetricGroup": "Pipeline;PortsUtil", + "MetricName": "ILP" + }, + { + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "MetricGroup": "BrMispredicts", + "MetricName": "IpMispredict" + }, + { + "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", + "MetricExpr": "CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "SMT", + "MetricName": "CORE_CLKS" + }, + { + "BriefDescription": "Instructions per Load (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_LOADS", + "MetricGroup": "InsType", + "MetricName": "IpLoad" + }, + { + "BriefDescription": "Instructions per Store (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_STORES", + "MetricGroup": "InsType", + "MetricName": "IpStore" + }, + { + "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", + "MetricGroup": "Branches;InsType", + "MetricName": "IpBranch" + }, + { + "BriefDescription": "Instructions per (near) call (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_CALL", + "MetricGroup": "Branches", + "MetricName": "IpCall" + }, + { + "BriefDescription": "Branch instructions per taken branch. ", + "MetricExpr": "BR_INST_RETIRED.ALL_BRANCHES / BR_INST_RETIRED.NEAR_TAKEN", + "MetricGroup": "Branches;PGO", + "MetricName": "BpTkBranch" + }, + { + "BriefDescription": "Instructions per Floating Point (FP) Operation (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE )", + "MetricGroup": "Flops;FpArith;InsType", + "MetricName": "IpFLOP" + }, + { + "BriefDescription": "Total number of retired Instructions, Sample with: INST_RETIRED.PREC_DIST", + "MetricExpr": "INST_RETIRED.ANY", + "MetricGroup": "Summary;TmaL1", + "MetricName": "Instructions" + }, + { + "BriefDescription": "Fraction of Uops delivered by the LSD (Loop Stream Detector; aka Loop Cache)", + "MetricExpr": "LSD.UOPS / (IDQ.DSB_UOPS + LSD.UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", + "MetricGroup": "LSD", + "MetricName": "LSD_Coverage" + }, + { + "BriefDescription": "Fraction of Uops delivered by the DSB (aka Decoded ICache; or Uop Cache)", + "MetricExpr": "IDQ.DSB_UOPS / (IDQ.DSB_UOPS + LSD.UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", + "MetricGroup": "DSB;FetchBW", + "MetricName": "DSB_Coverage" + }, + { + "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads (in core cycles)", + "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", + "MetricGroup": "MemoryBound;MemoryLat", + "MetricName": "Load_Miss_Real_Latency" + }, + { + "BriefDescription": "Memory-Level-Parallelism (average number of L1 miss demand load when there is at least one such miss. Per-Logical Processor)", + "MetricExpr": "L1D_PEND_MISS.PENDING / L1D_PEND_MISS.PENDING_CYCLES", + "MetricGroup": "MemoryBound;MemoryBW", + "MetricName": "MLP" + }, + { + "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", + "MetricConstraint": "NO_NMI_WATCHDOG", + "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING ) / ( 2 * CORE_CLKS )", + "MetricGroup": "MemoryTLB", + "MetricName": "Page_Walks_Utilization" + }, + { + "BriefDescription": "Average data fill bandwidth to the L1 data cache [GB / sec]", + "MetricExpr": "64 * L1D.REPLACEMENT / 1000000000 / duration_time", + "MetricGroup": "MemoryBW", + "MetricName": "L1D_Cache_Fill_BW" + }, + { + "BriefDescription": "Average data fill bandwidth to the L2 cache [GB / sec]", + "MetricExpr": "64 * L2_LINES_IN.ALL / 1000000000 / duration_time", + "MetricGroup": "MemoryBW", + "MetricName": "L2_Cache_Fill_BW" + }, + { + "BriefDescription": "Average per-core data access bandwidth to the L3 cache [GB / sec]", + "MetricExpr": "64 * OFFCORE_REQUESTS.ALL_REQUESTS / 1000000000 / duration_time", + "MetricGroup": "MemoryBW;Offcore", + "MetricName": "L3_Cache_Access_BW" + }, + { + "BriefDescription": "L1 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L1_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L1MPKI" + }, + { + "BriefDescription": "L2 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L2_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L2MPKI" + }, + { + "BriefDescription": "L3 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L3_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L3MPKI" + }, + { + "BriefDescription": "Average CPU Utilization", + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", + "MetricGroup": "HPC;Summary", + "MetricName": "CPU_Utilization" + }, + { + "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", + "MetricExpr": "(CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC) * msr@tsc@ / 1000000000 / duration_time", + "MetricGroup": "Summary;Power", + "MetricName": "Average_Frequency" + }, + { + "BriefDescription": "Giga Floating Point Operations Per Second", + "MetricExpr": "( ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / 1000000000 ) / duration_time", + "MetricGroup": "Flops;HPC", + "MetricName": "GFLOPs" + }, + { + "BriefDescription": "Average Frequency Utilization relative nominal frequency", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC", + "MetricGroup": "Power", + "MetricName": "Turbo_Utilization" + }, + { + "BriefDescription": "Fraction of cycles where both hardware Logical Processors were active", + "MetricExpr": "1 - CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_DISTRIBUTED", + "MetricGroup": "SMT", + "MetricName": "SMT_2T_Utilization" + }, + { + "BriefDescription": "Fraction of cycles spent in the Operating System (OS) Kernel mode", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD_P:k / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "OS", + "MetricName": "Kernel_Utilization" + }, + { + "BriefDescription": "Instructions per Far Branch ( Far Branches apply upon transition from application to operating system, handling interrupts, exceptions) [lower number means higher occurrence rate]", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.FAR_BRANCH:u", + "MetricGroup": "Branches;OS", + "MetricName": "IpFarBranch" + }, + { + "BriefDescription": "C6 residency percent per core", + "MetricExpr": "(cstate_core@c6\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C6_Core_Residency" + }, + { + "BriefDescription": "C7 residency percent per core", + "MetricExpr": "(cstate_core@c7\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C7_Core_Residency" + }, + { + "BriefDescription": "C6 residency percent per package", + "MetricExpr": "(cstate_pkg@c6\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C6_Pkg_Residency" + }, + { + "BriefDescription": "C7 residency percent per package", + "MetricExpr": "(cstate_pkg@c7\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C7_Pkg_Residency" + } +] -- cgit v1.2.3-70-g09d2 From aa1bd89235eee73746e7bac52d9e81afea270daa Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 2 Aug 2021 13:34:39 +0800 Subject: perf vendor events intel: Add core event list for Elkhartlake Add JSON core events for Elkhartlake to perf. Based on JSON list v1.02: https://download.01.org/perfmon/EHL/ Signed-off-by: Jin Yao Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210802053440.21035-2-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/x86/elkhartlake/cache.json | 226 +++++++++++ .../arch/x86/elkhartlake/floating-point.json | 24 ++ .../pmu-events/arch/x86/elkhartlake/frontend.json | 93 +++++ .../pmu-events/arch/x86/elkhartlake/memory.json | 86 +++++ .../pmu-events/arch/x86/elkhartlake/other.json | 424 +++++++++++++++++++++ .../pmu-events/arch/x86/elkhartlake/pipeline.json | 278 ++++++++++++++ .../arch/x86/elkhartlake/virtual-memory.json | 273 +++++++++++++ tools/perf/pmu-events/arch/x86/mapfile.csv | 1 + 8 files changed, 1405 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/cache.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/floating-point.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/frontend.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/memory.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/other.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/pipeline.json create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/virtual-memory.json diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/cache.json b/tools/perf/pmu-events/arch/x86/elkhartlake/cache.json new file mode 100644 index 000000000000..734be4ea095f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/cache.json @@ -0,0 +1,226 @@ +[ + { + "BriefDescription": "Counts the number of first level data cacheline (dirty) evictions caused by misses, stores, and prefetches.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x51", + "EventName": "DL1.DIRTY_EVICTION", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of first level data cacheline (dirty) evictions caused by misses, stores, and prefetches. Does not count evictions or dirty writebacks caused by snoops. Does not count a replacement unless a (dirty) line was written back.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of cacheable memory requests that miss in the LLC. Counts on a per core basis.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cacheable memory requests that miss in the Last Level Cache (LLC). If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x41" + }, + { + "BriefDescription": "Counts the number of cacheable memory requests that access the LLC. Counts on a per core basis.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x2e", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cacheable memory requests that access the Last Level Cache (LLC). Requests include demand loads, reads for ownership (RFO), instruction fetches and L1 HW prefetches. If the platform has an L3 cache, the LLC is the L3 cache, otherwise it is the L2 cache. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x4f" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in DRAM or MMIO (Non-DRAM).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_DRAM_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles a core is stalled due to an instruction cache or translation lookaside buffer (TLB) access which hit in DRAM or MMIO (non-DRAM).", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_L2_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles a core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) access which hit in the L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to an instruction cache or TLB miss which hit in the LLC or other core with HITE/F/M.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.IFETCH_LLC_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles a core is stalled due to an instruction cache or Translation Lookaside Buffer (TLB) access which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load miss which hit in DRAM or MMIO (Non-DRAM).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_DRAM_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_L2_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles a core is stalled due to a demand load which hit in the L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of cycles the core is stalled due to a demand load which hit in the LLC or other core with HITE/F/M.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.LOAD_LLC_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of cycles a core is stalled due to a demand load which hit in the Last Level Cache (LLC) or other core with HITE/F/M.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of cycles a core is stalled due to a store buffer being full.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "MEM_BOUND_STALLS.STORE_BUFFER_FULL", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts the number of load ops retired that hit in DRAM.", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.DRAM_HIT", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L1 data cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L1_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of load uops retired that miss in the L1 data cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L1_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of load uops retired that miss in the L2 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L2_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of load uops retired that hit in the L3 cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xd1", + "EventName": "MEM_LOAD_UOPS_RETIRED.L3_HIT", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of load uops retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of load uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x81" + }, + { + "BriefDescription": "Counts the number of store uops retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.ALL_STORES", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of store uops retired.", + "SampleAfterValue": "200003", + "UMask": "0x82" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to instruction cache misses.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ICACHE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x20" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/floating-point.json b/tools/perf/pmu-events/arch/x86/elkhartlake/floating-point.json new file mode 100644 index 000000000000..2515b9aa6e66 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/floating-point.json @@ -0,0 +1,24 @@ +[ + { + "BriefDescription": "Counts the number of cycles the floating point divider is busy. Does not imply a stall waiting for the divider.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcd", + "EventName": "CYCLES_DIV_BUSY.FPDIV", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of floating point divide uops retired (x87 and SSE, including x87 sqrt).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.FPDIV", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "2000003", + "UMask": "0x8" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/frontend.json b/tools/perf/pmu-events/arch/x86/elkhartlake/frontend.json new file mode 100644 index 000000000000..b7b8cb7bd868 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/frontend.json @@ -0,0 +1,93 @@ +[ + { + "BriefDescription": "Counts the total number of BACLEARS.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.ANY", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of BACLEARS, which occur when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of BACLEARS due to a conditional jump.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.COND", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of BACLEARS due to an indirect branch.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.INDIRECT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of BACLEARS due to a return branch.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.RETURN", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of BACLEARS due to a non-indirect, non-conditional jump.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe6", + "EventName": "BACLEARS.UNCOND", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of times a decode restriction reduces the decode throughput due to wrong instruction length prediction.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe9", + "EventName": "DECODE_RESTRICTION.PREDECODE_WRONG", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of requests to the instruction cache for one or more bytes of a cache line.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x80", + "EventName": "ICACHE.ACCESSES", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line or byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts the number of instruction cache misses.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x80", + "EventName": "ICACHE.MISSES", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of missed requests to the instruction cache. The event only counts new cache line accesses, so that multiple back to back fetches to the exact same cache line and byte chunk count as one. Specifically, the event counts when accesses from sequential code crosses the cache line boundary, or when a branch target is moved to a new line or to a non-sequential byte chunk of the same line.", + "SampleAfterValue": "200003", + "UMask": "0x2" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/memory.json b/tools/perf/pmu-events/arch/x86/elkhartlake/memory.json new file mode 100644 index 000000000000..4e4eab23a300 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/memory.json @@ -0,0 +1,86 @@ +[ + { + "BriefDescription": "Counts the number of memory ordering machine clears triggered by a snoop from an external agent.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of memory ordering machine clears triggered by a snoop from an external agent. Does not count internally generated machine clears such as those due to disambiguations.", + "SampleAfterValue": "20003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts cacheable demand data reads, L1 data cache hardware prefetches and software prefetches (except PREFETCHW) that were not supplied by the L3 cache.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_AND_L1PF_RD.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts cacheable demand data reads, L1 data cache hardware prefetches and software prefetches (except PREFETCHW) that were not supplied by the L3 cache.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_AND_L1PF_RD.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_AND_L1PF_RD.L3_MISS", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_AND_L1PF_RD.L3_MISS_LOCAL", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that were not supplied by the L3 cache.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x2104000002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/other.json b/tools/perf/pmu-events/arch/x86/elkhartlake/other.json new file mode 100644 index 000000000000..627691404155 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/other.json @@ -0,0 +1,424 @@ +[ + { + "BriefDescription": "Counts the total number of BTCLEARS.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xe8", + "EventName": "BTCLEAR.ANY", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of BTCLEARS which occurs when the Branch Target Buffer (BTB) predicts a taken branch.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BUS_LOCK.SELF_LOCKS", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EdgeDetect": "1", + "EventCode": "0x63", + "EventName": "BUS_LOCK.ALL", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "Counts the number of unhalted cycles a core is blocked due to an accepted lock issued by other cores.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x63", + "EventName": "BUS_LOCK.BLOCK_CYCLES", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of unhalted cycles a core is blocked due to an accepted lock issued by other cores. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BUS_LOCK.BLOCK_CYCLES", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x63", + "EventName": "BUS_LOCK.CYCLES_OTHER_BLOCK", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event BUS_LOCK.LOCK_CYCLES", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x63", + "EventName": "BUS_LOCK.CYCLES_SELF_BLOCK", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of unhalted cycles a core is blocked due to an accepted lock it issued.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x63", + "EventName": "BUS_LOCK.LOCK_CYCLES", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of unhalted cycles a core is blocked due to an accepted lock it issued. Counts on a per core basis.", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of bus locks a core issued its self (e.g. lock to UC or Split Lock) and does not include cache locks.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EdgeDetect": "1", + "EventCode": "0x63", + "EventName": "BUS_LOCK.SELF_LOCKS", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of bus locks a core issued its self (e.g. lock to UC or Split Lock) and does not include cache locks. Counts on a per core basis.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event MEM_BOUND_STALLS.LOAD_DRAM_HIT", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "C0_STALLS.LOAD_DRAM_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event MEM_BOUND_STALLS.LOAD_L2_HIT", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "C0_STALLS.LOAD_L2_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event MEM_BOUND_STALLS.LOAD_LLC_HIT", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x34", + "EventName": "C0_STALLS.LOAD_LLC_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of core cycles during which interrupts are masked (disabled).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcb", + "EventName": "HW_INTERRUPTS.MASKED", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of core cycles during which interrupts are masked (disabled). Increments by 1 each core cycle that EFLAGS.IF is 0, regardless of whether interrupts are pending or not.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of core cycles during which there are pending interrupts while interrupts are masked (disabled).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcb", + "EventName": "HW_INTERRUPTS.PENDING_AND_MASKED", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of core cycles during which there are pending interrupts while interrupts are masked (disabled). Increments by 1 each core cycle that both EFLAGS.IF is 0 and an INTR is pending (which means the APIC is telling the ROB to cause an INTR). This event does not increment if EFLAGS.IF is 0 but all interrupt in the APICs Interrupt Request Register (IRR) are inhibited by the PPR (thus either by ISRV or TPR) because in these cases the interrupts would be held up in the APIC and would not be pended to the ROB. This event does count when an interrupt is only inhibited by MOV/POP SS state machines or the STI state machine. These extra inhibits only last for a single instructions and would not be important.", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of hardware interrupts received by the processor.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcb", + "EventName": "HW_INTERRUPTS.RECEIVED", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "203", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts cacheable demand data reads, L1 data cache hardware prefetches and software prefetches (except PREFETCHW) that have any type of response.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_AND_L1PF_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_AND_L1PF_RD.ANY_RESPONSE", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts demand reads for ownership (RFO) and software prefetches for exclusive ownership (PREFETCHW) that have any type of response.", + "Counter": "0,1,2,3", + "EventCode": "0XB7", + "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.ALL", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a mispredicted jump or a machine clear. Only issue slots wasted due to fast nukes such as memory ordering nukes are counted. Other nukes are not accounted for. Counts all issue slots blocked during this recovery window including relevant microcode flows and while uops are not yet available in the instruction queue (IQ). Also includes the issue slots that were consumed by the backend but were thrown away because they were younger than the mispredict or machine clear.", + "SampleAfterValue": "1000003", + "UMask": "0x6" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to fast nukes such as memory ordering and memory disambiguation machine clears.", + "Counter": "0,1,2,3", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.FASTNUKE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the total number of issue slots that were not consumed by the backend because allocation is stalled due to a machine clear (nuke) of any kind including memory ordering and memory disambiguation.", + "Counter": "0,1,2,3", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MACHINE_CLEARS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to branch mispredicts.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MISPREDICT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event TOPDOWN_BAD_SPECULATION.FASTNUKE", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x73", + "EventName": "TOPDOWN_BAD_SPECULATION.MONUKE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the total number of issue slots every cycle that were not consumed by the backend due to backend stalls.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALL", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to certain allocation restrictions.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.ALLOC_RESTRICTIONS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to memory reservation stalls in which a scheduler is not able to accept uops.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.MEM_SCHEDULER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to IEC or FPC RAT stalls, which can be due to FIQ or IEC reservation stalls in which the integer, floating point or SIMD scheduler is not able to accept uops.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.NON_MEM_SCHEDULER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the physical register file unable to accept an entry (marble stalls).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REGISTER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to the reorder buffer being full (ROB stalls).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.REORDER_BUFFER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to scoreboards from the instruction queue (IQ), jump execution unit (JEU), or microcode sequencer (MS).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.SERIALIZATION", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "This event is deprecated.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x74", + "EventName": "TOPDOWN_BE_BOUND.STORE_BUFFER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not consumed by the backend due to frontend stalls.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ALL", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_DETECT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BACLEARS, which occurs when the Branch Target Buffer (BTB) prediction or lack thereof, was corrected by a later branch predictor in the frontend. Includes BACLEARS due to all branch types including conditional and unconditional jumps, returns, and indirect branches.", + "SampleAfterValue": "1000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.BRANCH_RESTEER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to BTCLEARS, which occurs when the Branch Target Buffer (BTB) predicts a taken branch.", + "SampleAfterValue": "1000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to the microcode sequencer (MS).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.CISC", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to decode stalls.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.DECODE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to ITLB misses.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.ITLB", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to Instruction Table Lookaside Buffer (ITLB) misses.", + "SampleAfterValue": "1000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to other common frontend stalls not categorized.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.OTHER", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of issue slots every cycle that were not delivered by the frontend due to wrong predecodes.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x71", + "EventName": "TOPDOWN_FE_BOUND.PREDECODE", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the total number of consumed retirement slots.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc2", + "EventName": "TOPDOWN_RETIRING.ALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "1000003" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/pipeline.json b/tools/perf/pmu-events/arch/x86/elkhartlake/pipeline.json new file mode 100644 index 000000000000..41e5dfad8f51 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/pipeline.json @@ -0,0 +1,278 @@ +[ + { + "BriefDescription": "Counts the total number of branch instructions retired for all branch types.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of instructions in which the instruction pointer (IP) of the processor is resteered due to a branch instruction and the branch instruction successfully retires. All branch type instructions are accounted for.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "Counts the number of near CALL branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xf9" + }, + { + "BriefDescription": "Counts the number of far branch instructions retired, includes far jump, far call and return, and interrupt call and return.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xbf" + }, + { + "BriefDescription": "Counts the number of near indirect CALL branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.IND_CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "Counts the number of retired JCC (Jump on Conditional Code) branch instructions retired, includes both taken and not taken branches.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.JCC", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "Counts the number of near indirect JMP and near indirect CALL branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.NON_RETURN_IND", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xeb" + }, + { + "BriefDescription": "Counts the number of near relative CALL branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.REL_CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xfd" + }, + { + "BriefDescription": "Counts the number of near RET branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.RETURN", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xf7" + }, + { + "BriefDescription": "Counts the number of taken JCC (Jump on Conditional Code) branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.TAKEN_JCC", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the total number of mispredicted branch instructions retired for all branch types.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of mispredicted branch instructions retired. All branch type instructions are accounted for. Prediction of the branch target address enables the processor to begin executing instructions before the non-speculative execution path is known. The branch prediction unit (BPU) predicts the target address based on the instruction pointer (IP) of the branch and on the execution path through which execution reached this IP. A branch misprediction occurs when the prediction is wrong, and results in discarding all instructions executed in the speculative path and re-fetching from the correct path.", + "SampleAfterValue": "200003" + }, + { + "BriefDescription": "Counts the number of mispredicted near indirect CALL branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.IND_CALL", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xfb" + }, + { + "BriefDescription": "Counts the number of mispredicted JCC (Jump on Conditional Code) branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.JCC", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x7e" + }, + { + "BriefDescription": "Counts the number of mispredicted near RET branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.RETURN", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xf7" + }, + { + "BriefDescription": "Counts the number of mispredicted taken JCC (Jump on Conditional Code) branch instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc5", + "EventName": "BR_MISP_RETIRED.TAKEN_JCC", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0xfe" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles. (Fixed event)", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.CORE", + "PDIR_COUNTER": "na", + "PEBScounters": "33", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses fixed counter 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of unhalted core clock cycles.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.CORE_P", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of core cycles while the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. The core frequency may change from time to time. For this reason this event may have a changing ratio with regards to time. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses fixed counter 2.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency. (Fixed event)", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PDIR_COUNTER": "na", + "PEBScounters": "34", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses fixed counter 2.", + "SampleAfterValue": "2000003", + "UMask": "0x3" + }, + { + "BriefDescription": "Counts the number of unhalted reference clock cycles at TSC frequency.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x3c", + "EventName": "CPU_CLK_UNHALTED.REF_TSC_P", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of reference cycles that the core is not in a halt state. The core enters the halt state when it is running the HLT instruction. This event is not affected by core frequency changes and increments at a fixed frequency that is also used for the Time Stamp Counter (TSC). This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "This event is deprecated.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcd", + "EventName": "CYCLES_DIV_BUSY.ANY", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the number of cycles the integer divider is busy. Does not imply a stall waiting for the divider.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xcd", + "EventName": "CYCLES_DIV_BUSY.IDIV", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the total number of instructions retired. (Fixed event)", + "CollectPEBSRecord": "2", + "Counter": "Fixed counter 0", + "EventName": "INST_RETIRED.ANY", + "PEBS": "1", + "PEBScounters": "32", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses fixed counter 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the total number of instructions retired.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc0", + "EventName": "INST_RETIRED.ANY_P", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the total number of instructions that retired. For instructions that consist of multiple uops, this event counts the retirement of the last uop of the instruction. This event continues counting during hardware interrupts, traps, and inside interrupt handlers. This event uses a programmable general purpose performance counter.", + "SampleAfterValue": "2000003" + }, + { + "BriefDescription": "Counts the total number of machine clears including memory ordering, memory disambiguation, self-modifying code, page faults and floating point assist.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc3", + "EventName": "MACHINE_CLEARS.ANY", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "20003" + }, + { + "BriefDescription": "Counts the number of uops that are from complex flows issued by the micro-sequencer (MS).", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.MS", + "PDIR_COUNTER": "na", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of uops that are from complex flows issued by the Microcode Sequencer (MS). This includes uops from flows due to complex instructions, faults, assists, and inserted flows.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/virtual-memory.json b/tools/perf/pmu-events/arch/x86/elkhartlake/virtual-memory.json new file mode 100644 index 000000000000..c58b589ff80f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/virtual-memory.json @@ -0,0 +1,273 @@ +[ + { + "BriefDescription": "Counts the number of page walks due to loads that miss the PDE (Page Directory Entry) cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.PDE_CACHE_MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of first level TLB misses but second level hits due to loads that did not start a page walk. Account for all pages sizes. Will result in a DTLB write from STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to any page size.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to any page size. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0xe" + }, + { + "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to a 2M or 4M page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 2M or 4M pages. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of page walks completed due to load DTLB misses to a 4K page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to loads (including SW prefetches) whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 4K pages. Includes page walks that page fault.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for loads every cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for loads every cycle. A page walk is outstanding from start till PMH becomes idle again (ready to serve next walk). Includes EPT-walk intervals.", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of page walks due to stores that miss the PDE (Page Directory Entry) cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.PDE_CACHE_MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks due to storse that miss the PDE (Page Directory Entry) cache.", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of page walks completed due to store DTLB misses to a 2M or 4M page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 2M or 4M pages. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of page walks completed due to store DTLB misses to a 4K page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to stores whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 4K pages. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for stores every cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for stores every cycle. A page walk is outstanding from start till PMH becomes idle again (ready to serve next walk). Includes EPT-walk intervals.", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of Extended Page Directory Entry hits.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x4f", + "EventName": "EPT.EPDE_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of Extended Page Directory Entry hits. The Extended Page Directory cache is used by Virtual Machine operating systems while the guest operating systems use the standard TLB caches.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of Extended Page Directory Entry misses.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x4f", + "EventName": "EPT.EPDE_MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number Extended Page Directory Entry misses. The Extended Page Directory cache is used by Virtual Machine operating systems while the guest operating systems use the standard TLB caches.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of Extended Page Directory Pointer Entry hits.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x4f", + "EventName": "EPT.EPDPE_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number Extended Page Directory Pointer Entry hits. The Extended Page Directory cache is used by Virtual Machine operating systems while the guest operating systems use the standard TLB caches.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of Extended Page Directory Pointer Entry misses.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x4f", + "EventName": "EPT.EPDPE_MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number Extended Page Directory Pointer Entry misses. The Extended Page Directory cache is used by Virtual Machine operating systems while the guest operating systems use the standard TLB caches.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of times there was an ITLB miss and a new translation was filled into the ITLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x81", + "EventName": "ITLB.FILLS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of times the machine was unable to find a translation in the Instruction Translation Lookaside Buffer (ITLB) and a new translation was filled into the ITLB. The event is speculative in nature, but will not count translations (page walks) that are begun and not finished, or translations that are finished but not filled into the ITLB.", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of page walks due to an instruction fetch that miss the PDE (Page Directory Entry) cache.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.PDE_CACHE_MISS", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Counts the number of first level TLB misses but second level hits due to an instruction fetch that did not start a page walk. Account for all pages sizes. Will results in a DTLB write from STLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.STLB_HIT", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Counts the number of page walks completed due to instruction fetch misses to a 2M or 4M page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to instruction fetches whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 2M or 4M pages. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of page walks completed due to instruction fetch misses to a 4K page.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks completed due to instruction fetches whose address translations missed in all Translation Lookaside Buffer (TLB) levels and were mapped to 4K pages. Includes page walks that page fault.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for instruction fetches every cycle.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PDIR_COUNTER": "na", + "PEBScounters": "0,1,2,3", + "PublicDescription": "Counts the number of page walks outstanding in the page miss handler (PMH) for instruction fetches every cycle. A page walk is outstanding from start till PMH becomes idle again (ready to serve next walk).", + "SampleAfterValue": "200003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts the number of memory retired ops that missed in the second level TLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.DTLB_MISS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x13" + }, + { + "BriefDescription": "Counts the number of load ops retired that miss in the second Level TLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.DTLB_MISS_LOADS", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x11" + }, + { + "BriefDescription": "Counts the number of store ops retired that miss in the second level TLB.", + "CollectPEBSRecord": "2", + "Counter": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xd0", + "EventName": "MEM_UOPS_RETIRED.DTLB_MISS_STORES", + "PEBS": "1", + "PEBScounters": "0,1,2,3", + "SampleAfterValue": "200003", + "UMask": "0x12" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 37382343d25f..0cf2d1fa6b76 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -41,6 +41,7 @@ GenuineIntel-6-A7,v1,icelake,core GenuineIntel-6-6A,v1,icelakex,core GenuineIntel-6-6C,v1,icelakex,core GenuineIntel-6-86,v1,tremontx,core +GenuineIntel-6-96,v1,elkhartlake,core AuthenticAMD-23-([12][0-9A-F]|[0-9A-F]),v2,amdzen1,core AuthenticAMD-23-[[:xdigit:]]+,v1,amdzen2,core AuthenticAMD-25-[[:xdigit:]]+,v1,amdzen3,core -- cgit v1.2.3-70-g09d2 From 43c117d809e4d0d1f80a418a0365faa6d307a3ed Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 2 Aug 2021 13:34:40 +0800 Subject: perf vendor events intel: Add basic metrics for Elkhartlake Add JSON metrics for Elkhartlake to perf. Signed-off-by: Jin Yao Reviewed-by: Andi Kleen Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210802053440.21035-3-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../arch/x86/elkhartlake/ehl-metrics.json | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/elkhartlake/ehl-metrics.json diff --git a/tools/perf/pmu-events/arch/x86/elkhartlake/ehl-metrics.json b/tools/perf/pmu-events/arch/x86/elkhartlake/ehl-metrics.json new file mode 100644 index 000000000000..b6f7126be1fd --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/elkhartlake/ehl-metrics.json @@ -0,0 +1,57 @@ +[ + { + "MetricExpr": "INST_RETIRED.ANY / cycles", + "BriefDescription": "Instructions Per Cycle (per Logical Processor)", + "MetricName": "IPC" + }, + { + "MetricExpr": "1 / IPC", + "BriefDescription": "Cycles Per Instruction (per Logical Processor)", + "MetricName": "CPI" + }, + { + "MetricExpr": "cycles", + "BriefDescription": "Per-Logical Processor actual clocks when the Logical Processor is active.", + "MetricName": "CLKS" + }, + { + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", + "MetricName": "IpMispredict" + }, + { + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", + "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", + "MetricName": "IpBranch" + }, + { + "MetricExpr": "INST_RETIRED.ANY", + "BriefDescription": "Total number of retired Instructions", + "MetricName": "Instructions" + }, + { + "MetricExpr": "64 * LONGEST_LAT_CACHE.MISS / 1000000000 ", + "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", + "MetricName": "L3_Cache_Fill_BW" + }, + { + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", + "BriefDescription": "Average CPU Utilization", + "MetricName": "CPU_Utilization" + }, + { + "MetricExpr": "(cycles / CPU_CLK_UNHALTED.REF_TSC) * msr@tsc@ / 1000000000 ", + "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", + "MetricName": "Average_Frequency" + }, + { + "MetricExpr": "cycles / CPU_CLK_UNHALTED.REF_TSC", + "BriefDescription": "Average Frequency Utilization relative nominal frequency", + "MetricName": "Turbo_Utilization" + }, + { + "MetricExpr": "cycles:k / cycles", + "BriefDescription": "Fraction of cycles spent in the Operating System (OS) Kernel mode", + "MetricName": "Kernel_Utilization" + } +] -- cgit v1.2.3-70-g09d2 From 880569296fb8989516be0492eb304cb88c879e5c Mon Sep 17 00:00:00 2001 From: Eirik Fuller Date: Fri, 25 Jun 2021 22:38:25 -0400 Subject: perf test: Handle fd gaps in test__dso_data_reopen https://github.com/beaker-project/restraint/issues/215 describes a file descriptor leak which revealed the test failure described here. The 'DSO data reopen' perf test assumes that RLIMIT_NOFILE limits the number of open file descriptors, but it actually limits newly opened file descriptors. When the file descriptor limit is reduced, file descriptors already open remain open regardless of the new limit. This test failure does not occur if open file descriptors are contiguous, beginning at zero. The following command triggers this perf test failure. perf test 'DSO data reopen' 3>/dev/null 8>/dev/null This patch determines the file descriptor limit by opening four files and then closing them. The limit is set to the fourth file descriptor, leaving only the first three available because any newly opened file descriptor must be less than the limit. Signed-off-by: Eirik Fuller Acked-by: Jiri Olsa Acked-by: Michael Petlan LPU-Reference: 20210626023825.1398547-1-efuller@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/dso-data.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 627c1aaf1c9e..43e1b01e5afc 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -308,10 +308,20 @@ int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_u return 0; } +static long new_limit(int count) +{ + int fd = open("/dev/null", O_RDONLY); + long ret = fd; + if (count > 0) + ret = new_limit(--count); + close(fd); + return ret; +} + int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; - long nr_end, nr = open_files_cnt(); + long nr_end, nr = open_files_cnt(), lim = new_limit(3); int fd, fd_extra; #define dso_0 (dsos[0]) @@ -334,7 +344,7 @@ int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_ /* Make sure we are able to open 3 fds anyway */ TEST_ASSERT_VAL("failed to set file limit", - !set_fd_limit((nr + 3))); + !set_fd_limit((lim))); TEST_ASSERT_VAL("failed to create dsos\n", !dsos__create(3, TEST_FILE_SIZE)); -- cgit v1.2.3-70-g09d2 From 6011cf68c88545e16cb32039c2cecfdae6a32315 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:48 +0100 Subject: KVM: arm64: Walk userspace page tables to compute the THP mapping size We currently rely on the kvm_is_transparent_hugepage() helper to discover whether a given page has the potential to be mapped as a block mapping. However, this API doesn't really give un everything we want: - we don't get the size: this is not crucial today as we only support PMD-sized THPs, but we'd like to have larger sizes in the future - we're the only user left of the API, and there is a will to remove it altogether To address the above, implement a simple walker using the existing page table infrastructure, and plumb it into transparent_hugepage_adjust(). No new page sizes are supported in the process. Signed-off-by: Marc Zyngier Reviewed-by: Alexandru Elisei Link: https://lore.kernel.org/r/20210726153552.1535838-3-maz@kernel.org --- arch/arm64/kvm/mmu.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 0625bf2353c2..183c107c06b2 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -433,6 +433,32 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size, return 0; } +static struct kvm_pgtable_mm_ops kvm_user_mm_ops = { + /* We shouldn't need any other callback to walk the PT */ + .phys_to_virt = kvm_host_va, +}; + +static int get_user_mapping_size(struct kvm *kvm, u64 addr) +{ + struct kvm_pgtable pgt = { + .pgd = (kvm_pte_t *)kvm->mm->pgd, + .ia_bits = VA_BITS, + .start_level = (KVM_PGTABLE_MAX_LEVELS - + CONFIG_PGTABLE_LEVELS), + .mm_ops = &kvm_user_mm_ops, + }; + kvm_pte_t pte = 0; /* Keep GCC quiet... */ + u32 level = ~0; + int ret; + + ret = kvm_pgtable_get_leaf(&pgt, addr, &pte, &level); + VM_BUG_ON(ret); + VM_BUG_ON(level >= KVM_PGTABLE_MAX_LEVELS); + VM_BUG_ON(!(pte & PTE_VALID)); + + return BIT(ARM64_HW_PGTABLE_LEVEL_SHIFT(level)); +} + static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { .zalloc_page = stage2_memcache_zalloc_page, .zalloc_pages_exact = kvm_host_zalloc_pages_exact, @@ -780,7 +806,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot, * Returns the size of the mapping. */ static unsigned long -transparent_hugepage_adjust(struct kvm_memory_slot *memslot, +transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned long hva, kvm_pfn_t *pfnp, phys_addr_t *ipap) { @@ -791,8 +817,8 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot, * sure that the HVA and IPA are sufficiently aligned and that the * block map is contained within the memslot. */ - if (kvm_is_transparent_hugepage(pfn) && - fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) { + if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE) && + get_user_mapping_size(kvm, hva) >= PMD_SIZE) { /* * The address we faulted on is backed by a transparent huge * page. However, because we map the compound huge page and @@ -1051,7 +1077,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * backed by a THP and thus use block mapping if possible. */ if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) - vma_pagesize = transparent_hugepage_adjust(memslot, hva, + vma_pagesize = transparent_hugepage_adjust(kvm, memslot, hva, &pfn, &fault_ipa); if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { -- cgit v1.2.3-70-g09d2 From f2cc327303b13a70311e823bd52aa0bca8c7ddbc Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:49 +0100 Subject: KVM: arm64: Avoid mapping size adjustment on permission fault Since we only support PMD-sized mappings for THP, getting a permission fault on a level that results in a mapping being larger than PAGE_SIZE is a sure indication that we have already upgraded our mapping to a PMD. In this case, there is no need to try and parse userspace page tables, as the fault information already tells us everything. Signed-off-by: Marc Zyngier Reviewed-by: Alexandru Elisei Link: https://lore.kernel.org/r/20210726153552.1535838-4-maz@kernel.org --- arch/arm64/kvm/mmu.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 183c107c06b2..116a2910a4a4 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1076,9 +1076,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * If we are not forced to use page mapping, check if we are * backed by a THP and thus use block mapping if possible. */ - if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) - vma_pagesize = transparent_hugepage_adjust(kvm, memslot, hva, - &pfn, &fault_ipa); + if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) { + if (fault_status == FSC_PERM && fault_granule > PAGE_SIZE) + vma_pagesize = fault_granule; + else + vma_pagesize = transparent_hugepage_adjust(kvm, memslot, + hva, &pfn, + &fault_ipa); + } if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { /* Check the VMM hasn't introduced a new VM_SHARED VMA */ -- cgit v1.2.3-70-g09d2 From 205d76ff0684a0b4fe3ff3a283d143a47439d191 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:50 +0100 Subject: KVM: Remove kvm_is_transparent_hugepage() and PageTransCompoundMap() Now that arm64 has stopped using kvm_is_transparent_hugepage(), we can remove it, as well as PageTransCompoundMap() which was only used by the former. Acked-by: Paolo Bonzini Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210726153552.1535838-5-maz@kernel.org --- include/linux/page-flags.h | 37 ------------------------------------- virt/kvm/kvm_main.c | 10 ---------- 2 files changed, 47 deletions(-) diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 5922031ffab6..1ace27c4a8e0 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -632,43 +632,6 @@ static inline int PageTransCompound(struct page *page) return PageCompound(page); } -/* - * PageTransCompoundMap is the same as PageTransCompound, but it also - * guarantees the primary MMU has the entire compound page mapped - * through pmd_trans_huge, which in turn guarantees the secondary MMUs - * can also map the entire compound page. This allows the secondary - * MMUs to call get_user_pages() only once for each compound page and - * to immediately map the entire compound page with a single secondary - * MMU fault. If there will be a pmd split later, the secondary MMUs - * will get an update through the MMU notifier invalidation through - * split_huge_pmd(). - * - * Unlike PageTransCompound, this is safe to be called only while - * split_huge_pmd() cannot run from under us, like if protected by the - * MMU notifier, otherwise it may result in page->_mapcount check false - * positives. - * - * We have to treat page cache THP differently since every subpage of it - * would get _mapcount inc'ed once it is PMD mapped. But, it may be PTE - * mapped in the current process so comparing subpage's _mapcount to - * compound_mapcount to filter out PTE mapped case. - */ -static inline int PageTransCompoundMap(struct page *page) -{ - struct page *head; - - if (!PageTransCompound(page)) - return 0; - - if (PageAnon(page)) - return atomic_read(&page->_mapcount) < 0; - - head = compound_head(page); - /* File THP is PMD mapped and not PTE mapped */ - return atomic_read(&page->_mapcount) == - atomic_read(compound_mapcount_ptr(head)); -} - /* * PageTransTail returns true for both transparent huge pages * and hugetlbfs pages, so it should only be called when it's known diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d20fba0fc290..7b72a2b35a7e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -189,16 +189,6 @@ bool kvm_is_reserved_pfn(kvm_pfn_t pfn) return true; } -bool kvm_is_transparent_hugepage(kvm_pfn_t pfn) -{ - struct page *page = pfn_to_page(pfn); - - if (!PageTransCompoundMap(page)) - return false; - - return is_transparent_hugepage(compound_head(page)); -} - /* * Switches to specified vcpu, until a matching vcpu_put() */ -- cgit v1.2.3-70-g09d2 From 0fe49630101b3ce23bd21a2788440ac719ec868a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:51 +0100 Subject: KVM: arm64: Use get_page() instead of kvm_get_pfn() When mapping a THP, we are guaranteed that the page isn't reserved, and we can safely avoid the kvm_is_reserved_pfn() call. Replace kvm_get_pfn() with get_page(pfn_to_page()). Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210726153552.1535838-6-maz@kernel.org --- arch/arm64/kvm/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 116a2910a4a4..6e002d30a478 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -840,7 +840,7 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot, *ipap &= PMD_MASK; kvm_release_pfn_clean(pfn); pfn &= ~(PTRS_PER_PMD - 1); - kvm_get_pfn(pfn); + get_page(pfn_to_page(pfn)); *pfnp = pfn; return PMD_SIZE; -- cgit v1.2.3-70-g09d2 From 63db506e07622c344a3c748a1c06293d48780f83 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:47 +0100 Subject: KVM: arm64: Introduce helper to retrieve a PTE and its level It is becoming a common need to fetch the PTE for a given address together with its level. Add such a helper. Signed-off-by: Marc Zyngier Reviewed-by: Quentin Perret Reviewed-by: Alexandru Elisei Link: https://lore.kernel.org/r/20210726153552.1535838-2-maz@kernel.org --- arch/arm64/include/asm/kvm_pgtable.h | 20 ++++++++++++++++++ arch/arm64/kvm/hyp/pgtable.c | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index f004c0115d89..e42b55bd50a2 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -432,6 +432,26 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size); int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, struct kvm_pgtable_walker *walker); +/** + * kvm_pgtable_get_leaf() - Walk a page-table and retrieve the leaf entry + * with its level. + * @pgt: Page-table structure initialised by kvm_pgtable_*_init() + * or a similar initialiser. + * @addr: Input address for the start of the walk. + * @ptep: Pointer to storage for the retrieved PTE. + * @level: Pointer to storage for the level of the retrieved PTE. + * + * The offset of @addr within a page is ignored. + * + * The walker will walk the page-table entries corresponding to the input + * address specified, retrieving the leaf corresponding to this address. + * Invalid entries are treated as leaf entries. + * + * Return: 0 on success, negative error code on failure. + */ +int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, + kvm_pte_t *ptep, u32 *level); + /** * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical * Addresses with compatible permission diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 05321f4165e3..78f36bd5df6c 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -326,6 +326,45 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, return _kvm_pgtable_walk(&walk_data); } +struct leaf_walk_data { + kvm_pte_t pte; + u32 level; +}; + +static int leaf_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, + enum kvm_pgtable_walk_flags flag, void * const arg) +{ + struct leaf_walk_data *data = arg; + + data->pte = *ptep; + data->level = level; + + return 0; +} + +int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, + kvm_pte_t *ptep, u32 *level) +{ + struct leaf_walk_data data; + struct kvm_pgtable_walker walker = { + .cb = leaf_walker, + .flags = KVM_PGTABLE_WALK_LEAF, + .arg = &data, + }; + int ret; + + ret = kvm_pgtable_walk(pgt, ALIGN_DOWN(addr, PAGE_SIZE), + PAGE_SIZE, &walker); + if (!ret) { + if (ptep) + *ptep = data.pte; + if (level) + *level = data.level; + } + + return ret; +} + struct hyp_map_data { u64 phys; kvm_pte_t attr; -- cgit v1.2.3-70-g09d2 From 36c3ce6c0d03a6c9992c3359f879cdc70fde836a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 26 Jul 2021 16:35:52 +0100 Subject: KVM: Get rid of kvm_get_pfn() Nobody is using kvm_get_pfn() anymore. Get rid of it. Acked-by: Paolo Bonzini Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210726153552.1535838-7-maz@kernel.org --- include/linux/kvm_host.h | 1 - virt/kvm/kvm_main.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ae7735b490b4..9818d271c2a1 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -824,7 +824,6 @@ void kvm_release_pfn_clean(kvm_pfn_t pfn); void kvm_release_pfn_dirty(kvm_pfn_t pfn); void kvm_set_pfn_dirty(kvm_pfn_t pfn); void kvm_set_pfn_accessed(kvm_pfn_t pfn); -void kvm_get_pfn(kvm_pfn_t pfn); void kvm_release_pfn(kvm_pfn_t pfn, bool dirty, struct gfn_to_pfn_cache *cache); int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 7b72a2b35a7e..1d3a03c0fed3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2215,7 +2215,7 @@ static int hva_to_pfn_remapped(struct vm_area_struct *vma, * Get a reference here because callers of *hva_to_pfn* and * *gfn_to_pfn* ultimately call kvm_release_pfn_clean on the * returned pfn. This is only needed if the VMA has VM_MIXEDMAP - * set, but the kvm_get_pfn/kvm_release_pfn_clean pair will + * set, but the kvm_try_get_pfn/kvm_release_pfn_clean pair will * simply do nothing for reserved pfns. * * Whoever called remap_pfn_range is also going to call e.g. @@ -2612,13 +2612,6 @@ void kvm_set_pfn_accessed(kvm_pfn_t pfn) } EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed); -void kvm_get_pfn(kvm_pfn_t pfn) -{ - if (!kvm_is_reserved_pfn(pfn)) - get_page(pfn_to_page(pfn)); -} -EXPORT_SYMBOL_GPL(kvm_get_pfn); - static int next_segment(unsigned long len, int offset) { if (len > PAGE_SIZE - offset) -- cgit v1.2.3-70-g09d2 From 2681bd85a4b92788e265934d0d76bd56b5b08d16 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 19 Jul 2021 15:31:49 -0700 Subject: perf tools: Remove repipe argument from perf_session__new() The repipe argument is only used by perf inject and the all others passes 'false'. Let's remove it from the function signature and add __perf_session__new() to be called from perf inject directly. This is a preparation of the change the pipe input/output. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719223153.1618812-2-namhyung@kernel.org [ Fixed up some trivial conflicts as this patchset fell thru the cracks ;-( ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/synthesize.c | 4 ++-- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-buildid-cache.c | 2 +- tools/perf/builtin-buildid-list.c | 2 +- tools/perf/builtin-c2c.c | 2 +- tools/perf/builtin-diff.c | 4 ++-- tools/perf/builtin-evlist.c | 2 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 3 +-- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 4 ++-- tools/perf/builtin-script.c | 4 ++-- tools/perf/builtin-stat.c | 4 ++-- tools/perf/builtin-timechart.c | 3 +-- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/tests/topology.c | 4 ++-- tools/perf/util/data-convert-bt.c | 2 +- tools/perf/util/data-convert-json.c | 2 +- tools/perf/util/session.c | 5 +++-- tools/perf/util/session.h | 12 ++++++++++-- 25 files changed, 43 insertions(+), 36 deletions(-) diff --git a/tools/perf/bench/synthesize.c b/tools/perf/bench/synthesize.c index b2924e3181dc..05f7c923c745 100644 --- a/tools/perf/bench/synthesize.c +++ b/tools/perf/bench/synthesize.c @@ -117,7 +117,7 @@ static int run_single_threaded(void) int err; perf_set_singlethreaded(); - session = perf_session__new(NULL, false, NULL); + session = perf_session__new(NULL, NULL); if (IS_ERR(session)) { pr_err("Session creation failed.\n"); return PTR_ERR(session); @@ -161,7 +161,7 @@ static int do_run_multi_threaded(struct target *target, init_stats(&time_stats); init_stats(&event_stats); for (i = 0; i < multi_iterations; i++) { - session = perf_session__new(NULL, false, NULL); + session = perf_session__new(NULL, NULL); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index cebb861be3e3..05eb098cb0e3 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -596,7 +596,7 @@ int cmd_annotate(int argc, const char **argv) data.path = input_name; - annotate.session = perf_session__new(&data, false, &annotate.tool); + annotate.session = perf_session__new(&data, &annotate.tool); if (IS_ERR(annotate.session)) return PTR_ERR(annotate.session); diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index ecd0d3cb6f5c..0db3cfc04c47 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -443,7 +443,7 @@ int cmd_buildid_cache(int argc, const char **argv) data.path = missing_filename; data.force = force; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); if (IS_ERR(session)) return PTR_ERR(session); } diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 833405c27dae..cebadd632234 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -65,7 +65,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits) if (filename__fprintf_build_id(input_name, stdout) > 0) goto out; - session = perf_session__new(&data, false, &build_id__mark_dso_hit_ops); + session = perf_session__new(&data, &build_id__mark_dso_hit_ops); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 6dea37f141b2..a812f32cf5d9 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2790,7 +2790,7 @@ static int perf_c2c__report(int argc, const char **argv) goto out; } - session = perf_session__new(&data, 0, &c2c.tool); + session = perf_session__new(&data, &c2c.tool); if (IS_ERR(session)) { err = PTR_ERR(session); pr_debug("Error creating perf session\n"); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 80450c0e8f36..d925096dd7f0 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1156,7 +1156,7 @@ static int check_file_brstack(void) int i; data__for_each_file(i, d) { - d->session = perf_session__new(&d->data, false, &pdiff.tool); + d->session = perf_session__new(&d->data, &pdiff.tool); if (IS_ERR(d->session)) { pr_err("Failed to open %s\n", d->data.path); return PTR_ERR(d->session); @@ -1188,7 +1188,7 @@ static int __cmd_diff(void) ret = -EINVAL; data__for_each_file(i, d) { - d->session = perf_session__new(&d->data, false, &pdiff.tool); + d->session = perf_session__new(&d->data, &pdiff.tool); if (IS_ERR(d->session)) { ret = PTR_ERR(d->session); pr_err("Failed to open %s\n", d->data.path); diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 4617b32c9c97..b1076177c37f 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -42,7 +42,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details }; bool has_tracepoint = false; - session = perf_session__new(&data, 0, &tool); + session = perf_session__new(&data, &tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index c88c61e7f8cc..ecad56357134 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -992,7 +992,7 @@ int cmd_inject(int argc, const char **argv) } data.path = inject.input_name; - inject.session = perf_session__new(&data, inject.output.is_pipe, &inject.tool); + inject.session = __perf_session__new(&data, inject.output.is_pipe, &inject.tool); if (IS_ERR(inject.session)) { ret = PTR_ERR(inject.session); goto out_close_output; diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 0062445e8ead..da03a341c63c 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -1953,7 +1953,7 @@ int cmd_kmem(int argc, const char **argv) data.path = input_name; - kmem_session = session = perf_session__new(&data, false, &perf_kmem); + kmem_session = session = perf_session__new(&data, &perf_kmem); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 1105c9e40a80..aa1b127ffb5b 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1093,7 +1093,7 @@ static int read_events(struct perf_kvm_stat *kvm) }; kvm->tool = eops; - kvm->session = perf_session__new(&file, false, &kvm->tool); + kvm->session = perf_session__new(&file, &kvm->tool); if (IS_ERR(kvm->session)) { pr_err("Initializing perf session failed\n"); return PTR_ERR(kvm->session); @@ -1447,7 +1447,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, /* * perf session */ - kvm->session = perf_session__new(&data, false, &kvm->tool); + kvm->session = perf_session__new(&data, &kvm->tool); if (IS_ERR(kvm->session)) { err = PTR_ERR(kvm->session); goto out; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 01326e370009..d70131b7b1b1 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -868,7 +868,7 @@ static int __cmd_report(bool display_info) .force = force, }; - session = perf_session__new(&data, false, &eops); + session = perf_session__new(&data, &eops); if (IS_ERR(session)) { pr_err("Initializing perf session failed\n"); return PTR_ERR(session); diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 0fd2a74dbaca..fcf65a59bea2 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -271,8 +271,7 @@ static int report_raw_events(struct perf_mem *mem) .force = mem->force, }; int ret; - struct perf_session *session = perf_session__new(&data, false, - &mem->tool); + struct perf_session *session = perf_session__new(&data, &mem->tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 671a21c9ee4d..472cd12f10c6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1681,7 +1681,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) signal(SIGUSR2, SIG_IGN); } - session = perf_session__new(data, false, tool); + session = perf_session__new(data, tool); if (IS_ERR(session)) { pr_err("Perf session creation failed.\n"); return PTR_ERR(session); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index dc0364f671b9..a0316ce910db 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1411,7 +1411,7 @@ int cmd_report(int argc, const char **argv) data.force = symbol_conf.force; repeat: - session = perf_session__new(&data, false, &report.tool); + session = perf_session__new(&data, &report.tool); if (IS_ERR(session)) { ret = PTR_ERR(session); goto exit; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 1ff10d4bccf3..635a6b5a9ec9 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1804,7 +1804,7 @@ static int perf_sched__read_events(struct perf_sched *sched) }; int rc = -1; - session = perf_session__new(&data, false, &sched->tool); + session = perf_session__new(&data, &sched->tool); if (IS_ERR(session)) { pr_debug("Error creating perf session"); return PTR_ERR(session); @@ -3011,7 +3011,7 @@ static int perf_sched__timehist(struct perf_sched *sched) symbol_conf.use_callchain = sched->show_callchain; - session = perf_session__new(&data, false, &sched->tool); + session = perf_session__new(&data, &sched->tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 064da7f3618d..e2e165b53499 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3294,7 +3294,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array, int num, char *temp; int i = 0; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); if (IS_ERR(session)) return PTR_ERR(session); @@ -4007,7 +4007,7 @@ script_found: use_browser = 0; } - session = perf_session__new(&data, false, &script.tool); + session = perf_session__new(&data, &script.tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 634375937db9..84de61795e67 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1996,7 +1996,7 @@ static int __cmd_record(int argc, const char **argv) return -1; } - session = perf_session__new(data, false, NULL); + session = perf_session__new(data, NULL); if (IS_ERR(session)) { pr_err("Perf session creation failed\n"); return PTR_ERR(session); @@ -2168,7 +2168,7 @@ static int __cmd_report(int argc, const char **argv) perf_stat.data.path = input_name; perf_stat.data.mode = PERF_DATA_MODE_READ; - session = perf_session__new(&perf_stat.data, false, &perf_stat.tool); + session = perf_session__new(&perf_stat.data, &perf_stat.tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4e380e7b5230..43bf4d67edb0 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1598,8 +1598,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) .force = tchart->force, }; - struct perf_session *session = perf_session__new(&data, false, - &tchart->tool); + struct perf_session *session = perf_session__new(&data, &tchart->tool); int ret = -EINVAL; if (IS_ERR(session)) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 02f8bb5dbc0f..a3ae9176a83e 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1740,7 +1740,7 @@ int cmd_top(int argc, const char **argv) signal(SIGWINCH, winch_sig); } - top.session = perf_session__new(NULL, false, NULL); + top.session = perf_session__new(NULL, NULL); if (IS_ERR(top.session)) { status = PTR_ERR(top.session); goto out_delete_evlist; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8f3582eb5254..2bf21194c7b3 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -4236,7 +4236,7 @@ static int trace__replay(struct trace *trace) /* add tid to output */ trace->multiple_threads = true; - session = perf_session__new(&data, false, &trace->tool); + session = perf_session__new(&data, &trace->tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index b5efe675b321..b9028e304ddd 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -38,7 +38,7 @@ static int session_write_header(char *path) .mode = PERF_DATA_MODE_WRITE, }; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); if (!perf_pmu__has_hybrid()) { @@ -77,7 +77,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) int i; struct aggr_cpu_id id; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); cpu__setup_cpunode_map(); diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index cace349fb700..aa862a26d95c 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -1634,7 +1634,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, err = -1; /* perf.data session */ - session = perf_session__new(&data, 0, &c.tool); + session = perf_session__new(&data, &c.tool); if (IS_ERR(session)) return PTR_ERR(session); diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index 355cd1948bdf..f1ab6edba446 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -334,7 +334,7 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, goto err; } - session = perf_session__new(&data, false, &c.tool); + session = perf_session__new(&data, &c.tool); if (IS_ERR(session)) { fprintf(stderr, "Error creating perf session!\n"); goto err_fclose; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 51f727402912..073c731f8a1a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -185,8 +185,9 @@ static int ordered_events__deliver_event(struct ordered_events *oe, session->tool, event->file_offset); } -struct perf_session *perf_session__new(struct perf_data *data, - bool repipe, struct perf_tool *tool) +struct perf_session *__perf_session__new(struct perf_data *data, + bool repipe, + struct perf_tool *tool) { int ret = -ENOMEM; struct perf_session *session = zalloc(sizeof(*session)); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index e31ba4c92a6c..9d19d2a918c6 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -54,8 +54,16 @@ struct decomp { struct perf_tool; -struct perf_session *perf_session__new(struct perf_data *data, - bool repipe, struct perf_tool *tool); +struct perf_session *__perf_session__new(struct perf_data *data, + bool repipe, + struct perf_tool *tool); + +static inline struct perf_session *perf_session__new(struct perf_data *data, + struct perf_tool *tool) +{ + return __perf_session__new(data, false, tool); +} + void perf_session__delete(struct perf_session *session); void perf_event_header__bswap(struct perf_event_header *hdr); -- cgit v1.2.3-70-g09d2 From 0ae03893623dd1ddf17c1210265e5d7f9e2f3ed6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 19 Jul 2021 15:31:50 -0700 Subject: perf tools: Pass a fd to perf_file_header__read_pipe() Currently it unconditionally writes to stdout for repipe. But perf inject can direct its output to a regular file. Then it needs to write the header to the file as well. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719223153.1618812-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 3 ++- tools/perf/util/header.c | 12 ++++++------ tools/perf/util/header.h | 2 +- tools/perf/util/session.c | 8 ++++---- tools/perf/util/session.h | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ecad56357134..01afa96db59d 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -992,7 +992,8 @@ int cmd_inject(int argc, const char **argv) } data.path = inject.input_name; - inject.session = __perf_session__new(&data, inject.output.is_pipe, &inject.tool); + inject.session = __perf_session__new(&data, inject.output.is_pipe, + perf_data__fd(&inject.output), &inject.tool); if (IS_ERR(inject.session)) { ret = PTR_ERR(inject.session); goto out_close_output; diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 44249027507a..f280b3a38646 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -3865,10 +3865,10 @@ static int perf_file_section__process(struct perf_file_section *section, static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, struct perf_header *ph, struct perf_data* data, - bool repipe) + bool repipe, int repipe_fd) { struct feat_fd ff = { - .fd = STDOUT_FILENO, + .fd = repipe_fd, .ph = ph, }; ssize_t ret; @@ -3891,13 +3891,13 @@ static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, return 0; } -static int perf_header__read_pipe(struct perf_session *session) +static int perf_header__read_pipe(struct perf_session *session, int repipe_fd) { struct perf_header *header = &session->header; struct perf_pipe_file_header f_header; if (perf_file_header__read_pipe(&f_header, header, session->data, - session->repipe) < 0) { + session->repipe, repipe_fd) < 0) { pr_debug("incompatible file format\n"); return -EINVAL; } @@ -3995,7 +3995,7 @@ static int evlist__prepare_tracepoint_events(struct evlist *evlist, struct tep_h return 0; } -int perf_session__read_header(struct perf_session *session) +int perf_session__read_header(struct perf_session *session, int repipe_fd) { struct perf_data *data = session->data; struct perf_header *header = &session->header; @@ -4016,7 +4016,7 @@ int perf_session__read_header(struct perf_session *session) * We can read 'pipe' data event from regular file, * check for the pipe header regardless of source. */ - err = perf_header__read_pipe(session); + err = perf_header__read_pipe(session, repipe_fd); if (!err || perf_data__is_pipe(data)) { data->is_pipe = true; return err; diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index ae6b1cf19a7d..c9e3265832d9 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -115,7 +115,7 @@ struct perf_session; struct perf_tool; union perf_event; -int perf_session__read_header(struct perf_session *session); +int perf_session__read_header(struct perf_session *session, int repipe_fd); int perf_session__write_header(struct perf_session *session, struct evlist *evlist, int fd, bool at_exit); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 073c731f8a1a..d2e27ff96030 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -102,11 +102,11 @@ static int perf_session__deliver_event(struct perf_session *session, struct perf_tool *tool, u64 file_offset); -static int perf_session__open(struct perf_session *session) +static int perf_session__open(struct perf_session *session, int repipe_fd) { struct perf_data *data = session->data; - if (perf_session__read_header(session) < 0) { + if (perf_session__read_header(session, repipe_fd) < 0) { pr_err("incompatible file format (rerun with -v to learn more)\n"); return -1; } @@ -186,7 +186,7 @@ static int ordered_events__deliver_event(struct ordered_events *oe, } struct perf_session *__perf_session__new(struct perf_data *data, - bool repipe, + bool repipe, int repipe_fd, struct perf_tool *tool) { int ret = -ENOMEM; @@ -211,7 +211,7 @@ struct perf_session *__perf_session__new(struct perf_data *data, session->data = data; if (perf_data__is_read(data)) { - ret = perf_session__open(session); + ret = perf_session__open(session, repipe_fd); if (ret < 0) goto out_delete; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 9d19d2a918c6..5d8bd14a0a39 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -55,13 +55,13 @@ struct decomp { struct perf_tool; struct perf_session *__perf_session__new(struct perf_data *data, - bool repipe, + bool repipe, int repipe_fd, struct perf_tool *tool); static inline struct perf_session *perf_session__new(struct perf_data *data, struct perf_tool *tool) { - return __perf_session__new(data, false, tool); + return __perf_session__new(data, false, -1, tool); } void perf_session__delete(struct perf_session *session); -- cgit v1.2.3-70-g09d2 From fea20d66f90cdbdc7dccf1fa001d40e084984e55 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 19 Jul 2021 15:31:51 -0700 Subject: perf inject: Fix output from a pipe to a file Sometimes it needs to save the perf inject data to a file for debugging. But normally it assumes the same format for input and output, so the end result cannot be used due to a broken format. # perf record -a -o - sleep 1 | perf inject -b -o my.data # perf report -i my.data --stdio 0x208 [0]: failed to process type: 0 [Invalid argument] Error: failed to process sample # To display the perf.data header info, please use --header/--header-only options. # In this case, it thought the data has a regular file header since the output is not a pipe. But actually it doesn't have one and has a pipe file header. At the end of the session, it tries to rewrite the regular file header with updated features and it overwrites the data just follows the pipe header. Fix it by checking either the input and the output is a pipe. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719223153.1618812-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 01afa96db59d..f9af24350f61 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -46,6 +46,7 @@ struct perf_inject { bool jit_mode; bool in_place_update; bool in_place_update_dry_run; + bool is_pipe; const char *input_name; struct perf_data output; u64 bytes_written; @@ -126,7 +127,7 @@ static int perf_event__repipe_attr(struct perf_tool *tool, if (ret) return ret; - if (!inject->output.is_pipe) + if (!inject->is_pipe) return 0; return perf_event__repipe_synth(tool, event); @@ -826,14 +827,14 @@ static int __cmd_inject(struct perf_inject *inject) if (!inject->itrace_synth_opts.set) auxtrace_index__free(&session->auxtrace_index); - if (!data_out->is_pipe && !inject->in_place_update) + if (!inject->is_pipe && !inject->in_place_update) lseek(fd, output_data_offset, SEEK_SET); ret = perf_session__process_events(session); if (ret) return ret; - if (!data_out->is_pipe && !inject->in_place_update) { + if (!inject->is_pipe && !inject->in_place_update) { if (inject->build_ids) perf_header__set_feat(&session->header, HEADER_BUILD_ID); @@ -992,8 +993,12 @@ int cmd_inject(int argc, const char **argv) } data.path = inject.input_name; - inject.session = __perf_session__new(&data, inject.output.is_pipe, - perf_data__fd(&inject.output), &inject.tool); + if (!strcmp(inject.input_name, "-") || inject.output.is_pipe) + inject.is_pipe = true; + + inject.session = __perf_session__new(&data, inject.is_pipe, + perf_data__fd(&inject.output), + &inject.tool); if (IS_ERR(inject.session)) { ret = PTR_ERR(inject.session); goto out_close_output; -- cgit v1.2.3-70-g09d2 From c3a057dc3aa9979ce6dc350e05eb2e4c021432cd Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 19 Jul 2021 15:31:52 -0700 Subject: perf inject: Fix output from a file to a pipe When the input is a regular file but the output is a pipe, it should write a pipe header. But just repiping would write a portion of the existing header which is different in 'size' value. So we need to prevent it and write a new pipe header along with other information like event attributes and features. This can handle something like this: # perf record -a -B sleep 1 # perf inject -b -i perf.data | perf report -i - Factor out perf_event__synthesize_for_pipe() to be shared between perf record and inject. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719223153.1618812-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 28 ++++++++++++++++++-- tools/perf/builtin-record.c | 38 +++------------------------ tools/perf/util/synthetic-events.c | 53 +++++++++++++++++++++++++++++++++++++- tools/perf/util/synthetic-events.h | 6 +++++ 4 files changed, 88 insertions(+), 37 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index f9af24350f61..6ad191e731fc 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -919,6 +919,7 @@ int cmd_inject(int argc, const char **argv) .use_stdio = true, }; int ret; + bool repipe = true; struct option options[] = { OPT_BOOLEAN('b', "build-ids", &inject.build_ids, @@ -993,10 +994,18 @@ int cmd_inject(int argc, const char **argv) } data.path = inject.input_name; - if (!strcmp(inject.input_name, "-") || inject.output.is_pipe) + if (!strcmp(inject.input_name, "-") || inject.output.is_pipe) { inject.is_pipe = true; + /* + * Do not repipe header when input is a regular file + * since either it can rewrite the header at the end + * or write a new pipe header. + */ + if (strcmp(inject.input_name, "-")) + repipe = false; + } - inject.session = __perf_session__new(&data, inject.is_pipe, + inject.session = __perf_session__new(&data, repipe, perf_data__fd(&inject.output), &inject.tool); if (IS_ERR(inject.session)) { @@ -1007,6 +1016,21 @@ int cmd_inject(int argc, const char **argv) if (zstd_init(&(inject.session->zstd_data), 0) < 0) pr_warning("Decompression initialization failed.\n"); + if (!data.is_pipe && inject.output.is_pipe) { + ret = perf_header__write_pipe(perf_data__fd(&inject.output)); + if (ret < 0) { + pr_err("Couldn't write a new pipe header.\n"); + goto out_delete; + } + + ret = perf_event__synthesize_for_pipe(&inject.tool, + inject.session, + &inject.output, + perf_event__repipe); + if (ret < 0) + goto out_delete; + } + if (inject.build_ids && !inject.build_id_all) { /* * to make sure the mmap records are ordered correctly diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 472cd12f10c6..548c1dbde6c5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1387,7 +1387,6 @@ static int record__synthesize(struct record *rec, bool tail) struct perf_data *data = &rec->data; struct record_opts *opts = &rec->opts; struct perf_tool *tool = &rec->tool; - int fd = perf_data__fd(data); int err = 0; event_op f = process_synthesized_event; @@ -1395,41 +1394,12 @@ static int record__synthesize(struct record *rec, bool tail) return 0; if (data->is_pipe) { - /* - * We need to synthesize events first, because some - * features works on top of them (on report side). - */ - err = perf_event__synthesize_attrs(tool, rec->evlist, - process_synthesized_event); - if (err < 0) { - pr_err("Couldn't synthesize attrs.\n"); - goto out; - } - - err = perf_event__synthesize_features(tool, session, rec->evlist, + err = perf_event__synthesize_for_pipe(tool, session, data, process_synthesized_event); - if (err < 0) { - pr_err("Couldn't synthesize features.\n"); - return err; - } + if (err < 0) + goto out; - if (have_tracepoints(&rec->evlist->core.entries)) { - /* - * FIXME err <= 0 here actually means that - * there were no tracepoints so its not really - * an error, just that we don't need to - * synthesize anything. We really have to - * return this more properly and also - * propagate errors that now are calling die() - */ - err = perf_event__synthesize_tracing_data(tool, fd, rec->evlist, - process_synthesized_event); - if (err <= 0) { - pr_err("Couldn't record tracing data.\n"); - goto out; - } - rec->bytes_written += err; - } + rec->bytes_written += err; } err = perf_event__synth_time_conv(record__pick_pc(rec), tool, diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 35aa0c0f7cd9..a7e981b2d7de 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only +#include "util/cgroup.h" +#include "util/data.h" #include "util/debug.h" #include "util/dso.h" #include "util/event.h" @@ -16,7 +18,6 @@ #include "util/synthetic-events.h" #include "util/target.h" #include "util/time-utils.h" -#include "util/cgroup.h" #include #include #include @@ -2179,3 +2180,53 @@ int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session free(ff.buf); return ret; } + +int perf_event__synthesize_for_pipe(struct perf_tool *tool, + struct perf_session *session, + struct perf_data *data, + perf_event__handler_t process) +{ + int err; + int ret = 0; + struct evlist *evlist = session->evlist; + + /* + * We need to synthesize events first, because some + * features works on top of them (on report side). + */ + err = perf_event__synthesize_attrs(tool, evlist, process); + if (err < 0) { + pr_err("Couldn't synthesize attrs.\n"); + return err; + } + ret += err; + + err = perf_event__synthesize_features(tool, session, evlist, process); + if (err < 0) { + pr_err("Couldn't synthesize features.\n"); + return err; + } + ret += err; + + if (have_tracepoints(&evlist->core.entries)) { + int fd = perf_data__fd(data); + + /* + * FIXME err <= 0 here actually means that + * there were no tracepoints so its not really + * an error, just that we don't need to + * synthesize anything. We really have to + * return this more properly and also + * propagate errors that now are calling die() + */ + err = perf_event__synthesize_tracing_data(tool, fd, evlist, + process); + if (err <= 0) { + pr_err("Couldn't record tracing data.\n"); + return err; + } + ret += err; + } + + return ret; +} diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h index e7a3e9589738..c845e2b9b444 100644 --- a/tools/perf/util/synthetic-events.h +++ b/tools/perf/util/synthetic-events.h @@ -14,6 +14,7 @@ struct evsel; struct machine; struct perf_counts_values; struct perf_cpu_map; +struct perf_data; struct perf_event_attr; struct perf_event_mmap_page; struct perf_sample; @@ -101,4 +102,9 @@ static inline int perf_event__synthesize_bpf_events(struct perf_session *session } #endif // HAVE_LIBBPF_SUPPORT +int perf_event__synthesize_for_pipe(struct perf_tool *tool, + struct perf_session *session, + struct perf_data *data, + perf_event__handler_t process); + #endif // __PERF_SYNTHETIC_EVENTS_H -- cgit v1.2.3-70-g09d2 From ec02f2b134d86b4a91c5d82eed03319060718a97 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 19 Jul 2021 15:31:53 -0700 Subject: perf tools: Add pipe_test.sh to verify pipe operations It builds a test program and use it to verify pipe behavior with perf record, inject and report. $ perf test pipe -v 80: perf pipe recording and injection test : --- start --- test child forked, pid 1109301 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 1109315 1109315 -1 |test.file.MGNff [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 99.99% test.file.MGNff test.file.MGNffM [.] noploop [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB - ] 99.99% test.file.MGNff test.file.MGNffM [.] noploop [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.153 MB /tmp/perf.data.dmsnlx (3995 samples) ] 99.99% test.file.MGNff test.file.MGNffM [.] noploop test child finished with 0 ---- end ---- perf pipe recording and injection test: Ok Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Ian Rogers Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210719223153.1618812-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/pipe_test.sh | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 tools/perf/tests/shell/pipe_test.sh diff --git a/tools/perf/tests/shell/pipe_test.sh b/tools/perf/tests/shell/pipe_test.sh new file mode 100755 index 000000000000..1b32b4f28391 --- /dev/null +++ b/tools/perf/tests/shell/pipe_test.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# perf pipe recording and injection test +# SPDX-License-Identifier: GPL-2.0 + +# skip if there's no compiler +if ! [ -x "$(command -v cc)" ]; then + echo "failed: no compiler, install gcc" + exit 2 +fi + +file=$(mktemp /tmp/test.file.XXXXXX) +data=$(mktemp /tmp/perf.data.XXXXXX) + +cat < +#include +#include + +volatile int done; + +void sigalrm(int sig) { + done = 1; +} + +__attribute__((noinline)) void noploop(void) { + while (!done) + continue; +} + +int main(int argc, char *argv[]) { + int sec = 1; + + if (argc > 1) + sec = atoi(argv[1]); + + signal(SIGALRM, sigalrm); + alarm(sec); + + noploop(); + return 0; +} +EOF + + +if ! perf record -e task-clock:u -o - ${file} | perf report -i - --task | grep test.file; then + echo "cannot find the test file in the perf report" + exit 1 +fi + +if ! perf record -e task-clock:u -o - ${file} | perf inject -b | perf report -i - | grep noploop; then + echo "cannot find noploop function in pipe #1" + exit 1 +fi + +perf record -e task-clock:u -o - ${file} | perf inject -b -o ${data} +if ! perf report -i ${data} | grep noploop; then + echo "cannot find noploop function in pipe #2" + exit 1 +fi + +perf record -e task-clock:u -o ${data} ${file} +if ! perf inject -b -i ${data} | perf report -i - | grep noploop; then + echo "cannot find noploop function in pipe #3" + exit 1 +fi + + +rm -f ${file} ${data} ${data}.old +exit 0 -- cgit v1.2.3-70-g09d2 From 70115558ab02fe8d28a6634350b3491a542aaa02 Mon Sep 17 00:00:00 2001 From: Jaehyoung Choi Date: Fri, 30 Jul 2021 22:29:05 +0300 Subject: pinctrl: samsung: Fix pinctrl bank pin count Commit 1abd18d1a51a ("pinctrl: samsung: Register pinctrl before GPIO") changes the order of GPIO and pinctrl registration: now pinctrl is registered before GPIO. That means gpio_chip->ngpio is not set when samsung_pinctrl_register() called, and one cannot rely on that value anymore. Use `pin_bank->nr_pins' instead of `pin_bank->gpio_chip.ngpio' to fix mentioned inconsistency. Fixes: 1abd18d1a51a ("pinctrl: samsung: Register pinctrl before GPIO") Signed-off-by: Jaehyoung Choi Signed-off-by: Sam Protsenko Link: https://lore.kernel.org/r/20210730192905.7173-1-semen.protsenko@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/pinctrl/samsung/pinctrl-samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index 376876bd6605..2975b4369f32 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -918,7 +918,7 @@ static int samsung_pinctrl_register(struct platform_device *pdev, pin_bank->grange.pin_base = drvdata->pin_base + pin_bank->pin_base; pin_bank->grange.base = pin_bank->grange.pin_base; - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; + pin_bank->grange.npins = pin_bank->nr_pins; pin_bank->grange.gc = &pin_bank->gpio_chip; pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); } -- cgit v1.2.3-70-g09d2 From 0ab410a93d627ae73136d1a52c096262360b7992 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 19 Jul 2021 13:38:59 +0100 Subject: KVM: arm64: Narrow PMU sysreg reset values to architectural requirements A number of the PMU sysregs expose reset values that are not compliant with the architecture (set bits in the RES0 ranges, for example). This in turn has the effect that we need to pointlessly mask some register fields when using them. Let's start by making sure we don't have illegal values in the shadow registers at reset time. This affects all the registers that dedicate one bit per counter, the counters themselves, PMEVTYPERn_EL0 and PMSELR_EL0. Reported-by: Alexandre Chartre Reviewed-by: Alexandre Chartre Acked-by: Russell King (Oracle) Signed-off-by: Marc Zyngier Reviewed-by: Alexandru Elisei Link: https://lore.kernel.org/r/20210719123902.1493805-2-maz@kernel.org --- arch/arm64/kvm/sys_regs.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index f6f126eb6ac1..96bdfa0e68b2 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -603,6 +603,41 @@ static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu, return REG_HIDDEN; } +static void reset_pmu_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + u64 n, mask = BIT(ARMV8_PMU_CYCLE_IDX); + + /* No PMU available, any PMU reg may UNDEF... */ + if (!kvm_arm_support_pmu_v3()) + return; + + n = read_sysreg(pmcr_el0) >> ARMV8_PMU_PMCR_N_SHIFT; + n &= ARMV8_PMU_PMCR_N_MASK; + if (n) + mask |= GENMASK(n - 1, 0); + + reset_unknown(vcpu, r); + __vcpu_sys_reg(vcpu, r->reg) &= mask; +} + +static void reset_pmevcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + reset_unknown(vcpu, r); + __vcpu_sys_reg(vcpu, r->reg) &= GENMASK(31, 0); +} + +static void reset_pmevtyper(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + reset_unknown(vcpu, r); + __vcpu_sys_reg(vcpu, r->reg) &= ARMV8_PMU_EVTYPE_MASK; +} + +static void reset_pmselr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) +{ + reset_unknown(vcpu, r); + __vcpu_sys_reg(vcpu, r->reg) &= ARMV8_PMU_COUNTER_MASK; +} + static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) { u64 pmcr, val; @@ -944,16 +979,18 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr } #define PMU_SYS_REG(r) \ - SYS_DESC(r), .reset = reset_unknown, .visibility = pmu_visibility + SYS_DESC(r), .reset = reset_pmu_reg, .visibility = pmu_visibility /* Macro to expand the PMEVCNTRn_EL0 register */ #define PMU_PMEVCNTR_EL0(n) \ { PMU_SYS_REG(SYS_PMEVCNTRn_EL0(n)), \ + .reset = reset_pmevcntr, \ .access = access_pmu_evcntr, .reg = (PMEVCNTR0_EL0 + n), } /* Macro to expand the PMEVTYPERn_EL0 register */ #define PMU_PMEVTYPER_EL0(n) \ { PMU_SYS_REG(SYS_PMEVTYPERn_EL0(n)), \ + .reset = reset_pmevtyper, \ .access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), } static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p, @@ -1595,13 +1632,13 @@ static const struct sys_reg_desc sys_reg_descs[] = { { PMU_SYS_REG(SYS_PMSWINC_EL0), .access = access_pmswinc, .reg = PMSWINC_EL0 }, { PMU_SYS_REG(SYS_PMSELR_EL0), - .access = access_pmselr, .reg = PMSELR_EL0 }, + .access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 }, { PMU_SYS_REG(SYS_PMCEID0_EL0), .access = access_pmceid, .reset = NULL }, { PMU_SYS_REG(SYS_PMCEID1_EL0), .access = access_pmceid, .reset = NULL }, { PMU_SYS_REG(SYS_PMCCNTR_EL0), - .access = access_pmu_evcntr, .reg = PMCCNTR_EL0 }, + .access = access_pmu_evcntr, .reset = reset_unknown, .reg = PMCCNTR_EL0 }, { PMU_SYS_REG(SYS_PMXEVTYPER_EL0), .access = access_pmu_evtyper, .reset = NULL }, { PMU_SYS_REG(SYS_PMXEVCNTR_EL0), -- cgit v1.2.3-70-g09d2 From f5eff40058a856c23c5ec2f31756f107a2b1ef84 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 19 Jul 2021 13:39:00 +0100 Subject: KVM: arm64: Drop unnecessary masking of PMU registers We always sanitise our PMU sysreg on the write side, so there is no need to do it on the read side as well. Drop the unnecessary masking. Acked-by: Russell King (Oracle) Reviewed-by: Alexandre Chartre Reviewed-by: Alexandru Elisei Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210719123902.1493805-3-maz@kernel.org --- arch/arm64/kvm/pmu-emul.c | 3 +-- arch/arm64/kvm/sys_regs.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index f33825c995cb..fae4e95b586c 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -373,7 +373,6 @@ static u64 kvm_pmu_overflow_status(struct kvm_vcpu *vcpu) reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1); - reg &= kvm_pmu_valid_counter_mask(vcpu); } return reg; @@ -569,7 +568,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) if (val & ARMV8_PMU_PMCR_E) { kvm_pmu_enable_counter_mask(vcpu, - __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask); + __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); } else { kvm_pmu_disable_counter_mask(vcpu, mask); } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 96bdfa0e68b2..f22139658e48 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -880,7 +880,7 @@ static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, kvm_pmu_disable_counter_mask(vcpu, val); } } else { - p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask; + p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0); } return true; @@ -904,7 +904,7 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p, /* accessing PMINTENCLR_EL1 */ __vcpu_sys_reg(vcpu, PMINTENSET_EL1) &= ~val; } else { - p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1) & mask; + p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1); } return true; @@ -926,7 +926,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p, /* accessing PMOVSCLR_EL0 */ __vcpu_sys_reg(vcpu, PMOVSSET_EL0) &= ~(p->regval & mask); } else { - p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0) & mask; + p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0); } return true; -- cgit v1.2.3-70-g09d2 From ca4f202d08ba7f24cc97dce14c6d20ec7a679135 Mon Sep 17 00:00:00 2001 From: Alexandre Chartre Date: Mon, 19 Jul 2021 13:39:01 +0100 Subject: KVM: arm64: Disabling disabled PMU counters wastes a lot of time In a KVM guest on arm64, performance counters interrupts have an unnecessary overhead which slows down execution when using the "perf record" command and limits the "perf record" sampling period. The problem is that when a guest VM disables counters by clearing the PMCR_EL0.E bit (bit 0), KVM will disable all counters defined in PMCR_EL0 even if they are not enabled in PMCNTENSET_EL0. KVM disables a counter by calling into the perf framework, in particular by calling perf_event_create_kernel_counter() which is a time consuming operation. So, for example, with a Neoverse N1 CPU core which has 6 event counters and one cycle counter, KVM will always disable all 7 counters even if only one is enabled. This typically happens when using the "perf record" command in a guest VM: perf will disable all event counters with PMCNTENTSET_EL0 and only uses the cycle counter. And when using the "perf record" -F option with a high profiling frequency, the overhead of KVM disabling all counters instead of one on every counter interrupt becomes very noticeable. The problem is fixed by having KVM disable only counters which are enabled in PMCNTENSET_EL0. If a counter is not enabled in PMCNTENSET_EL0 then KVM will not enable it when setting PMCR_EL0.E and it will remain disabled as long as it is not enabled in PMCNTENSET_EL0. So there is effectively no need to disable a counter when clearing PMCR_EL0.E if it is not enabled PMCNTENSET_EL0. Acked-by: Russell King (Oracle) Reviewed-by: Alexandru Elisei Signed-off-by: Alexandre Chartre [maz: moved 'mask' close to the actual user, simplifying the patch] Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210712170345.660272-1-alexandre.chartre@oracle.com Link: https://lore.kernel.org/r/20210719123902.1493805-4-maz@kernel.org --- arch/arm64/kvm/pmu-emul.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index fae4e95b586c..dc65b58dc68f 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -563,20 +563,21 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) */ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) { - unsigned long mask = kvm_pmu_valid_counter_mask(vcpu); int i; if (val & ARMV8_PMU_PMCR_E) { kvm_pmu_enable_counter_mask(vcpu, __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); } else { - kvm_pmu_disable_counter_mask(vcpu, mask); + kvm_pmu_disable_counter_mask(vcpu, + __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); } if (val & ARMV8_PMU_PMCR_C) kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); if (val & ARMV8_PMU_PMCR_P) { + unsigned long mask = kvm_pmu_valid_counter_mask(vcpu); mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); for_each_set_bit(i, &mask, 32) kvm_pmu_set_counter_value(vcpu, i, 0); -- cgit v1.2.3-70-g09d2 From 7a3ba3095a32f9c4ec8f30d680fea5150e12c3f3 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 19 Jul 2021 13:39:02 +0100 Subject: KVM: arm64: Remove PMSWINC_EL0 shadow register We keep an entry for the PMSWINC_EL0 register in the vcpu structure, while *never* writing anything there outside of reset. Given that the register is defined as write-only, that we always trap when this register is accessed, there is little point in saving anything anyway. Get rid of the entry, and save a mighty 8 bytes per vcpu structure. We still need to keep it exposed to userspace in order to preserve backward compatibility with previously saved VMs. Since userspace cannot expect any effect of writing to PMSWINC_EL0, treat the register as RAZ/WI for the purpose of userspace access. Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210719123902.1493805-5-maz@kernel.org --- arch/arm64/include/asm/kvm_host.h | 1 - arch/arm64/kvm/sys_regs.c | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 41911585ae0c..afc169630884 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -185,7 +185,6 @@ enum vcpu_sysreg { PMCNTENSET_EL0, /* Count Enable Set Register */ PMINTENSET_EL1, /* Interrupt Enable Set Register */ PMOVSSET_EL0, /* Overflow Flag Status Set Register */ - PMSWINC_EL0, /* Software Increment Register */ PMUSERENR_EL0, /* User Enable Register */ /* Pointer Authentication Registers in a strict increasing order. */ diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index f22139658e48..a1f5101f49a3 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1286,6 +1286,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, return __set_id_reg(vcpu, rd, uaddr, true); } +static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, + const struct kvm_one_reg *reg, void __user *uaddr) +{ + int err; + u64 val; + + /* Perform the access even if we are going to ignore the value */ + err = reg_from_user(&val, uaddr, sys_reg_to_index(rd)); + if (err) + return err; + + return 0; +} + static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { @@ -1629,8 +1643,13 @@ static const struct sys_reg_desc sys_reg_descs[] = { .access = access_pmcnten, .reg = PMCNTENSET_EL0 }, { PMU_SYS_REG(SYS_PMOVSCLR_EL0), .access = access_pmovs, .reg = PMOVSSET_EL0 }, + /* + * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was + * previously (and pointlessly) advertised in the past... + */ { PMU_SYS_REG(SYS_PMSWINC_EL0), - .access = access_pmswinc, .reg = PMSWINC_EL0 }, + .get_user = get_raz_id_reg, .set_user = set_wi_reg, + .access = access_pmswinc, .reset = NULL }, { PMU_SYS_REG(SYS_PMSELR_EL0), .access = access_pmselr, .reset = reset_pmselr, .reg = PMSELR_EL0 }, { PMU_SYS_REG(SYS_PMCEID0_EL0), -- cgit v1.2.3-70-g09d2 From 0b8f11737cffc1a406d1134b58687abc29d76b52 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:23 -0700 Subject: KVM: Add infrastructure and macro to mark VM as bugged Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: <3a0998645c328bf0895f1290e61821b70f048549.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 28 +++++++++++++++++++++++++++- virt/kvm/kvm_main.c | 10 +++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ae7735b490b4..5342592841be 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -150,6 +150,7 @@ static inline bool is_error_page(struct page *page) #define KVM_REQ_MMU_RELOAD (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_UNBLOCK 2 #define KVM_REQ_UNHALT 3 +#define KVM_REQ_VM_BUGGED (4 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQUEST_ARCH_BASE 8 #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \ @@ -596,6 +597,7 @@ struct kvm { pid_t userspace_pid; unsigned int max_halt_poll_ns; u32 dirty_ring_size; + bool vm_bugged; #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER struct notifier_block pm_notifier; @@ -629,6 +631,31 @@ struct kvm { #define vcpu_err(vcpu, fmt, ...) \ kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__) +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); +static inline void kvm_vm_bugged(struct kvm *kvm) +{ + kvm->vm_bugged = true; + kvm_make_all_cpus_request(kvm, KVM_REQ_VM_BUGGED); +} + +#define KVM_BUG(cond, kvm, fmt...) \ +({ \ + int __ret = (cond); \ + \ + if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt)) \ + kvm_vm_bugged(kvm); \ + unlikely(__ret); \ +}) + +#define KVM_BUG_ON(cond, kvm) \ +({ \ + int __ret = (cond); \ + \ + if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged)) \ + kvm_vm_bugged(kvm); \ + unlikely(__ret); \ +}) + static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm) { return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET); @@ -946,7 +973,6 @@ void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc); bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, struct kvm_vcpu *except, unsigned long *vcpu_bitmap, cpumask_var_t tmp); -bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, struct kvm_vcpu *except); bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req, diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d20fba0fc290..965c51ab0fe3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3598,7 +3598,7 @@ static long kvm_vcpu_ioctl(struct file *filp, struct kvm_fpu *fpu = NULL; struct kvm_sregs *kvm_sregs = NULL; - if (vcpu->kvm->mm != current->mm) + if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged) return -EIO; if (unlikely(_IOC_TYPE(ioctl) != KVMIO)) @@ -3808,7 +3808,7 @@ static long kvm_vcpu_compat_ioctl(struct file *filp, void __user *argp = compat_ptr(arg); int r; - if (vcpu->kvm->mm != current->mm) + if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged) return -EIO; switch (ioctl) { @@ -3874,7 +3874,7 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, { struct kvm_device *dev = filp->private_data; - if (dev->kvm->mm != current->mm) + if (dev->kvm->mm != current->mm || dev->kvm->vm_bugged) return -EIO; switch (ioctl) { @@ -4196,7 +4196,7 @@ static long kvm_vm_ioctl(struct file *filp, void __user *argp = (void __user *)arg; int r; - if (kvm->mm != current->mm) + if (kvm->mm != current->mm || kvm->vm_bugged) return -EIO; switch (ioctl) { case KVM_CREATE_VCPU: @@ -4407,7 +4407,7 @@ static long kvm_vm_compat_ioctl(struct file *filp, struct kvm *kvm = filp->private_data; int r; - if (kvm->mm != current->mm) + if (kvm->mm != current->mm || kvm->vm_bugged) return -EIO; switch (ioctl) { #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT -- cgit v1.2.3-70-g09d2 From 7ee3e8c39d3aed6ff4cc618d86ba9128f0c80087 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:24 -0700 Subject: KVM: Export kvm_make_all_cpus_request() for use in marking VMs as bugged Export kvm_make_all_cpus_request() and hoist the request helper declarations of request up to the KVM_REQ_* definitions in preparation for adding a "VM bugged" framework. The framework will add KVM_BUG() and KVM_BUG_ON() as alternatives to full BUG()/BUG_ON() for cases where KVM has definitely hit a bug (in itself or in silicon) and the VM is all but guaranteed to be hosed. Marking a VM bugged will trigger a request to all vCPUs to allow arch code to forcefully evict each vCPU from its run loop. Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Message-Id: <1d8cbbc8065d831343e70b5dcaea92268145eef1.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5342592841be..b7bf9d6a7780 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -159,6 +159,15 @@ static inline bool is_error_page(struct page *page) }) #define KVM_ARCH_REQ(nr) KVM_ARCH_REQ_FLAGS(nr, 0) +bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, + struct kvm_vcpu *except, + unsigned long *vcpu_bitmap, cpumask_var_t tmp); +bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); +bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, + struct kvm_vcpu *except); +bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req, + unsigned long *vcpu_bitmap); + #define KVM_USERSPACE_IRQ_SOURCE_ID 0 #define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1 @@ -631,7 +640,6 @@ struct kvm { #define vcpu_err(vcpu, fmt, ...) \ kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__) -bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); static inline void kvm_vm_bugged(struct kvm *kvm) { kvm->vm_bugged = true; @@ -970,14 +978,6 @@ void kvm_mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc); void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc); #endif -bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req, - struct kvm_vcpu *except, - unsigned long *vcpu_bitmap, cpumask_var_t tmp); -bool kvm_make_all_cpus_request_except(struct kvm *kvm, unsigned int req, - struct kvm_vcpu *except); -bool kvm_make_cpus_request_mask(struct kvm *kvm, unsigned int req, - unsigned long *vcpu_bitmap); - long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); long kvm_arch_vcpu_ioctl(struct file *filp, -- cgit v1.2.3-70-g09d2 From 673692735fdc40ed7da32c0cb3517adaf4227b2b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:25 -0700 Subject: KVM: x86: Use KVM_BUG/KVM_BUG_ON to handle bugs that are fatal to the VM Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: <0e8760a26151f47dc47052b25ca8b84fffe0641e.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 2 +- arch/x86/kvm/vmx/vmx.c | 23 ++++++++++++++--------- arch/x86/kvm/x86.c | 4 ++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index e8ccab50ebf6..4ce6d827fccd 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1560,7 +1560,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)); break; default: - WARN_ON_ONCE(1); + KVM_BUG_ON(1, vcpu->kvm); } } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 927a552393b9..fb1ac33a9902 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2274,7 +2274,7 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) vcpu->arch.cr4 |= vmcs_readl(GUEST_CR4) & guest_owned_bits; break; default: - WARN_ON_ONCE(1); + KVM_BUG_ON(1, vcpu->kvm); break; } } @@ -4996,6 +4996,7 @@ static int handle_cr(struct kvm_vcpu *vcpu) return kvm_complete_insn_gp(vcpu, err); case 3: WARN_ON_ONCE(enable_unrestricted_guest); + err = kvm_set_cr3(vcpu, val); return kvm_complete_insn_gp(vcpu, err); case 4: @@ -5021,14 +5022,13 @@ static int handle_cr(struct kvm_vcpu *vcpu) } break; case 2: /* clts */ - WARN_ONCE(1, "Guest should always own CR0.TS"); - vmx_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS)); - trace_kvm_cr_write(0, kvm_read_cr0(vcpu)); - return kvm_skip_emulated_instruction(vcpu); + KVM_BUG(1, vcpu->kvm, "Guest always owns CR0.TS"); + return -EIO; case 1: /*mov from cr*/ switch (cr) { case 3: WARN_ON_ONCE(enable_unrestricted_guest); + val = kvm_read_cr3(vcpu); kvm_register_write(vcpu, reg, val); trace_kvm_cr_read(cr, val); @@ -5338,7 +5338,9 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu) static int handle_nmi_window(struct kvm_vcpu *vcpu) { - WARN_ON_ONCE(!enable_vnmi); + if (KVM_BUG_ON(!enable_vnmi, vcpu->kvm)) + return -EIO; + exec_controls_clearbit(to_vmx(vcpu), CPU_BASED_NMI_WINDOW_EXITING); ++vcpu->stat.nmi_window_exits; kvm_make_request(KVM_REQ_EVENT, vcpu); @@ -5896,7 +5898,8 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) * below) should never happen as that means we incorrectly allowed a * nested VM-Enter with an invalid vmcs12. */ - WARN_ON_ONCE(vmx->nested.nested_run_pending); + if (KVM_BUG_ON(vmx->nested.nested_run_pending, vcpu->kvm)) + return -EIO; /* If guest state is invalid, start emulating */ if (vmx->emulation_required) @@ -6274,7 +6277,9 @@ static int vmx_sync_pir_to_irr(struct kvm_vcpu *vcpu) int max_irr; bool max_irr_updated; - WARN_ON(!vcpu->arch.apicv_active); + if (KVM_BUG_ON(!vcpu->arch.apicv_active, vcpu->kvm)) + return -EIO; + if (pi_test_on(&vmx->pi_desc)) { pi_clear_on(&vmx->pi_desc); /* @@ -6357,7 +6362,7 @@ static void handle_external_interrupt_irqoff(struct kvm_vcpu *vcpu) unsigned int vector = intr_info & INTR_INFO_VECTOR_MASK; gate_desc *desc = (gate_desc *)host_idt_base + vector; - if (WARN_ONCE(!is_external_intr(intr_info), + if (KVM_BUG(!is_external_intr(intr_info), vcpu->kvm, "KVM: unexpected VM-Exit interrupt info: 0x%x", intr_info)) return; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e5d5c5ed7dd4..338844b82c4c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9395,6 +9395,10 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) } if (kvm_request_pending(vcpu)) { + if (kvm_check_request(KVM_REQ_VM_BUGGED, vcpu)) { + r = -EIO; + goto out; + } if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) { if (unlikely(!kvm_x86_ops.nested_ops->get_nested_state_pages(vcpu))) { r = 0; -- cgit v1.2.3-70-g09d2 From 19025e7bc5977b35c73bea99841245f93470105e Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:26 -0700 Subject: KVM: x86/mmu: Mark VM as bugged if page fault returns RET_PF_INVALID Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: <298980aa5fc5707184ac082287d13a800cd9c25f.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 66f7f5bc3482..ce1d955a0536 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5134,7 +5134,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code, if (r == RET_PF_INVALID) { r = kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, lower_32_bits(error_code), false); - if (WARN_ON_ONCE(r == RET_PF_INVALID)) + if (KVM_BUG_ON(r == RET_PF_INVALID, vcpu->kvm)) return -EIO; } -- cgit v1.2.3-70-g09d2 From e489a4a6bddb83385cb3d896776c5a7b2ec653d8 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:29 -0700 Subject: KVM: x86: Hoist kvm_dirty_regs check out of sync_regs() Move the kvm_dirty_regs vs. KVM_SYNC_X86_VALID_FIELDS check out of sync_regs() and into its sole caller, kvm_arch_vcpu_ioctl_run(). This allows a future patch to allow synchronizing select state for protected VMs. Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: <889017a8d31cea46472e0c64b234ef5919278ed9.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 338844b82c4c..e906c05e530e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9980,7 +9980,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) goto out; } - if (kvm_run->kvm_valid_regs & ~KVM_SYNC_X86_VALID_FIELDS) { + if ((kvm_run->kvm_valid_regs & ~KVM_SYNC_X86_VALID_FIELDS) || + (kvm_run->kvm_dirty_regs & ~KVM_SYNC_X86_VALID_FIELDS)) { r = -EINVAL; goto out; } @@ -10585,9 +10586,6 @@ static void store_regs(struct kvm_vcpu *vcpu) static int sync_regs(struct kvm_vcpu *vcpu) { - if (vcpu->run->kvm_dirty_regs & ~KVM_SYNC_X86_VALID_FIELDS) - return -EINVAL; - if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_REGS) { __set_regs(vcpu, &vcpu->run->s.regs.regs); vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_REGS; -- cgit v1.2.3-70-g09d2 From 03fffc5493c8c8d850586df5740c985026c313bf Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:50 -0700 Subject: KVM: x86/mmu: Refactor shadow walk in __direct_map() to reduce indentation Employ a 'continue' to reduce the indentation for linking a new shadow page during __direct_map() in preparation for linking private pages. Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: <702419686d5700373123f6ea84e7a946c2cad8b4.1625186503.git.isaku.yamahata@intel.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index ce1d955a0536..85c70492f863 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -2939,15 +2939,16 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, break; drop_large_spte(vcpu, it.sptep); - if (!is_shadow_present_pte(*it.sptep)) { - sp = kvm_mmu_get_page(vcpu, base_gfn, it.addr, - it.level - 1, true, ACC_ALL); - - link_shadow_page(vcpu, it.sptep, sp); - if (is_tdp && huge_page_disallowed && - req_level >= it.level) - account_huge_nx_page(vcpu->kvm, sp); - } + if (is_shadow_present_pte(*it.sptep)) + continue; + + sp = kvm_mmu_get_page(vcpu, base_gfn, it.addr, + it.level - 1, true, ACC_ALL); + + link_shadow_page(vcpu, it.sptep, sp); + if (is_tdp && huge_page_disallowed && + req_level >= it.level) + account_huge_nx_page(vcpu->kvm, sp); } ret = mmu_set_spte(vcpu, it.sptep, ACC_ALL, -- cgit v1.2.3-70-g09d2 From 7fa2a347512ab06ea1558302564879c060d52b0c Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Fri, 2 Jul 2021 15:04:51 -0700 Subject: KVM: x86/mmu: Return old SPTE from mmu_spte_clear_track_bits() Return the old SPTE when clearing a SPTE and push the "old SPTE present" check to the caller. Private shadow page support will use the old SPTE in rmap_remove() to determine whether or not there is a linked private shadow page. Signed-off-by: Sean Christopherson Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini Message-Id: Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 85c70492f863..d9e3ac6dda05 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -592,9 +592,9 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte) * Rules for using mmu_spte_clear_track_bits: * It sets the sptep from present to nonpresent, and track the * state bits, it is used to clear the last level sptep. - * Returns non-zero if the PTE was previously valid. + * Returns the old PTE. */ -static int mmu_spte_clear_track_bits(u64 *sptep) +static u64 mmu_spte_clear_track_bits(u64 *sptep) { kvm_pfn_t pfn; u64 old_spte = *sptep; @@ -605,7 +605,7 @@ static int mmu_spte_clear_track_bits(u64 *sptep) old_spte = __update_clear_spte_slow(sptep, 0ull); if (!is_shadow_present_pte(old_spte)) - return 0; + return old_spte; pfn = spte_to_pfn(old_spte); @@ -622,7 +622,7 @@ static int mmu_spte_clear_track_bits(u64 *sptep) if (is_dirty_spte(old_spte)) kvm_set_pfn_dirty(pfn); - return 1; + return old_spte; } /* @@ -1119,7 +1119,9 @@ out: static void drop_spte(struct kvm *kvm, u64 *sptep) { - if (mmu_spte_clear_track_bits(sptep)) + u64 old_spte = mmu_spte_clear_track_bits(sptep); + + if (is_shadow_present_pte(old_spte)) rmap_remove(kvm, sptep); } -- cgit v1.2.3-70-g09d2 From ec1cf69c376970f42761e641cf5074b84f8db243 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 25 Jun 2021 11:32:06 -0400 Subject: KVM: X86: Add per-vm stat for max rmap list size Add a new statistic max_mmu_rmap_size, which stores the maximum size of rmap for the vm. Signed-off-by: Peter Xu Message-Id: <20210625153214.43106-2-peterx@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu/mmu.c | 2 ++ arch/x86/kvm/x86.c | 1 + 3 files changed, 4 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 974cbfb1eefe..d798650ad793 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1209,6 +1209,7 @@ struct kvm_vm_stat { u64 lpages; u64 nx_lpage_splits; u64 max_mmu_page_hash_collisions; + u64 max_mmu_rmap_size; }; struct kvm_vcpu_stat { diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index d9e3ac6dda05..0b2954b5fbc6 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -2698,6 +2698,8 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, if (is_shadow_present_pte(*sptep)) { if (!was_rmapped) { rmap_count = rmap_add(vcpu, sptep, gfn); + if (rmap_count > vcpu->kvm->stat.max_mmu_rmap_size) + vcpu->kvm->stat.max_mmu_rmap_size = rmap_count; if (rmap_count > RMAP_RECYCLE_THRESHOLD) rmap_recycle(vcpu, sptep, gfn); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e906c05e530e..ab200f2cb1f0 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -235,6 +235,7 @@ const struct _kvm_stats_desc kvm_vm_stats_desc[] = { STATS_DESC_ICOUNTER(VM, mmu_unsync), STATS_DESC_ICOUNTER(VM, lpages), STATS_DESC_ICOUNTER(VM, nx_lpage_splits), + STATS_DESC_PCOUNTER(VM, max_mmu_rmap_size), STATS_DESC_PCOUNTER(VM, max_mmu_page_hash_collisions) }; static_assert(ARRAY_SIZE(kvm_vm_stats_desc) == -- cgit v1.2.3-70-g09d2 From 38f703663d4c82ead5b51b8860deeef19d6dcb6d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 27 Jul 2021 12:32:51 +0200 Subject: KVM: arm64: Count VMID-wide TLB invalidations KVM/ARM has an architecture-specific implementation of kvm_flush_remote_tlbs; however, unlike the generic one, it does not count the flushes in kvm->stat.remote_tlb_flush, so that it inexorably remained stuck to zero. Signed-off-by: Paolo Bonzini Reviewed-by: Oliver Upton Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210727103251.16561-1-pbonzini@redhat.com --- arch/arm64/kvm/mmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 0625bf2353c2..2ca0a494a111 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -81,6 +81,7 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot) void kvm_flush_remote_tlbs(struct kvm *kvm) { kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu); + ++kvm->stat.generic.remote_tlb_flush; } static bool kvm_is_device_pfn(unsigned long pfn) -- cgit v1.2.3-70-g09d2 From 013cc4c6788f1ce9885d3c0281904f93ee8f2271 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 28 Jul 2021 21:06:23 +0800 Subject: KVM: arm64: Fix comments related to GICv2 PMR reporting Remove the repeated word 'the' from two comments. Signed-off-by: Jason Wang Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210728130623.12017-1-wangborong@cdjrlc.com --- arch/arm64/kvm/vgic/vgic-mmio-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v2.c b/arch/arm64/kvm/vgic/vgic-mmio-v2.c index a016f07adc28..5f9014ae595b 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v2.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v2.c @@ -282,7 +282,7 @@ static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu, case GIC_CPU_PRIMASK: /* * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the - * the PMR field as GICH_VMCR.VMPriMask rather than + * PMR field as GICH_VMCR.VMPriMask rather than * GICC_PMR.Priority, so we expose the upper five bits of * priority mask to userspace using the lower bits in the * unsigned long. @@ -329,7 +329,7 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu, case GIC_CPU_PRIMASK: /* * Our KVM_DEV_TYPE_ARM_VGIC_V2 device ABI exports the - * the PMR field as GICH_VMCR.VMPriMask rather than + * PMR field as GICH_VMCR.VMPriMask rather than * GICC_PMR.Priority, so we expose the upper five bits of * priority mask to userspace using the lower bits in the * unsigned long. -- cgit v1.2.3-70-g09d2 From 59103c79f46ab49453270ec9165cfdb38422088f Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Sat, 31 Jul 2021 10:17:10 +0800 Subject: iommu/arm-smmu-v3: Implement the unmap_pages() IOMMU driver callback Implement the unmap_pages() callback for ARM SMMUV3 driver to allow calls from iommu_unmap to unmap multiple pages of the same size in one call. Also remove the unmap() callback for the ARM SMMUV3 driver as it will no longer be used. Signed-off-by: Xiang Chen Acked-by: Will Deacon Link: https://lore.kernel.org/r/1627697831-158822-2-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Joerg Roedel --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 6346f21726f4..2060e6d019a3 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2450,8 +2450,9 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, return ops->map(ops, iova, paddr, size, prot, gfp); } -static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, - size_t size, struct iommu_iotlb_gather *gather) +static size_t arm_smmu_unmap_pages(struct iommu_domain *domain, unsigned long iova, + size_t pgsize, size_t pgcount, + struct iommu_iotlb_gather *gather) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops; @@ -2459,7 +2460,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, if (!ops) return 0; - return ops->unmap(ops, iova, size, gather); + return ops->unmap_pages(ops, iova, pgsize, pgcount, gather); } static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain) @@ -2823,7 +2824,7 @@ static struct iommu_ops arm_smmu_ops = { .domain_free = arm_smmu_domain_free, .attach_dev = arm_smmu_attach_dev, .map = arm_smmu_map, - .unmap = arm_smmu_unmap, + .unmap_pages = arm_smmu_unmap_pages, .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, .iova_to_phys = arm_smmu_iova_to_phys, -- cgit v1.2.3-70-g09d2 From 9eec3f9b9e243b554b5804bbdb58ea61068adbda Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Sat, 31 Jul 2021 10:17:11 +0800 Subject: iommu/arm-smmu-v3: Implement the map_pages() IOMMU driver callback Implement the map_pages() callback for ARM SMMUV3 driver to allow calls from iommu_map to map multiple pages of the same size in one call. Also remove the map() callback for the ARM SMMUV3 driver as it will no longer be used. Signed-off-by: Xiang Chen Acked-by: Will Deacon Link: https://lore.kernel.org/r/1627697831-158822-3-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Joerg Roedel --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 2060e6d019a3..35d54919c583 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2439,15 +2439,16 @@ out_unlock: return ret; } -static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot, gfp_t gfp) +static int arm_smmu_map_pages(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t pgsize, size_t pgcount, + int prot, gfp_t gfp, size_t *mapped) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; if (!ops) return -ENODEV; - return ops->map(ops, iova, paddr, size, prot, gfp); + return ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, gfp, mapped); } static size_t arm_smmu_unmap_pages(struct iommu_domain *domain, unsigned long iova, @@ -2823,7 +2824,7 @@ static struct iommu_ops arm_smmu_ops = { .domain_alloc = arm_smmu_domain_alloc, .domain_free = arm_smmu_domain_free, .attach_dev = arm_smmu_attach_dev, - .map = arm_smmu_map, + .map_pages = arm_smmu_map_pages, .unmap_pages = arm_smmu_unmap_pages, .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, -- cgit v1.2.3-70-g09d2 From 1694caef426247bb406c2b04672336ef77b5fb87 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Thu, 1 Jul 2021 17:41:01 +0200 Subject: x86/kvm: remove non-x86 stuff from arch/x86/kvm/ioapic.h The file has been moved to arch/x86 long time ago. Time to get rid of non-x86 stuff. Signed-off-by: Juergen Gross Message-Id: <20210701154105.23215-3-jgross@suse.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/ioapic.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index 11e4065e1617..bbd4a5d18b5d 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h @@ -35,11 +35,7 @@ struct kvm_vcpu; #define IOAPIC_INIT 0x5 #define IOAPIC_EXTINT 0x7 -#ifdef CONFIG_X86 #define RTC_GSI 8 -#else -#define RTC_GSI -1U -#endif struct dest_map { /* vcpu bitmap where IRQ has been sent */ -- cgit v1.2.3-70-g09d2 From 605c713023e3925d0444f495a42c903cb6ce875f Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 25 Jun 2021 11:32:07 -0400 Subject: KVM: Introduce kvm_get_kvm_safe() Introduce this safe version of kvm_get_kvm() so that it can be called even during vm destruction. Use it in kvm_debugfs_open() and remove the verbose comment. Prepare to be used elsewhere. Signed-off-by: Peter Xu Message-Id: <20210625153214.43106-3-peterx@redhat.com> [Preserve the comment in kvm_debugfs_open. - Paolo] Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b7bf9d6a7780..de58a0890b1a 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -755,6 +755,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, void kvm_exit(void); void kvm_get_kvm(struct kvm *kvm); +bool kvm_get_kvm_safe(struct kvm *kvm); void kvm_put_kvm(struct kvm *kvm); bool file_is_kvm(struct file *file); void kvm_put_kvm_no_destroy(struct kvm *kvm); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 965c51ab0fe3..5cc79373827f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1120,6 +1120,16 @@ void kvm_get_kvm(struct kvm *kvm) } EXPORT_SYMBOL_GPL(kvm_get_kvm); +/* + * Make sure the vm is not during destruction, which is a safe version of + * kvm_get_kvm(). Return true if kvm referenced successfully, false otherwise. + */ +bool kvm_get_kvm_safe(struct kvm *kvm) +{ + return refcount_inc_not_zero(&kvm->users_count); +} +EXPORT_SYMBOL_GPL(kvm_get_kvm_safe); + void kvm_put_kvm(struct kvm *kvm) { if (refcount_dec_and_test(&kvm->users_count)) @@ -4969,12 +4979,12 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file, struct kvm_stat_data *stat_data = (struct kvm_stat_data *) inode->i_private; - /* The debugfs files are a reference to the kvm struct which - * is still valid when kvm_destroy_vm is called. - * To avoid the race between open and the removal of the debugfs - * directory we test against the users count. + /* + * The debugfs files are a reference to the kvm struct which + * is still valid when kvm_destroy_vm is called. kvm_get_kvm_safe + * avoids the race between open and the removal of the debugfs directory. */ - if (!refcount_inc_not_zero(&stat_data->kvm->users_count)) + if (!kvm_get_kvm_safe(stat_data->kvm)) return -ENOENT; if (simple_attr_open(inode, file, get, -- cgit v1.2.3-70-g09d2 From 76cd325ea75bb2a84c329782d7b8015b6a970c34 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Tue, 13 Jul 2021 22:09:52 +0000 Subject: KVM: x86/mmu: Rename cr2_or_gpa to gpa in fast_page_fault fast_page_fault is only called from direct_page_fault where we know the address is a gpa. Fixes: 736c291c9f36 ("KVM: x86: Use gpa_t for cr2/gpa to fix TDP support on 32-bit KVM") Reviewed-by: Ben Gardon Reviewed-by: Sean Christopherson Signed-off-by: David Matlack Message-Id: <20210713220957.3493520-2-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 0b2954b5fbc6..6f5910b7b9bc 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3103,8 +3103,7 @@ static bool is_access_allowed(u32 fault_err_code, u64 spte) /* * Returns one of RET_PF_INVALID, RET_PF_FIXED or RET_PF_SPURIOUS. */ -static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, - u32 error_code) +static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code) { struct kvm_shadow_walk_iterator iterator; struct kvm_mmu_page *sp; @@ -3120,7 +3119,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, do { u64 new_spte; - for_each_shadow_entry_lockless(vcpu, cr2_or_gpa, iterator, spte) + for_each_shadow_entry_lockless(vcpu, gpa, iterator, spte) if (!is_shadow_present_pte(spte)) break; @@ -3199,8 +3198,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, } while (true); - trace_fast_page_fault(vcpu, cr2_or_gpa, error_code, iterator.sptep, - spte, ret); + trace_fast_page_fault(vcpu, gpa, error_code, iterator.sptep, spte, ret); walk_shadow_page_lockless_end(vcpu); return ret; -- cgit v1.2.3-70-g09d2 From 61bcd360aa9851cec969b7b40f23fd1faa7f85a4 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Tue, 13 Jul 2021 22:09:53 +0000 Subject: KVM: x86/mmu: Fix use of enums in trace_fast_page_fault Enum values have to be exported to userspace since the formatting is not done in the kernel. Without doing this perf maps RET_PF_FIXED and RET_PF_SPURIOUS to 0, which results in incorrect output: $ perf record -a -e kvmmmu:fast_page_fault --filter "ret==3" -- ./access_tracking_perf_test $ perf script | head -1 [...] new 610006048d25877 spurious 0 fixed 0 <------ should be 1 Fix this by exporting the enum values to userspace with TRACE_DEFINE_ENUM. Fixes: c4371c2a682e ("KVM: x86/mmu: Return unique RET_PF_* values if the fault was fixed") Signed-off-by: David Matlack Message-Id: <20210713220957.3493520-3-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu_internal.h | 3 +++ arch/x86/kvm/mmu/mmutrace.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index 35567293c1fd..626cb848dab4 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -140,6 +140,9 @@ void kvm_flush_remote_tlbs_with_address(struct kvm *kvm, * RET_PF_INVALID: the spte is invalid, let the real page fault path update it. * RET_PF_FIXED: The faulting entry has been fixed. * RET_PF_SPURIOUS: The faulting entry was already fixed, e.g. by another vCPU. + * + * Any names added to this enum should be exported to userspace for use in + * tracepoints via TRACE_DEFINE_ENUM() in mmutrace.h */ enum { RET_PF_RETRY = 0, diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index efbad33a0645..2924a4081a19 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -54,6 +54,12 @@ { PFERR_RSVD_MASK, "RSVD" }, \ { PFERR_FETCH_MASK, "F" } +TRACE_DEFINE_ENUM(RET_PF_RETRY); +TRACE_DEFINE_ENUM(RET_PF_EMULATE); +TRACE_DEFINE_ENUM(RET_PF_INVALID); +TRACE_DEFINE_ENUM(RET_PF_FIXED); +TRACE_DEFINE_ENUM(RET_PF_SPURIOUS); + /* * A pagetable walk has started */ -- cgit v1.2.3-70-g09d2 From c5c8c7c53004cb70715320018c3b4287071c1cfd Mon Sep 17 00:00:00 2001 From: David Matlack Date: Tue, 13 Jul 2021 22:09:54 +0000 Subject: KVM: x86/mmu: Make walk_shadow_page_lockless_{begin,end} interoperate with the TDP MMU Acquire the RCU read lock in walk_shadow_page_lockless_begin and release it in walk_shadow_page_lockless_end when the TDP MMU is enabled. This should not introduce any functional changes but is used in the following commit to make fast_page_fault interoperate with the TDP MMU. Signed-off-by: David Matlack Message-Id: <20210713220957.3493520-4-dmatlack@google.com> [Use if...else instead of if(){return;}] Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 52 +++++++++++++++++++++++++++------------------- arch/x86/kvm/mmu/tdp_mmu.c | 6 ++---- arch/x86/kvm/mmu/tdp_mmu.h | 10 +++++++++ 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 6f5910b7b9bc..d5b0c8b0e9e9 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -686,28 +686,36 @@ static bool mmu_spte_age(u64 *sptep) static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu) { - /* - * Prevent page table teardown by making any free-er wait during - * kvm_flush_remote_tlbs() IPI to all active vcpus. - */ - local_irq_disable(); + if (is_tdp_mmu(vcpu->arch.mmu)) { + kvm_tdp_mmu_walk_lockless_begin(); + } else { + /* + * Prevent page table teardown by making any free-er wait during + * kvm_flush_remote_tlbs() IPI to all active vcpus. + */ + local_irq_disable(); - /* - * Make sure a following spte read is not reordered ahead of the write - * to vcpu->mode. - */ - smp_store_mb(vcpu->mode, READING_SHADOW_PAGE_TABLES); + /* + * Make sure a following spte read is not reordered ahead of the write + * to vcpu->mode. + */ + smp_store_mb(vcpu->mode, READING_SHADOW_PAGE_TABLES); + } } static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu) { - /* - * Make sure the write to vcpu->mode is not reordered in front of - * reads to sptes. If it does, kvm_mmu_commit_zap_page() can see us - * OUTSIDE_GUEST_MODE and proceed to free the shadow page table. - */ - smp_store_release(&vcpu->mode, OUTSIDE_GUEST_MODE); - local_irq_enable(); + if (is_tdp_mmu(vcpu->arch.mmu)) { + kvm_tdp_mmu_walk_lockless_end(); + } else { + /* + * Make sure the write to vcpu->mode is not reordered in front of + * reads to sptes. If it does, kvm_mmu_commit_zap_page() can see us + * OUTSIDE_GUEST_MODE and proceed to free the shadow page table. + */ + smp_store_release(&vcpu->mode, OUTSIDE_GUEST_MODE); + local_irq_enable(); + } } static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu, bool maybe_indirect) @@ -3617,6 +3625,8 @@ static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct) /* * Return the level of the lowest level SPTE added to sptes. * That SPTE may be non-present. + * + * Must be called between walk_shadow_page_lockless_{begin,end}. */ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) { @@ -3624,8 +3634,6 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level int leaf = -1; u64 spte; - walk_shadow_page_lockless_begin(vcpu); - for (shadow_walk_init(&iterator, vcpu, addr), *root_level = iterator.level; shadow_walk_okay(&iterator); @@ -3639,8 +3647,6 @@ static int get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level break; } - walk_shadow_page_lockless_end(vcpu); - return leaf; } @@ -3652,11 +3658,15 @@ static bool get_mmio_spte(struct kvm_vcpu *vcpu, u64 addr, u64 *sptep) int root, leaf, level; bool reserved = false; + walk_shadow_page_lockless_begin(vcpu); + if (is_tdp_mmu(vcpu->arch.mmu)) leaf = kvm_tdp_mmu_get_walk(vcpu, addr, sptes, &root); else leaf = get_walk(vcpu, addr, sptes, &root); + walk_shadow_page_lockless_end(vcpu); + if (unlikely(leaf < 0)) { *sptep = 0ull; return reserved; diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 0853370bd811..228f0cc5e2cf 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1516,6 +1516,8 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, /* * Return the level of the lowest level SPTE added to sptes. * That SPTE may be non-present. + * + * Must be called between kvm_tdp_mmu_walk_lockless_{begin,end}. */ int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level) @@ -1527,14 +1529,10 @@ int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, *root_level = vcpu->arch.mmu->shadow_root_level; - rcu_read_lock(); - tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { leaf = iter.level; sptes[leaf] = iter.old_spte; } - rcu_read_unlock(); - return leaf; } diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h index 1cae4485b3bc..93e1bf5089c4 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.h +++ b/arch/x86/kvm/mmu/tdp_mmu.h @@ -77,6 +77,16 @@ bool kvm_tdp_mmu_write_protect_gfn(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn, int min_level); +static inline void kvm_tdp_mmu_walk_lockless_begin(void) +{ + rcu_read_lock(); +} + +static inline void kvm_tdp_mmu_walk_lockless_end(void) +{ + rcu_read_unlock(); +} + int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level); -- cgit v1.2.3-70-g09d2 From 6e8eb2060cc7fbc4d388d0ab70502e265aec98c6 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Tue, 13 Jul 2021 22:09:55 +0000 Subject: KVM: x86/mmu: fast_page_fault support for the TDP MMU Make fast_page_fault interoperate with the TDP MMU by leveraging walk_shadow_page_lockless_{begin,end} to acquire the RCU read lock and introducing a new helper function kvm_tdp_mmu_fast_pf_get_last_sptep to grab the lowest level sptep. Suggested-by: Ben Gardon Signed-off-by: David Matlack Message-Id: <20210713220957.3493520-5-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 50 ++++++++++++++++++++++++++++++++++------------ arch/x86/kvm/mmu/tdp_mmu.c | 41 +++++++++++++++++++++++++++++++++++++ arch/x86/kvm/mmu/tdp_mmu.h | 2 ++ 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index d5b0c8b0e9e9..29010abb659c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3108,15 +3108,41 @@ static bool is_access_allowed(u32 fault_err_code, u64 spte) return spte & PT_PRESENT_MASK; } +/* + * Returns the last level spte pointer of the shadow page walk for the given + * gpa, and sets *spte to the spte value. This spte may be non-preset. If no + * walk could be performed, returns NULL and *spte does not contain valid data. + * + * Contract: + * - Must be called between walk_shadow_page_lockless_{begin,end}. + * - The returned sptep must not be used after walk_shadow_page_lockless_end. + */ +static u64 *fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, gpa_t gpa, u64 *spte) +{ + struct kvm_shadow_walk_iterator iterator; + u64 old_spte; + u64 *sptep = NULL; + + for_each_shadow_entry_lockless(vcpu, gpa, iterator, old_spte) { + sptep = iterator.sptep; + *spte = old_spte; + + if (!is_shadow_present_pte(old_spte)) + break; + } + + return sptep; +} + /* * Returns one of RET_PF_INVALID, RET_PF_FIXED or RET_PF_SPURIOUS. */ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code) { - struct kvm_shadow_walk_iterator iterator; struct kvm_mmu_page *sp; int ret = RET_PF_INVALID; u64 spte = 0ull; + u64 *sptep = NULL; uint retry_count = 0; if (!page_fault_can_be_fast(error_code)) @@ -3127,14 +3153,15 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code) do { u64 new_spte; - for_each_shadow_entry_lockless(vcpu, gpa, iterator, spte) - if (!is_shadow_present_pte(spte)) - break; + if (is_tdp_mmu(vcpu->arch.mmu)) + sptep = kvm_tdp_mmu_fast_pf_get_last_sptep(vcpu, gpa, &spte); + else + sptep = fast_pf_get_last_sptep(vcpu, gpa, &spte); if (!is_shadow_present_pte(spte)) break; - sp = sptep_to_sp(iterator.sptep); + sp = sptep_to_sp(sptep); if (!is_last_spte(spte, sp->role.level)) break; @@ -3192,8 +3219,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code) * since the gfn is not stable for indirect shadow page. See * Documentation/virt/kvm/locking.rst to get more detail. */ - if (fast_pf_fix_direct_spte(vcpu, sp, iterator.sptep, spte, - new_spte)) { + if (fast_pf_fix_direct_spte(vcpu, sp, sptep, spte, new_spte)) { ret = RET_PF_FIXED; break; } @@ -3206,7 +3232,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code) } while (true); - trace_fast_page_fault(vcpu, gpa, error_code, iterator.sptep, spte, ret); + trace_fast_page_fault(vcpu, gpa, error_code, sptep, spte, ret); walk_shadow_page_lockless_end(vcpu); return ret; @@ -3841,11 +3867,9 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, if (page_fault_handle_page_track(vcpu, error_code, gfn)) return RET_PF_EMULATE; - if (!is_tdp_mmu_fault) { - r = fast_page_fault(vcpu, gpa, error_code); - if (r != RET_PF_INVALID) - return r; - } + r = fast_page_fault(vcpu, gpa, error_code); + if (r != RET_PF_INVALID) + return r; r = mmu_topup_memory_caches(vcpu, false); if (r) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 228f0cc5e2cf..88aff5d0512c 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -527,6 +527,10 @@ static inline bool tdp_mmu_set_spte_atomic_no_dirty_log(struct kvm *kvm, if (is_removed_spte(iter->old_spte)) return false; + /* + * Note, fast_pf_fix_direct_spte() can also modify TDP MMU SPTEs and + * does not hold the mmu_lock. + */ if (cmpxchg64(rcu_dereference(iter->sptep), iter->old_spte, new_spte) != iter->old_spte) return false; @@ -1536,3 +1540,40 @@ int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, return leaf; } + +/* + * Returns the last level spte pointer of the shadow page walk for the given + * gpa, and sets *spte to the spte value. This spte may be non-preset. If no + * walk could be performed, returns NULL and *spte does not contain valid data. + * + * Contract: + * - Must be called between kvm_tdp_mmu_walk_lockless_{begin,end}. + * - The returned sptep must not be used after kvm_tdp_mmu_walk_lockless_end. + * + * WARNING: This function is only intended to be called during fast_page_fault. + */ +u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr, + u64 *spte) +{ + struct tdp_iter iter; + struct kvm_mmu *mmu = vcpu->arch.mmu; + gfn_t gfn = addr >> PAGE_SHIFT; + tdp_ptep_t sptep = NULL; + + tdp_mmu_for_each_pte(iter, mmu, gfn, gfn + 1) { + *spte = iter.old_spte; + sptep = iter.sptep; + } + + /* + * Perform the rcu_dereference to get the raw spte pointer value since + * we are passing it up to fast_page_fault, which is shared with the + * legacy MMU and thus does not retain the TDP MMU-specific __rcu + * annotation. + * + * This is safe since fast_page_fault obeys the contracts of this + * function as well as all TDP MMU contracts around modifying SPTEs + * outside of mmu_lock. + */ + return rcu_dereference(sptep); +} diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h index 93e1bf5089c4..361b47f98cc5 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.h +++ b/arch/x86/kvm/mmu/tdp_mmu.h @@ -89,6 +89,8 @@ static inline void kvm_tdp_mmu_walk_lockless_end(void) int kvm_tdp_mmu_get_walk(struct kvm_vcpu *vcpu, u64 addr, u64 *sptes, int *root_level); +u64 *kvm_tdp_mmu_fast_pf_get_last_sptep(struct kvm_vcpu *vcpu, u64 addr, + u64 *spte); #ifdef CONFIG_X86_64 bool kvm_mmu_init_tdp_mmu(struct kvm *kvm); -- cgit v1.2.3-70-g09d2 From 71ba3f3189c78f756a659568fb473600fd78f207 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 26 Jul 2021 12:30:52 -0400 Subject: KVM: x86: enable TDP MMU by default With the addition of fast page fault support, the TDP-specific MMU has reached feature parity with the original MMU. All my testing in the last few months has been done with the TDP MMU; switch the default on 64-bit machines. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/tdp_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 88aff5d0512c..41cee1d22918 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -10,7 +10,7 @@ #include #include -static bool __read_mostly tdp_mmu_enabled = false; +static bool __read_mostly tdp_mmu_enabled = true; module_param_named(tdp_mmu, tdp_mmu_enabled, bool, 0644); /* Initializes the TDP MMU for the VM, if enabled. */ -- cgit v1.2.3-70-g09d2 From df63202fe52bd1583ce1418c755a81d6d41af3b9 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Tue, 13 Jul 2021 17:20:19 +0300 Subject: KVM: x86: APICv: drop immediate APICv disablement on current vCPU Special case of disabling the APICv on the current vCPU right away in kvm_request_apicv_update doesn't bring much benefit vs raising KVM_REQ_APICV_UPDATE on it instead, since this request will be processed on the next entry to the guest. (the comment about having another #VMEXIT is wrong). It also hides various assumptions that APIVc enable state matches the APICv inhibit state, as this special case only makes those states match on the current vCPU. Previous patches fixed few such assumptions so now it should be safe to drop this special case. Signed-off-by: Maxim Levitsky Message-Id: <20210713142023.106183-5-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ab200f2cb1f0..54fdadacb27f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9264,7 +9264,6 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv); */ void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) { - struct kvm_vcpu *except; unsigned long old, new, expected; if (!kvm_x86_ops.check_apicv_inhibit_reasons || @@ -9290,16 +9289,7 @@ void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) if (kvm_x86_ops.pre_update_apicv_exec_ctrl) static_call(kvm_x86_pre_update_apicv_exec_ctrl)(kvm, activate); - /* - * Sending request to update APICV for all other vcpus, - * while update the calling vcpu immediately instead of - * waiting for another #VMEXIT to handle the request. - */ - except = kvm_get_running_vcpu(); - kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, - except); - if (except) - kvm_vcpu_update_apicv(except); + kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE); } EXPORT_SYMBOL_GPL(kvm_request_apicv_update); -- cgit v1.2.3-70-g09d2 From df37ed38e6c26064d5f97ebbe5cacc75eeb89153 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:39 -0700 Subject: KVM: x86: Flush the guest's TLB on INIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flush the guest's TLB on INIT, as required by Intel's SDM. Although AMD's APM states that the TLBs are unchanged by INIT, it's not clear that that's correct as the APM also states that the TLB is flush on "External initialization of the processor." Regardless, relying on the guest to be paranoid is unnecessarily risky, while an unnecessary flush is benign from a functional perspective and likely has no measurable impact on guest performance. Note, as of the April 2021 version of Intels' SDM, it also contradicts itself with respect to TLB flushing. The overview of INIT explicitly calls out the TLBs as being invalidated, while a table later in the same section says they are unchanged. 9.1 INITIALIZATION OVERVIEW: The major difference is that during an INIT, the internal caches, MSRs, MTRRs, and x87 FPU state are left unchanged (although, the TLBs and BTB are invalidated as with a hardware reset) Table 9-1: Register Power up Reset INIT Data and Code Cache, TLBs: Invalid[6] Invalid[6] Unchanged Given Core2's erratum[*] about global TLB entries not being flush on INIT, it's safe to assume that the table is simply wrong. AZ28. INIT Does Not Clear Global Entries in the TLB Problem: INIT may not flush a TLB entry when: • The processor is in protected mode with paging enabled and the page global enable flag is set (PGE bit of CR4 register) • G bit for the page table entry is set • TLB entry is present in TLB when INIT occurs • Software may encounter unexpected page fault or incorrect address translation due to a TLB entry erroneously left in TLB after INIT. Workaround: Write to CR3, CR4 (setting bits PSE, PGE or PAE) or CR0 (setting bits PG or PE) registers before writing to memory early in BIOS code to clear all the global entries from TLB. Status: For the steppings affected, see the Summary Tables of Changes. [*] https://www.intel.com/content/dam/support/us/en/documents/processors/mobile/celeron/sb/320121.pdf Fixes: 6aa8b732ca01 ("[PATCH] kvm: userspace interface") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-2-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 54fdadacb27f..164ecca7769e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10872,6 +10872,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) */ if (old_cr0 & X86_CR0_PG) kvm_mmu_reset_context(vcpu); + + /* + * Intel's SDM states that all TLB entries are flushed on INIT. AMD's + * APM states the TLBs are untouched by INIT, but it also states that + * the TLBs are flushed on "External initialization of the processor." + * Flush the guest TLB regardless of vendor, there is no meaningful + * benefit in relying on the guest to flush the TLB immediately after + * INIT. A spurious TLB flush is benign and likely negligible from a + * performance perspective. + */ + if (init_event) + kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); } void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) -- cgit v1.2.3-70-g09d2 From afc8de0118be84f4058b9977d481aeb3e0758dbb Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:40 -0700 Subject: KVM: nVMX: Set LDTR to its architecturally defined value on nested VM-Exit Set L1's LDTR on VM-Exit per the Intel SDM: The host-state area does not contain a selector field for LDTR. LDTR is established as follows on all VM exits: the selector is cleared to 0000H, the segment is marked unusable and is otherwise undefined (although the base address is always canonical). This is likely a benign bug since the LDTR is unusable, as it means the L1 VMM is conditioned to reload its LDTR in order to function properly on bare metal. Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1") Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-3-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/nested.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 1a52134b0c42..7f8184f432b4 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4298,6 +4298,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, }; vmx_set_segment(vcpu, &seg, VCPU_SREG_TR); + memset(&seg, 0, sizeof(seg)); + seg.unusable = 1; + vmx_set_segment(vcpu, &seg, VCPU_SREG_LDTR); + kvm_set_dr(vcpu, 7, 0x400); vmcs_write64(GUEST_IA32_DEBUGCTL, 0); -- cgit v1.2.3-70-g09d2 From 4f117ce4aefca0e90cd44680219d4c261c1381b9 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:41 -0700 Subject: KVM: SVM: Zero out GDTR.base and IDTR.base on INIT Explicitly set GDTR.base and IDTR.base to zero when intializing the VMCB. Functionally this only affects INIT, as the bases are implicitly set to zero on RESET by virtue of the VMCB being zero allocated. Per AMD's APM, GDTR.base and IDTR.base are zeroed after RESET and INIT. Fixes: 04d2cc7780d4 ("KVM: Move main vcpu loop into subarch independent code") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-4-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4ce6d827fccd..7845232b6fb6 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1241,7 +1241,9 @@ static void init_vmcb(struct kvm_vcpu *vcpu) SVM_SELECTOR_S_MASK | SVM_SELECTOR_CODE_MASK; save->cs.limit = 0xffff; + save->gdtr.base = 0; save->gdtr.limit = 0xffff; + save->idtr.base = 0; save->idtr.limit = 0xffff; init_sys_seg(&save->ldtr, SEG_TYPE_LDT); -- cgit v1.2.3-70-g09d2 From 2a24be79b6b7061a486239c3a3489eb67b9587f6 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:42 -0700 Subject: KVM: VMX: Set EDX at INIT with CPUID.0x1, Family-Model-Stepping Set EDX at RESET/INIT based on the userspace-defined CPUID model when possible, i.e. when CPUID.0x1.EAX is defind by userspace. At RESET/INIT, all CPUs that support CPUID set EDX to the FMS enumerated in CPUID.0x1.EAX. If no CPUID match is found, fall back to KVM's default of 0x600 (Family '6'), which is the least awful approximation of KVM's virtual CPU model. Fixes: 6aa8b732ca01 ("[PATCH] kvm: userspace interface") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-5-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index fb1ac33a9902..6946a5161d38 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4394,6 +4394,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_vmx *vmx = to_vmx(vcpu); struct msr_data apic_base_msr; + u32 eax, dummy; u64 cr0; vmx->rmode.vm86_active = 0; @@ -4401,7 +4402,11 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmx->msr_ia32_umwait_control = 0; - vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); + eax = 1; + if (!kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true)) + eax = get_rdx_init_val(); + kvm_rdx_write(vcpu, eax); + vmx->hv_deadline_tsc = -1; kvm_set_cr8(vcpu, 0); -- cgit v1.2.3-70-g09d2 From 067a456d091d05fdae32cae350410d905968b645 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:43 -0700 Subject: KVM: SVM: Require exact CPUID.0x1 match when stuffing EDX at INIT Do not allow an inexact CPUID "match" when querying the guest's CPUID.0x1 to stuff EDX during INIT. In the common case, where the guest CPU model is an AMD variant, allowing an inexact match is a nop since KVM doesn't emulate Intel's goofy "out-of-range" logic for AMD and Hygon. If the vCPU model happens to be an Intel variant, an inexact match is possible if and only if the max CPUID leaf is precisely '0'. Aside from the fact that there's probably no CPU in existence with a single CPUID leaf, if the max CPUID leaf is '0', that means that CPUID.0.EAX is '0', and thus an inexact match for CPUID.0x1.EAX will also yield '0'. So, with lots of twisty logic, no functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-6-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 7845232b6fb6..f4b6fec6252f 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1346,7 +1346,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) } init_vmcb(vcpu); - kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, false); + kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true); kvm_rdx_write(vcpu, eax); if (kvm_vcpu_apicv_active(vcpu) && !init_event) -- cgit v1.2.3-70-g09d2 From 665f4d9238ad83c36dd4e078ccab45b3ddec211d Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:44 -0700 Subject: KVM: SVM: Fall back to KVM's hardcoded value for EDX at RESET/INIT At vCPU RESET/INIT (mostly RESET), stuff EDX with KVM's hardcoded, default Family-Model-Stepping ID of 0x600 if CPUID.0x1 isn't defined. At RESET, the CPUID lookup is guaranteed to "miss" because KVM emulates RESET before exposing the vCPU to userspace, i.e. userspace can't possibly have done set the vCPU's CPUID model, and thus KVM will always write '0'. At INIT, using 0x600 is less bad than using '0'. While initializing EDX to '0' is _extremely_ unlikely to be noticed by the guest, let alone break the guest, and can be overridden by userspace for the RESET case, using 0x600 is preferable as it will allow consolidating the relevant VMX and SVM RESET/INIT logic in the future. And, digging through old specs suggests that neither Intel nor AMD have ever shipped a CPU that initialized EDX to '0' at RESET. Regarding 0x600 as KVM's default Family, it is a sane default and in many ways the most appropriate. Prior to the 386 implementations, DX was undefined at RESET. With the 386, 486, 586/P5, and 686/P6/Athlon, both Intel and AMD set EDX to 3, 4, 5, and 6 respectively. AMD switched to using '15' as its primary Family with the introduction of AMD64, but Intel has continued using '6' for the last few decades. So, '6' is a valid Family for both Intel and AMD CPUs, is compatible with both 32-bit and 64-bit CPUs (albeit not a perfect fit for 64-bit AMD), and of the common Families (3 - 6), is the best fit with respect to KVM's virtual CPU model. E.g. prior to the P6, Intel CPUs did not have a STI window. Modern operating systems, Linux included, rely on the STI window, e.g. for "safe halt", and KVM unconditionally assumes the virtual CPU has an STI window. Thus enumerating a Family ID of 3, 4, or 5 would be provably wrong. Opportunistically remove a stale comment. Fixes: 66f7b72e1171 ("KVM: x86: Make register state after reset conform to specification") Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-7-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f4b6fec6252f..05c1e60d829a 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1264,7 +1264,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) kvm_mmu_reset_context(vcpu); save->cr4 = X86_CR4_PAE; - /* rdx = ?? */ if (npt_enabled) { /* Setup VMCB for Nested Paging */ @@ -1346,7 +1345,15 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) } init_vmcb(vcpu); - kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true); + /* + * Fall back to KVM's default Family/Model/Stepping if no CPUID match + * is found. Note, it's impossible to get a match at RESET since KVM + * emulates RESET before exposing the vCPU to userspace, i.e. it's + * impossible for kvm_cpuid() to find a valid entry on RESET. But, go + * through the motions in case that's ever remedied, and to be pedantic. + */ + if (!kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true)) + eax = get_rdx_init_val(); kvm_rdx_write(vcpu, eax); if (kvm_vcpu_apicv_active(vcpu) && !init_event) -- cgit v1.2.3-70-g09d2 From 61152cd907d59ffd6b0a9479b2fa3b3b7b080409 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:45 -0700 Subject: KVM: VMX: Remove explicit MMU reset in enter_rmode() Drop an explicit MMU reset when entering emulated real mode now that the vCPU INIT/RESET path correctly handles conditional MMU resets, e.g. if INIT arrives while the vCPU is in 64-bit mode. Note, while there are multiple other direct calls to vmx_set_cr0(), i.e. paths that change CR0 without invoking kvm_post_set_cr0(), only the INIT emulation can reach enter_rmode(). CLTS emulation only toggles CR.TS, VM-Exit (and late VM-Fail) emulation cannot architecturally transition to Real Mode, and VM-Enter to Real Mode is possible if and only if Unrestricted Guest is enabled (exposed to L1). This effectively reverts commit 8668a3c468ed ("KVM: VMX: Reset mmu context when entering real mode") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-8-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6946a5161d38..207393a429d1 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2852,8 +2852,6 @@ static void enter_rmode(struct kvm_vcpu *vcpu) fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.segs[VCPU_SREG_DS]); fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.segs[VCPU_SREG_GS]); fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.segs[VCPU_SREG_FS]); - - kvm_mmu_reset_context(vcpu); } int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) -- cgit v1.2.3-70-g09d2 From 5d2d7e41e3b80f37ec8673825fae07ffe9f140c3 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:46 -0700 Subject: KVM: SVM: Drop explicit MMU reset at RESET/INIT Drop an explicit MMU reset in SVM's vCPU RESET/INIT flow now that the common x86 path correctly handles conditional MMU resets, e.g. if INIT arrives while the vCPU is in 64-bit mode. This reverts commit ebae871a509d ("kvm: svm: reset mmu on VCPU reset"). Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-9-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 05c1e60d829a..a9af9bff4755 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1261,7 +1261,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) * It also updates the guest-visible cr0 value. */ svm_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); - kvm_mmu_reset_context(vcpu); save->cr4 = X86_CR4_PAE; -- cgit v1.2.3-70-g09d2 From c2f79a65b4b66681894ef7d7e3912ba55acc20d5 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:49 -0700 Subject: KVM: x86: WARN if the APIC map is dirty without an in-kernel local APIC WARN if KVM ends up in a state where it thinks its APIC map needs to be recalculated, but KVM is not emulating the local APIC. This is mostly to document KVM's "rules" in order to provide clarity in future cleanups. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-12-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ba5a27879f1d..add4dd1e3528 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -192,6 +192,9 @@ void kvm_recalculate_apic_map(struct kvm *kvm) if (atomic_read_acquire(&kvm->arch.apic_map_dirty) == CLEAN) return; + WARN_ONCE(!irqchip_in_kernel(kvm), + "Dirty APIC map without an in-kernel local APIC"); + mutex_lock(&kvm->arch.apic_map_lock); /* * Read kvm->arch.apic_map_dirty before kvm->arch.apic_map -- cgit v1.2.3-70-g09d2 From 549240e8e09e063b7ba44c9f8497e8499562a34c Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:50 -0700 Subject: KVM: x86: Remove defunct BSP "update" in local APIC reset Remove a BSP APIC update in kvm_lapic_reset() that is a glorified and confusing nop. When the code was originally added, kvm_vcpu_is_bsp() queried kvm->arch.bsp_vcpu, i.e. the intent was to set the BSP bit in the BSP vCPU's APIC. But, stuffing the BSP bit at INIT was wrong since the guest can change its BSP(s); this was fixed by commit 58d269d8cccc ("KVM: x86: BSP in MSR_IA32_APICBASE is writable"). In other words, kvm_vcpu_is_bsp() is now purely a reflection of vcpu->arch.apic_base.MSR_IA32_APICBASE_BSP, thus the update will always set the current value and kvm_lapic_set_base() is effectively a nop if the new and old values match. The RESET case, which does need to stuff the BSP for the reset vCPU, is handled by vendor code (though this will soon be moved to common code). No functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-13-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index add4dd1e3528..a24ce8fe93e5 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2367,9 +2367,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) apic->highest_isr_cache = -1; update_divide_count(apic); atomic_set(&apic->lapic_timer.pending, 0); - if (kvm_vcpu_is_bsp(vcpu)) - kvm_lapic_set_base(vcpu, - vcpu->arch.apic_base | MSR_IA32_APICBASE_BSP); + vcpu->arch.pv_eoi.msr_val = 0; apic_update_ppr(apic); if (vcpu->arch.apicv_active) { -- cgit v1.2.3-70-g09d2 From 0214f6bbe564632adba299e38023d681c1bd68c5 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:51 -0700 Subject: KVM: x86: Migrate the PIT only if vcpu0 is migrated, not any BSP Make vcpu0 the arbitrary owner of the PIT, as was intended when PIT migration was added by commit 2f5997140f22 ("KVM: migrate PIT timer"). The PIT was unintentionally turned into being owned by the BSP by commit c5af89b68abb ("KVM: Introduce kvm_vcpu_is_bsp() function."), and was then unintentionally converted to a shared ownership model when kvm_vcpu_is_bsp() was modified to check the APIC base MSR instead of hardcoding vcpu0 as the BSP. Functionally, this just means the PIT's hrtimer is migrated less often. The real motivation is to remove the usage of kvm_vcpu_is_bsp(), so that more legacy/broken crud can be removed in a future patch. Fixes: 58d269d8cccc ("KVM: x86: BSP in MSR_IA32_APICBASE is writable") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-14-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/i8254.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index a6e218c6140d..5a69cce4d72d 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -220,7 +220,8 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) struct kvm_pit *pit = vcpu->kvm->arch.vpit; struct hrtimer *timer; - if (!kvm_vcpu_is_bsp(vcpu) || !pit) + /* Somewhat arbitrarily make vcpu0 the owner of the PIT. */ + if (vcpu->vcpu_id || !pit) return; timer = &pit->pit_state.timer; -- cgit v1.2.3-70-g09d2 From 01913c57c225a8301e9a53447507f310a4be22b6 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:52 -0700 Subject: KVM: x86: Don't force set BSP bit when local APIC is managed by userspace Don't set the BSP bit in vcpu->arch.apic_base when the local APIC is managed by userspace. Forcing all vCPUs to be BSPs is non-sensical, and was dead code when it was added by commit 97222cc83163 ("KVM: Emulate local APIC in kernel"). At the time, kvm_lapic_set_base() was invoked if and only if the local APIC was in-kernel (and it couldn't be called before the vCPU created its APIC). kvm_lapic_set_base() eventually gained generic usage, but the latent bug escaped notice because the only true consumer would be the guest itself in the form of an explicit RDMSRs on APs. Out of Linux, SeaBIOS, and EDK2/OVMF, only OVMF consumes the BSP bit from the APIC_BASE MSR. For the vast majority of usage in OVMF, BSP confusion would be benign. OVMF's BSP election upon SMI rendezvous might be broken, but practically no one runs KVM with an out-of-kernel local APIC, let alone does so while utilizing SMIs with OVMF. Fixes: 97222cc83163 ("KVM: Emulate local APIC in kernel") Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-15-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index a24ce8fe93e5..acb201d16b5e 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2268,9 +2268,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) u64 old_value = vcpu->arch.apic_base; struct kvm_lapic *apic = vcpu->arch.apic; - if (!apic) - value |= MSR_IA32_APICBASE_BSP; - vcpu->arch.apic_base = value; if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) -- cgit v1.2.3-70-g09d2 From 503bc49424df4802ca34e4e1a024381fd7ced80e Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:53 -0700 Subject: KVM: x86: Set BSP bit in reset BSP vCPU's APIC base by default Set the BSP bit appropriately during local APIC "reset" instead of relying on vendor code to clean up at a later point. This is a step towards consolidating the local APIC, VMX, and SVM xAPIC initialization code. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-16-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index acb201d16b5e..0fb282b64c8f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2321,6 +2321,7 @@ EXPORT_SYMBOL_GPL(kvm_apic_update_apicv); void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) { struct kvm_lapic *apic = vcpu->arch.apic; + u64 msr_val; int i; if (!apic) @@ -2330,8 +2331,10 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) hrtimer_cancel(&apic->lapic_timer.timer); if (!init_event) { - kvm_lapic_set_base(vcpu, APIC_DEFAULT_PHYS_BASE | - MSR_IA32_APICBASE_ENABLE); + msr_val = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE; + if (kvm_vcpu_is_reset_bsp(vcpu)) + msr_val |= MSR_IA32_APICBASE_BSP; + kvm_lapic_set_base(vcpu, msr_val); kvm_apic_set_xapic_id(apic, vcpu->vcpu_id); } kvm_apic_set_version(apic->vcpu); -- cgit v1.2.3-70-g09d2 From f0428b3dcb2d7efe4b2a2304841645b48f0b6499 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:54 -0700 Subject: KVM: VMX: Stuff vcpu->arch.apic_base directly at vCPU RESET Write vcpu->arch.apic_base directly instead of bouncing through kvm_set_apic_base(). This is a glorified nop, and is a step towards cleaning up the mess that is local APIC creation. When using an in-kernel APIC, kvm_create_lapic() explicitly sets vcpu->arch.apic_base to MSR_IA32_APICBASE_ENABLE to avoid its own kvm_lapic_set_base() call in kvm_lapic_reset() from triggering state changes. That call during RESET exists purely to set apic->base_address to the default base value. As a result, by the time VMX gets control, the only missing piece is the BSP bit being set for the reset BSP. For a userspace APIC, there are no side effects to process (for the APIC). In both cases, the call to kvm_update_cpuid_runtime() is a nop because the vCPU hasn't yet been exposed to userspace, i.e. there can't be any CPUID entries. No functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-17-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 207393a429d1..2fc232e1bc20 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4391,7 +4391,6 @@ static void init_vmcs(struct vcpu_vmx *vmx) static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_vmx *vmx = to_vmx(vcpu); - struct msr_data apic_base_msr; u32 eax, dummy; u64 cr0; @@ -4409,12 +4408,10 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_set_cr8(vcpu, 0); if (!init_event) { - apic_base_msr.data = APIC_DEFAULT_PHYS_BASE | - MSR_IA32_APICBASE_ENABLE; + vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | + MSR_IA32_APICBASE_ENABLE; if (kvm_vcpu_is_reset_bsp(vcpu)) - apic_base_msr.data |= MSR_IA32_APICBASE_BSP; - apic_base_msr.host_initiated = true; - kvm_set_apic_base(vcpu, &apic_base_msr); + vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; } vmx_segment_cache_clear(vmx); -- cgit v1.2.3-70-g09d2 From 421221234ada41b4a9f0beeb08e30b07388bd4bd Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:55 -0700 Subject: KVM: x86: Open code necessary bits of kvm_lapic_set_base() at vCPU RESET Stuff vcpu->arch.apic_base and apic->base_address directly during APIC reset, as opposed to bouncing through kvm_set_apic_base() while fudging the ENABLE bit during creation to avoid the other, unwanted side effects. This is a step towards consolidating the APIC RESET logic across x86, VMX, and SVM. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-18-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 0fb282b64c8f..295a9d02a9a5 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2321,7 +2321,6 @@ EXPORT_SYMBOL_GPL(kvm_apic_update_apicv); void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) { struct kvm_lapic *apic = vcpu->arch.apic; - u64 msr_val; int i; if (!apic) @@ -2331,10 +2330,13 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) hrtimer_cancel(&apic->lapic_timer.timer); if (!init_event) { - msr_val = APIC_DEFAULT_PHYS_BASE | MSR_IA32_APICBASE_ENABLE; + vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | + MSR_IA32_APICBASE_ENABLE; if (kvm_vcpu_is_reset_bsp(vcpu)) - msr_val |= MSR_IA32_APICBASE_BSP; - kvm_lapic_set_base(vcpu, msr_val); + vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; + + apic->base_address = APIC_DEFAULT_PHYS_BASE; + kvm_apic_set_xapic_id(apic, vcpu->vcpu_id); } kvm_apic_set_version(apic->vcpu); @@ -2477,11 +2479,6 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns) lapic_timer_advance_dynamic = false; } - /* - * APIC is created enabled. This will prevent kvm_lapic_set_base from - * thinking that APIC state has changed. - */ - vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE; static_branch_inc(&apic_sw_disabled.key); /* sw disabled at reset */ kvm_iodevice_init(&apic->dev, &apic_mmio_ops); -- cgit v1.2.3-70-g09d2 From 4547700a4d190ac419abffa317069aaccf1ac118 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:56 -0700 Subject: KVM: x86: Consolidate APIC base RESET initialization code Consolidate the APIC base RESET logic, which is currently spread out across both x86 and vendor code. For an in-kernel APIC, the vendor code is redundant. But for a userspace APIC, KVM relies on the vendor code to initialize vcpu->arch.apic_base. Hoist the vcpu->arch.apic_base initialization above the !apic check so that it applies to both flavors of APIC emulation, and delete the vendor code. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-19-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 12 +++++++----- arch/x86/kvm/svm/svm.c | 6 ------ arch/x86/kvm/vmx/vmx.c | 7 ------- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 295a9d02a9a5..76fb00921203 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2323,6 +2323,13 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) struct kvm_lapic *apic = vcpu->arch.apic; int i; + if (!init_event) { + vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | + MSR_IA32_APICBASE_ENABLE; + if (kvm_vcpu_is_reset_bsp(vcpu)) + vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; + } + if (!apic) return; @@ -2330,11 +2337,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) hrtimer_cancel(&apic->lapic_timer.timer); if (!init_event) { - vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | - MSR_IA32_APICBASE_ENABLE; - if (kvm_vcpu_is_reset_bsp(vcpu)) - vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; - apic->base_address = APIC_DEFAULT_PHYS_BASE; kvm_apic_set_xapic_id(apic, vcpu->vcpu_id); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index a9af9bff4755..acb7bd14110b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1336,12 +1336,6 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) svm->spec_ctrl = 0; svm->virt_spec_ctrl = 0; - if (!init_event) { - vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | - MSR_IA32_APICBASE_ENABLE; - if (kvm_vcpu_is_reset_bsp(vcpu)) - vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; - } init_vmcb(vcpu); /* diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 2fc232e1bc20..e487f10e2877 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4407,13 +4407,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmx->hv_deadline_tsc = -1; kvm_set_cr8(vcpu, 0); - if (!init_event) { - vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE | - MSR_IA32_APICBASE_ENABLE; - if (kvm_vcpu_is_reset_bsp(vcpu)) - vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; - } - vmx_segment_cache_clear(vmx); seg_setup(VCPU_SREG_CS); -- cgit v1.2.3-70-g09d2 From 49d8665cc20b973995b5f519222d3270daa82f3f Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:57 -0700 Subject: KVM: x86: Move EDX initialization at vCPU RESET to common code Move the EDX initialization at vCPU RESET, which is now identical between VMX and SVM, into common code. No functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-20-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 5 ----- arch/x86/kvm/svm/svm.c | 13 ------------- arch/x86/kvm/vmx/vmx.c | 6 ------ arch/x86/kvm/x86.c | 13 +++++++++++++ 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index d798650ad793..ec8e4aca69c8 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1773,11 +1773,6 @@ static inline unsigned long read_msr(unsigned long msr) } #endif -static inline u32 get_rdx_init_val(void) -{ - return 0x600; /* P6 family */ -} - static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) { kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index acb7bd14110b..f42ec7d4b0cd 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1330,25 +1330,12 @@ static void init_vmcb(struct kvm_vcpu *vcpu) static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_svm *svm = to_svm(vcpu); - u32 dummy; - u32 eax = 1; svm->spec_ctrl = 0; svm->virt_spec_ctrl = 0; init_vmcb(vcpu); - /* - * Fall back to KVM's default Family/Model/Stepping if no CPUID match - * is found. Note, it's impossible to get a match at RESET since KVM - * emulates RESET before exposing the vCPU to userspace, i.e. it's - * impossible for kvm_cpuid() to find a valid entry on RESET. But, go - * through the motions in case that's ever remedied, and to be pedantic. - */ - if (!kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true)) - eax = get_rdx_init_val(); - kvm_rdx_write(vcpu, eax); - if (kvm_vcpu_apicv_active(vcpu) && !init_event) avic_update_vapic_bar(svm, APIC_DEFAULT_PHYS_BASE); } diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e487f10e2877..ad41f3423acf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4391,7 +4391,6 @@ static void init_vmcs(struct vcpu_vmx *vmx) static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_vmx *vmx = to_vmx(vcpu); - u32 eax, dummy; u64 cr0; vmx->rmode.vm86_active = 0; @@ -4399,11 +4398,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmx->msr_ia32_umwait_control = 0; - eax = 1; - if (!kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true)) - eax = get_rdx_init_val(); - kvm_rdx_write(vcpu, eax); - vmx->hv_deadline_tsc = -1; kvm_set_cr8(vcpu, 0); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 164ecca7769e..ed8b6d1b4e85 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10792,6 +10792,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { unsigned long old_cr0 = kvm_read_cr0(vcpu); + u32 eax, dummy; kvm_lapic_reset(vcpu, init_event); @@ -10858,6 +10859,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vcpu->arch.regs_avail = ~0; vcpu->arch.regs_dirty = ~0; + /* + * Fall back to KVM's default Family/Model/Stepping of 0x600 (P6/Athlon) + * if no CPUID match is found. Note, it's impossible to get a match at + * RESET since KVM emulates RESET before exposing the vCPU to userspace, + * i.e. it'simpossible for kvm_cpuid() to find a valid entry on RESET. + * But, go through the motions in case that's ever remedied. + */ + eax = 1; + if (!kvm_cpuid(vcpu, &eax, &dummy, &dummy, &dummy, true)) + eax = 0x600; + kvm_rdx_write(vcpu, eax); + vcpu->arch.ia32_xss = 0; static_call(kvm_x86_vcpu_reset)(vcpu, init_event); -- cgit v1.2.3-70-g09d2 From 9e90e215d9c9f013cc354c4fe1a1313531a97a05 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:58 -0700 Subject: KVM: SVM: Don't bother writing vmcb->save.rip at vCPU RESET/INIT Drop unnecessary initialization of vmcb->save.rip during vCPU RESET/INIT, as svm_vcpu_run() unconditionally propagates VCPU_REGS_RIP to save.rip. No true functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-21-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index f42ec7d4b0cd..9007adeb01fb 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1253,8 +1253,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm_set_efer(vcpu, 0); save->dr6 = 0xffff0ff0; kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); - save->rip = 0x0000fff0; - vcpu->arch.regs[VCPU_REGS_RIP] = save->rip; + vcpu->arch.regs[VCPU_REGS_RIP] = 0x0000fff0; /* * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. -- cgit v1.2.3-70-g09d2 From ee5a5584cba316bc90bc2fad0c6d10b71f1791cb Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:32:59 -0700 Subject: KVM: VMX: Invert handling of CR0.WP for EPT without unrestricted guest Opt-in to forcing CR0.WP=1 for shadow paging, and stop lying about WP being "always on" for unrestricted guest. In addition to making KVM a wee bit more honest, this paves the way for additional cleanup. No functional change intended. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-22-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ad41f3423acf..2e84c31efb81 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -136,8 +136,7 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO); #define KVM_VM_CR0_ALWAYS_OFF (X86_CR0_NW | X86_CR0_CD) #define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR0_NE #define KVM_VM_CR0_ALWAYS_ON \ - (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | \ - X86_CR0_WP | X86_CR0_PG | X86_CR0_PE) + (KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE) #define KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST X86_CR4_VMXE #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE) @@ -2995,9 +2994,7 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu) kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR); } -static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, - unsigned long cr0, - struct kvm_vcpu *vcpu) +static void ept_update_paging_mode_cr0(unsigned long cr0, struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -3016,9 +3013,6 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, vcpu->arch.cr0 = cr0; vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); } - - if (!(cr0 & X86_CR0_WP)) - *hw_cr0 &= ~X86_CR0_WP; } void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) @@ -3031,6 +3025,8 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; else { hw_cr0 |= KVM_VM_CR0_ALWAYS_ON; + if (!enable_ept) + hw_cr0 |= X86_CR0_WP; if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE)) enter_pmode(vcpu); @@ -3049,7 +3045,7 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) #endif if (enable_ept && !is_unrestricted_guest(vcpu)) - ept_update_paging_mode_cr0(&hw_cr0, cr0, vcpu); + ept_update_paging_mode_cr0(cr0, vcpu); vmcs_writel(CR0_READ_SHADOW, cr0); vmcs_writel(GUEST_CR0, hw_cr0); -- cgit v1.2.3-70-g09d2 From 4f0dcb544038e016277fb691f1e60d52d7448cf6 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:00 -0700 Subject: KVM: VMX: Remove direct write to vcpu->arch.cr0 during vCPU RESET/INIT Remove a bogus write to vcpu->arch.cr0 that immediately precedes vmx_set_cr0() during vCPU RESET/INIT. For RESET, this is a nop since the "old" CR0 value is meaningless. But for INIT, if the vCPU is coming from paging enabled mode, crushing vcpu->arch.cr0 will cause the various is_paging() checks in vmx_set_cr0() to get false negatives. For the exit_lmode() case, the false negative is benign as vmx_set_efer() is called immediately after vmx_set_cr0(). For EPT without unrestricted guest, the false negative will cause KVM to unnecessarily run with CR3 load/store exiting. But again, this is benign, albeit sub-optimal. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-23-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 2e84c31efb81..1e555fb732bf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4387,7 +4387,6 @@ static void init_vmcs(struct vcpu_vmx *vmx) static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { struct vcpu_vmx *vmx = to_vmx(vcpu); - u64 cr0; vmx->rmode.vm86_active = 0; vmx->spec_ctrl = 0; @@ -4455,9 +4454,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); - cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; - vmx->vcpu.arch.cr0 = cr0; - vmx_set_cr0(vcpu, cr0); /* enter rmode */ + vmx_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); vmx_set_cr4(vcpu, 0); vmx_set_efer(vcpu, 0); -- cgit v1.2.3-70-g09d2 From c834fd7fc1308a0e0429d203a6c3af528cd902fa Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:01 -0700 Subject: KVM: VMX: Fold ept_update_paging_mode_cr0() back into vmx_set_cr0() Move the CR0/CR3/CR4 shenanigans for EPT without unrestricted guest back into vmx_set_cr0(). This will allow a future patch to eliminate the rather gross stuffing of vcpu->arch.cr0 in the paging transition cases by snapshotting the old CR0. No functional change intended. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-24-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 1e555fb732bf..e4b1c24ad079 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2994,27 +2994,6 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu) kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR); } -static void ept_update_paging_mode_cr0(unsigned long cr0, struct kvm_vcpu *vcpu) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - - if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) - vmx_cache_reg(vcpu, VCPU_EXREG_CR3); - if (!(cr0 & X86_CR0_PG)) { - /* From paging/starting to nonpaging */ - exec_controls_setbit(vmx, CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING); - vcpu->arch.cr0 = cr0; - vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); - } else if (!is_paging(vcpu)) { - /* From nonpaging to paging */ - exec_controls_clearbit(vmx, CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING); - vcpu->arch.cr0 = cr0; - vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); - } -} - void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -3044,8 +3023,23 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } #endif - if (enable_ept && !is_unrestricted_guest(vcpu)) - ept_update_paging_mode_cr0(cr0, vcpu); + if (enable_ept && !is_unrestricted_guest(vcpu)) { + if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) + vmx_cache_reg(vcpu, VCPU_EXREG_CR3); + if (!(cr0 & X86_CR0_PG)) { + /* From paging/starting to nonpaging */ + exec_controls_setbit(vmx, CPU_BASED_CR3_LOAD_EXITING | + CPU_BASED_CR3_STORE_EXITING); + vcpu->arch.cr0 = cr0; + vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); + } else if (!is_paging(vcpu)) { + /* From nonpaging to paging */ + exec_controls_clearbit(vmx, CPU_BASED_CR3_LOAD_EXITING | + CPU_BASED_CR3_STORE_EXITING); + vcpu->arch.cr0 = cr0; + vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); + } + } vmcs_writel(CR0_READ_SHADOW, cr0); vmcs_writel(GUEST_CR0, hw_cr0); -- cgit v1.2.3-70-g09d2 From 470750b3425513b9f63f176e564e63e0e7998afc Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:02 -0700 Subject: KVM: nVMX: Do not clear CR3 load/store exiting bits if L1 wants 'em Keep CR3 load/store exiting enable as needed when running L2 in order to honor L1's desires. This fixes a largely theoretical bug where L1 could intercept CR3 but not CR0.PG and end up not getting the desired CR3 exits when L2 enables paging. In other words, the existing !is_paging() check inadvertantly handles the normal case for L2 where vmx_set_cr0() is called during VM-Enter, which is guaranteed to run with paging enabled, and thus will never clear the bits. Removing the !is_paging() check will also allow future consolidation and cleanup of the related code. From a performance perspective, this is all a nop, as the VMCS controls shadow will optimize away the VMWRITE when the controls are in the desired state. Add a comment explaining why CR3 is intercepted, with a big disclaimer about not querying the old CR3. Because vmx_set_cr0() is used for flows that are not directly tied to MOV CR3, e.g. vCPU RESET/INIT and nested VM-Enter, it's possible that is_paging() is not synchronized with CR3 load/store exiting. This is actually guaranteed in the current code, as KVM starts with CR3 interception disabled. Obviously that can be fixed, but there's no good reason to play whack-a-mole, and it tends to end poorly, e.g. descriptor table exiting for UMIP emulation attempted to be precise in the past and ended up botching the interception toggling. Fixes: fe3ef05c7572 ("KVM: nVMX: Prepare vmcs02 from vmcs01 and vmcs12") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-25-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e4b1c24ad079..9f69ccc096a3 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2994,10 +2994,14 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu) kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR); } +#define CR3_EXITING_BITS (CPU_BASED_CR3_LOAD_EXITING | \ + CPU_BASED_CR3_STORE_EXITING) + void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { struct vcpu_vmx *vmx = to_vmx(vcpu); unsigned long hw_cr0; + u32 tmp; hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); if (is_unrestricted_guest(vcpu)) @@ -3024,18 +3028,42 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) #endif if (enable_ept && !is_unrestricted_guest(vcpu)) { + /* + * Ensure KVM has an up-to-date snapshot of the guest's CR3. If + * the below code _enables_ CR3 exiting, vmx_cache_reg() will + * (correctly) stop reading vmcs.GUEST_CR3 because it thinks + * KVM's CR3 is installed. + */ if (!kvm_register_is_available(vcpu, VCPU_EXREG_CR3)) vmx_cache_reg(vcpu, VCPU_EXREG_CR3); + + /* + * When running with EPT but not unrestricted guest, KVM must + * intercept CR3 accesses when paging is _disabled_. This is + * necessary because restricted guests can't actually run with + * paging disabled, and so KVM stuffs its own CR3 in order to + * run the guest when identity mapped page tables. + * + * Do _NOT_ check the old CR0.PG, e.g. to optimize away the + * update, it may be stale with respect to CR3 interception, + * e.g. after nested VM-Enter. + * + * Lastly, honor L1's desires, i.e. intercept CR3 loads and/or + * stores to forward them to L1, even if KVM does not need to + * intercept them to preserve its identity mapped page tables. + */ if (!(cr0 & X86_CR0_PG)) { - /* From paging/starting to nonpaging */ - exec_controls_setbit(vmx, CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING); - vcpu->arch.cr0 = cr0; - vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); - } else if (!is_paging(vcpu)) { - /* From nonpaging to paging */ - exec_controls_clearbit(vmx, CPU_BASED_CR3_LOAD_EXITING | - CPU_BASED_CR3_STORE_EXITING); + exec_controls_setbit(vmx, CR3_EXITING_BITS); + } else if (!is_guest_mode(vcpu)) { + exec_controls_clearbit(vmx, CR3_EXITING_BITS); + } else { + tmp = exec_controls_get(vmx); + tmp &= ~CR3_EXITING_BITS; + tmp |= get_vmcs12(vcpu)->cpu_based_vm_exec_control & CR3_EXITING_BITS; + exec_controls_set(vmx, tmp); + } + + if (!is_paging(vcpu) != !(cr0 & X86_CR0_PG)) { vcpu->arch.cr0 = cr0; vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); } -- cgit v1.2.3-70-g09d2 From 81ca0e7340eedcbe67911d97f292837e0cf39709 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:03 -0700 Subject: KVM: VMX: Pull GUEST_CR3 from the VMCS iff CR3 load exiting is disabled Tweak the logic for grabbing vmcs.GUEST_CR3 in vmx_cache_reg() to look directly at the execution controls, as opposed to effectively inferring the controls based on vCPUs. Inferring the controls isn't wrong, but it creates a very subtle dependency between the caching logic, the state of vcpu->arch.cr0 (via is_paging()), and the behavior of vmx_set_cr0(). Using the execution controls doesn't completely eliminate the dependency in vmx_set_cr0(), e.g. neglecting to cache CR3 before enabling interception would still break the guest, but it does reduce the code dependency and mostly eliminate the logical dependency (that CR3 loads are intercepted in certain scenarios). Eliminating the subtle read of vcpu->arch.cr0 will also allow for additional cleanup in vmx_set_cr0(). Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-26-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 9f69ccc096a3..0c1e578967ff 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2262,8 +2262,11 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) vcpu->arch.cr0 |= vmcs_readl(GUEST_CR0) & guest_owned_bits; break; case VCPU_EXREG_CR3: - if (is_unrestricted_guest(vcpu) || - (enable_ept && is_paging(vcpu))) + /* + * When intercepting CR3 loads, e.g. for shadowing paging, KVM's + * CR3 is loaded into hardware, not the guest's CR3. + */ + if (!(exec_controls_get(to_vmx(vcpu)) & CPU_BASED_CR3_LOAD_EXITING)) vcpu->arch.cr3 = vmcs_readl(GUEST_CR3); break; case VCPU_EXREG_CR4: -- cgit v1.2.3-70-g09d2 From 908b7d43c02c5f1f95beff66ce4ca30dfc3b134c Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:04 -0700 Subject: KVM: x86/mmu: Skip the permission_fault() check on MMIO if CR0.PG=0 Skip the MMU permission_fault() check if paging is disabled when verifying the cached MMIO GVA is usable. The check is unnecessary and can theoretically get a false positive since the MMU doesn't zero out "permissions" or "pkru_mask" when guest paging is disabled. The obvious alternative is to zero out all the bitmasks when configuring nonpaging MMUs, but that's unnecessary work and doesn't align with the MMU's general approach of doing as little as possible for flows that are supposed to be unreachable. This is nearly a nop as the false positive is nothing more than an insignificant performance blip, and more or less limited to string MMIO when L1 is running with paging disabled. KVM doesn't cache MMIO if L2 is active with nested TDP since the "GVA" is really an L2 GPA. If L2 is active without nested TDP, then paging can't be disabled as neither VMX nor SVM allows entering the guest without paging of some form. Jumping back to L1 with paging disabled, in that case direct_map is true and so KVM will use CR2 as a GPA; the only time it doesn't is if the fault from the emulator doesn't match or emulator_can_use_gpa(), and that fails only on string MMIO and other instructions with multiple memory operands. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-27-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ed8b6d1b4e85..c56788f8d180 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -6568,9 +6568,9 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, * there is no pkey in EPT page table for L1 guest or EPT * shadow page table for L2 guest. */ - if (vcpu_match_mmio_gva(vcpu, gva) - && !permission_fault(vcpu, vcpu->arch.walk_mmu, - vcpu->arch.mmio_access, 0, access)) { + if (vcpu_match_mmio_gva(vcpu, gva) && (!is_paging(vcpu) || + !permission_fault(vcpu, vcpu->arch.walk_mmu, + vcpu->arch.mmio_access, 0, access))) { *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | (gva & (PAGE_SIZE - 1)); trace_vcpu_match_mmio(gva, *gpa, write, false); -- cgit v1.2.3-70-g09d2 From 32437c2aea428f9c3479904e342b02f5eee3a7f6 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:05 -0700 Subject: KVM: VMX: Process CR0.PG side effects after setting CR0 assets Move the long mode and EPT w/o unrestricted guest side effect processing down in vmx_set_cr0() so that the EPT && !URG case doesn't have to stuff vcpu->arch.cr0 early. This also fixes an oddity where CR0 might not be marked available, i.e. the early vcpu->arch.cr0 write would appear to be in danger of being overwritten, though that can't actually happen in the current code since CR0.TS is the only guest-owned bit, and CR0.TS is not read by vmx_set_cr4(). Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-28-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 0c1e578967ff..aa547100f0df 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3003,9 +3003,11 @@ void ept_save_pdptrs(struct kvm_vcpu *vcpu) void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { struct vcpu_vmx *vmx = to_vmx(vcpu); - unsigned long hw_cr0; + unsigned long hw_cr0, old_cr0_pg; u32 tmp; + old_cr0_pg = kvm_read_cr0_bits(vcpu, X86_CR0_PG); + hw_cr0 = (cr0 & ~KVM_VM_CR0_ALWAYS_OFF); if (is_unrestricted_guest(vcpu)) hw_cr0 |= KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST; @@ -3021,11 +3023,16 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) enter_rmode(vcpu); } + vmcs_writel(CR0_READ_SHADOW, cr0); + vmcs_writel(GUEST_CR0, hw_cr0); + vcpu->arch.cr0 = cr0; + kvm_register_mark_available(vcpu, VCPU_EXREG_CR0); + #ifdef CONFIG_X86_64 if (vcpu->arch.efer & EFER_LME) { - if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) + if (!old_cr0_pg && (cr0 & X86_CR0_PG)) enter_lmode(vcpu); - if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) + else if (old_cr0_pg && !(cr0 & X86_CR0_PG)) exit_lmode(vcpu); } #endif @@ -3066,17 +3073,11 @@ void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) exec_controls_set(vmx, tmp); } - if (!is_paging(vcpu) != !(cr0 & X86_CR0_PG)) { - vcpu->arch.cr0 = cr0; + /* Note, vmx_set_cr4() consumes the new vcpu->arch.cr0. */ + if ((old_cr0_pg ^ cr0) & X86_CR0_PG) vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); - } } - vmcs_writel(CR0_READ_SHADOW, cr0); - vmcs_writel(GUEST_CR0, hw_cr0); - vcpu->arch.cr0 = cr0; - kvm_register_mark_available(vcpu, VCPU_EXREG_CR0); - /* depends on vcpu->arch.cr0 to be set to a new value */ vmx->emulation_required = emulation_required(vcpu); } -- cgit v1.2.3-70-g09d2 From 1dd7a4f18fbcc0db1acc07df5c1ae8ba4ce10593 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:06 -0700 Subject: KVM: VMX: Skip emulation required checks during pmode/rmode transitions Don't refresh "emulation required" when stuffing segments during transitions to/from real mode when running without unrestricted guest. The checks are unnecessary as vmx_set_cr0() unconditionally rechecks "emulation required". They also happen to be broken, as enter_pmode() and enter_rmode() run with a stale vcpu->arch.cr0. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-29-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index aa547100f0df..ff3f75105ae9 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2719,6 +2719,8 @@ static __init int alloc_kvm_area(void) return 0; } +static void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); + static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg, struct kvm_segment *save) { @@ -2735,7 +2737,7 @@ static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg, save->dpl = save->selector & SEGMENT_RPL_MASK; save->s = 1; } - vmx_set_segment(vcpu, save, seg); + __vmx_set_segment(vcpu, save, seg); } static void enter_pmode(struct kvm_vcpu *vcpu) @@ -2756,7 +2758,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu) vmx->rmode.vm86_active = 0; - vmx_set_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); + __vmx_set_segment(vcpu, &vmx->rmode.segs[VCPU_SREG_TR], VCPU_SREG_TR); flags = vmcs_readl(GUEST_RFLAGS); flags &= RMODE_GUEST_OWNED_EFLAGS_BITS; @@ -3291,7 +3293,7 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var) return ar; } -void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) +static void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { struct vcpu_vmx *vmx = to_vmx(vcpu); const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; @@ -3304,7 +3306,7 @@ void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) vmcs_write16(sf->selector, var->selector); else if (var->s) fix_rmode_seg(seg, &vmx->rmode.segs[seg]); - goto out; + return; } vmcs_writel(sf->base, var->base); @@ -3326,9 +3328,13 @@ void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) var->type |= 0x1; /* Accessed */ vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(var)); +} -out: - vmx->emulation_required = emulation_required(vcpu); +void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) +{ + __vmx_set_segment(vcpu, var, seg); + + to_vmx(vcpu)->emulation_required = emulation_required(vcpu); } static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) -- cgit v1.2.3-70-g09d2 From 816be9e9be8d2e19dcea35fbec06f00cd5749fed Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:07 -0700 Subject: KVM: nVMX: Don't evaluate "emulation required" on nested VM-Exit Use the "internal" variants of setting segment registers when stuffing state on nested VM-Exit in order to skip the "emulation required" updates. VM-Exit must always go to protected mode, and all segments are mostly hardcoded (to valid values) on VM-Exit. The bits of the segments that aren't hardcoded are explicitly checked during VM-Enter, e.g. the selector RPLs must all be zero. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-30-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/nested.c | 16 ++++++++-------- arch/x86/kvm/vmx/vmx.c | 6 ++---- arch/x86/kvm/vmx/vmx.h | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 7f8184f432b4..a77cfc8bcf11 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4267,7 +4267,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, seg.l = 1; else seg.db = 1; - vmx_set_segment(vcpu, &seg, VCPU_SREG_CS); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_CS); seg = (struct kvm_segment) { .base = 0, .limit = 0xFFFFFFFF, @@ -4278,17 +4278,17 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, .g = 1 }; seg.selector = vmcs12->host_ds_selector; - vmx_set_segment(vcpu, &seg, VCPU_SREG_DS); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_DS); seg.selector = vmcs12->host_es_selector; - vmx_set_segment(vcpu, &seg, VCPU_SREG_ES); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_ES); seg.selector = vmcs12->host_ss_selector; - vmx_set_segment(vcpu, &seg, VCPU_SREG_SS); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_SS); seg.selector = vmcs12->host_fs_selector; seg.base = vmcs12->host_fs_base; - vmx_set_segment(vcpu, &seg, VCPU_SREG_FS); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_FS); seg.selector = vmcs12->host_gs_selector; seg.base = vmcs12->host_gs_base; - vmx_set_segment(vcpu, &seg, VCPU_SREG_GS); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_GS); seg = (struct kvm_segment) { .base = vmcs12->host_tr_base, .limit = 0x67, @@ -4296,11 +4296,11 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, .type = 11, .present = 1 }; - vmx_set_segment(vcpu, &seg, VCPU_SREG_TR); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_TR); memset(&seg, 0, sizeof(seg)); seg.unusable = 1; - vmx_set_segment(vcpu, &seg, VCPU_SREG_LDTR); + __vmx_set_segment(vcpu, &seg, VCPU_SREG_LDTR); kvm_set_dr(vcpu, 7, 0x400); vmcs_write64(GUEST_IA32_DEBUGCTL, 0); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index ff3f75105ae9..359c30be62bb 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2719,8 +2719,6 @@ static __init int alloc_kvm_area(void) return 0; } -static void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); - static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg, struct kvm_segment *save) { @@ -3293,7 +3291,7 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var) return ar; } -static void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) +void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { struct vcpu_vmx *vmx = to_vmx(vcpu); const struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; @@ -3330,7 +3328,7 @@ static void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, in vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(var)); } -void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) +static void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { __vmx_set_segment(vcpu, var, seg); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index db88ed4f2121..fd076bd26676 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -371,7 +371,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); void set_cr4_guest_host_mask(struct vcpu_vmx *vmx); void ept_save_pdptrs(struct kvm_vcpu *vcpu); void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); -void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); +void __vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); -- cgit v1.2.3-70-g09d2 From ef8a0fa59be78e7b80bdf35c3391d60c061c7b24 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:08 -0700 Subject: KVM: SVM: Tweak order of cr0/cr4/efer writes at RESET/INIT Hoist svm_set_cr0() up in the sequence of register initialization during vCPU RESET/INIT, purely to match VMX so that a future patch can move the sequences to common x86. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-31-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 9007adeb01fb..0afa060798a5 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1249,18 +1249,13 @@ static void init_vmcb(struct kvm_vcpu *vcpu) init_sys_seg(&save->ldtr, SEG_TYPE_LDT); init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); + svm_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); svm_set_cr4(vcpu, 0); svm_set_efer(vcpu, 0); save->dr6 = 0xffff0ff0; kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); vcpu->arch.regs[VCPU_REGS_RIP] = 0x0000fff0; - /* - * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. - * It also updates the guest-visible cr0 value. - */ - svm_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); - save->cr4 = X86_CR4_PAE; if (npt_enabled) { -- cgit v1.2.3-70-g09d2 From 6cfe7b83acdcdd4d4ea9354f007a88bc0ccb16b9 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:09 -0700 Subject: KVM: SVM: Drop redundant writes to vmcb->save.cr4 at RESET/INIT Drop direct writes to vmcb->save.cr4 during vCPU RESET/INIT, as the values being written are fully redundant with respect to svm_set_cr4(vcpu, 0) a few lines earlier. Note, svm_set_cr4() also correctly forces X86_CR4_PAE when NPT is disabled. No functional change intended. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-32-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 0afa060798a5..1038bfdd7bbb 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1256,8 +1256,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); vcpu->arch.regs[VCPU_REGS_RIP] = 0x0000fff0; - save->cr4 = X86_CR4_PAE; - if (npt_enabled) { /* Setup VMCB for Nested Paging */ control->nested_ctl |= SVM_NESTED_CTL_NP_ENABLE; @@ -1267,7 +1265,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm_clr_intercept(svm, INTERCEPT_CR3_WRITE); save->g_pat = vcpu->arch.pat; save->cr3 = 0; - save->cr4 = 0; } svm->current_vmcb->asid_generation = 0; svm->asid = 0; -- cgit v1.2.3-70-g09d2 From d0f9f826d8ac06446391ceb3d4a440f5b48b3134 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:10 -0700 Subject: KVM: SVM: Stuff save->dr6 at during VMSA sync, not at RESET/INIT Move code to stuff vmcb->save.dr6 to its architectural init value from svm_vcpu_reset() into sev_es_sync_vmsa(). Except for protected guests, a.k.a. SEV-ES guests, vmcb->save.dr6 is set during VM-Enter, i.e. the extra write is unnecessary. For SEV-ES, stuffing save->dr6 handles a theoretical case where the VMSA could be encrypted before the first KVM_RUN. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-33-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/sev.c | 1 + arch/x86/kvm/svm/svm.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 6710d9ee2e4b..9f1585f40c85 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -584,6 +584,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) save->xcr0 = svm->vcpu.arch.xcr0; save->pkru = svm->vcpu.arch.pkru; save->xss = svm->vcpu.arch.ia32_xss; + save->dr6 = svm->vcpu.arch.dr6; /* * SEV-ES will use a VMSA that is pointed to by the VMCB, not diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 1038bfdd7bbb..64563f876fdf 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1252,7 +1252,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); svm_set_cr4(vcpu, 0); svm_set_efer(vcpu, 0); - save->dr6 = 0xffff0ff0; kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); vcpu->arch.regs[VCPU_REGS_RIP] = 0x0000fff0; -- cgit v1.2.3-70-g09d2 From 400dd54b37172b64e4ceaa6bfaf2729585840375 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:11 -0700 Subject: KVM: VMX: Skip pointless MSR bitmap update when setting EFER Split setup_msrs() into vmx_setup_uret_msrs() and an open coded refresh of the MSR bitmap, and skip the latter when refreshing the user return MSRs during an EFER load. Only the x2APIC MSRs are dynamically exposed and hidden, and those are not affected by a change in EFER. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-34-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 359c30be62bb..d5d9fc5df259 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1647,11 +1647,12 @@ static void vmx_setup_uret_msr(struct vcpu_vmx *vmx, unsigned int msr, } /* - * Set up the vmcs to automatically save and restore system - * msrs. Don't touch the 64-bit msrs if the guest is in legacy - * mode, as fiddling with msrs is very expensive. + * Configuring user return MSRs to automatically save, load, and restore MSRs + * that need to be shoved into hardware when running the guest. Note, omitting + * an MSR here does _NOT_ mean it's not emulated, only that it will not be + * loaded into hardware when running the guest. */ -static void setup_msrs(struct vcpu_vmx *vmx) +static void vmx_setup_uret_msrs(struct vcpu_vmx *vmx) { #ifdef CONFIG_X86_64 bool load_syscall_msrs; @@ -1681,9 +1682,6 @@ static void setup_msrs(struct vcpu_vmx *vmx) */ vmx_setup_uret_msr(vmx, MSR_IA32_TSX_CTRL, boot_cpu_has(X86_FEATURE_RTM)); - if (cpu_has_vmx_msr_bitmap()) - vmx_update_msr_bitmap(&vmx->vcpu); - /* * The set of MSRs to load may have changed, reload MSRs before the * next VM-Enter. @@ -2874,7 +2872,7 @@ int vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) msr->data = efer & ~EFER_LME; } - setup_msrs(vmx); + vmx_setup_uret_msrs(vmx); return 0; } @@ -4470,7 +4468,10 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) if (kvm_mpx_supported()) vmcs_write64(GUEST_BNDCFGS, 0); - setup_msrs(vmx); + vmx_setup_uret_msrs(vmx); + + if (cpu_has_vmx_msr_bitmap()) + vmx_update_msr_bitmap(&vmx->vcpu); vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */ -- cgit v1.2.3-70-g09d2 From 432979b5034208890e323e86724417f02825abb7 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:12 -0700 Subject: KVM: VMX: Refresh list of user return MSRs after setting guest CPUID After a CPUID update, refresh the list of user return MSRs that are loaded into hardware when running the vCPU. This is necessary to handle the oddball case where userspace exposes X86_FEATURE_RDTSCP to the guest after the vCPU is running. Fixes: 0023ef39dc35 ("kvm: vmx: Set IA32_TSC_AUX for legacy mode guests") Fixes: 4e47c7a6d714 ("KVM: VMX: Add instruction rdtscp support for guest") Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-35-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index d5d9fc5df259..09c5a021e49b 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7170,6 +7170,8 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) /* xsaves_enabled is recomputed in vmx_compute_secondary_exec_control(). */ vcpu->arch.xsaves_enabled = false; + vmx_setup_uret_msrs(vmx); + if (cpu_has_secondary_exec_ctrls()) { vmx_compute_secondary_exec_control(vmx); vmcs_set_secondary_exec_control(vmx); -- cgit v1.2.3-70-g09d2 From c5c9f920f7a50ea205c9efec7e589556ebaf85dc Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:13 -0700 Subject: KVM: VMX: Don't _explicitly_ reconfigure user return MSRs on vCPU INIT When emulating vCPU INIT, do not unconditionally refresh the list of user return MSRs that need to be loaded into hardware when running the guest. Unconditionally refreshing the list is confusing, as the vast majority of MSRs are not modified on INIT. The real motivation is to handle the case where an INIT during long mode obviates the need to load the SYSCALL MSRs, and that is handled as needed by vmx_set_efer(). Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-36-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 09c5a021e49b..2e2b469b8ced 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4410,6 +4410,8 @@ static void init_vmcs(struct vcpu_vmx *vmx) vmx->pt_desc.guest.output_mask = 0x7F; vmcs_write64(GUEST_IA32_RTIT_CTL, 0); } + + vmx_setup_uret_msrs(vmx); } static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) @@ -4468,8 +4470,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) if (kvm_mpx_supported()) vmcs_write64(GUEST_BNDCFGS, 0); - vmx_setup_uret_msrs(vmx); - if (cpu_has_vmx_msr_bitmap()) vmx_update_msr_bitmap(&vmx->vcpu); -- cgit v1.2.3-70-g09d2 From f39e805ee115a67878c5475f1ef84466d424bb2e Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:14 -0700 Subject: KVM: x86: Move setting of sregs during vCPU RESET/INIT to common x86 Move the setting of CR0, CR4, EFER, RFLAGS, and RIP from vendor code to common x86. VMX and SVM now have near-identical sequences, the only difference being that VMX updates the exception bitmap. Updating the bitmap on SVM is unnecessary, but benign. Unfortunately it can't be left behind in VMX due to the need to update exception intercepts after the control registers are set. Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-37-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 6 ------ arch/x86/kvm/vmx/vmx.c | 9 --------- arch/x86/kvm/x86.c | 8 ++++++++ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 64563f876fdf..8ebdcd92007d 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1249,12 +1249,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) init_sys_seg(&save->ldtr, SEG_TYPE_LDT); init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); - svm_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); - svm_set_cr4(vcpu, 0); - svm_set_efer(vcpu, 0); - kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); - vcpu->arch.regs[VCPU_REGS_RIP] = 0x0000fff0; - if (npt_enabled) { /* Setup VMCB for Nested Paging */ control->nested_ctl |= SVM_NESTED_CTL_NP_ENABLE; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 2e2b469b8ced..7518d4cf8156 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4455,9 +4455,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmcs_write64(GUEST_IA32_DEBUGCTL, 0); } - kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); - kvm_rip_write(vcpu, 0xfff0); - vmcs_writel(GUEST_GDTR_BASE, 0); vmcs_write32(GUEST_GDTR_LIMIT, 0xffff); @@ -4485,12 +4482,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); - vmx_set_cr0(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); - vmx_set_cr4(vcpu, 0); - vmx_set_efer(vcpu, 0); - - vmx_update_exception_bitmap(vcpu); - vpid_sync_context(vmx->vpid); if (init_event) vmx_clear_hlt(vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c56788f8d180..6c55f2e83a7c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10875,6 +10875,14 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) static_call(kvm_x86_vcpu_reset)(vcpu, init_event); + kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); + kvm_rip_write(vcpu, 0xfff0); + + static_call(kvm_x86_set_cr0)(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); + static_call(kvm_x86_set_cr4)(vcpu, 0); + static_call(kvm_x86_set_efer)(vcpu, 0); + static_call(kvm_x86_update_exception_bitmap)(vcpu); + /* * Reset the MMU context if paging was enabled prior to INIT (which is * implied if CR0.PG=1 as CR0 will be '0' prior to RESET). Unlike the -- cgit v1.2.3-70-g09d2 From 9e4784e19daaa5cd637753d5300fc5a42d0c694a Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:15 -0700 Subject: KVM: VMX: Remove obsolete MSR bitmap refresh at vCPU RESET/INIT Remove an unnecessary MSR bitmap refresh during vCPU RESET/INIT. In both cases, the MSR bitmap already has the desired values and state. At RESET, the vCPU is guaranteed to be running with x2APIC disabled, the x2APIC MSRs are guaranteed to be intercepted due to the MSR bitmap being initialized to all ones by alloc_loaded_vmcs(), and vmx->msr_bitmap_mode is guaranteed to be zero, i.e. reflecting x2APIC disabled. At INIT, the APIC_BASE MSR is not modified, thus there can't be any change in x2APIC state. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-38-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 7518d4cf8156..af7aa9bb4bdb 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4467,9 +4467,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) if (kvm_mpx_supported()) vmcs_write64(GUEST_BNDCFGS, 0); - if (cpu_has_vmx_msr_bitmap()) - vmx_update_msr_bitmap(&vmx->vcpu); - vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */ if (cpu_has_vmx_tpr_shadow() && !init_event) { -- cgit v1.2.3-70-g09d2 From 284036c644a1dc71890503c849b22c3126308067 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:16 -0700 Subject: KVM: nVMX: Remove obsolete MSR bitmap refresh at nested transitions Drop unnecessary MSR bitmap updates during nested transitions, as L1's APIC_BASE MSR is not modified by the standard VM-Enter/VM-Exit flows, and L2's MSR bitmap is managed separately. In the unlikely event that L1 is pathological and loads APIC_BASE via the VM-Exit load list, KVM will handle updating the bitmap in its normal WRMSR flows. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-39-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/nested.c | 6 ------ arch/x86/kvm/vmx/vmx.c | 2 +- arch/x86/kvm/vmx/vmx.h | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index a77cfc8bcf11..0d0dd6580cfd 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4305,9 +4305,6 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, kvm_set_dr(vcpu, 7, 0x400); vmcs_write64(GUEST_IA32_DEBUGCTL, 0); - if (cpu_has_vmx_msr_bitmap()) - vmx_update_msr_bitmap(vcpu); - if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr, vmcs12->vm_exit_msr_load_count)) nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_MSR_FAIL); @@ -4386,9 +4383,6 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu) kvm_mmu_reset_context(vcpu); - if (cpu_has_vmx_msr_bitmap()) - vmx_update_msr_bitmap(vcpu); - /* * This nasty bit of open coding is a compromise between blindly * loading L1's MSRs using the exit load lists (incorrect emulation diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index af7aa9bb4bdb..6e79f1b2653b 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3865,7 +3865,7 @@ static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode) } } -void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) +static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); u8 mode = vmx_msr_bitmap_mode(vcpu); diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index fd076bd26676..a408a9070662 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -376,7 +376,6 @@ u64 construct_eptp(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu); -void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu); bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu); -- cgit v1.2.3-70-g09d2 From 002f87a41e9a6ef795f7f493f9434f51fb9f7d35 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:17 -0700 Subject: KVM: VMX: Don't redo x2APIC MSR bitmaps when userspace filter is changed Drop an explicit call to update the x2APIC MSRs when the userspace MSR filter is modified. The x2APIC MSRs are deliberately exempt from userspace filtering. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-40-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 6e79f1b2653b..7100e70ab718 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3936,7 +3936,6 @@ static void vmx_msr_filter_changed(struct kvm_vcpu *vcpu) } pt_update_intercept_for_msr(vcpu); - vmx_update_msr_bitmap_x2apic(vcpu, vmx_msr_bitmap_mode(vcpu)); } static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu, -- cgit v1.2.3-70-g09d2 From e7c701dd7a5019c8628007c91c0e8d804c194667 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:18 -0700 Subject: KVM: VMX: Remove unnecessary initialization of msr_bitmap_mode Don't bother initializing msr_bitmap_mode to 0, all of struct vcpu_vmx is zero initialized. No functional change intended. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-41-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 7100e70ab718..308820173505 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -6841,7 +6841,6 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C6_RESIDENCY, MSR_TYPE_R); vmx_disable_intercept_for_msr(vcpu, MSR_CORE_C7_RESIDENCY, MSR_TYPE_R); } - vmx->msr_bitmap_mode = 0; vmx->loaded_vmcs = &vmx->vmcs01; cpu = get_cpu(); -- cgit v1.2.3-70-g09d2 From 84ec8d2d539f7286d4504c2d377002f1ea7458d6 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:19 -0700 Subject: KVM: VMX: Smush x2APIC MSR bitmap adjustments into single function Consolidate all of the dynamic MSR bitmap adjustments into vmx_update_msr_bitmap_x2apic(), and rename the mode tracker to reflect that it is x2APIC specific. If KVM gains more cases of dynamic MSR pass-through, odds are very good that those new cases will be better off with their own logic, e.g. see Intel PT MSRs and MSR_IA32_SPEC_CTRL. Attempting to handle all updates in a common helper did more harm than good, as KVM ended up collecting a large number of useless "updates". Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-42-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 55 +++++++++++++++++++------------------------------- arch/x86/kvm/vmx/vmx.h | 2 +- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 308820173505..96d9147620bf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -3812,21 +3812,6 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type) vmx_set_msr_bitmap_write(msr_bitmap, msr); } -static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu) -{ - u8 mode = 0; - - if (cpu_has_secondary_exec_ctrls() && - (secondary_exec_controls_get(to_vmx(vcpu)) & - SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) { - mode |= MSR_BITMAP_MODE_X2APIC; - if (enable_apicv && kvm_vcpu_apicv_active(vcpu)) - mode |= MSR_BITMAP_MODE_X2APIC_APICV; - } - - return mode; -} - static void vmx_reset_x2apic_msrs(struct kvm_vcpu *vcpu, u8 mode) { unsigned long *msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap; @@ -3844,11 +3829,29 @@ static void vmx_reset_x2apic_msrs(struct kvm_vcpu *vcpu, u8 mode) } } -static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode) +static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu) { + struct vcpu_vmx *vmx = to_vmx(vcpu); + u8 mode; + if (!cpu_has_vmx_msr_bitmap()) return; + if (cpu_has_secondary_exec_ctrls() && + (secondary_exec_controls_get(vmx) & + SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) { + mode = MSR_BITMAP_MODE_X2APIC; + if (enable_apicv && kvm_vcpu_apicv_active(vcpu)) + mode |= MSR_BITMAP_MODE_X2APIC_APICV; + } else { + mode = 0; + } + + if (mode == vmx->x2apic_msr_bitmap_mode) + return; + + vmx->x2apic_msr_bitmap_mode = mode; + vmx_reset_x2apic_msrs(vcpu, mode); /* @@ -3865,21 +3868,6 @@ static void vmx_update_msr_bitmap_x2apic(struct kvm_vcpu *vcpu, u8 mode) } } -static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) -{ - struct vcpu_vmx *vmx = to_vmx(vcpu); - u8 mode = vmx_msr_bitmap_mode(vcpu); - u8 changed = mode ^ vmx->msr_bitmap_mode; - - if (!changed) - return; - - if (changed & (MSR_BITMAP_MODE_X2APIC | MSR_BITMAP_MODE_X2APIC_APICV)) - vmx_update_msr_bitmap_x2apic(vcpu, mode); - - vmx->msr_bitmap_mode = mode; -} - void pt_update_intercept_for_msr(struct kvm_vcpu *vcpu) { struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -4139,8 +4127,7 @@ static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); } - if (cpu_has_vmx_msr_bitmap()) - vmx_update_msr_bitmap(vcpu); + vmx_update_msr_bitmap_x2apic(vcpu); } u32 vmx_exec_control(struct vcpu_vmx *vmx) @@ -6190,7 +6177,7 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu) } secondary_exec_controls_set(vmx, sec_exec_control); - vmx_update_msr_bitmap(vcpu); + vmx_update_msr_bitmap_x2apic(vcpu); } static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu) diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index a408a9070662..0ecc41189292 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -227,7 +227,7 @@ struct nested_vmx { struct vcpu_vmx { struct kvm_vcpu vcpu; u8 fail; - u8 msr_bitmap_mode; + u8 x2apic_msr_bitmap_mode; /* * If true, host state has been stored in vmx->loaded_vmcs for -- cgit v1.2.3-70-g09d2 From 7aa13fc3d8260c4215b8aea971d120e675d8781f Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:20 -0700 Subject: KVM: VMX: Remove redundant write to set vCPU as active at RESET/INIT Drop a call to vmx_clear_hlt() during vCPU INIT, the guest's activity state is unconditionally set to "active" a few lines earlier in vmx_vcpu_reset(). No functional change intended. Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-43-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 96d9147620bf..b306ca2238ed 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4466,8 +4466,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); vpid_sync_context(vmx->vpid); - if (init_event) - vmx_clear_hlt(vcpu); } static void vmx_enable_irq_window(struct kvm_vcpu *vcpu) -- cgit v1.2.3-70-g09d2 From e54949408abfbe3905ae19ac3b42ecd2d29bc3c5 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:21 -0700 Subject: KVM: VMX: Move RESET-only VMWRITE sequences to init_vmcs() Move VMWRITE sequences in vmx_vcpu_reset() guarded by !init_event into init_vmcs() to make it more obvious that they're, uh, initializing the VMCS. No meaningful functional change intended (though the order of VMWRITEs and whatnot is different). Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-44-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index b306ca2238ed..ae8e62df16dd 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4397,6 +4397,19 @@ static void init_vmcs(struct vcpu_vmx *vmx) vmcs_write64(GUEST_IA32_RTIT_CTL, 0); } + vmcs_write32(GUEST_SYSENTER_CS, 0); + vmcs_writel(GUEST_SYSENTER_ESP, 0); + vmcs_writel(GUEST_SYSENTER_EIP, 0); + vmcs_write64(GUEST_IA32_DEBUGCTL, 0); + + if (cpu_has_vmx_tpr_shadow()) { + vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0); + if (cpu_need_tpr_shadow(&vmx->vcpu)) + vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, + __pa(vmx->vcpu.arch.apic->regs)); + vmcs_write32(TPR_THRESHOLD, 0); + } + vmx_setup_uret_msrs(vmx); } @@ -4434,13 +4447,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmcs_write32(GUEST_LDTR_LIMIT, 0xffff); vmcs_write32(GUEST_LDTR_AR_BYTES, 0x00082); - if (!init_event) { - vmcs_write32(GUEST_SYSENTER_CS, 0); - vmcs_writel(GUEST_SYSENTER_ESP, 0); - vmcs_writel(GUEST_SYSENTER_EIP, 0); - vmcs_write64(GUEST_IA32_DEBUGCTL, 0); - } - vmcs_writel(GUEST_GDTR_BASE, 0); vmcs_write32(GUEST_GDTR_LIMIT, 0xffff); @@ -4455,14 +4461,6 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0); /* 22.2.1 */ - if (cpu_has_vmx_tpr_shadow() && !init_event) { - vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, 0); - if (cpu_need_tpr_shadow(vcpu)) - vmcs_write64(VIRTUAL_APIC_PAGE_ADDR, - __pa(vcpu->arch.apic->regs)); - vmcs_write32(TPR_THRESHOLD, 0); - } - kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu); vpid_sync_context(vmx->vpid); -- cgit v1.2.3-70-g09d2 From 265e43530cb2eb14d5b78e89d310c79959e0eb26 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:22 -0700 Subject: KVM: SVM: Emulate #INIT in response to triple fault shutdown Emulate a full #INIT instead of simply initializing the VMCB if the guest hits a shutdown. Initializing the VMCB but not other vCPU state, much of which is mirrored by the VMCB, results in incoherent and broken vCPU state. Ideally, KVM would not automatically init anything on shutdown, and instead put the vCPU into e.g. KVM_MP_STATE_UNINITIALIZED and force userspace to explicitly INIT or RESET the vCPU. Even better would be to add KVM_MP_STATE_SHUTDOWN, since technically NMI can break shutdown (and SMI on Intel CPUs). But, that ship has sailed, and emulating #INIT is the next best thing as that has at least some connection with reality since there exist bare metal platforms that automatically INIT the CPU if it hits shutdown. Fixes: 46fe4ddd9dbb ("[PATCH] KVM: SVM: Propagate cpu shutdown events to userspace") Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-45-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 10 +++++++--- arch/x86/kvm/x86.c | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 8ebdcd92007d..4102e9e3bcdc 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -2050,11 +2050,15 @@ static int shutdown_interception(struct kvm_vcpu *vcpu) return -EINVAL; /* - * VMCB is undefined after a SHUTDOWN intercept - * so reinitialize it. + * VMCB is undefined after a SHUTDOWN intercept. INIT the vCPU to put + * the VMCB in a known good state. Unfortuately, KVM doesn't have + * KVM_MP_STATE_SHUTDOWN and can't add it without potentially breaking + * userspace. At a platform view, INIT is acceptable behavior as + * there exist bare metal platforms that automatically INIT the CPU + * in response to shutdown. */ clear_page(svm->vmcb); - init_vmcb(vcpu); + kvm_vcpu_reset(vcpu, true); kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; return 0; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6c55f2e83a7c..5b04c07c1ec5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10906,6 +10906,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) if (init_event) kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); } +EXPORT_SYMBOL_GPL(kvm_vcpu_reset); void kvm_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector) { -- cgit v1.2.3-70-g09d2 From 46f4898b207ffeeeaebc0fdd4bf4082bf0f88107 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:23 -0700 Subject: KVM: SVM: Drop redundant clearing of vcpu->arch.hflags at INIT/RESET Drop redundant clears of vcpu->arch.hflags in init_vmcb() since kvm_vcpu_reset() always clears hflags, and it is also always zero at vCPU creation time. And of course, the second clearing in init_vmcb() was always redundant. Suggested-by: Reiji Watanabe Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-46-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/svm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 4102e9e3bcdc..9d72b1df426e 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1161,8 +1161,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) struct vmcb_control_area *control = &svm->vmcb->control; struct vmcb_save_area *save = &svm->vmcb->save; - vcpu->arch.hflags = 0; - svm_set_intercept(svm, INTERCEPT_CR0_READ); svm_set_intercept(svm, INTERCEPT_CR3_READ); svm_set_intercept(svm, INTERCEPT_CR4_READ); @@ -1264,7 +1262,6 @@ static void init_vmcb(struct kvm_vcpu *vcpu) svm->nested.vmcb12_gpa = INVALID_GPA; svm->nested.last_vmcb12_gpa = INVALID_GPA; - vcpu->arch.hflags = 0; if (!kvm_pause_in_guest(vcpu->kvm)) { control->pause_filter_count = pause_filter_count; -- cgit v1.2.3-70-g09d2 From 4c72ab5aa6e0ac2a5c11f9180e1fff89d7f2d38b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 13 Jul 2021 09:33:24 -0700 Subject: KVM: x86: Preserve guest's CR0.CD/NW on INIT Preserve CR0.CD and CR0.NW on INIT instead of forcing them to '1', as defined by both Intel's SDM and AMD's APM. Note, current versions of Intel's SDM are very poorly written with respect to INIT behavior. Table 9-1. "IA-32 and Intel 64 Processor States Following Power-up, Reset, or INIT" quite clearly lists power-up, RESET, _and_ INIT as setting CR0=60000010H, i.e. CD/NW=1. But the SDM then attempts to qualify CD/NW behavior in a footnote: 2. The CD and NW flags are unchanged, bit 4 is set to 1, all other bits are cleared. Presumably that footnote is only meant for INIT, as the RESET case and especially the power-up case are rather non-sensical. Another footnote all but confirms that: 6. Internal caches are invalid after power-up and RESET, but left unchanged with an INIT. Bare metal testing shows that CD/NW are indeed preserved on INIT (someone else can hack their BIOS to check RESET and power-up :-D). Reported-by: Reiji Watanabe Reviewed-by: Reiji Watanabe Signed-off-by: Sean Christopherson Message-Id: <20210713163324.627647-47-seanjc@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5b04c07c1ec5..4d246b7f6ce1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -10792,6 +10792,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) { unsigned long old_cr0 = kvm_read_cr0(vcpu); + unsigned long new_cr0; u32 eax, dummy; kvm_lapic_reset(vcpu, init_event); @@ -10878,7 +10879,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_set_rflags(vcpu, X86_EFLAGS_FIXED); kvm_rip_write(vcpu, 0xfff0); - static_call(kvm_x86_set_cr0)(vcpu, X86_CR0_NW | X86_CR0_CD | X86_CR0_ET); + /* + * CR0.CD/NW are set on RESET, preserved on INIT. Note, some versions + * of Intel's SDM list CD/NW as being set on INIT, but they contradict + * (or qualify) that with a footnote stating that CD/NW are preserved. + */ + new_cr0 = X86_CR0_ET; + if (init_event) + new_cr0 |= (old_cr0 & (X86_CR0_NW | X86_CR0_CD)); + else + new_cr0 |= X86_CR0_NW | X86_CR0_CD; + + static_call(kvm_x86_set_cr0)(vcpu, new_cr0); static_call(kvm_x86_set_cr4)(vcpu, 0); static_call(kvm_x86_set_efer)(vcpu, 0); static_call(kvm_x86_update_exception_bitmap)(vcpu); -- cgit v1.2.3-70-g09d2 From db105fab8d141fc0d9179600c51eba0d168dad34 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 2 Aug 2021 08:52:50 -0400 Subject: KVM: nSVM: remove useless kvm_clear_*_queue For an event to be in injected state when nested_svm_vmrun executes, it must have come from exitintinfo when svm_complete_interrupts ran: vcpu_enter_guest static_call(kvm_x86_run) -> svm_vcpu_run svm_complete_interrupts // now the event went from "exitintinfo" to "injected" static_call(kvm_x86_handle_exit) -> handle_exit svm_invoke_exit_handler vmrun_interception nested_svm_vmrun However, no event could have been in exitintinfo before a VMRUN vmexit. The code in svm.c is a bit more permissive than the one in vmx.c: if (is_external_interrupt(svm->vmcb->control.exit_int_info) && exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH && exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI) but in any case, a VMRUN instruction would not even start to execute during an attempted event delivery. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm/nested.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index 61738ff8ef33..5e13357da21e 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -659,11 +659,6 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) goto out; } - - /* Clear internal status */ - kvm_clear_exception_queue(vcpu); - kvm_clear_interrupt_queue(vcpu); - /* * Since vmcb01 is not in use, we can use it to store some of the L1 * state. -- cgit v1.2.3-70-g09d2 From 47a70bea54b7afa983c71fa409785c067f4e865b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 2 Aug 2021 17:06:43 +0200 Subject: iommu/amd: Remove stale amd_iommu_unmap_flush usage Remove the new use of the variable introduced in the AMD driver branch. The variable was removed already in the iommu core branch, causing build errors when the brances are merged. Cc: Nadav Amit Cc: Zhen Lei Signed-off-by: Joerg Roedel Link: https://lore.kernel.org/r/20210802150643.3634-1-joro@8bytes.org --- drivers/iommu/amd/init.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 239556c1f698..bdcf167b4afe 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -1850,11 +1850,9 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) return ret; if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE)) { - if (!amd_iommu_unmap_flush) - pr_info("IOMMU batching is disabled due to virtualization\n"); - + pr_info("Using strict mode due to virtualization\n"); + iommu_set_dma_strict(); amd_iommu_np_cache = true; - amd_iommu_unmap_flush = true; } init_iommu_perf_ctr(iommu); -- cgit v1.2.3-70-g09d2 From d21faba11693c10072ce3b96b696445175f49be2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 2 Aug 2021 17:26:19 +0100 Subject: PCI: Bulk conversion to generic_handle_domain_irq() Wherever possible, replace constructs that match either generic_handle_irq(irq_find_mapping()) or generic_handle_irq(irq_linear_revmap()) to a single call to generic_handle_domain_irq(). Link: https://lore.kernel.org/r/20210802162630.2219813-4-maz@kernel.org Signed-off-by: Marc Zyngier Signed-off-by: Bjorn Helgaas Acked-by: Krzysztof Kozlowski --- drivers/pci/controller/dwc/pci-dra7xx.c | 16 ++++++---------- drivers/pci/controller/dwc/pci-keystone.c | 14 +++++--------- drivers/pci/controller/dwc/pcie-designware-host.c | 9 ++++----- drivers/pci/controller/dwc/pcie-uniphier.c | 8 +++----- drivers/pci/controller/mobiveil/pcie-mobiveil-host.c | 15 ++++++--------- drivers/pci/controller/pci-aardvark.c | 5 ++--- drivers/pci/controller/pci-ftpci100.c | 2 +- drivers/pci/controller/pci-tegra.c | 8 +++----- drivers/pci/controller/pci-xgene-msi.c | 9 +++------ drivers/pci/controller/pcie-altera-msi.c | 10 ++++------ drivers/pci/controller/pcie-altera.c | 10 ++++------ drivers/pci/controller/pcie-brcmstb.c | 9 ++++----- drivers/pci/controller/pcie-iproc-msi.c | 4 +--- drivers/pci/controller/pcie-mediatek-gen3.c | 13 ++++--------- drivers/pci/controller/pcie-mediatek.c | 12 ++++-------- drivers/pci/controller/pcie-microchip-host.c | 18 +++++++----------- drivers/pci/controller/pcie-rcar-host.c | 8 +++----- drivers/pci/controller/pcie-rockchip-host.c | 8 +++----- drivers/pci/controller/pcie-xilinx-cpm.c | 4 ++-- drivers/pci/controller/pcie-xilinx-nwl.c | 13 +++---------- drivers/pci/controller/pcie-xilinx.c | 9 ++++----- 21 files changed, 76 insertions(+), 128 deletions(-) diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c index 047cfbdc1330..fbbb78f6885e 100644 --- a/drivers/pci/controller/dwc/pci-dra7xx.c +++ b/drivers/pci/controller/dwc/pci-dra7xx.c @@ -204,7 +204,7 @@ static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); unsigned long val; - int pos, irq; + int pos; val = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + (index * MSI_REG_CTRL_BLOCK_SIZE)); @@ -213,9 +213,8 @@ static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index) pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, 0); while (pos != MAX_MSI_IRQS_PER_CTRL) { - irq = irq_find_mapping(pp->irq_domain, - (index * MAX_MSI_IRQS_PER_CTRL) + pos); - generic_handle_irq(irq); + generic_handle_domain_irq(pp->irq_domain, + (index * MAX_MSI_IRQS_PER_CTRL) + pos); pos++; pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, pos); } @@ -257,7 +256,7 @@ static void dra7xx_pcie_msi_irq_handler(struct irq_desc *desc) struct dw_pcie *pci; struct pcie_port *pp; unsigned long reg; - u32 virq, bit; + u32 bit; chained_irq_enter(chip, desc); @@ -276,11 +275,8 @@ static void dra7xx_pcie_msi_irq_handler(struct irq_desc *desc) case INTB: case INTC: case INTD: - for_each_set_bit(bit, ®, PCI_NUM_INTX) { - virq = irq_find_mapping(dra7xx->irq_domain, bit); - if (virq) - generic_handle_irq(virq); - } + for_each_set_bit(bit, ®, PCI_NUM_INTX) + generic_handle_domain_irq(dra7xx->irq_domain, bit); break; } diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index bde3b2824e89..865258d8c53c 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c @@ -259,14 +259,12 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, struct dw_pcie *pci = ks_pcie->pci; struct device *dev = pci->dev; u32 pending; - int virq; pending = ks_pcie_app_readl(ks_pcie, IRQ_STATUS(offset)); if (BIT(0) & pending) { - virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset); - dev_dbg(dev, ": irq: irq_offset %d, virq %d\n", offset, virq); - generic_handle_irq(virq); + dev_dbg(dev, ": irq: irq_offset %d", offset); + generic_handle_domain_irq(ks_pcie->legacy_irq_domain, offset); } /* EOI the INTx interrupt */ @@ -579,7 +577,7 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc) struct pcie_port *pp = &pci->pp; struct device *dev = pci->dev; struct irq_chip *chip = irq_desc_get_chip(desc); - u32 vector, virq, reg, pos; + u32 vector, reg, pos; dev_dbg(dev, "%s, irq %d\n", __func__, irq); @@ -600,10 +598,8 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc) continue; vector = offset + (pos << 3); - virq = irq_linear_revmap(pp->irq_domain, vector); - dev_dbg(dev, "irq: bit %d, vector %d, virq %d\n", pos, vector, - virq); - generic_handle_irq(virq); + dev_dbg(dev, "irq: bit %d, vector %d\n", pos, vector); + generic_handle_domain_irq(pp->irq_domain, vector); } chained_irq_exit(chip, desc); diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index a608ae1fad57..d1d9b8344ec9 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -55,7 +55,7 @@ static struct msi_domain_info dw_pcie_msi_domain_info = { /* MSI int handler */ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) { - int i, pos, irq; + int i, pos; unsigned long val; u32 status, num_ctrls; irqreturn_t ret = IRQ_NONE; @@ -74,10 +74,9 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) pos = 0; while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, pos)) != MAX_MSI_IRQS_PER_CTRL) { - irq = irq_find_mapping(pp->irq_domain, - (i * MAX_MSI_IRQS_PER_CTRL) + - pos); - generic_handle_irq(irq); + generic_handle_domain_irq(pp->irq_domain, + (i * MAX_MSI_IRQS_PER_CTRL) + + pos); pos++; } } diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c index 7e8bad326770..d842fd018129 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier.c +++ b/drivers/pci/controller/dwc/pcie-uniphier.c @@ -235,7 +235,7 @@ static void uniphier_pcie_irq_handler(struct irq_desc *desc) struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long reg; - u32 val, bit, virq; + u32 val, bit; /* INT for debug */ val = readl(priv->base + PCL_RCV_INT); @@ -257,10 +257,8 @@ static void uniphier_pcie_irq_handler(struct irq_desc *desc) val = readl(priv->base + PCL_RCV_INTX); reg = FIELD_GET(PCL_RCV_INTX_ALL_STATUS, val); - for_each_set_bit(bit, ®, PCI_NUM_INTX) { - virq = irq_linear_revmap(priv->legacy_irq_domain, bit); - generic_handle_irq(virq); - } + for_each_set_bit(bit, ®, PCI_NUM_INTX) + generic_handle_domain_irq(priv->legacy_irq_domain, bit); chained_irq_exit(chip, desc); } diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c index c637de3a389b..f3547aa60140 100644 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c @@ -92,7 +92,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc) u32 msi_data, msi_addr_lo, msi_addr_hi; u32 intr_status, msi_status; unsigned long shifted_status; - u32 bit, virq, val, mask; + u32 bit, val, mask; /* * The core provides a single interrupt for both INTx/MSI messages. @@ -114,11 +114,10 @@ static void mobiveil_pcie_isr(struct irq_desc *desc) shifted_status >>= PAB_INTX_START; do { for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) { - virq = irq_find_mapping(rp->intx_domain, - bit + 1); - if (virq) - generic_handle_irq(virq); - else + int ret; + ret = generic_handle_domain_irq(rp->intx_domain, + bit + 1); + if (ret) dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n", bit); @@ -155,9 +154,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc) dev_dbg(dev, "MSI registers, data: %08x, addr: %08x:%08x\n", msi_data, msi_addr_hi, msi_addr_lo); - virq = irq_find_mapping(msi->dev_domain, msi_data); - if (virq) - generic_handle_irq(virq); + generic_handle_domain_irq(msi->dev_domain, msi_data); msi_status = readl_relaxed(pcie->apb_csr_base + MSI_STATUS_OFFSET); diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index c95ebe808f92..d3515e207e12 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -1049,7 +1049,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) { u32 isr0_val, isr0_mask, isr0_status; u32 isr1_val, isr1_mask, isr1_status; - int i, virq; + int i; isr0_val = advk_readl(pcie, PCIE_ISR0_REG); isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); @@ -1077,8 +1077,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), PCIE_ISR1_REG); - virq = irq_find_mapping(pcie->irq_domain, i); - generic_handle_irq(virq); + generic_handle_domain_irq(pcie->irq_domain, i); } } diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index aefef1986201..88980a44461d 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -314,7 +314,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc) for (i = 0; i < 4; i++) { if ((irq_stat & BIT(i)) == 0) continue; - generic_handle_irq(irq_find_mapping(p->irqdomain, i)); + generic_handle_domain_irq(p->irqdomain, i); } chained_irq_exit(irqchip, desc); diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index c979229a6d0d..36f898643a4c 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -1553,12 +1553,10 @@ static void tegra_pcie_msi_irq(struct irq_desc *desc) while (reg) { unsigned int offset = find_first_bit(®, 32); unsigned int index = i * 32 + offset; - unsigned int irq; + int ret; - irq = irq_find_mapping(msi->domain->parent, index); - if (irq) { - generic_handle_irq(irq); - } else { + ret = generic_handle_domain_irq(msi->domain->parent, index); + if (ret) { /* * that's weird who triggered this? * just clear it diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c index 1c34c897a7e2..f1624bbb9f83 100644 --- a/drivers/pci/controller/pci-xgene-msi.c +++ b/drivers/pci/controller/pci-xgene-msi.c @@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc) struct irq_chip *chip = irq_desc_get_chip(desc); struct xgene_msi_group *msi_groups; struct xgene_msi *xgene_msi; - unsigned int virq; - int msir_index, msir_val, hw_irq; + int msir_index, msir_val, hw_irq, ret; u32 intr_index, grp_select, msi_grp; chained_irq_enter(chip, desc); @@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc) * CPU0 */ hw_irq = hwirq_to_canonical_hwirq(hw_irq); - virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq); - WARN_ON(!virq); - if (virq != 0) - generic_handle_irq(virq); + ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq); + WARN_ON_ONCE(ret); msir_val &= ~(1 << intr_index); } grp_select &= ~(1 << msir_index); diff --git a/drivers/pci/controller/pcie-altera-msi.c b/drivers/pci/controller/pcie-altera-msi.c index 98aa1dccc6e6..7b1d3ebc34ec 100644 --- a/drivers/pci/controller/pcie-altera-msi.c +++ b/drivers/pci/controller/pcie-altera-msi.c @@ -55,7 +55,7 @@ static void altera_msi_isr(struct irq_desc *desc) struct altera_msi *msi; unsigned long status; u32 bit; - u32 virq; + int ret; chained_irq_enter(chip, desc); msi = irq_desc_get_handler_data(desc); @@ -65,11 +65,9 @@ static void altera_msi_isr(struct irq_desc *desc) /* Dummy read from vector to clear the interrupt */ readl_relaxed(msi->vector_base + (bit * sizeof(u32))); - virq = irq_find_mapping(msi->inner_domain, bit); - if (virq) - generic_handle_irq(virq); - else - dev_err(&msi->pdev->dev, "unexpected MSI\n"); + ret = generic_handle_domain_irq(msi->inner_domain, bit); + if (ret) + dev_err_ratelimited(&msi->pdev->dev, "unexpected MSI\n"); } } diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c index 523bd928b380..2513e9363236 100644 --- a/drivers/pci/controller/pcie-altera.c +++ b/drivers/pci/controller/pcie-altera.c @@ -646,7 +646,7 @@ static void altera_pcie_isr(struct irq_desc *desc) struct device *dev; unsigned long status; u32 bit; - u32 virq; + int ret; chained_irq_enter(chip, desc); pcie = irq_desc_get_handler_data(desc); @@ -658,11 +658,9 @@ static void altera_pcie_isr(struct irq_desc *desc) /* clear interrupts */ cra_writel(pcie, 1 << bit, P2A_INT_STATUS); - virq = irq_find_mapping(pcie->irq_domain, bit); - if (virq) - generic_handle_irq(virq); - else - dev_err(dev, "unexpected IRQ, INT%d\n", bit); + ret = generic_handle_domain_irq(pcie->irq_domain, bit); + if (ret) + dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n", bit); } } diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c index 08bc788d9422..cc30215f5a43 100644 --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@ -476,7 +476,7 @@ static struct msi_domain_info brcm_msi_domain_info = { static void brcm_pcie_msi_isr(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); - unsigned long status, virq; + unsigned long status; struct brcm_msi *msi; struct device *dev; u32 bit; @@ -489,10 +489,9 @@ static void brcm_pcie_msi_isr(struct irq_desc *desc) status >>= msi->legacy_shift; for_each_set_bit(bit, &status, msi->nr) { - virq = irq_find_mapping(msi->inner_domain, bit); - if (virq) - generic_handle_irq(virq); - else + int ret; + ret = generic_handle_domain_irq(msi->inner_domain, bit); + if (ret) dev_dbg(dev, "unexpected MSI\n"); } diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c index 35a82124a126..757b7fbcdc59 100644 --- a/drivers/pci/controller/pcie-iproc-msi.c +++ b/drivers/pci/controller/pcie-iproc-msi.c @@ -326,7 +326,6 @@ static void iproc_msi_handler(struct irq_desc *desc) struct iproc_msi *msi; u32 eq, head, tail, nr_events; unsigned long hwirq; - int virq; chained_irq_enter(chip, desc); @@ -362,8 +361,7 @@ static void iproc_msi_handler(struct irq_desc *desc) /* process all outstanding events */ while (nr_events--) { hwirq = decode_msi_hwirq(msi, eq, head); - virq = irq_find_mapping(msi->inner_domain, hwirq); - generic_handle_irq(virq); + generic_handle_domain_irq(msi->inner_domain, hwirq); head++; head %= EQ_LEN; diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index f3aeb8d4eaca..17c59b0d6978 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -645,7 +645,6 @@ static void mtk_pcie_msi_handler(struct mtk_pcie_port *port, int set_idx) { struct mtk_msi_set *msi_set = &port->msi_sets[set_idx]; unsigned long msi_enable, msi_status; - unsigned int virq; irq_hw_number_t bit, hwirq; msi_enable = readl_relaxed(msi_set->base + PCIE_MSI_SET_ENABLE_OFFSET); @@ -659,8 +658,7 @@ static void mtk_pcie_msi_handler(struct mtk_pcie_port *port, int set_idx) for_each_set_bit(bit, &msi_status, PCIE_MSI_IRQS_PER_SET) { hwirq = bit + set_idx * PCIE_MSI_IRQS_PER_SET; - virq = irq_find_mapping(port->msi_bottom_domain, hwirq); - generic_handle_irq(virq); + generic_handle_domain_irq(port->msi_bottom_domain, hwirq); } } while (true); } @@ -670,18 +668,15 @@ static void mtk_pcie_irq_handler(struct irq_desc *desc) struct mtk_pcie_port *port = irq_desc_get_handler_data(desc); struct irq_chip *irqchip = irq_desc_get_chip(desc); unsigned long status; - unsigned int virq; irq_hw_number_t irq_bit = PCIE_INTX_SHIFT; chained_irq_enter(irqchip, desc); status = readl_relaxed(port->base + PCIE_INT_STATUS_REG); for_each_set_bit_from(irq_bit, &status, PCI_NUM_INTX + - PCIE_INTX_SHIFT) { - virq = irq_find_mapping(port->intx_domain, - irq_bit - PCIE_INTX_SHIFT); - generic_handle_irq(virq); - } + PCIE_INTX_SHIFT) + generic_handle_domain_irq(port->intx_domain, + irq_bit - PCIE_INTX_SHIFT); irq_bit = PCIE_MSI_SHIFT; for_each_set_bit_from(irq_bit, &status, PCIE_MSI_SET_NUM + diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index 25bee693834f..4cb5ea8e1069 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -602,7 +602,6 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) struct mtk_pcie_port *port = irq_desc_get_handler_data(desc); struct irq_chip *irqchip = irq_desc_get_chip(desc); unsigned long status; - u32 virq; u32 bit = INTX_SHIFT; chained_irq_enter(irqchip, desc); @@ -612,9 +611,8 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { /* Clear the INTx */ writel(1 << bit, port->base + PCIE_INT_STATUS); - virq = irq_find_mapping(port->irq_domain, - bit - INTX_SHIFT); - generic_handle_irq(virq); + generic_handle_domain_irq(port->irq_domain, + bit - INTX_SHIFT); } } @@ -623,10 +621,8 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc) unsigned long imsi_status; while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { - for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { - virq = irq_find_mapping(port->inner_domain, bit); - generic_handle_irq(virq); - } + for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) + generic_handle_domain_irq(port->inner_domain, bit); } /* Clear MSI interrupt status */ writel(MSI_STATUS, port->base + PCIE_INT_STATUS); diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c index fdab8202ae5d..329f930d17aa 100644 --- a/drivers/pci/controller/pcie-microchip-host.c +++ b/drivers/pci/controller/pcie-microchip-host.c @@ -412,16 +412,14 @@ static void mc_handle_msi(struct irq_desc *desc) port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; unsigned long status; u32 bit; - u32 virq; + int ret; status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL); if (status & PM_MSI_INT_MSI_MASK) { status = readl_relaxed(bridge_base_addr + ISTATUS_MSI); for_each_set_bit(bit, &status, msi->num_vectors) { - virq = irq_find_mapping(msi->dev_domain, bit); - if (virq) - generic_handle_irq(virq); - else + ret = generic_handle_domain_irq(msi->dev_domain, bit); + if (ret) dev_err_ratelimited(dev, "bad MSI IRQ %d\n", bit); } @@ -570,17 +568,15 @@ static void mc_handle_intx(struct irq_desc *desc) port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; unsigned long status; u32 bit; - u32 virq; + int ret; status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL); if (status & PM_MSI_INT_INTX_MASK) { status &= PM_MSI_INT_INTX_MASK; status >>= PM_MSI_INT_INTX_SHIFT; for_each_set_bit(bit, &status, PCI_NUM_INTX) { - virq = irq_find_mapping(port->intx_domain, bit); - if (virq) - generic_handle_irq(virq); - else + ret = generic_handle_domain_irq(port->intx_domain, bit); + if (ret) dev_err_ratelimited(dev, "bad INTx IRQ %d\n", bit); } @@ -745,7 +741,7 @@ static void mc_handle_event(struct irq_desc *desc) events = get_events(port); for_each_set_bit(bit, &events, NUM_EVENTS) - generic_handle_irq(irq_find_mapping(port->event_domain, bit)); + generic_handle_domain_irq(port->event_domain, bit); chained_irq_exit(chip, desc); } diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c index 765cf2b45e24..00a8267eda14 100644 --- a/drivers/pci/controller/pcie-rcar-host.c +++ b/drivers/pci/controller/pcie-rcar-host.c @@ -486,12 +486,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data) while (reg) { unsigned int index = find_first_bit(®, 32); - unsigned int msi_irq; + int ret; - msi_irq = irq_find_mapping(msi->domain->parent, index); - if (msi_irq) { - generic_handle_irq(msi_irq); - } else { + ret = generic_handle_domain_irq(msi->domain->parent, index); + if (ret) { /* Unknown MSI, just clear it */ dev_dbg(dev, "unexpected MSI\n"); rcar_pci_write_reg(pcie, BIT(index), PCIEMSIFR); diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index 78d04ac29cd5..c52316d0bfd2 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -517,7 +517,7 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) struct device *dev = rockchip->dev; u32 reg; u32 hwirq; - u32 virq; + int ret; chained_irq_enter(chip, desc); @@ -528,10 +528,8 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc) hwirq = ffs(reg) - 1; reg &= ~BIT(hwirq); - virq = irq_find_mapping(rockchip->irq_domain, hwirq); - if (virq) - generic_handle_irq(virq); - else + ret = generic_handle_domain_irq(rockchip->irq_domain, hwirq); + if (ret) dev_err(dev, "unexpected IRQ, INT%d\n", hwirq); } diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c index 67937facd90c..95426df03200 100644 --- a/drivers/pci/controller/pcie-xilinx-cpm.c +++ b/drivers/pci/controller/pcie-xilinx-cpm.c @@ -222,7 +222,7 @@ static void xilinx_cpm_pcie_intx_flow(struct irq_desc *desc) pcie_read(port, XILINX_CPM_PCIE_REG_IDRN)); for_each_set_bit(i, &val, PCI_NUM_INTX) - generic_handle_irq(irq_find_mapping(port->intx_domain, i)); + generic_handle_domain_irq(port->intx_domain, i); chained_irq_exit(chip, desc); } @@ -282,7 +282,7 @@ static void xilinx_cpm_pcie_event_flow(struct irq_desc *desc) val = pcie_read(port, XILINX_CPM_PCIE_REG_IDR); val &= pcie_read(port, XILINX_CPM_PCIE_REG_IMR); for_each_set_bit(i, &val, 32) - generic_handle_irq(irq_find_mapping(port->cpm_domain, i)); + generic_handle_domain_irq(port->cpm_domain, i); pcie_write(port, val, XILINX_CPM_PCIE_REG_IDR); /* diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 8689311c5ef6..3d178d5b652b 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c @@ -318,18 +318,14 @@ static void nwl_pcie_leg_handler(struct irq_desc *desc) struct nwl_pcie *pcie; unsigned long status; u32 bit; - u32 virq; chained_irq_enter(chip, desc); pcie = irq_desc_get_handler_data(desc); while ((status = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) & MSGF_LEG_SR_MASKALL) != 0) { - for_each_set_bit(bit, &status, PCI_NUM_INTX) { - virq = irq_find_mapping(pcie->legacy_irq_domain, bit); - if (virq) - generic_handle_irq(virq); - } + for_each_set_bit(bit, &status, PCI_NUM_INTX) + generic_handle_domain_irq(pcie->legacy_irq_domain, bit); } chained_irq_exit(chip, desc); @@ -340,16 +336,13 @@ static void nwl_pcie_handle_msi_irq(struct nwl_pcie *pcie, u32 status_reg) struct nwl_msi *msi; unsigned long status; u32 bit; - u32 virq; msi = &pcie->msi; while ((status = nwl_bridge_readl(pcie, status_reg)) != 0) { for_each_set_bit(bit, &status, 32) { nwl_bridge_writel(pcie, 1 << bit, status_reg); - virq = irq_find_mapping(msi->dev_domain, bit); - if (virq) - generic_handle_irq(virq); + generic_handle_domain_irq(msi->dev_domain, bit); } } } diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c index 14001febf59a..aa9bdcebc838 100644 --- a/drivers/pci/controller/pcie-xilinx.c +++ b/drivers/pci/controller/pcie-xilinx.c @@ -385,7 +385,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) } if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) { - unsigned int irq; + struct irq_domain *domain; val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); @@ -399,19 +399,18 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & XILINX_PCIE_RPIFR2_MSG_DATA; - irq = irq_find_mapping(port->msi_domain->parent, val); + domain = port->msi_domain->parent; } else { val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >> XILINX_PCIE_RPIFR1_INTR_SHIFT; - irq = irq_find_mapping(port->leg_domain, val); + domain = port->leg_domain; } /* Clear interrupt FIFO register 1 */ pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, XILINX_PCIE_REG_RPIFR1); - if (irq) - generic_handle_irq(irq); + generic_handle_domain_irq(domain, val); } if (status & XILINX_PCIE_INTR_SLV_UNSUPP) -- cgit v1.2.3-70-g09d2 From 7eab7a6968278c735b1ca6387056a408f7960265 Mon Sep 17 00:00:00 2001 From: Fengnan Chang Date: Tue, 22 Jun 2021 19:50:59 +0800 Subject: f2fs: compress: remove unneeded read when rewrite whole cluster when we overwrite the whole page in cluster, we don't need read original data before write, because after write_end(), writepages() can help to load left data in that cluster. Signed-off-by: Fengnan Chang Signed-off-by: Chao Yu Acked-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 28ad1f533c2a..d7f9d66577f5 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3329,6 +3329,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, *fsdata = NULL; + if (len == PAGE_SIZE) + goto repeat; + ret = f2fs_prepare_compress_overwrite(inode, pagep, index, fsdata); if (ret < 0) { -- cgit v1.2.3-70-g09d2 From b7ec2061737f12c33e45beeb967d17f31abc1ada Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 26 Jul 2021 09:12:15 -0700 Subject: f2fs: do not submit NEW_ADDR to read node block After the below patch, give cp is errored, we drop dirty node pages. This can give NEW_ADDR to read node pages. Don't do WARN_ON() which gives generic/475 failure. Fixes: 28607bf3aa6f ("f2fs: drop dirty node pages when cp is in error status") Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index c945a9730f3c..5840b82ce311 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1330,7 +1330,8 @@ static int read_node_page(struct page *page, int op_flags) if (err) return err; - if (unlikely(ni.blk_addr == NULL_ADDR) || + /* NEW_ADDR can be seen, after cp_error drops some dirty node pages */ + if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR) || is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) { ClearPageUptodate(page); return -ENOENT; -- cgit v1.2.3-70-g09d2 From 093f0bac32b617960899c7e00f4550373c383dd0 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Sun, 25 Jul 2021 21:18:19 -0700 Subject: f2fs: change fiemap way in printing compression chunk When we print out a discontinuous compression chunk, it shows like a continuous chunk now. To show it more correctly, I've changed the way of printing fiemap info like below. Plus, eliminated NEW_ADDR(-1) in fiemap info, since it is not in fiemap user api manual. Let's assume 16KB compression cluster. Logical Physical Length Flags 0: 0000000000000000 00000002c091f000 0000000000004000 1008 1: 0000000000004000 00000002c0920000 0000000000004000 1008 ... 9: 0000000000034000 0000000f8c623000 0000000000004000 1008 10: 0000000000038000 000000101a6eb000 0000000000004000 1008 0: 0000000000000000 00000002c091f000 0000000000004000 1008 1: 0000000000004000 00000002c0920000 0000000000004000 1008 ... 9: 0000000000034000 0000000f8c623000 0000000000001000 1008 10: 0000000000035000 000000101a6ea000 0000000000003000 1008 11: 0000000000038000 000000101a6eb000 0000000000002000 1008 12: 000000000003a000 00000002c3544000 0000000000002000 1008 Flags 0x1000 => FIEMAP_EXTENT_MERGED 0x0008 => FIEMAP_EXTENT_ENCODED Signed-off-by: Daeho Jeong Tested-by: Eric Biggers Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 75 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index d7f9d66577f5..cb71d7317ad2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1843,8 +1843,9 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 logical = 0, phys = 0, size = 0; u32 flags = 0; int ret = 0; - bool compr_cluster = false; + bool compr_cluster = false, compr_appended; unsigned int cluster_size = F2FS_I(inode)->i_cluster_size; + unsigned int count_in_cluster = 0; loff_t maxbytes; if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) { @@ -1892,15 +1893,17 @@ next: map.m_next_pgofs = &next_pgofs; map.m_seg_type = NO_CHECK_TYPE; - if (compr_cluster) - map.m_len = cluster_size - 1; + if (compr_cluster) { + map.m_lblk += 1; + map.m_len = cluster_size - count_in_cluster; + } ret = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_FIEMAP); if (ret) goto out; /* HOLE */ - if (!(map.m_flags & F2FS_MAP_FLAGS)) { + if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) { start_blk = next_pgofs; if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode, @@ -1910,6 +1913,14 @@ next: flags |= FIEMAP_EXTENT_LAST; } + compr_appended = false; + /* In a case of compressed cluster, append this to the last extent */ + if (compr_cluster && ((map.m_flags & F2FS_MAP_UNWRITTEN) || + !(map.m_flags & F2FS_MAP_FLAGS))) { + compr_appended = true; + goto skip_fill; + } + if (size) { flags |= FIEMAP_EXTENT_MERGED; if (IS_ENCRYPTED(inode)) @@ -1926,38 +1937,36 @@ next: if (start_blk > last_blk) goto out; - if (compr_cluster) { - compr_cluster = false; - - - logical = blks_to_bytes(inode, start_blk - 1); - phys = blks_to_bytes(inode, map.m_pblk); - size = blks_to_bytes(inode, cluster_size); - - flags |= FIEMAP_EXTENT_ENCODED; - - start_blk += cluster_size - 1; - - if (start_blk > last_blk) - goto out; - - goto prep_next; - } - +skip_fill: if (map.m_pblk == COMPRESS_ADDR) { compr_cluster = true; - start_blk++; - goto prep_next; - } - - logical = blks_to_bytes(inode, start_blk); - phys = blks_to_bytes(inode, map.m_pblk); - size = blks_to_bytes(inode, map.m_len); - flags = 0; - if (map.m_flags & F2FS_MAP_UNWRITTEN) - flags = FIEMAP_EXTENT_UNWRITTEN; + count_in_cluster = 1; + } else if (compr_appended) { + unsigned int appended_blks = cluster_size - + count_in_cluster + 1; + size += blks_to_bytes(inode, appended_blks); + start_blk += appended_blks; + compr_cluster = false; + } else { + logical = blks_to_bytes(inode, start_blk); + phys = __is_valid_data_blkaddr(map.m_pblk) ? + blks_to_bytes(inode, map.m_pblk) : 0; + size = blks_to_bytes(inode, map.m_len); + flags = 0; + + if (compr_cluster) { + flags = FIEMAP_EXTENT_ENCODED; + count_in_cluster += map.m_len; + if (count_in_cluster == cluster_size) { + compr_cluster = false; + size += blks_to_bytes(inode, 1); + } + } else if (map.m_flags & F2FS_MAP_UNWRITTEN) { + flags = FIEMAP_EXTENT_UNWRITTEN; + } - start_blk += bytes_to_blks(inode, size); + start_blk += bytes_to_blks(inode, size); + } prep_next: cond_resched(); -- cgit v1.2.3-70-g09d2 From 4931e0c93e124357308893a3e5e224cbeeabc721 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Wed, 28 Jul 2021 12:38:11 -0700 Subject: f2fs: turn back remapped address in compressed page endio Turned back the remmaped sector address to the address in the partition, when ending io, for compress cache to work properly. Fixes: 6ce19aff0b8c ("f2fs: compress: add compress_inode to cache compressed blocks") Signed-off-by: Daeho Jeong Signed-off-by: Youngjin Gil Signed-off-by: Hyeong Jun Kim Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index cb71d7317ad2..948083c88d17 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -116,6 +116,7 @@ struct bio_post_read_ctx { struct f2fs_sb_info *sbi; struct work_struct work; unsigned int enabled_steps; + block_t fs_blkaddr; }; static void f2fs_finish_read_bio(struct bio *bio) @@ -228,7 +229,7 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) struct bio_vec *bv; struct bvec_iter_all iter_all; bool all_compressed = true; - block_t blkaddr = SECTOR_TO_BLOCK(ctx->bio->bi_iter.bi_sector); + block_t blkaddr = ctx->fs_blkaddr; bio_for_each_segment_all(bv, ctx->bio, iter_all) { struct page *page = bv->bv_page; @@ -1003,6 +1004,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, ctx->bio = bio; ctx->sbi = sbi; ctx->enabled_steps = post_read_steps; + ctx->fs_blkaddr = blkaddr; bio->bi_private = ctx; } -- cgit v1.2.3-70-g09d2 From 2e650912c037a501ea6fc367c7075ead63a114f7 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Fri, 30 Jul 2021 08:10:48 -0700 Subject: f2fs: show sbi status in debugfs/f2fs/status We need to get sbi->s_flag to understand the current f2fs status as well. One example is SBI_NEED_FSCK. Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 53ed1e9191f0..473ad04d1891 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -333,11 +333,12 @@ static int stat_show(struct seq_file *s, void *v) list_for_each_entry(si, &f2fs_stat_list, stat_list) { update_general_status(si->sbi); - seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s]=====\n", + seq_printf(s, "\n=====[ partition info(%pg). #%d, %s, CP: %s (sbi: 0x%lx)]=====\n", si->sbi->sb->s_bdev, i++, f2fs_readonly(si->sbi->sb) ? "RO": "RW", is_set_ckpt_flags(si->sbi, CP_DISABLED_FLAG) ? - "Disabled": (f2fs_cp_error(si->sbi) ? "Error": "Good")); + "Disabled": (f2fs_cp_error(si->sbi) ? "Error": "Good"), + si->sbi->s_flag); seq_printf(s, "[SB: 1] [CP: 2] [SIT: %d] [NAT: %d] ", si->sit_area_segs, si->nat_area_segs); seq_printf(s, "[SSA: %d] [MAIN: %d", -- cgit v1.2.3-70-g09d2 From 277afbde6ca2b38729683fc17c031b4bc942068d Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 29 Jul 2021 09:22:17 +0800 Subject: f2fs: fix wrong checkpoint_changed value in f2fs_remount() In f2fs_remount(), return value of test_opt() is an unsigned int type variable, however when we compare it to a bool type variable, it cause wrong result, fix it. Fixes: 4354994f097d ("f2fs: checkpoint disabling") Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 72eb9d70969f..3617aa5f0477 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2062,11 +2062,10 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool need_restart_ckpt = false, need_stop_ckpt = false; bool need_restart_flush = false, need_stop_flush = false; bool no_extent_cache = !test_opt(sbi, EXTENT_CACHE); - bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); + bool enable_checkpoint = !test_opt(sbi, DISABLE_CHECKPOINT); bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); - bool checkpoint_changed; #ifdef CONFIG_QUOTA int i, j; #endif @@ -2111,8 +2110,6 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) err = parse_options(sb, data, true); if (err) goto restore_opts; - checkpoint_changed = - disable_checkpoint != test_opt(sbi, DISABLE_CHECKPOINT); /* * Previous and new state of filesystem is RO, @@ -2234,7 +2231,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) need_stop_flush = true; } - if (checkpoint_changed) { + if (enable_checkpoint == !!test_opt(sbi, DISABLE_CHECKPOINT)) { if (test_opt(sbi, DISABLE_CHECKPOINT)) { err = f2fs_disable_checkpoint(sbi); if (err) -- cgit v1.2.3-70-g09d2 From 2787991516468bfafafb9bf2b45a848e6b202e7c Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 20 Jul 2021 09:03:29 +0800 Subject: f2fs: fix to force keeping write barrier for strict fsync mode [1] https://www.mail-archive.com/linux-f2fs-devel@lists.sourceforge.net/msg15126.html As [1] reported, if lower device doesn't support write barrier, in below case: - write page #0; persist - overwrite page #0 - fsync - write data page #0 OPU into device's cache - write inode page into device's cache - issue flush If SPO is triggered during flush command, inode page can be persisted before data page #0, so that after recovery, inode page can be recovered with new physical block address of data page #0, however there may contains dummy data in new physical block address. Then what user will see is: after overwrite & fsync + SPO, old data in file was corrupted, if any user do care about such case, we can suggest user to use STRICT fsync mode, in this mode, we will force to use atomic write sematics to keep write order in between data/node and last node, so that it avoids potential data corruption during fsync(). Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index b1cb5b50faac..e931782abdab 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -301,6 +301,18 @@ static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, f2fs_exist_written_data(sbi, ino, UPDATE_INO)) goto flush_out; goto out; + } else { + /* + * for OPU case, during fsync(), node can be persisted before + * data when lower device doesn't support write barrier, result + * in data corruption after SPO. + * So for strict fsync mode, force to use atomic write sematics + * to keep write order in between data/node and last node to + * avoid potential data corruption. + */ + if (F2FS_OPTION(sbi).fsync_mode == + FSYNC_MODE_STRICT && !atomic) + atomic = true; } go_write: /* -- cgit v1.2.3-70-g09d2 From dc675a97129c4d9d5af55a3d7f23d7e092b8e032 Mon Sep 17 00:00:00 2001 From: Laibin Qiu Date: Sat, 31 Jul 2021 11:26:46 +0800 Subject: f2fs: fix min_seq_blocks can not make sense in some scenes. F2FS have dirty page count control for batched sequential write in writepages, and get the value of min_seq_blocks by blocks_per_seg * segs_per_sec(segs_per_sec defaults to 1). But in some scenes we set a lager section size, Min_seq_blocks will become too large to achieve the expected effect(eg. 4thread sequential write, the number of merge requests will be reduced). Signed-off-by: Laibin Qiu Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f9b7fb785e1d..0f976cefe425 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -5159,7 +5159,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi) sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC; sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; - sm_info->min_seq_blocks = sbi->blocks_per_seg * sbi->segs_per_sec; + sm_info->min_seq_blocks = sbi->blocks_per_seg; sm_info->min_hot_blocks = DEF_MIN_HOT_BLOCKS; sm_info->min_ssr_sections = reserved_sections(sbi); -- cgit v1.2.3-70-g09d2 From 26c22cfde5dd6e63f25c48458b0185dcb0fbb2fd Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Fri, 16 Jul 2021 15:39:12 -0300 Subject: vfio: Use config not menuconfig for VFIO_NOIOMMU VFIO_NOIOMMU is supposed to be an element in the VFIO menu, not start a new menu. Correct this copy-paste mistake. Fixes: 03a76b60f8ba ("vfio: Include No-IOMMU mode") Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/0-v1-3f0b685c3679+478-vfio_menuconfig_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index 67d0bf4efa16..e44bf736e2b2 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -29,7 +29,7 @@ menuconfig VFIO If you don't know what to do here, say N. -menuconfig VFIO_NOIOMMU +config VFIO_NOIOMMU bool "VFIO No-IOMMU support" depends on VFIO help -- cgit v1.2.3-70-g09d2 From e7500b3ede2c66380a7e9faa6a81e6df2f8e4e55 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Wed, 21 Jul 2021 10:05:48 -0300 Subject: vfio/pci: Make vfio_pci_regops->rw() return ssize_t The only implementation of this in IGD returns a -ERRNO which is implicitly cast through a size_t and then casted again and returned as a ssize_t in vfio_pci_rw(). Fix the vfio_pci_regops->rw() return type to be ssize_t so all is consistent. Fixes: 28541d41c9e0 ("vfio/pci: Add infrastructure for additional device specific regions") Signed-off-by: Yishai Hadas Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Reviewed-by: Max Gurtovoy Link: https://lore.kernel.org/r/0-v3-5db12d1bf576+c910-vfio_rw_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci_igd.c | 10 +++++----- drivers/vfio/pci/vfio_pci_private.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci_igd.c b/drivers/vfio/pci/vfio_pci_igd.c index 228df565e9bc..aa0a29fd2762 100644 --- a/drivers/vfio/pci/vfio_pci_igd.c +++ b/drivers/vfio/pci/vfio_pci_igd.c @@ -25,8 +25,8 @@ #define OPREGION_RVDS 0x3c2 #define OPREGION_VERSION 0x16 -static size_t vfio_pci_igd_rw(struct vfio_pci_device *vdev, char __user *buf, - size_t count, loff_t *ppos, bool iswrite) +static ssize_t vfio_pci_igd_rw(struct vfio_pci_device *vdev, char __user *buf, + size_t count, loff_t *ppos, bool iswrite) { unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS; void *base = vdev->region[i].data; @@ -160,9 +160,9 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_device *vdev) return ret; } -static size_t vfio_pci_igd_cfg_rw(struct vfio_pci_device *vdev, - char __user *buf, size_t count, loff_t *ppos, - bool iswrite) +static ssize_t vfio_pci_igd_cfg_rw(struct vfio_pci_device *vdev, + char __user *buf, size_t count, loff_t *ppos, + bool iswrite) { unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) - VFIO_PCI_NUM_REGIONS; struct pci_dev *pdev = vdev->region[i].data; diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h index 5a36272cecbf..bbc56c857ef0 100644 --- a/drivers/vfio/pci/vfio_pci_private.h +++ b/drivers/vfio/pci/vfio_pci_private.h @@ -56,7 +56,7 @@ struct vfio_pci_device; struct vfio_pci_region; struct vfio_pci_regops { - size_t (*rw)(struct vfio_pci_device *vdev, char __user *buf, + ssize_t (*rw)(struct vfio_pci_device *vdev, char __user *buf, size_t count, loff_t *ppos, bool iswrite); void (*release)(struct vfio_pci_device *vdev, struct vfio_pci_region *region); -- cgit v1.2.3-70-g09d2 From 15a5896e61acb7cbad5efd9cf807a4d9a5e8315d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 26 Jul 2021 16:35:23 +0200 Subject: vfio/mdev: turn mdev_init into a subsys_initcall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this setups with buіlt-in mdev and mdev-drivers fail to register like this: [1.903149] Driver 'intel_vgpu_mdev' was unable to register with bus_type 'mdev' because the bus was not initialized. Signed-off-by: Christoph Hellwig Reviewed-by: Cornelia Huck Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/20210726143524.155779-2-hch@lst.de Signed-off-by: Alex Williamson --- drivers/vfio/mdev/mdev_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index e4581ec093a6..b16606ebafa1 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -398,7 +398,7 @@ static void __exit mdev_exit(void) mdev_bus_unregister(); } -module_init(mdev_init) +subsys_initcall(mdev_init) module_exit(mdev_exit) MODULE_VERSION(DRIVER_VERSION); -- cgit v1.2.3-70-g09d2 From 3fb1712d85962f81265b5018922a2da13cdf6033 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 26 Jul 2021 16:35:24 +0200 Subject: vfio/mdev: don't warn if ->request is not set Only a single driver actually sets the ->request method, so don't print a scary warning if it isn't. Signed-off-by: Christoph Hellwig Reviewed-by: Cornelia Huck Reviewed-by: Jason Gunthorpe Link: https://lore.kernel.org/r/20210726143524.155779-3-hch@lst.de Signed-off-by: Alex Williamson --- drivers/vfio/mdev/mdev_core.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index b16606ebafa1..b314101237fe 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -138,10 +138,6 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops) if (!dev) return -EINVAL; - /* Not mandatory, but its absence could be a problem */ - if (!ops->request) - dev_info(dev, "Driver cannot be asked to release device\n"); - mutex_lock(&parent_list_lock); /* Check for duplicate */ -- cgit v1.2.3-70-g09d2 From d3d9c4570285090b533b00946b72647361f0345b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:22 -0700 Subject: scsi: ufs: Fix memory corruption by ufshcd_read_desc_param() If param_offset > buff_len then the memcpy() statement in ufshcd_read_desc_param() corrupts memory since it copies 256 + buff_len - param_offset bytes into a buffer with size buff_len. Since param_offset < 256 this results in writing past the bound of the output buffer. Link: https://lore.kernel.org/r/20210722033439.26550-2-bvanassche@acm.org Fixes: cbe193f6f093 ("scsi: ufs: Fix potential NULL pointer access during memcpy") Reviewed-by: Avri Altman Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 40d371f6e147..5829b25f5999 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3426,9 +3426,11 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, if (is_kmalloc) { /* Make sure we don't copy more data than available */ - if (param_offset + param_size > buff_len) - param_size = buff_len - param_offset; - memcpy(param_read_buf, &desc_buf[param_offset], param_size); + if (param_offset >= buff_len) + ret = -EINVAL; + else + memcpy(param_read_buf, &desc_buf[param_offset], + min_t(u32, param_size, buff_len - param_offset)); } out: if (is_kmalloc) -- cgit v1.2.3-70-g09d2 From f1ecbe1e54d5709b839e71f48ab26aab42cb7b82 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:23 -0700 Subject: scsi: ufs: Reduce power management code duplication Move the dev_get_drvdata() calls into the ufshcd_{system,runtime}_*() functions. Remove ufshcd_runtime_idle() since it is empty. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210722033439.26550-3-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Reviewed-by: Avri Altman Reviewed-by: Bean Huo Reviewed-by: Daejun Park Reviewed-by: Stanley Chu Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/cdns-pltfrm.c | 7 ++--- drivers/scsi/ufs/tc-dwc-g210-pci.c | 32 ++--------------------- drivers/scsi/ufs/tc-dwc-g210-pltfrm.c | 7 ++--- drivers/scsi/ufs/ufs-exynos.c | 7 ++--- drivers/scsi/ufs/ufs-hisi.c | 7 ++--- drivers/scsi/ufs/ufs-mediatek.c | 7 ++--- drivers/scsi/ufs/ufs-qcom.c | 7 ++--- drivers/scsi/ufs/ufshcd-pci.c | 48 ++--------------------------------- drivers/scsi/ufs/ufshcd-pltfrm.c | 47 ---------------------------------- drivers/scsi/ufs/ufshcd-pltfrm.h | 18 ------------- drivers/scsi/ufs/ufshcd.c | 41 +++++++++++++++--------------- drivers/scsi/ufs/ufshcd.h | 9 +++---- 12 files changed, 41 insertions(+), 196 deletions(-) diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c index 908ff39c4856..7da8be2f35c4 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/scsi/ufs/cdns-pltfrm.c @@ -318,11 +318,8 @@ static int cdns_ufs_pltfrm_remove(struct platform_device *pdev) } static const struct dev_pm_ops cdns_ufs_dev_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c index ec4589afbc13..679289e1a78e 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pci.c +++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c @@ -23,31 +23,6 @@ static int tc_type = TC_G210_INV; module_param(tc_type, int, 0); MODULE_PARM_DESC(tc_type, "Test Chip Type (20 = 20-bit, 40 = 40-bit)"); -static int tc_dwc_g210_pci_suspend(struct device *dev) -{ - return ufshcd_system_suspend(dev_get_drvdata(dev)); -} - -static int tc_dwc_g210_pci_resume(struct device *dev) -{ - return ufshcd_system_resume(dev_get_drvdata(dev)); -} - -static int tc_dwc_g210_pci_runtime_suspend(struct device *dev) -{ - return ufshcd_runtime_suspend(dev_get_drvdata(dev)); -} - -static int tc_dwc_g210_pci_runtime_resume(struct device *dev) -{ - return ufshcd_runtime_resume(dev_get_drvdata(dev)); -} - -static int tc_dwc_g210_pci_runtime_idle(struct device *dev) -{ - return ufshcd_runtime_idle(dev_get_drvdata(dev)); -} - /* * struct ufs_hba_dwc_vops - UFS DWC specific variant operations */ @@ -143,11 +118,8 @@ tc_dwc_g210_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } static const struct dev_pm_ops tc_dwc_g210_pci_pm_ops = { - .suspend = tc_dwc_g210_pci_suspend, - .resume = tc_dwc_g210_pci_resume, - .runtime_suspend = tc_dwc_g210_pci_runtime_suspend, - .runtime_resume = tc_dwc_g210_pci_runtime_resume, - .runtime_idle = tc_dwc_g210_pci_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c index a1268e4f44d6..783ec43efa78 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c +++ b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c @@ -84,11 +84,8 @@ static int tc_dwc_g210_pltfm_remove(struct platform_device *pdev) } static const struct dev_pm_ops tc_dwc_g210_pltfm_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) }; static struct platform_driver tc_dwc_g210_pltfm_driver = { diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index cf46d6f86e0e..5aa096e5b6cc 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -1287,11 +1287,8 @@ static const struct of_device_id exynos_ufs_of_match[] = { }; static const struct dev_pm_ops exynos_ufs_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/ufs-hisi.c b/drivers/scsi/ufs/ufs-hisi.c index 5b147a48161b..6b706de8354b 100644 --- a/drivers/scsi/ufs/ufs-hisi.c +++ b/drivers/scsi/ufs/ufs-hisi.c @@ -572,11 +572,8 @@ static int ufs_hisi_remove(struct platform_device *pdev) } static const struct dev_pm_ops ufs_hisi_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index d2c251628a05..80b3545dd17d 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -1140,11 +1140,8 @@ static int ufs_mtk_remove(struct platform_device *pdev) } static const struct dev_pm_ops ufs_mtk_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 9b1d18d7c9bb..9d9770f1db4f 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1546,11 +1546,8 @@ MODULE_DEVICE_TABLE(acpi, ufs_qcom_acpi_match); #endif static const struct dev_pm_ops ufs_qcom_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, - .runtime_suspend = ufshcd_pltfrm_runtime_suspend, - .runtime_resume = ufshcd_pltfrm_runtime_resume, - .runtime_idle = ufshcd_pltfrm_runtime_idle, + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, }; diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index e6c334bfb4c2..b3bcc5c882da 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -385,48 +385,6 @@ static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = { .device_reset = ufs_intel_device_reset, }; -#ifdef CONFIG_PM_SLEEP -/** - * ufshcd_pci_suspend - suspend power management function - * @dev: pointer to PCI device handle - * - * Returns 0 if successful - * Returns non-zero otherwise - */ -static int ufshcd_pci_suspend(struct device *dev) -{ - return ufshcd_system_suspend(dev_get_drvdata(dev)); -} - -/** - * ufshcd_pci_resume - resume power management function - * @dev: pointer to PCI device handle - * - * Returns 0 if successful - * Returns non-zero otherwise - */ -static int ufshcd_pci_resume(struct device *dev) -{ - return ufshcd_system_resume(dev_get_drvdata(dev)); -} - -#endif /* !CONFIG_PM_SLEEP */ - -#ifdef CONFIG_PM -static int ufshcd_pci_runtime_suspend(struct device *dev) -{ - return ufshcd_runtime_suspend(dev_get_drvdata(dev)); -} -static int ufshcd_pci_runtime_resume(struct device *dev) -{ - return ufshcd_runtime_resume(dev_get_drvdata(dev)); -} -static int ufshcd_pci_runtime_idle(struct device *dev) -{ - return ufshcd_runtime_idle(dev_get_drvdata(dev)); -} -#endif /* !CONFIG_PM */ - /** * ufshcd_pci_shutdown - main function to put the controller in reset state * @pdev: pointer to PCI device handle @@ -510,10 +468,8 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) } static const struct dev_pm_ops ufshcd_pci_pm_ops = { - SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, - ufshcd_pci_runtime_resume, - ufshcd_pci_runtime_idle) - SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, ufshcd_pci_resume) + SET_SYSTEM_SLEEP_PM_OPS(ufshcd_system_suspend, ufshcd_system_resume) + SET_RUNTIME_PM_OPS(ufshcd_runtime_suspend, ufshcd_runtime_resume, NULL) #ifdef CONFIG_PM_SLEEP .prepare = ufshcd_suspend_prepare, .complete = ufshcd_resume_complete, diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 298e22ef907e..8859c13f4e09 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -170,53 +170,6 @@ out: return err; } -#ifdef CONFIG_PM -/** - * ufshcd_pltfrm_suspend - suspend power management function - * @dev: pointer to device handle - * - * Returns 0 if successful - * Returns non-zero otherwise - */ -int ufshcd_pltfrm_suspend(struct device *dev) -{ - return ufshcd_system_suspend(dev_get_drvdata(dev)); -} -EXPORT_SYMBOL_GPL(ufshcd_pltfrm_suspend); - -/** - * ufshcd_pltfrm_resume - resume power management function - * @dev: pointer to device handle - * - * Returns 0 if successful - * Returns non-zero otherwise - */ -int ufshcd_pltfrm_resume(struct device *dev) -{ - return ufshcd_system_resume(dev_get_drvdata(dev)); -} -EXPORT_SYMBOL_GPL(ufshcd_pltfrm_resume); - -int ufshcd_pltfrm_runtime_suspend(struct device *dev) -{ - return ufshcd_runtime_suspend(dev_get_drvdata(dev)); -} -EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_suspend); - -int ufshcd_pltfrm_runtime_resume(struct device *dev) -{ - return ufshcd_runtime_resume(dev_get_drvdata(dev)); -} -EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_resume); - -int ufshcd_pltfrm_runtime_idle(struct device *dev) -{ - return ufshcd_runtime_idle(dev_get_drvdata(dev)); -} -EXPORT_SYMBOL_GPL(ufshcd_pltfrm_runtime_idle); - -#endif /* CONFIG_PM */ - void ufshcd_pltfrm_shutdown(struct platform_device *pdev) { ufshcd_shutdown((struct ufs_hba *)platform_get_drvdata(pdev)); diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.h b/drivers/scsi/ufs/ufshcd-pltfrm.h index 772a8e848098..c33e28ac6ef6 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.h +++ b/drivers/scsi/ufs/ufshcd-pltfrm.h @@ -33,22 +33,4 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, const struct ufs_hba_variant_ops *vops); void ufshcd_pltfrm_shutdown(struct platform_device *pdev); -#ifdef CONFIG_PM - -int ufshcd_pltfrm_suspend(struct device *dev); -int ufshcd_pltfrm_resume(struct device *dev); -int ufshcd_pltfrm_runtime_suspend(struct device *dev); -int ufshcd_pltfrm_runtime_resume(struct device *dev); -int ufshcd_pltfrm_runtime_idle(struct device *dev); - -#else /* !CONFIG_PM */ - -#define ufshcd_pltfrm_suspend NULL -#define ufshcd_pltfrm_resume NULL -#define ufshcd_pltfrm_runtime_suspend NULL -#define ufshcd_pltfrm_runtime_resume NULL -#define ufshcd_pltfrm_runtime_idle NULL - -#endif /* CONFIG_PM */ - #endif /* UFSHCD_PLTFRM_H_ */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5829b25f5999..eff3c0eb9c1a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -9278,15 +9278,17 @@ out: } /** - * ufshcd_system_suspend - system suspend routine - * @hba: per adapter instance + * ufshcd_system_suspend - system suspend callback + * @dev: Device associated with the UFS controller. * - * Check the description of ufshcd_suspend() function for more details. + * Executed before putting the system into a sleep state in which the contents + * of main memory are preserved. * * Returns 0 for success and non-zero for failure */ -int ufshcd_system_suspend(struct ufs_hba *hba) +int ufshcd_system_suspend(struct device *dev) { + struct ufs_hba *hba = dev_get_drvdata(dev); int ret = 0; ktime_t start = ktime_get(); @@ -9303,16 +9305,19 @@ out: EXPORT_SYMBOL(ufshcd_system_suspend); /** - * ufshcd_system_resume - system resume routine - * @hba: per adapter instance + * ufshcd_system_resume - system resume callback + * @dev: Device associated with the UFS controller. + * + * Executed after waking the system up from a sleep state in which the contents + * of main memory were preserved. * * Returns 0 for success and non-zero for failure */ - -int ufshcd_system_resume(struct ufs_hba *hba) +int ufshcd_system_resume(struct device *dev) { - int ret = 0; + struct ufs_hba *hba = dev_get_drvdata(dev); ktime_t start = ktime_get(); + int ret = 0; if (pm_runtime_suspended(hba->dev)) goto out; @@ -9329,15 +9334,16 @@ out: EXPORT_SYMBOL(ufshcd_system_resume); /** - * ufshcd_runtime_suspend - runtime suspend routine - * @hba: per adapter instance + * ufshcd_runtime_suspend - runtime suspend callback + * @dev: Device associated with the UFS controller. * * Check the description of ufshcd_suspend() function for more details. * * Returns 0 for success and non-zero for failure */ -int ufshcd_runtime_suspend(struct ufs_hba *hba) +int ufshcd_runtime_suspend(struct device *dev) { + struct ufs_hba *hba = dev_get_drvdata(dev); int ret; ktime_t start = ktime_get(); @@ -9352,7 +9358,7 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend); /** * ufshcd_runtime_resume - runtime resume routine - * @hba: per adapter instance + * @dev: Device associated with the UFS controller. * * This function basically brings controller * to active state. Following operations are done in this function: @@ -9360,8 +9366,9 @@ EXPORT_SYMBOL(ufshcd_runtime_suspend); * 1. Turn on all the controller related clocks * 2. Turn ON VCC rail */ -int ufshcd_runtime_resume(struct ufs_hba *hba) +int ufshcd_runtime_resume(struct device *dev) { + struct ufs_hba *hba = dev_get_drvdata(dev); int ret; ktime_t start = ktime_get(); @@ -9374,12 +9381,6 @@ int ufshcd_runtime_resume(struct ufs_hba *hba) } EXPORT_SYMBOL(ufshcd_runtime_resume); -int ufshcd_runtime_idle(struct ufs_hba *hba) -{ - return 0; -} -EXPORT_SYMBOL(ufshcd_runtime_idle); - /** * ufshcd_shutdown - shutdown routine * @hba: per adapter instance diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index b4322ce11d58..7da7b202f5c5 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1030,11 +1030,10 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) return 0; } -extern int ufshcd_runtime_suspend(struct ufs_hba *hba); -extern int ufshcd_runtime_resume(struct ufs_hba *hba); -extern int ufshcd_runtime_idle(struct ufs_hba *hba); -extern int ufshcd_system_suspend(struct ufs_hba *hba); -extern int ufshcd_system_resume(struct ufs_hba *hba); +extern int ufshcd_runtime_suspend(struct device *dev); +extern int ufshcd_runtime_resume(struct device *dev); +extern int ufshcd_system_suspend(struct device *dev); +extern int ufshcd_system_resume(struct device *dev); extern int ufshcd_shutdown(struct ufs_hba *hba); extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba, int agreed_gear, -- cgit v1.2.3-70-g09d2 From 9bb25e5d9d2948249631d3396f72e48035b4f380 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:24 -0700 Subject: scsi: ufs: Only include power management code if necessary This patch slightly reduces the UFS driver size if built with power management support disabled. Link: https://lore.kernel.org/r/20210722033439.26550-4-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Reviewed-by: Avri Altman Reviewed-by: Bean Huo Reviewed-by: Daejun Park Reviewed-by: Stanley Chu Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 8 ++++++++ drivers/scsi/ufs/ufshcd.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index eff3c0eb9c1a..68180e8f9687 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8805,6 +8805,7 @@ static void ufshcd_vreg_set_lpm(struct ufs_hba *hba) usleep_range(5000, 5100); } +#ifdef CONFIG_PM static int ufshcd_vreg_set_hpm(struct ufs_hba *hba) { int ret = 0; @@ -8832,6 +8833,7 @@ vcc_disable: out: return ret; } +#endif /* CONFIG_PM */ static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba) { @@ -9239,6 +9241,7 @@ static int ufshcd_suspend(struct ufs_hba *hba) return ret; } +#ifdef CONFIG_PM /** * ufshcd_resume - helper function for resume operations * @hba: per adapter instance @@ -9276,7 +9279,9 @@ out: ufshcd_update_evt_hist(hba, UFS_EVT_RESUME_ERR, (u32)ret); return ret; } +#endif /* CONFIG_PM */ +#ifdef CONFIG_PM_SLEEP /** * ufshcd_system_suspend - system suspend callback * @dev: Device associated with the UFS controller. @@ -9332,7 +9337,9 @@ out: return ret; } EXPORT_SYMBOL(ufshcd_system_resume); +#endif /* CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM /** * ufshcd_runtime_suspend - runtime suspend callback * @dev: Device associated with the UFS controller. @@ -9380,6 +9387,7 @@ int ufshcd_runtime_resume(struct device *dev) return ret; } EXPORT_SYMBOL(ufshcd_runtime_resume); +#endif /* CONFIG_PM */ /** * ufshcd_shutdown - shutdown routine diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 7da7b202f5c5..26f2128b8f3e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1030,10 +1030,14 @@ static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) return 0; } +#ifdef CONFIG_PM extern int ufshcd_runtime_suspend(struct device *dev); extern int ufshcd_runtime_resume(struct device *dev); +#endif +#ifdef CONFIG_PM_SLEEP extern int ufshcd_system_suspend(struct device *dev); extern int ufshcd_system_resume(struct device *dev); +#endif extern int ufshcd_shutdown(struct ufs_hba *hba); extern int ufshcd_dme_configure_adapt(struct ufs_hba *hba, int agreed_gear, -- cgit v1.2.3-70-g09d2 From 568dd9959611f097bdce821cef63a50844da98c6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:25 -0700 Subject: scsi: ufs: Rename the second ufshcd_probe_hba() argument Rename the second argument of ufshcd_probe_hba() such that the name of that argument reflects its purpose instead of how the function is called. See also commit 1b9e21412f72 ("scsi: ufs: Split ufshcd_probe_hba() based on its called flow"). Link: https://lore.kernel.org/r/20210722033439.26550-5-bvanassche@acm.org Cc: Asutosh Das Cc: Can Guo Reviewed-by: Avri Altman Reviewed-by: Bean Huo Reviewed-by: Daejun Park Reviewed-by: Stanley Chu Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 68180e8f9687..e077345f74d1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8028,13 +8028,13 @@ out: } /** - * ufshcd_probe_hba - probe hba to detect device and initialize + * ufshcd_probe_hba - probe hba to detect device and initialize it * @hba: per-adapter instance - * @async: asynchronous execution or not + * @init_dev_params: whether or not to call ufshcd_device_params_init(). * * Execute link-startup and verify device initialization */ -static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) +static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) { int ret; unsigned long flags; @@ -8066,7 +8066,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) * Initialize UFS device parameters used by driver, these * parameters are associated with UFS descriptors. */ - if (async) { + if (init_dev_params) { ret = ufshcd_device_params_init(hba); if (ret) goto out; -- cgit v1.2.3-70-g09d2 From 8a686f26eaa4b8a5c494b6b69e8a97815e3ffb82 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:26 -0700 Subject: scsi: ufs: Use DECLARE_COMPLETION_ONSTACK() where appropriate From Documentation/scheduler/completion.rst: "When a completion is declared as a local variable within a function, then the initialization should always use DECLARE_COMPLETION_ONSTACK() explicitly, not just to make lockdep happy, but also to make it clear that limited scope had been considered and is intentional." Link: https://lore.kernel.org/r/20210722033439.26550-6-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Reviewed-by: Avri Altman Reviewed-by: Bean Huo Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e077345f74d1..77d705ed0150 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2956,11 +2956,11 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, enum dev_cmd_type cmd_type, int timeout) { struct request_queue *q = hba->cmd_queue; + DECLARE_COMPLETION_ONSTACK(wait); struct request *req; struct ufshcd_lrb *lrbp; int err; int tag; - struct completion wait; down_read(&hba->clk_scaling_lock); @@ -2985,7 +2985,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, goto out; } - init_completion(&wait); lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag); @@ -3992,14 +3991,13 @@ EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr); */ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) { - struct completion uic_async_done; + DECLARE_COMPLETION_ONSTACK(uic_async_done); unsigned long flags; u8 status; int ret; bool reenable_intr = false; mutex_lock(&hba->uic_cmd_mutex); - init_completion(&uic_async_done); ufshcd_add_delay_before_dme_cmd(hba); spin_lock_irqsave(hba->host->host_lock, flags); @@ -6700,11 +6698,11 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, enum query_opcode desc_op) { struct request_queue *q = hba->cmd_queue; + DECLARE_COMPLETION_ONSTACK(wait); struct request *req; struct ufshcd_lrb *lrbp; int err = 0; int tag; - struct completion wait; u8 upiu_flags; down_read(&hba->clk_scaling_lock); @@ -6722,7 +6720,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, goto out; } - init_completion(&wait); lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = NULL; -- cgit v1.2.3-70-g09d2 From 4728ab4a8e64902b0b0c5238ed09128ea20aa5ce Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:27 -0700 Subject: scsi: ufs: Remove ufshcd_valid_tag() scsi_add_host() allocates shost->can_queue tags. ufshcd_init() sets shost->can_queue to hba->nutrs. In other words, we know that tag values will less than hba->nutrs. Hence remove the checks that verify that blk_get_request() returns a tag less than hba->nutrs. This check was introduced by commit 14497328b6a6 ("scsi: ufs: verify command tag validity"). Keep the tag >= 0 check because it helps to detect use-after-free issues. Link: https://lore.kernel.org/r/20210722033439.26550-7-bvanassche@acm.org CC: Avri Altman Cc: Alim Akhtar Reviewed-by: Bean Huo Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 42 ++++++++++-------------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 77d705ed0150..17ef4ceafb22 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -253,11 +253,6 @@ static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable); static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba); static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba); -static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag) -{ - return tag >= 0 && tag < hba->nutrs; -} - static inline void ufshcd_enable_irq(struct ufs_hba *hba) { if (!hba->is_irq_enabled) { @@ -2701,20 +2696,12 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i) */ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { + struct ufs_hba *hba = shost_priv(host); + int tag = cmd->request->tag; struct ufshcd_lrb *lrbp; - struct ufs_hba *hba; - int tag; int err = 0; - hba = shost_priv(host); - - tag = cmd->request->tag; - if (!ufshcd_valid_tag(hba, tag)) { - dev_err(hba->dev, - "%s: invalid command tag %d: cmd=0x%p, cmd->request=0x%p", - __func__, tag, cmd, cmd->request); - BUG(); - } + WARN_ONCE(tag < 0, "Invalid tag %d\n", tag); if (!down_read_trylock(&hba->clk_scaling_lock)) return SCSI_MLQUEUE_HOST_BUSY; @@ -2975,7 +2962,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, goto out_unlock; } tag = req->tag; - WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + WARN_ONCE(tag < 0, "Invalid tag %d\n", tag); /* Set the timeout such that the SCSI error handler is not activated. */ req->timeout = msecs_to_jiffies(2 * timeout); blk_mq_start_request(req); @@ -6713,7 +6700,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, goto out_unlock; } tag = req->tag; - WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + WARN_ONCE(tag < 0, "Invalid tag %d\n", tag); if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { err = -EBUSY; @@ -7015,24 +7002,15 @@ out: */ static int ufshcd_abort(struct scsi_cmnd *cmd) { - struct Scsi_Host *host; - struct ufs_hba *hba; + struct Scsi_Host *host = cmd->device->host; + struct ufs_hba *hba = shost_priv(host); + unsigned int tag = cmd->request->tag; + struct ufshcd_lrb *lrbp = &hba->lrb[tag]; unsigned long flags; - unsigned int tag; int err = 0; - struct ufshcd_lrb *lrbp; u32 reg; - host = cmd->device->host; - hba = shost_priv(host); - tag = cmd->request->tag; - lrbp = &hba->lrb[tag]; - if (!ufshcd_valid_tag(hba, tag)) { - dev_err(hba->dev, - "%s: invalid command tag %d: cmd=0x%p, cmd->request=0x%p", - __func__, tag, cmd, cmd->request); - BUG(); - } + WARN_ONCE(tag < 0, "Invalid tag %d\n", tag); ufshcd_hold(hba, false); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); -- cgit v1.2.3-70-g09d2 From 35c7d874f5993db04ce3aa310ae088f14b801eda Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:28 -0700 Subject: scsi: ufs: Verify UIC locking requirements at runtime Instead of documenting the locking requirements of the UIC code as comments, use lockdep_assert_held() such that lockdep verifies the lockdep requirements at runtime if lockdep is enabled. Link: https://lore.kernel.org/r/20210722033439.26550-8-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Reviewed-by: Avri Altman Reviewed-by: Bean Huo Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 16 +++++++++------- drivers/scsi/ufs/ufshcd.h | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 17ef4ceafb22..8e3873e00bc4 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2242,15 +2242,15 @@ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba) } /** - * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers + * ufshcd_dispatch_uic_cmd - Dispatch an UIC command to the Unipro layer * @hba: per adapter instance * @uic_cmd: UIC command - * - * Mutex must be held. */ static inline void ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) { + lockdep_assert_held(&hba->uic_cmd_mutex); + WARN_ON(hba->active_uic_cmd); hba->active_uic_cmd = uic_cmd; @@ -2268,11 +2268,10 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) } /** - * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command + * ufshcd_wait_for_uic_cmd - Wait for completion of an UIC command * @hba: per adapter instance * @uic_cmd: UIC command * - * Must be called with mutex held. * Returns 0 only if success. */ static int @@ -2281,6 +2280,8 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) int ret; unsigned long flags; + lockdep_assert_held(&hba->uic_cmd_mutex); + if (wait_for_completion_timeout(&uic_cmd->done, msecs_to_jiffies(UIC_CMD_TIMEOUT))) { ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; @@ -2310,14 +2311,15 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) * @uic_cmd: UIC command * @completion: initialize the completion only if this is set to true * - * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called - * with mutex held and host_lock locked. * Returns 0 only if success. */ static int __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd, bool completion) { + lockdep_assert_held(&hba->uic_cmd_mutex); + lockdep_assert_held(hba->host->host_lock); + if (!ufshcd_ready_for_uic_cmd(hba)) { dev_err(hba->dev, "Controller not ready to accept UIC commands\n"); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 26f2128b8f3e..139e43c6f776 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -708,7 +708,7 @@ struct ufs_hba_monitor { * @priv: pointer to variant specific private data * @irq: Irq number of the controller * @active_uic_cmd: handle of active UIC command - * @uic_cmd_mutex: mutex for uic command + * @uic_cmd_mutex: mutex for UIC command * @tmf_tag_set: TMF tag set. * @tmf_queue: Used to allocate TMF tags. * @pwr_done: completion for power mode change -- cgit v1.2.3-70-g09d2 From 9c202090edd4c7679adf5bf040d7ee19966feae6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:29 -0700 Subject: scsi: ufs: Improve static type checking for the host controller state Assign a name to the enumeration type for UFS host controller states and remove the default clause from switch statements on this enumeration type to make the compiler warn about unhandled enumeration labels. Link: https://lore.kernel.org/r/20210722033439.26550-9-bvanassche@acm.org Cc: Can Guo Reviewed-by: Avri Altman Reviewed-by: Keoseong Park Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 15 --------------- drivers/scsi/ufs/ufshcd.h | 25 +++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 8e3873e00bc4..3ef2a2dda700 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -128,15 +128,6 @@ enum { UFSHCD_CAN_QUEUE = 32, }; -/* UFSHCD states */ -enum { - UFSHCD_STATE_RESET, - UFSHCD_STATE_ERROR, - UFSHCD_STATE_OPERATIONAL, - UFSHCD_STATE_EH_SCHEDULED_FATAL, - UFSHCD_STATE_EH_SCHEDULED_NON_FATAL, -}; - /* UFSHCD error handling flags */ enum { UFSHCD_EH_IN_PROGRESS = (1 << 0), @@ -2737,12 +2728,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) set_host_byte(cmd, DID_ERROR); cmd->scsi_done(cmd); goto out; - default: - dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n", - __func__, hba->ufshcd_state); - set_host_byte(cmd, DID_BAD_TARGET); - cmd->scsi_done(cmd); - goto out; } hba->req_abort_count = 0; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 139e43c6f776..334b49cb00b3 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -476,6 +476,27 @@ struct ufs_stats { struct ufs_event_hist event[UFS_EVT_CNT]; }; +/** + * enum ufshcd_state - UFS host controller state + * @UFSHCD_STATE_RESET: Link is not operational. Postpone SCSI command + * processing. + * @UFSHCD_STATE_OPERATIONAL: The host controller is operational and can process + * SCSI commands. + * @UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: The error handler has been scheduled. + * SCSI commands may be submitted to the controller. + * @UFSHCD_STATE_EH_SCHEDULED_FATAL: The error handler has been scheduled. Fail + * newly submitted SCSI commands with error code DID_BAD_TARGET. + * @UFSHCD_STATE_ERROR: An unrecoverable error occurred, e.g. link recovery + * failed. Fail all SCSI commands with error code DID_ERROR. + */ +enum ufshcd_state { + UFSHCD_STATE_RESET, + UFSHCD_STATE_OPERATIONAL, + UFSHCD_STATE_EH_SCHEDULED_NON_FATAL, + UFSHCD_STATE_EH_SCHEDULED_FATAL, + UFSHCD_STATE_ERROR, +}; + enum ufshcd_quirks { /* Interrupt aggregation support is broken */ UFSHCD_QUIRK_BROKEN_INTR_AGGR = 1 << 0, @@ -712,7 +733,7 @@ struct ufs_hba_monitor { * @tmf_tag_set: TMF tag set. * @tmf_queue: Used to allocate TMF tags. * @pwr_done: completion for power mode change - * @ufshcd_state: UFSHCD states + * @ufshcd_state: UFSHCD state * @eh_flags: Error handling flags * @intr_mask: Interrupt Mask Bits * @ee_ctrl_mask: Exception event control mask @@ -810,7 +831,7 @@ struct ufs_hba { struct mutex uic_cmd_mutex; struct completion *uic_async_done; - u32 ufshcd_state; + enum ufshcd_state ufshcd_state; u32 eh_flags; u32 intr_mask; u16 ee_ctrl_mask; /* Exception event mask */ -- cgit v1.2.3-70-g09d2 From 3d2ac73d13476fd996e3423863371805780a0663 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:30 -0700 Subject: scsi: ufs: Remove several wmb() calls From arch/arm/include/asm/io.h #define __iowmb() wmb() [ ... ] #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) From Documentation/memory-barriers.txt: "Note that, when using writel(), a prior wmb() is not needed to guarantee that the cache coherent memory writes have completed before writing to the MMIO region." In other words, calling wmb() before writel() is not necessary. Hence remove the wmb() calls that precede a writel() call. Remove the wmb() calls that precede a ufshcd_send_command() call since the latter function uses writel(). Remove the wmb() call from ufshcd_wait_for_dev_cmd() since the following chain of events guarantees that the CPU will see up-to-date LRB values: - UFS controller writes to host memory. - UFS controller posts completion interrupt after the memory writes from the previous step are visible to the CPU. - complete(hba->dev_cmd.complete) is called from the UFS interrupt handler. - The wait_for_completion(hba->dev_cmd.complete) call in ufshcd_wait_for_dev_cmd() returns. Link: https://lore.kernel.org/r/20210722033439.26550-10-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Tested-by: Avri altman Reviewed-by: Avri Altman Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3ef2a2dda700..867678ea23ad 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2777,8 +2777,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ufshcd_release(hba); goto out; } - /* Make sure descriptors are ready before ringing the doorbell */ - wmb(); ufshcd_send_command(hba, tag); out: @@ -2888,8 +2886,6 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, time_left = wait_for_completion_timeout(hba->dev_cmd.complete, msecs_to_jiffies(max_timeout)); - /* Make sure descriptors are ready before ringing the doorbell */ - wmb(); spin_lock_irqsave(hba->host->host_lock, flags); hba->dev_cmd.complete = NULL; if (likely(time_left)) { @@ -2968,8 +2964,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, hba->dev_cmd.complete = &wait; ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr); - /* Make sure descriptors are ready before ringing the doorbell */ - wmb(); ufshcd_send_command(hba, tag); err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout); @@ -6557,9 +6551,6 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, /* send command to the controller */ __set_bit(task_tag, &hba->outstanding_tasks); - /* Make sure descriptors are ready before ringing the task doorbell */ - wmb(); - ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL); /* Make sure that doorbell is committed immediately */ wmb(); @@ -6731,8 +6722,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, hba->dev_cmd.complete = &wait; ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr); - /* Make sure descriptors are ready before ringing the doorbell */ - wmb(); ufshcd_send_command(hba, tag); /* -- cgit v1.2.3-70-g09d2 From 815b9a27b0a3055585db37c422146067e55e0617 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:31 -0700 Subject: scsi: ufs: Inline ufshcd_outstanding_req_clear() Inline ufshcd_outstanding_req_clear() since it only has one caller and since its body is only one line long. Link: https://lore.kernel.org/r/20210722033439.26550-11-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Reviewed-by: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 867678ea23ad..7780a7d7a3b1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -743,16 +743,6 @@ static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos) ufshcd_writel(hba, ~(1 << pos), REG_UTP_TASK_REQ_LIST_CLEAR); } -/** - * ufshcd_outstanding_req_clear - Clear a bit in outstanding request field - * @hba: per adapter instance - * @tag: position of the bit to be cleared - */ -static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag) -{ - clear_bit(tag, &hba->outstanding_reqs); -} - /** * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY * @reg: Register value of host controller status @@ -2907,7 +2897,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, * we also need to clear the outstanding_request * field in hba */ - ufshcd_outstanding_req_clear(hba, lrbp->task_tag); + clear_bit(lrbp->task_tag, &hba->outstanding_reqs); } return err; -- cgit v1.2.3-70-g09d2 From 1f522c5049016cfea4f9d131ae9089e6fdba3980 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:32 -0700 Subject: scsi: ufs: Revert "Utilize Transfer Request List Completion Notification Register" Using the UTRLCNR register involves two MMIO accesses in the hot path while using the doorbell register only involves a single MMIO access. Since MMIO accesses take time, do not use the UTRLCNR register. The spinlock contention on the SCSI host lock that is reintroduced by this commit will be addressed later. This reverts commit 6f7151729647e58ac7c522081255fd0c07b38105. Link: https://lore.kernel.org/r/20210722033439.26550-12-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Tested-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 52 ++++++++++++++--------------------------------- drivers/scsi/ufs/ufshcd.h | 5 ----- drivers/scsi/ufs/ufshci.h | 1 - 3 files changed, 15 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 7780a7d7a3b1..8d986f2221a0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2088,6 +2088,7 @@ static inline void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) { struct ufshcd_lrb *lrbp = &hba->lrb[task_tag]; + unsigned long flags; lrbp->issue_time_stamp = ktime_get(); lrbp->compl_time_stamp = ktime_set(0, 0); @@ -2096,19 +2097,10 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) ufshcd_clk_scaling_start_busy(hba); if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_start_monitor(hba, lrbp); - if (ufshcd_has_utrlcnr(hba)) { - set_bit(task_tag, &hba->outstanding_reqs); - ufshcd_writel(hba, 1 << task_tag, - REG_UTP_TRANSFER_REQ_DOOR_BELL); - } else { - unsigned long flags; - - spin_lock_irqsave(hba->host->host_lock, flags); - set_bit(task_tag, &hba->outstanding_reqs); - ufshcd_writel(hba, 1 << task_tag, - REG_UTP_TRANSFER_REQ_DOOR_BELL); - spin_unlock_irqrestore(hba->host->host_lock, flags); - } + spin_lock_irqsave(hba->host->host_lock, flags); + set_bit(task_tag, &hba->outstanding_reqs); + ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); + spin_unlock_irqrestore(hba->host->host_lock, flags); /* Make sure that doorbell is committed immediately */ wmb(); } @@ -5270,17 +5262,17 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, } /** - * ufshcd_trc_handler - handle transfer requests completion + * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance - * @use_utrlcnr: get completed requests from UTRLCNR * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr) +static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) { - unsigned long completed_reqs = 0; + unsigned long completed_reqs, flags; + u32 tr_doorbell; /* Resetting interrupt aggregation counters first and reading the * DOOR_BELL afterward allows us to handle all the completed requests. @@ -5293,24 +5285,10 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr) !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); - if (use_utrlcnr) { - u32 utrlcnr; - - utrlcnr = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_LIST_COMPL); - if (utrlcnr) { - ufshcd_writel(hba, utrlcnr, - REG_UTP_TRANSFER_REQ_LIST_COMPL); - completed_reqs = utrlcnr; - } - } else { - unsigned long flags; - u32 tr_doorbell; - - spin_lock_irqsave(hba->host->host_lock, flags); - tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - spin_unlock_irqrestore(hba->host->host_lock, flags); - } + spin_lock_irqsave(hba->host->host_lock, flags); + tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + completed_reqs = tr_doorbell ^ hba->outstanding_reqs; + spin_unlock_irqrestore(hba->host->host_lock, flags); if (completed_reqs) { __ufshcd_transfer_req_compl(hba, completed_reqs); @@ -5792,7 +5770,7 @@ out: /* Complete requests that have door-bell cleared */ static void ufshcd_complete_requests(struct ufs_hba *hba) { - ufshcd_trc_handler(hba, false); + ufshcd_transfer_req_compl(hba); ufshcd_tmc_handler(hba); } @@ -6433,7 +6411,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) retval |= ufshcd_tmc_handler(hba); if (intr_status & UTP_TRANSFER_REQ_COMPL) - retval |= ufshcd_trc_handler(hba, ufshcd_has_utrlcnr(hba)); + retval |= ufshcd_transfer_req_compl(hba); return retval; } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 334b49cb00b3..56f48dd34020 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1208,11 +1208,6 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba) return ufshcd_readl(hba, REG_UFS_VERSION); } -static inline bool ufshcd_has_utrlcnr(struct ufs_hba *hba) -{ - return (hba->ufs_version >= ufshci_version(3, 0)); -} - static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, bool up, enum ufs_notify_change_status status) { diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 5affb1fce5ad..de95be5d11d4 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -39,7 +39,6 @@ enum { REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58, REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C, REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60, - REG_UTP_TRANSFER_REQ_LIST_COMPL = 0x64, REG_UTP_TASK_REQ_LIST_BASE_L = 0x70, REG_UTP_TASK_REQ_LIST_BASE_H = 0x74, REG_UTP_TASK_REQ_DOOR_BELL = 0x78, -- cgit v1.2.3-70-g09d2 From a024ad0d49550e4ea1156e677cd9382e1eefbdd7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:33 -0700 Subject: scsi: ufs: Optimize serialization of setup_xfer_req() calls Reduce the number of times the host lock is taken in the hot path. Additionally, inline ufshcd_vops_setup_xfer_req() because that function is too short to keep it. Link: https://lore.kernel.org/r/20210722033439.26550-13-bvanassche@acm.org Fixes: a45f937110fa ("scsi: ufs: Optimize host lock on transfer requests send/compl paths") Cc: Jaegeuk Kim Cc: Stanley Chu Cc: Can Guo Cc: Bean Huo Cc: Asutosh Das Reviewed-by: Daejun Park Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 3 ++- drivers/scsi/ufs/ufshcd.h | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 8d986f2221a0..41e0697324e3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2092,12 +2092,13 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) lrbp->issue_time_stamp = ktime_get(); lrbp->compl_time_stamp = ktime_set(0, 0); - ufshcd_vops_setup_xfer_req(hba, task_tag, (lrbp->cmd ? true : false)); ufshcd_add_command_trace(hba, task_tag, UFS_CMD_SEND); ufshcd_clk_scaling_start_busy(hba); if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_start_monitor(hba, lrbp); spin_lock_irqsave(hba->host->host_lock, flags); + if (hba->vops && hba->vops->setup_xfer_req) + hba->vops->setup_xfer_req(hba, task_tag, !!lrbp->cmd); set_bit(task_tag, &hba->outstanding_reqs); ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); spin_unlock_irqrestore(hba->host->host_lock, flags); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 56f48dd34020..38a09ab52f53 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1269,18 +1269,6 @@ static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba, return -ENOTSUPP; } -static inline void ufshcd_vops_setup_xfer_req(struct ufs_hba *hba, int tag, - bool is_scsi_cmd) -{ - if (hba->vops && hba->vops->setup_xfer_req) { - unsigned long flags; - - spin_lock_irqsave(hba->host->host_lock, flags); - hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd); - spin_unlock_irqrestore(hba->host->host_lock, flags); - } -} - static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba, int tag, u8 tm_function) { -- cgit v1.2.3-70-g09d2 From 169f5eb28869098ac02d7e03abea36e8ac599bcc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:34 -0700 Subject: scsi: ufs: Optimize SCSI command processing Use a spinlock to protect hba->outstanding_reqs instead of using atomic operations to update this member variable. This patch is a performance improvement because it reduces the number of atomic operations in the hot path (test_and_clear_bit()) and because it reduces the lock contention on the SCSI host lock. On my test setup this patch improves IOPS by about 1%. Link: https://lore.kernel.org/r/20210722033439.26550-14-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Reviewed-by: Daejun Park Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 29 ++++++++++++++++++----------- drivers/scsi/ufs/ufshcd.h | 2 ++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 41e0697324e3..e402cc92fb62 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2096,12 +2096,14 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) ufshcd_clk_scaling_start_busy(hba); if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_start_monitor(hba, lrbp); - spin_lock_irqsave(hba->host->host_lock, flags); + + spin_lock_irqsave(&hba->outstanding_lock, flags); if (hba->vops && hba->vops->setup_xfer_req) hba->vops->setup_xfer_req(hba, task_tag, !!lrbp->cmd); - set_bit(task_tag, &hba->outstanding_reqs); + __set_bit(task_tag, &hba->outstanding_reqs); ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->outstanding_lock, flags); + /* Make sure that doorbell is committed immediately */ wmb(); } @@ -2890,7 +2892,9 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, * we also need to clear the outstanding_request * field in hba */ - clear_bit(lrbp->task_tag, &hba->outstanding_reqs); + spin_lock_irqsave(&hba->outstanding_lock, flags); + __clear_bit(lrbp->task_tag, &hba->outstanding_reqs); + spin_unlock_irqrestore(&hba->outstanding_lock, flags); } return err; @@ -5230,8 +5234,6 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, bool update_scaling = false; for_each_set_bit(index, &completed_reqs, hba->nutrs) { - if (!test_and_clear_bit(index, &hba->outstanding_reqs)) - continue; lrbp = &hba->lrb[index]; lrbp->compl_time_stamp = ktime_get(); cmd = lrbp->cmd; @@ -5286,10 +5288,14 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->outstanding_lock, flags); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - spin_unlock_irqrestore(hba->host->host_lock, flags); + completed_reqs = ~tr_doorbell & hba->outstanding_reqs; + WARN_ONCE(completed_reqs & ~hba->outstanding_reqs, + "completed: %#lx; outstanding: %#lx\n", completed_reqs, + hba->outstanding_reqs); + hba->outstanding_reqs &= ~completed_reqs; + spin_unlock_irqrestore(&hba->outstanding_lock, flags); if (completed_reqs) { __ufshcd_transfer_req_compl(hba, completed_reqs); @@ -9411,10 +9417,11 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) hba = shost_priv(host); hba->host = host; hba->dev = dev; - *hba_handle = hba; hba->dev_ref_clk_freq = REF_CLK_FREQ_INVAL; - INIT_LIST_HEAD(&hba->clk_list_head); + spin_lock_init(&hba->outstanding_lock); + + *hba_handle = hba; out_error: return err; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 38a09ab52f53..963a3810f89a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -720,6 +720,7 @@ struct ufs_hba_monitor { * @lrb: local reference block * @cmd_queue: Used to allocate command tags from hba->host->tag_set. * @outstanding_tasks: Bits representing outstanding task requests + * @outstanding_lock: Protects @outstanding_reqs. * @outstanding_reqs: Bits representing outstanding transfer requests * @capabilities: UFS Controller Capabilities * @nutrs: Transfer Request Queue depth supported by controller @@ -806,6 +807,7 @@ struct ufs_hba { struct ufshcd_lrb *lrb; unsigned long outstanding_tasks; + spinlock_t outstanding_lock; unsigned long outstanding_reqs; u32 capabilities; -- cgit v1.2.3-70-g09d2 From 64180742605f772d511903c9e50262afb13726c6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:35 -0700 Subject: scsi: ufs: Fix the SCSI abort handler Make the following changes in ufshcd_abort(): - Return FAILED instead of SUCCESS if the abort handler notices that a SCSI command has already been completed. Returning SUCCESS in this case triggers a use-after-free and may trigger a kernel crash. - Fix the code for aborting SCSI commands submitted to a WLUN. The current approach for aborting SCSI commands that have been submitted to a WLUN and that timed out is as follows: - Report to the SCSI core that the command has completed successfully. Let the block layer free any data buffers associated with the command. - Mark the command as outstanding in 'outstanding_reqs'. - If the block layer tries to reuse the tag associated with the aborted command, busy-wait until the tag is freed. This approach can result in: - Memory corruption if the controller accesses the data buffer after the block layer has freed the associated data buffers. - A race condition if ufshcd_queuecommand() or ufshcd_exec_dev_cmd() checks the bit that corresponds to an aborted command in 'outstanding_reqs' after it has been cleared and before it is reset. - High energy consumption if ufshcd_queuecommand() repeatedly returns SCSI_MLQUEUE_HOST_BUSY. Fix this by reporting to the SCSI error handler that aborting a SCSI command failed if the SCSI command was submitted to a WLUN. Link: https://lore.kernel.org/r/20210722033439.26550-15-bvanassche@acm.org Fixes: 7a7e66c65d41 ("scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()") Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 54 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e402cc92fb62..d52ba03ea963 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2725,15 +2725,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) WARN_ON(ufshcd_is_clkgating_allowed(hba) && (hba->clk_gating.state != CLKS_ON)); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { - if (hba->pm_op_in_progress) - set_host_byte(cmd, DID_BAD_TARGET); - else - err = SCSI_MLQUEUE_HOST_BUSY; - ufshcd_release(hba); - goto out; - } - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = cmd; @@ -2937,11 +2928,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, req->timeout = msecs_to_jiffies(2 * timeout); blk_mq_start_request(req); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { - err = -EBUSY; - goto out; - } - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag); @@ -6958,19 +6944,19 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) unsigned int tag = cmd->request->tag; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; unsigned long flags; - int err = 0; + int err = FAILED; u32 reg; WARN_ONCE(tag < 0, "Invalid tag %d\n", tag); ufshcd_hold(hba, false); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - /* If command is already aborted/completed, return SUCCESS */ + /* If command is already aborted/completed, return FAILED. */ if (!(test_bit(tag, &hba->outstanding_reqs))) { dev_err(hba->dev, "%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n", __func__, tag, hba->outstanding_reqs, reg); - goto out; + goto release; } /* Print Transfer Request of aborted task */ @@ -6999,7 +6985,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) dev_err(hba->dev, "%s: cmd was completed, but without a notifying intr, tag = %d", __func__, tag); - goto cleanup; + __ufshcd_transfer_req_compl(hba, 1UL << tag); + goto release; } /* @@ -7012,36 +6999,33 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) */ if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); - __ufshcd_transfer_req_compl(hba, (1UL << tag)); - set_bit(tag, &hba->outstanding_reqs); + spin_lock_irqsave(host->host_lock, flags); hba->force_reset = true; ufshcd_schedule_eh_work(hba); spin_unlock_irqrestore(host->host_lock, flags); - goto out; + goto release; } /* Skip task abort in case previous aborts failed and report failure */ - if (lrbp->req_abort_skip) - err = -EIO; - else - err = ufshcd_try_to_abort_task(hba, tag); + if (lrbp->req_abort_skip) { + dev_err(hba->dev, "%s: skipping abort\n", __func__); + ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); + goto release; + } - if (!err) { -cleanup: - __ufshcd_transfer_req_compl(hba, (1UL << tag)); -out: - err = SUCCESS; - } else { + err = ufshcd_try_to_abort_task(hba, tag); + if (err) { dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); err = FAILED; + goto release; } - /* - * This ufshcd_release() corresponds to the original scsi cmd that got - * aborted here (as we won't get any IRQ for it). - */ + err = SUCCESS; + +release: + /* Matches the ufshcd_hold() call at the start of this function. */ ufshcd_release(hba); return err; } -- cgit v1.2.3-70-g09d2 From ac1bc2ba060f9609972fb486073ebd9eab1ef3b6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:36 -0700 Subject: scsi: ufs: Request sense data asynchronously Clearing a unit attention synchronously from inside the UFS error handler may trigger the following deadlock: - ufshcd_err_handler() calls ufshcd_err_handling_unprepare() and the latter function calls ufshcd_clear_ua_wluns(). - ufshcd_clear_ua_wluns() submits a REQUEST SENSE command and that command activates the SCSI error handler. - The SCSI error handler calls ufshcd_host_reset_and_restore(). - ufshcd_host_reset_and_restore() executes the following code: ufshcd_schedule_eh_work(hba); flush_work(&hba->eh_work); This sequence results in a deadlock (circular wait). Fix this by requesting sense data asynchronously. Link: https://lore.kernel.org/r/20210722033439.26550-16-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 64 ++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d52ba03ea963..d4db56650bba 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7880,8 +7880,39 @@ out: return ret; } +static void ufshcd_request_sense_done(struct request *rq, blk_status_t error) +{ + if (error != BLK_STS_OK) + pr_err("%s: REQUEST SENSE failed (%d)", __func__, error); + blk_put_request(rq); +} + static int -ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp); +ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev) +{ + /* + * From SPC-6: the REQUEST SENSE command with any allocation length + * clears the sense data. + */ + static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, 0, 0}; + struct scsi_request *rq; + struct request *req; + + req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, /*flags=*/0); + if (IS_ERR(req)) + return PTR_ERR(req); + + rq = scsi_req(req); + rq->cmd_len = ARRAY_SIZE(cmd); + memcpy(rq->cmd, cmd, rq->cmd_len); + rq->retries = 3; + req->timeout = 1 * HZ; + req->rq_flags |= RQF_PM | RQF_QUIET; + + blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true, + ufshcd_request_sense_done); + return 0; +} static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun) { @@ -7909,7 +7940,7 @@ static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun) if (ret) goto out_err; - ret = ufshcd_send_request_sense(hba, sdp); + ret = ufshcd_request_sense_async(hba, sdp); scsi_device_put(sdp); out_err: if (ret) @@ -8509,35 +8540,6 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) } } -static int -ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp) -{ - unsigned char cmd[6] = {REQUEST_SENSE, - 0, - 0, - 0, - UFS_SENSE_SIZE, - 0}; - char *buffer; - int ret; - - buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL); - if (!buffer) { - ret = -ENOMEM; - goto out; - } - - ret = scsi_execute(sdp, cmd, DMA_FROM_DEVICE, buffer, - UFS_SENSE_SIZE, NULL, NULL, - msecs_to_jiffies(1000), 3, 0, RQF_PM, NULL); - if (ret) - pr_err("%s: failed with err %d\n", __func__, ret); - - kfree(buffer); -out: - return ret; -} - /** * ufshcd_set_dev_pwr_mode - sends START STOP UNIT command to set device * power mode -- cgit v1.2.3-70-g09d2 From a113eaaf86373362b053279049907ff82b5df6c8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:37 -0700 Subject: scsi: ufs: Synchronize SCSI and UFS error handling Use the SCSI error handler instead of a custom error handling strategy. This change reduces the number of potential races in the UFS drivers since the UFS error handler and the SCSI error handler no longer run concurrently. Link: https://lore.kernel.org/r/20210722033439.26550-17-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Tested-by: Bean Huo Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 102 +++++++++++++++++++++++++--------------------- drivers/scsi/ufs/ufshcd.h | 4 -- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d4db56650bba..570efb6df6af 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include "../scsi_transport_api.h" #include "ufshcd.h" #include "ufs_quirks.h" #include "unipro.h" @@ -233,7 +235,6 @@ static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up); static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode); -static void ufshcd_schedule_eh_work(struct ufs_hba *hba); static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on); static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on); static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, @@ -3914,6 +3915,35 @@ out: } EXPORT_SYMBOL_GPL(ufshcd_dme_get_attr); +static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba) +{ + lockdep_assert_held(hba->host->host_lock); + + return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) || + (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK)); +} + +static void ufshcd_schedule_eh(struct ufs_hba *hba) +{ + bool schedule_eh = false; + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + /* handle fatal errors only when link is not in error state */ + if (hba->ufshcd_state != UFSHCD_STATE_ERROR) { + if (hba->force_reset || ufshcd_is_link_broken(hba) || + ufshcd_is_saved_err_fatal(hba)) + hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL; + else + hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL; + schedule_eh = true; + } + spin_unlock_irqrestore(hba->host->host_lock, flags); + + if (schedule_eh) + scsi_schedule_eh(hba->host); +} + /** * ufshcd_uic_pwr_ctrl - executes UIC commands (which affects the link power * state) and waits for it to take effect. @@ -3934,6 +3964,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) { DECLARE_COMPLETION_ONSTACK(uic_async_done); unsigned long flags; + bool schedule_eh = false; u8 status; int ret; bool reenable_intr = false; @@ -4003,10 +4034,14 @@ out: ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); if (ret) { ufshcd_set_link_broken(hba); - ufshcd_schedule_eh_work(hba); + schedule_eh = true; } + out_unlock: spin_unlock_irqrestore(hba->host->host_lock, flags); + + if (schedule_eh) + ufshcd_schedule_eh(hba); mutex_unlock(&hba->uic_cmd_mutex); return ret; @@ -5838,27 +5873,6 @@ out: return err_handling; } -/* host lock must be held before calling this func */ -static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba) -{ - return (hba->saved_uic_err & UFSHCD_UIC_DL_PA_INIT_ERROR) || - (hba->saved_err & (INT_FATAL_ERRORS | UFSHCD_UIC_HIBERN8_MASK)); -} - -/* host lock must be held before calling this func */ -static inline void ufshcd_schedule_eh_work(struct ufs_hba *hba) -{ - /* handle fatal errors only when link is not in error state */ - if (hba->ufshcd_state != UFSHCD_STATE_ERROR) { - if (hba->force_reset || ufshcd_is_link_broken(hba) || - ufshcd_is_saved_err_fatal(hba)) - hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_FATAL; - else - hba->ufshcd_state = UFSHCD_STATE_EH_SCHEDULED_NON_FATAL; - queue_work(hba->eh_wq, &hba->eh_work); - } -} - static void ufshcd_clk_scaling_allow(struct ufs_hba *hba, bool allow) { down_write(&hba->clk_scaling_lock); @@ -5992,11 +6006,11 @@ static bool ufshcd_is_pwr_mode_restore_needed(struct ufs_hba *hba) /** * ufshcd_err_handler - handle UFS errors that require s/w attention - * @work: pointer to work structure + * @host: SCSI host pointer */ -static void ufshcd_err_handler(struct work_struct *work) +static void ufshcd_err_handler(struct Scsi_Host *host) { - struct ufs_hba *hba; + struct ufs_hba *hba = shost_priv(host); unsigned long flags; bool err_xfer = false; bool err_tm = false; @@ -6004,10 +6018,9 @@ static void ufshcd_err_handler(struct work_struct *work) int tag; bool needs_reset = false, needs_restore = false; - hba = container_of(work, struct ufs_hba, eh_work); - down(&hba->host_sem); spin_lock_irqsave(hba->host->host_lock, flags); + hba->host->host_eh_scheduled = 0; if (ufshcd_err_handling_should_stop(hba)) { if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; @@ -6321,7 +6334,6 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) "host_regs: "); ufshcd_print_pwr_info(hba); } - ufshcd_schedule_eh_work(hba); retval |= IRQ_HANDLED; } /* @@ -6333,6 +6345,10 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) hba->errors = 0; hba->uic_error = 0; spin_unlock(hba->host->host_lock); + + if (queue_eh_work) + ufshcd_schedule_eh(hba); + return retval; } @@ -6995,15 +7011,17 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) * will be to send LU reset which, again, is a spec violation. * To avoid these unnecessary/illegal steps, first we clean up * the lrb taken by this cmd and re-set it in outstanding_reqs, - * then queue the eh_work and bail. + * then queue the error handler and bail. */ if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); spin_lock_irqsave(host->host_lock, flags); hba->force_reset = true; - ufshcd_schedule_eh_work(hba); spin_unlock_irqrestore(host->host_lock, flags); + + ufshcd_schedule_eh(hba); + goto release; } @@ -7136,11 +7154,10 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) spin_lock_irqsave(hba->host->host_lock, flags); hba->force_reset = true; - ufshcd_schedule_eh_work(hba); dev_err(hba->dev, "%s: reset in progress - 1\n", __func__); spin_unlock_irqrestore(hba->host->host_lock, flags); - flush_work(&hba->eh_work); + ufshcd_err_handler(hba->host); spin_lock_irqsave(hba->host->host_lock, flags); if (hba->ufshcd_state == UFSHCD_STATE_ERROR) @@ -8528,8 +8545,6 @@ static void ufshcd_hba_exit(struct ufs_hba *hba) if (hba->is_powered) { ufshcd_exit_clk_scaling(hba); ufshcd_exit_clk_gating(hba); - if (hba->eh_wq) - destroy_workqueue(hba->eh_wq); ufs_debugfs_hba_exit(hba); ufshcd_variant_hba_exit(hba); ufshcd_setup_vreg(hba, false); @@ -9374,6 +9389,10 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba) return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32)); } +static struct scsi_transport_template ufshcd_transport_template = { + .eh_strategy_handler = ufshcd_err_handler, +}; + /** * ufshcd_alloc_host - allocate Host Bus Adapter (HBA) * @dev: pointer to device handle @@ -9400,6 +9419,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) err = -ENOMEM; goto out_error; } + host->transportt = &ufshcd_transport_template; hba = shost_priv(host); hba->host = host; hba->dev = dev; @@ -9438,7 +9458,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) int err; struct Scsi_Host *host = hba->host; struct device *dev = hba->dev; - char eh_wq_name[sizeof("ufs_eh_wq_00")]; if (!mmio_base) { dev_err(hba->dev, @@ -9492,17 +9511,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) hba->max_pwr_info.is_valid = false; - /* Initialize work queues */ - snprintf(eh_wq_name, sizeof(eh_wq_name), "ufs_eh_wq_%d", - hba->host->host_no); - hba->eh_wq = create_singlethread_workqueue(eh_wq_name); - if (!hba->eh_wq) { - dev_err(hba->dev, "%s: failed to create eh workqueue\n", - __func__); - err = -ENOMEM; - goto out_disable; - } - INIT_WORK(&hba->eh_work, ufshcd_err_handler); INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); sema_init(&hba->host_sem, 1); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 963a3810f89a..52ea6f350b18 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -741,8 +741,6 @@ struct ufs_hba_monitor { * @is_powered: flag to check if HBA is powered * @shutting_down: flag to check if shutdown has been invoked * @host_sem: semaphore used to serialize concurrent contexts - * @eh_wq: Workqueue that eh_work works on - * @eh_work: Worker to handle UFS errors that require s/w attention * @eeh_work: Worker to handle exception events * @errors: HBA errors * @uic_error: UFS interconnect layer error status @@ -845,8 +843,6 @@ struct ufs_hba { struct semaphore host_sem; /* Work Queues */ - struct workqueue_struct *eh_wq; - struct work_struct eh_work; struct work_struct eeh_work; /* HBA Errors */ -- cgit v1.2.3-70-g09d2 From 73dc3c4ac703c6fea4b40e8ed1ddd80564da3dea Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:38 -0700 Subject: scsi: ufs: Retry aborted SCSI commands instead of completing these successfully Neither SAM nor the UFS standard require that the UFS controller fills in the completion status of commands that have been aborted (LUN RESET aborts pending commands). Hence do not rely on the completion status provided by the UFS controller for aborted commands but instead ask the SCSI core to retry SCSI commands that have been aborted. Link: https://lore.kernel.org/r/20210722033439.26550-18-bvanassche@acm.org Cc: Adrian Hunter Cc: Stanley Chu Cc: Can Guo Cc: Asutosh Das Cc: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 570efb6df6af..49cbb0375526 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5243,10 +5243,12 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) /** * __ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance - * @completed_reqs: requests to complete + * @completed_reqs: bitmask that indicates which requests to complete + * @retry_requests: whether to ask the SCSI core to retry completed requests */ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, - unsigned long completed_reqs) + unsigned long completed_reqs, + bool retry_requests) { struct ufshcd_lrb *lrbp; struct scsi_cmnd *cmd; @@ -5262,7 +5264,8 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) ufshcd_update_monitor(hba, lrbp); ufshcd_add_command_trace(hba, index, UFS_CMD_COMP); - result = ufshcd_transfer_rsp_status(hba, lrbp); + result = retry_requests ? DID_BUS_BUSY << 16 : + ufshcd_transfer_rsp_status(hba, lrbp); scsi_dma_unmap(cmd); cmd->result = result; /* Mark completed command as NULL in LRB */ @@ -5288,12 +5291,14 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, /** * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance + * @retry_requests: whether or not to ask to retry requests * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) +static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba, + bool retry_requests) { unsigned long completed_reqs, flags; u32 tr_doorbell; @@ -5319,7 +5324,8 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) spin_unlock_irqrestore(&hba->outstanding_lock, flags); if (completed_reqs) { - __ufshcd_transfer_req_compl(hba, completed_reqs); + __ufshcd_transfer_req_compl(hba, completed_reqs, + retry_requests); return IRQ_HANDLED; } else { return IRQ_NONE; @@ -5798,7 +5804,13 @@ out: /* Complete requests that have door-bell cleared */ static void ufshcd_complete_requests(struct ufs_hba *hba) { - ufshcd_transfer_req_compl(hba); + ufshcd_transfer_req_compl(hba, /*retry_requests=*/false); + ufshcd_tmc_handler(hba); +} + +static void ufshcd_retry_aborted_requests(struct ufs_hba *hba) +{ + ufshcd_transfer_req_compl(hba, /*retry_requests=*/true); ufshcd_tmc_handler(hba); } @@ -6118,8 +6130,7 @@ static void ufshcd_err_handler(struct Scsi_Host *host) } lock_skip_pending_xfer_clear: - /* Complete the requests that are cleared by s/w */ - ufshcd_complete_requests(hba); + ufshcd_retry_aborted_requests(hba); spin_lock_irqsave(hba->host->host_lock, flags); hba->silence_err_logs = false; @@ -6420,7 +6431,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) retval |= ufshcd_tmc_handler(hba); if (intr_status & UTP_TRANSFER_REQ_COMPL) - retval |= ufshcd_transfer_req_compl(hba); + retval |= ufshcd_transfer_req_compl(hba, /*retry_requests=*/false); return retval; } @@ -6839,7 +6850,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) err = ufshcd_clear_cmd(hba, pos); if (err) break; - __ufshcd_transfer_req_compl(hba, pos); + __ufshcd_transfer_req_compl(hba, pos, /*retry_requests=*/true); } } @@ -7001,7 +7012,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) dev_err(hba->dev, "%s: cmd was completed, but without a notifying intr, tag = %d", __func__, tag); - __ufshcd_transfer_req_compl(hba, 1UL << tag); + __ufshcd_transfer_req_compl(hba, 1UL << tag, /*retry_requests=*/false); goto release; } @@ -7069,7 +7080,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) ufshpb_reset_host(hba); ufshcd_hba_stop(hba); hba->silence_err_logs = true; - ufshcd_complete_requests(hba); + ufshcd_retry_aborted_requests(hba); hba->silence_err_logs = false; /* scale up clocks to max frequency before full reinitialization */ -- cgit v1.2.3-70-g09d2 From 52ac8b358b0cb7e91c966225fca61be5d1c984bc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 27 May 2021 08:09:15 -0400 Subject: KVM: Block memslot updates across range_start() and range_end() We would like to avoid taking mmu_lock for .invalidate_range_{start,end}() notifications that are unrelated to KVM. Because mmu_notifier_count must be modified while holding mmu_lock for write, and must always be paired across start->end to stay balanced, lock elision must happen in both or none. Therefore, in preparation for this change, this patch prevents memslot updates across range_start() and range_end(). Note, technically flag-only memslot updates could be allowed in parallel, but stalling a memslot update for a relatively short amount of time is not a scalability issue, and this is all more than complex enough. A long note on the locking: a previous version of the patch used an rwsem to block the memslot update while the MMU notifier run, but this resulted in the following deadlock involving the pseudo-lock tagged as "mmu_notifier_invalidate_range_start". ====================================================== WARNING: possible circular locking dependency detected 5.12.0-rc3+ #6 Tainted: G OE ------------------------------------------------------ qemu-system-x86/3069 is trying to acquire lock: ffffffff9c775ca0 (mmu_notifier_invalidate_range_start){+.+.}-{0:0}, at: __mmu_notifier_invalidate_range_end+0x5/0x190 but task is already holding lock: ffffaff7410a9160 (&kvm->mmu_notifier_slots_lock){.+.+}-{3:3}, at: kvm_mmu_notifier_invalidate_range_start+0x36d/0x4f0 [kvm] which lock already depends on the new lock. This corresponds to the following MMU notifier logic: invalidate_range_start take pseudo lock down_read() (*) release pseudo lock invalidate_range_end take pseudo lock (**) up_read() release pseudo lock At point (*) we take the mmu_notifiers_slots_lock inside the pseudo lock; at point (**) we take the pseudo lock inside the mmu_notifiers_slots_lock. This could cause a deadlock (ignoring for a second that the pseudo lock is not a lock): - invalidate_range_start waits on down_read(), because the rwsem is held by install_new_memslots - install_new_memslots waits on down_write(), because the rwsem is held till (another) invalidate_range_end finishes - invalidate_range_end sits waits on the pseudo lock, held by invalidate_range_start. Removing the fairness of the rwsem breaks the cycle (in lockdep terms, it would change the *shared* rwsem readers into *shared recursive* readers), so open-code the wait using a readers count and a spinlock. This also allows handling blockable and non-blockable critical section in the same way. Losing the rwsem fairness does theoretically allow MMU notifiers to block install_new_memslots forever. Note that mm/mmu_notifier.c's own retry scheme in mmu_interval_read_begin also uses wait/wake_up and is likewise not fair. Signed-off-by: Paolo Bonzini --- Documentation/virt/kvm/locking.rst | 6 ++++ include/linux/kvm_host.h | 5 ++++ virt/kvm/kvm_main.c | 58 +++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst index 35eca377543d..8138201efb09 100644 --- a/Documentation/virt/kvm/locking.rst +++ b/Documentation/virt/kvm/locking.rst @@ -21,6 +21,12 @@ The acquisition orders for mutexes are as follows: can be taken inside a kvm->srcu read-side critical section, while kvm->slots_lock cannot. +- kvm->mn_active_invalidate_count ensures that pairs of + invalidate_range_start() and invalidate_range_end() callbacks + use the same memslots array. kvm->slots_lock and kvm->slots_arch_lock + are taken on the waiting side in install_new_memslots, so MMU notifiers + must not take either kvm->slots_lock or kvm->slots_arch_lock. + On x86: - vcpu->mutex is taken outside kvm->arch.hyperv.hv_lock diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index de58a0890b1a..5b6a69caccb5 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -548,6 +548,11 @@ struct kvm { struct kvm_memslots __rcu *memslots[KVM_ADDRESS_SPACE_NUM]; struct kvm_vcpu *vcpus[KVM_MAX_VCPUS]; + /* Used to wait for completion of MMU notifiers. */ + spinlock_t mn_invalidate_lock; + unsigned long mn_active_invalidate_count; + struct rcuwait mn_memslots_update_rcuwait; + /* * created_vcpus is protected by kvm->lock, and is incremented * at the beginning of KVM_CREATE_VCPU. online_vcpus is only diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 5cc79373827f..8f9024d65866 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -604,11 +604,9 @@ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn, trace_kvm_set_spte_hva(address); /* - * .change_pte() must be surrounded by .invalidate_range_{start,end}(), - * and so always runs with an elevated notifier count. This obviates - * the need to bump the sequence count. + * .change_pte() must be surrounded by .invalidate_range_{start,end}(). */ - WARN_ON_ONCE(!kvm->mmu_notifier_count); + WARN_ON_ONCE(!READ_ONCE(kvm->mn_active_invalidate_count)); kvm_handle_hva_range(mn, address, address + 1, pte, kvm_set_spte_gfn); } @@ -658,6 +656,18 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, trace_kvm_unmap_hva_range(range->start, range->end); + /* + * Prevent memslot modification between range_start() and range_end() + * so that conditionally locking provides the same result in both + * functions. Without that guarantee, the mmu_notifier_count + * adjustments will be imbalanced. + * + * Pairs with the decrement in range_end(). + */ + spin_lock(&kvm->mn_invalidate_lock); + kvm->mn_active_invalidate_count++; + spin_unlock(&kvm->mn_invalidate_lock); + __kvm_handle_hva_range(kvm, &hva_range); return 0; @@ -694,9 +704,22 @@ static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn, .flush_on_ret = false, .may_block = mmu_notifier_range_blockable(range), }; + bool wake; __kvm_handle_hva_range(kvm, &hva_range); + /* Pairs with the increment in range_start(). */ + spin_lock(&kvm->mn_invalidate_lock); + wake = (--kvm->mn_active_invalidate_count == 0); + spin_unlock(&kvm->mn_invalidate_lock); + + /* + * There can only be one waiter, since the wait happens under + * slots_lock. + */ + if (wake) + rcuwait_wake_up(&kvm->mn_memslots_update_rcuwait); + BUG_ON(kvm->mmu_notifier_count < 0); } @@ -977,6 +1000,9 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(&kvm->irq_lock); mutex_init(&kvm->slots_lock); mutex_init(&kvm->slots_arch_lock); + spin_lock_init(&kvm->mn_invalidate_lock); + rcuwait_init(&kvm->mn_memslots_update_rcuwait); + INIT_LIST_HEAD(&kvm->devices); BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); @@ -1099,6 +1125,16 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm_coalesced_mmio_free(kvm); #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); + /* + * At this point, pending calls to invalidate_range_start() + * have completed but no more MMU notifiers will run, so + * mn_active_invalidate_count may remain unbalanced. + * No threads can be waiting in install_new_memslots as the + * last reference on KVM has been dropped, but freeing + * memslots would deadlock without this manual intervention. + */ + WARN_ON(rcuwait_active(&kvm->mn_memslots_update_rcuwait)); + kvm->mn_active_invalidate_count = 0; #else kvm_arch_flush_shadow_all(kvm); #endif @@ -1360,7 +1396,21 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, WARN_ON(gen & KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS); slots->generation = gen | KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS; + /* + * Do not store the new memslots while there are invalidations in + * progress (preparatory change for the next commit). + */ + spin_lock(&kvm->mn_invalidate_lock); + prepare_to_rcuwait(&kvm->mn_memslots_update_rcuwait); + while (kvm->mn_active_invalidate_count) { + set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock(&kvm->mn_invalidate_lock); + schedule(); + spin_lock(&kvm->mn_invalidate_lock); + } + finish_rcuwait(&kvm->mn_memslots_update_rcuwait); rcu_assign_pointer(kvm->memslots[as_id], slots); + spin_unlock(&kvm->mn_invalidate_lock); /* * Acquired in kvm_set_memslot. Must be released before synchronize -- cgit v1.2.3-70-g09d2 From ab09511fb69bdd4c4767053d7766f4bb9d6e36ec Mon Sep 17 00:00:00 2001 From: satya priya Date: Fri, 23 Jul 2021 14:01:12 +0530 Subject: dt-bindings: mfd: pm8008: Add gpio-ranges and spmi-gpio compatible Add gpio-ranges and "qcom,spmi-gpio" compatible to match with the parent qcom,pmic-gpio.yaml binding. Signed-off-by: satya priya Reviewed-by: Rob Herring Reviewed-by: Bjorn Andersson Reviewed-by: Guru Das Srinagesh Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/qcom,pm8008.yaml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/qcom,pm8008.yaml b/Documentation/devicetree/bindings/mfd/qcom,pm8008.yaml index 779936850ee0..ec3138c1bbfc 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,pm8008.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,pm8008.yaml @@ -53,7 +53,9 @@ patternProperties: properties: compatible: - const: qcom,pm8008-gpio + items: + - const: qcom,pm8008-gpio + - const: qcom,spmi-gpio reg: description: Peripheral address of one of the two GPIO peripherals. @@ -61,6 +63,9 @@ patternProperties: gpio-controller: true + gpio-ranges: + maxItems: 1 + interrupt-controller: true "#interrupt-cells": @@ -75,6 +80,7 @@ patternProperties: - gpio-controller - interrupt-controller - "#gpio-cells" + - gpio-ranges - "#interrupt-cells" additionalProperties: false @@ -107,10 +113,11 @@ examples: interrupt-parent = <&tlmm>; interrupts = <32 IRQ_TYPE_EDGE_RISING>; - gpio@c000 { - compatible = "qcom,pm8008-gpio"; + pm8008_gpios: gpio@c000 { + compatible = "qcom,pm8008-gpio", "qcom,spmi-gpio"; reg = <0xc000>; gpio-controller; + gpio-ranges = <&pm8008_gpios 0 0 2>; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; -- cgit v1.2.3-70-g09d2 From 071064f14d87536e38235df1bdeabe404023203f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 3 Aug 2021 03:45:41 -0400 Subject: KVM: Don't take mmu_lock for range invalidation unless necessary Avoid taking mmu_lock for .invalidate_range_{start,end}() notifications that are unrelated to KVM. This is possible now that memslot updates are blocked from range_start() to range_end(); that ensures that lock elision happens in both or none, and therefore that mmu_notifier_count updates (which must occur while holding mmu_lock for write) are always paired across start->end. Based on patches originally written by Ben Gardon. Signed-off-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 8f9024d65866..930aeb8d3c3e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -496,17 +496,6 @@ static __always_inline int __kvm_handle_hva_range(struct kvm *kvm, idx = srcu_read_lock(&kvm->srcu); - /* The on_lock() path does not yet support lock elision. */ - if (!IS_KVM_NULL_FN(range->on_lock)) { - locked = true; - KVM_MMU_LOCK(kvm); - - range->on_lock(kvm, range->start, range->end); - - if (IS_KVM_NULL_FN(range->handler)) - goto out_unlock; - } - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { slots = __kvm_memslots(kvm, i); kvm_for_each_memslot(slot, slots) { @@ -538,6 +527,10 @@ static __always_inline int __kvm_handle_hva_range(struct kvm *kvm, if (!locked) { locked = true; KVM_MMU_LOCK(kvm); + if (!IS_KVM_NULL_FN(range->on_lock)) + range->on_lock(kvm, range->start, range->end); + if (IS_KVM_NULL_FN(range->handler)) + break; } ret |= range->handler(kvm, &gfn_range); } @@ -546,7 +539,6 @@ static __always_inline int __kvm_handle_hva_range(struct kvm *kvm, if (range->flush_on_ret && (ret || kvm->tlbs_dirty)) kvm_flush_remote_tlbs(kvm); -out_unlock: if (locked) KVM_MMU_UNLOCK(kvm); @@ -605,8 +597,14 @@ static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn, /* * .change_pte() must be surrounded by .invalidate_range_{start,end}(). + * If mmu_notifier_count is zero, then no in-progress invalidations, + * including this one, found a relevant memslot at start(); rechecking + * memslots here is unnecessary. Note, a false positive (count elevated + * by a different invalidation) is sub-optimal but functionally ok. */ WARN_ON_ONCE(!READ_ONCE(kvm->mn_active_invalidate_count)); + if (!READ_ONCE(kvm->mmu_notifier_count)) + return; kvm_handle_hva_range(mn, address, address + 1, pte, kvm_set_spte_gfn); } @@ -1398,7 +1396,8 @@ static struct kvm_memslots *install_new_memslots(struct kvm *kvm, /* * Do not store the new memslots while there are invalidations in - * progress (preparatory change for the next commit). + * progress, otherwise the locking in invalidate_range_start and + * invalidate_range_end will be unbalanced. */ spin_lock(&kvm->mn_invalidate_lock); prepare_to_rcuwait(&kvm->mn_memslots_update_rcuwait); -- cgit v1.2.3-70-g09d2 From 269e9552d208179bc14ea7f80a9e3e8ae97795a2 Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Mon, 12 Jul 2021 22:33:38 -0400 Subject: KVM: const-ify all relevant uses of struct kvm_memory_slot As alluded to in commit f36f3f2846b5 ("KVM: add "new" argument to kvm_arch_commit_memory_region"), a bunch of other places where struct kvm_memory_slot is used, needs to be refactored to preserve the "const"ness of struct kvm_memory_slot across-the-board. Signed-off-by: Hamza Mahfooz Message-Id: <20210713023338.57108-1-someguy@effective-light.com> [Do not touch body of slot_rmap_walk_init. - Paolo] Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 4 ++-- arch/x86/kvm/mmu/mmu.c | 42 ++++++++++++++++++++--------------------- arch/x86/kvm/mmu/mmu_internal.h | 4 ++-- arch/x86/kvm/mmu/tdp_mmu.c | 7 ++++--- arch/x86/kvm/mmu/tdp_mmu.h | 6 +++--- arch/x86/kvm/x86.c | 7 ++----- 6 files changed, 34 insertions(+), 36 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ec8e4aca69c8..99f37781a6fc 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1537,12 +1537,12 @@ void kvm_mmu_uninit_vm(struct kvm *kvm); void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu); void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, - struct kvm_memory_slot *memslot, + const struct kvm_memory_slot *memslot, int start_level); void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, const struct kvm_memory_slot *memslot); void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, - struct kvm_memory_slot *memslot); + const struct kvm_memory_slot *memslot); void kvm_mmu_zap_all(struct kvm *kvm); void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen); unsigned long kvm_mmu_calculate_default_mmu_pages(struct kvm *kvm); diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 29010abb659c..e702361b4409 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -794,7 +794,7 @@ static struct kvm_lpage_info *lpage_info_slot(gfn_t gfn, return &slot->arch.lpage_info[level - 2][idx]; } -static void update_gfn_disallow_lpage_count(struct kvm_memory_slot *slot, +static void update_gfn_disallow_lpage_count(const struct kvm_memory_slot *slot, gfn_t gfn, int count) { struct kvm_lpage_info *linfo; @@ -807,12 +807,12 @@ static void update_gfn_disallow_lpage_count(struct kvm_memory_slot *slot, } } -void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn) +void kvm_mmu_gfn_disallow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn) { update_gfn_disallow_lpage_count(slot, gfn, 1); } -void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn) +void kvm_mmu_gfn_allow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn) { update_gfn_disallow_lpage_count(slot, gfn, -1); } @@ -999,7 +999,7 @@ static void pte_list_remove(struct kvm_rmap_head *rmap_head, u64 *sptep) } static struct kvm_rmap_head *__gfn_to_rmap(gfn_t gfn, int level, - struct kvm_memory_slot *slot) + const struct kvm_memory_slot *slot) { unsigned long idx; @@ -1228,7 +1228,7 @@ static bool spte_wrprot_for_clear_dirty(u64 *sptep) * Returns true iff any D or W bits were cleared. */ static bool __rmap_clear_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head, - struct kvm_memory_slot *slot) + const struct kvm_memory_slot *slot) { u64 *sptep; struct rmap_iterator iter; @@ -1387,7 +1387,7 @@ static bool rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) } static bool kvm_zap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, - struct kvm_memory_slot *slot) + const struct kvm_memory_slot *slot) { u64 *sptep; struct rmap_iterator iter; @@ -1452,7 +1452,7 @@ restart: struct slot_rmap_walk_iterator { /* input fields. */ - struct kvm_memory_slot *slot; + const struct kvm_memory_slot *slot; gfn_t start_gfn; gfn_t end_gfn; int start_level; @@ -1479,7 +1479,7 @@ rmap_walk_init_level(struct slot_rmap_walk_iterator *iterator, int level) static void slot_rmap_walk_init(struct slot_rmap_walk_iterator *iterator, - struct kvm_memory_slot *slot, int start_level, + const struct kvm_memory_slot *slot, int start_level, int end_level, gfn_t start_gfn, gfn_t end_gfn) { iterator->slot = slot; @@ -5313,12 +5313,13 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_max_root_level, EXPORT_SYMBOL_GPL(kvm_configure_mmu); /* The return value indicates if tlb flush on all vcpus is needed. */ -typedef bool (*slot_level_handler) (struct kvm *kvm, struct kvm_rmap_head *rmap_head, - struct kvm_memory_slot *slot); +typedef bool (*slot_level_handler) (struct kvm *kvm, + struct kvm_rmap_head *rmap_head, + const struct kvm_memory_slot *slot); /* The caller should hold mmu-lock before calling this function. */ static __always_inline bool -slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot, +slot_handle_level_range(struct kvm *kvm, const struct kvm_memory_slot *memslot, slot_level_handler fn, int start_level, int end_level, gfn_t start_gfn, gfn_t end_gfn, bool flush_on_yield, bool flush) @@ -5345,7 +5346,7 @@ slot_handle_level_range(struct kvm *kvm, struct kvm_memory_slot *memslot, } static __always_inline bool -slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot, +slot_handle_level(struct kvm *kvm, const struct kvm_memory_slot *memslot, slot_level_handler fn, int start_level, int end_level, bool flush_on_yield) { @@ -5356,7 +5357,7 @@ slot_handle_level(struct kvm *kvm, struct kvm_memory_slot *memslot, } static __always_inline bool -slot_handle_leaf(struct kvm *kvm, struct kvm_memory_slot *memslot, +slot_handle_leaf(struct kvm *kvm, const struct kvm_memory_slot *memslot, slot_level_handler fn, bool flush_on_yield) { return slot_handle_level(kvm, memslot, fn, PG_LEVEL_4K, @@ -5615,7 +5616,8 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) if (start >= end) continue; - flush = slot_handle_level_range(kvm, memslot, + flush = slot_handle_level_range(kvm, + (const struct kvm_memory_slot *) memslot, kvm_zap_rmapp, PG_LEVEL_4K, KVM_MAX_HUGEPAGE_LEVEL, start, end - 1, true, flush); @@ -5643,13 +5645,13 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) static bool slot_rmap_write_protect(struct kvm *kvm, struct kvm_rmap_head *rmap_head, - struct kvm_memory_slot *slot) + const struct kvm_memory_slot *slot) { return __rmap_write_protect(kvm, rmap_head, false); } void kvm_mmu_slot_remove_write_access(struct kvm *kvm, - struct kvm_memory_slot *memslot, + const struct kvm_memory_slot *memslot, int start_level) { bool flush = false; @@ -5685,7 +5687,7 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, struct kvm_rmap_head *rmap_head, - struct kvm_memory_slot *slot) + const struct kvm_memory_slot *slot) { u64 *sptep; struct rmap_iterator iter; @@ -5724,10 +5726,8 @@ restart: } void kvm_mmu_zap_collapsible_sptes(struct kvm *kvm, - const struct kvm_memory_slot *memslot) + const struct kvm_memory_slot *slot) { - /* FIXME: const-ify all uses of struct kvm_memory_slot. */ - struct kvm_memory_slot *slot = (struct kvm_memory_slot *)memslot; bool flush = false; if (kvm_memslots_have_rmaps(kvm)) { @@ -5763,7 +5763,7 @@ void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm, } void kvm_mmu_slot_leaf_clear_dirty(struct kvm *kvm, - struct kvm_memory_slot *memslot) + const struct kvm_memory_slot *memslot) { bool flush = false; diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_internal.h index 626cb848dab4..ca7b7595bbfc 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -124,8 +124,8 @@ static inline bool is_nx_huge_page_enabled(void) int mmu_try_to_unsync_pages(struct kvm_vcpu *vcpu, gfn_t gfn, bool can_unsync); -void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); -void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn); +void kvm_mmu_gfn_disallow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn); +void kvm_mmu_gfn_allow_lpage(const struct kvm_memory_slot *slot, gfn_t gfn); bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, struct kvm_memory_slot *slot, u64 gfn, int min_level); diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 41cee1d22918..43f12f5d12c0 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -1246,8 +1246,8 @@ retry: * only affect leaf SPTEs down to min_level. * Returns true if an SPTE has been changed and the TLBs need to be flushed. */ -bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, - int min_level) +bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, + const struct kvm_memory_slot *slot, int min_level) { struct kvm_mmu_page *root; bool spte_set = false; @@ -1317,7 +1317,8 @@ retry: * each SPTE. Returns true if an SPTE has been changed and the TLBs need to * be flushed. */ -bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, struct kvm_memory_slot *slot) +bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, + const struct kvm_memory_slot *slot) { struct kvm_mmu_page *root; bool spte_set = false; diff --git a/arch/x86/kvm/mmu/tdp_mmu.h b/arch/x86/kvm/mmu/tdp_mmu.h index 361b47f98cc5..b224d126adf9 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.h +++ b/arch/x86/kvm/mmu/tdp_mmu.h @@ -61,10 +61,10 @@ bool kvm_tdp_mmu_age_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range); bool kvm_tdp_mmu_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range); bool kvm_tdp_mmu_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range); -bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, struct kvm_memory_slot *slot, - int min_level); +bool kvm_tdp_mmu_wrprot_slot(struct kvm *kvm, + const struct kvm_memory_slot *slot, int min_level); bool kvm_tdp_mmu_clear_dirty_slot(struct kvm *kvm, - struct kvm_memory_slot *slot); + const struct kvm_memory_slot *slot); void kvm_tdp_mmu_clear_dirty_pt_masked(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t gfn, unsigned long mask, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4d246b7f6ce1..348452bb16bc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11520,7 +11520,7 @@ static void kvm_mmu_update_cpu_dirty_logging(struct kvm *kvm, bool enable) static void kvm_mmu_slot_apply_flags(struct kvm *kvm, struct kvm_memory_slot *old, - struct kvm_memory_slot *new, + const struct kvm_memory_slot *new, enum kvm_mr_change change) { bool log_dirty_pages = new->flags & KVM_MEM_LOG_DIRTY_PAGES; @@ -11600,10 +11600,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, kvm_mmu_change_mmu_pages(kvm, kvm_mmu_calculate_default_mmu_pages(kvm)); - /* - * FIXME: const-ify all uses of struct kvm_memory_slot. - */ - kvm_mmu_slot_apply_flags(kvm, old, (struct kvm_memory_slot *) new, change); + kvm_mmu_slot_apply_flags(kvm, old, new, change); /* Free the arrays associated with the old memslot. */ if (change == KVM_MR_MOVE) -- cgit v1.2.3-70-g09d2 From ced75a2f5da71de5775fda44250e27d7b8024355 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Mon, 2 Aug 2021 15:26:39 +0200 Subject: MAINTAINERS: Add Luis Chamberlain as modules maintainer Luis has kindly agreed to help maintain the module loader. As my responsibilities have shifted, I've found myself with less cycles to devote to upstream maintenance these days. Luis is already very involved and engaged upstream, and with his experience maintaining the kmod module loader and usermode helper, I believe he is a great fit for this area of the kernel. Acked-by: Luis Chamberlain Signed-off-by: Jessica Yu --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..d2bdcc8dc25f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12526,6 +12526,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ F: drivers/media/dvb-frontends/mn88473* MODULE SUPPORT +M: Luis Chamberlain M: Jessica Yu S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next -- cgit v1.2.3-70-g09d2 From c11a1ae9b8f65ef7b82a5a1155581a6e6bafa375 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 21 Jul 2021 20:34:39 -0700 Subject: scsi: ufs: Add fault injection support Make it easier to test the UFS error handler and abort handler. Link: https://lore.kernel.org/r/20210722033439.26550-19-bvanassche@acm.org Acked-by: Bean Huo Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/Kconfig | 7 ++++ drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufs-fault-injection.c | 70 ++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-fault-injection.h | 24 ++++++++++++ drivers/scsi/ufs/ufshcd.c | 8 ++++ 5 files changed, 110 insertions(+) create mode 100644 drivers/scsi/ufs/ufs-fault-injection.c create mode 100644 drivers/scsi/ufs/ufs-fault-injection.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index ee650526c560..432df76e6318 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -192,3 +192,10 @@ config SCSI_UFS_HPB L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB read command by piggybacking physical page number for bypassing FTL (flash translation layer)'s L2P address translation. + +config SCSI_UFS_FAULT_INJECTION + bool "UFS Fault Injection Support" + depends on SCSI_UFSHCD && FAULT_INJECTION + help + Enable fault injection support in the UFS driver. This makes it easier + to test the UFS error handler and abort handler. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index cce9b3916f5b..c407da9b5171 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -9,6 +9,7 @@ ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o +ufshcd-core-$(CONFIG_SCSI_UFS_FAULT_INJECTION) += ufs-fault-injection.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/ufs-fault-injection.c b/drivers/scsi/ufs/ufs-fault-injection.c new file mode 100644 index 000000000000..7ac7c4e7ff83 --- /dev/null +++ b/drivers/scsi/ufs/ufs-fault-injection.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include "ufs-fault-injection.h" + +static int ufs_fault_get(char *buffer, const struct kernel_param *kp); +static int ufs_fault_set(const char *val, const struct kernel_param *kp); + +static const struct kernel_param_ops ufs_fault_ops = { + .get = ufs_fault_get, + .set = ufs_fault_set, +}; + +enum { FAULT_INJ_STR_SIZE = 80 }; + +/* + * For more details about fault injection, please refer to + * Documentation/fault-injection/fault-injection.rst. + */ +static char g_trigger_eh_str[FAULT_INJ_STR_SIZE]; +module_param_cb(trigger_eh, &ufs_fault_ops, g_trigger_eh_str, 0644); +MODULE_PARM_DESC(trigger_eh, + "Fault injection. trigger_eh=,,,"); +static DECLARE_FAULT_ATTR(ufs_trigger_eh_attr); + +static char g_timeout_str[FAULT_INJ_STR_SIZE]; +module_param_cb(timeout, &ufs_fault_ops, g_timeout_str, 0644); +MODULE_PARM_DESC(timeout, + "Fault injection. timeout=,,,"); +static DECLARE_FAULT_ATTR(ufs_timeout_attr); + +static int ufs_fault_get(char *buffer, const struct kernel_param *kp) +{ + const char *fault_str = kp->arg; + + return sysfs_emit(buffer, "%s\n", fault_str); +} + +static int ufs_fault_set(const char *val, const struct kernel_param *kp) +{ + struct fault_attr *attr = NULL; + + if (kp->arg == g_trigger_eh_str) + attr = &ufs_trigger_eh_attr; + else if (kp->arg == g_timeout_str) + attr = &ufs_timeout_attr; + + if (WARN_ON_ONCE(!attr)) + return -EINVAL; + + if (!setup_fault_attr(attr, (char *)val)) + return -EINVAL; + + strlcpy(kp->arg, val, FAULT_INJ_STR_SIZE); + + return 0; +} + +bool ufs_trigger_eh(void) +{ + return should_fail(&ufs_trigger_eh_attr, 1); +} + +bool ufs_fail_completion(void) +{ + return should_fail(&ufs_timeout_attr, 1); +} diff --git a/drivers/scsi/ufs/ufs-fault-injection.h b/drivers/scsi/ufs/ufs-fault-injection.h new file mode 100644 index 000000000000..6d0cd8e10c87 --- /dev/null +++ b/drivers/scsi/ufs/ufs-fault-injection.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _UFS_FAULT_INJECTION_H +#define _UFS_FAULT_INJECTION_H + +#include +#include + +#ifdef CONFIG_SCSI_UFS_FAULT_INJECTION +bool ufs_trigger_eh(void); +bool ufs_fail_completion(void); +#else +static inline bool ufs_trigger_eh(void) +{ + return false; +} + +static inline bool ufs_fail_completion(void) +{ + return false; +} +#endif + +#endif /* _UFS_FAULT_INJECTION_H */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 49cbb0375526..47a5085f16a9 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -24,6 +24,7 @@ #include "unipro.h" #include "ufs-sysfs.h" #include "ufs-debugfs.h" +#include "ufs-fault-injection.h" #include "ufs_bsg.h" #include "ufshcd-crypto.h" #include "ufshpb.h" @@ -2758,6 +2759,10 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ufshcd_send_command(hba, tag); out: up_read(&hba->clk_scaling_lock); + + if (ufs_trigger_eh()) + scsi_schedule_eh(hba->host); + return err; } @@ -5314,6 +5319,9 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba, !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); + if (ufs_fail_completion()) + return IRQ_HANDLED; + spin_lock_irqsave(&hba->outstanding_lock, flags); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = ~tr_doorbell & hba->outstanding_reqs; -- cgit v1.2.3-70-g09d2 From 018c14911dd7e2feedd96d440f12ea999e459fff Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Tue, 13 Jul 2021 19:50:21 +0200 Subject: scsi: target: tcmu: Add new feature KEEP_BUF When running command pipelining for WRITE direction commands (e.g. tape device write), userspace sends cmd completion to cmd ring before processing write data. In that case userspace has to copy data before sending completion, because cmd completion also implicitly releases the data buffer in data area. The new feature KEEP_BUF allows userspace to optionally keep the buffer after completion by setting new bit TCMU_UFLAG_KEEP_BUF in tcmu_cmd_entry_hdr->uflags. In that case buffer has to be released explicitly by writing the cmd_id to new action item free_kept_buf. All kept buffers are released during reset_ring and if userspace closes uio device (tcmu_release). Link: https://lore.kernel.org/r/20210713175021.20103-1-bostroesser@gmail.com Reviewed-by: Mike Christie Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 150 +++++++++++++++++++++++++++++++--- include/uapi/linux/target_core_user.h | 2 + 2 files changed, 141 insertions(+), 11 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index fbb6ffaddfbe..9f552f48084c 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -191,6 +191,7 @@ struct tcmu_cmd { unsigned long deadline; #define TCMU_CMD_BIT_EXPIRED 0 +#define TCMU_CMD_BIT_KEEP_BUF 1 unsigned long flags; }; @@ -1315,11 +1316,13 @@ unlock: mutex_unlock(&udev->cmdr_lock); } -static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *entry) +static bool tcmu_handle_completion(struct tcmu_cmd *cmd, + struct tcmu_cmd_entry *entry, bool keep_buf) { struct se_cmd *se_cmd = cmd->se_cmd; struct tcmu_dev *udev = cmd->tcmu_dev; bool read_len_valid = false; + bool ret = true; uint32_t read_len; /* @@ -1330,6 +1333,13 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * WARN_ON_ONCE(se_cmd); goto out; } + if (test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags)) { + pr_err("cmd_id %u already completed with KEEP_BUF, ring is broken\n", + entry->hdr.cmd_id); + set_bit(TCMU_DEV_BIT_BROKEN, &udev->flags); + ret = false; + goto out; + } list_del_init(&cmd->queue_entry); @@ -1379,8 +1389,22 @@ done: target_complete_cmd(cmd->se_cmd, entry->rsp.scsi_status); out: - tcmu_cmd_free_data(cmd, cmd->dbi_cnt); - tcmu_free_cmd(cmd); + if (!keep_buf) { + tcmu_cmd_free_data(cmd, cmd->dbi_cnt); + tcmu_free_cmd(cmd); + } else { + /* + * Keep this command after completion, since userspace still + * needs the data buffer. Mark it with TCMU_CMD_BIT_KEEP_BUF + * and reset potential TCMU_CMD_BIT_EXPIRED, so we don't accept + * a second completion later. + * Userspace can free the buffer later by writing the cmd_id + * to new action attribute free_kept_buf. + */ + clear_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags); + set_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags); + } + return ret; } static int tcmu_run_tmr_queue(struct tcmu_dev *udev) @@ -1432,6 +1456,7 @@ static bool tcmu_handle_completions(struct tcmu_dev *udev) while (udev->cmdr_last_cleaned != READ_ONCE(mb->cmd_tail)) { struct tcmu_cmd_entry *entry = udev->cmdr + udev->cmdr_last_cleaned; + bool keep_buf; /* * Flush max. up to end of cmd ring since current entry might @@ -1453,7 +1478,11 @@ static bool tcmu_handle_completions(struct tcmu_dev *udev) } WARN_ON(tcmu_hdr_get_op(entry->hdr.len_op) != TCMU_OP_CMD); - cmd = xa_erase(&udev->commands, entry->hdr.cmd_id); + keep_buf = !!(entry->hdr.uflags & TCMU_UFLAG_KEEP_BUF); + if (keep_buf) + cmd = xa_load(&udev->commands, entry->hdr.cmd_id); + else + cmd = xa_erase(&udev->commands, entry->hdr.cmd_id); if (!cmd) { pr_err("cmd_id %u not found, ring is broken\n", entry->hdr.cmd_id); @@ -1461,7 +1490,8 @@ static bool tcmu_handle_completions(struct tcmu_dev *udev) return false; } - tcmu_handle_completion(cmd, entry); + if (!tcmu_handle_completion(cmd, entry, keep_buf)) + break; UPDATE_HEAD(udev->cmdr_last_cleaned, tcmu_hdr_get_len(entry->hdr.len_op), @@ -1619,7 +1649,8 @@ static void tcmu_dev_call_rcu(struct rcu_head *p) static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd) { - if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) { + if (test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags) || + test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags)) { kmem_cache_free(tcmu_cmd_cache, cmd); return 0; } @@ -1903,6 +1934,38 @@ static int tcmu_open(struct uio_info *info, struct inode *inode) static int tcmu_release(struct uio_info *info, struct inode *inode) { struct tcmu_dev *udev = container_of(info, struct tcmu_dev, uio_info); + struct tcmu_cmd *cmd; + unsigned long i; + bool freed = false; + + mutex_lock(&udev->cmdr_lock); + + xa_for_each(&udev->commands, i, cmd) { + /* Cmds with KEEP_BUF set are no longer on the ring, but + * userspace still holds the data buffer. If userspace closes + * we implicitly free these cmds and buffers, since after new + * open the (new ?) userspace cannot find the cmd in the ring + * and thus never will release the buffer by writing cmd_id to + * free_kept_buf action attribute. + */ + if (!test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags)) + continue; + pr_debug("removing KEEP_BUF cmd %u on dev %s from ring\n", + cmd->cmd_id, udev->name); + freed = true; + + xa_erase(&udev->commands, i); + tcmu_cmd_free_data(cmd, cmd->dbi_cnt); + tcmu_free_cmd(cmd); + } + /* + * We only freed data space, not ring space. Therefore we dont call + * run_tmr_queue, but call run_qfull_queue if tmr_list is empty. + */ + if (freed && list_empty(&udev->tmr_queue)) + run_qfull_queue(udev, false); + + mutex_unlock(&udev->cmdr_lock); clear_bit(TCMU_DEV_BIT_OPEN, &udev->flags); @@ -2147,7 +2210,8 @@ static int tcmu_configure_device(struct se_device *dev) mb->version = TCMU_MAILBOX_VERSION; mb->flags = TCMU_MAILBOX_FLAG_CAP_OOOC | TCMU_MAILBOX_FLAG_CAP_READ_LEN | - TCMU_MAILBOX_FLAG_CAP_TMR; + TCMU_MAILBOX_FLAG_CAP_TMR | + TCMU_MAILBOX_FLAG_CAP_KEEP_BUF; mb->cmdr_off = CMDR_OFF; mb->cmdr_size = udev->cmdr_size; @@ -2279,12 +2343,16 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level) mutex_lock(&udev->cmdr_lock); xa_for_each(&udev->commands, i, cmd) { - pr_debug("removing cmd %u on dev %s from ring (is expired %d)\n", - cmd->cmd_id, udev->name, - test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)); + pr_debug("removing cmd %u on dev %s from ring %s\n", + cmd->cmd_id, udev->name, + test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags) ? + "(is expired)" : + (test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags) ? + "(is keep buffer)" : "")); xa_erase(&udev->commands, i); - if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) { + if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags) && + !test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags)) { WARN_ON(!cmd->se_cmd); list_del_init(&cmd->queue_entry); cmd->se_cmd->priv = NULL; @@ -2933,6 +3001,65 @@ static ssize_t tcmu_reset_ring_store(struct config_item *item, const char *page, } CONFIGFS_ATTR_WO(tcmu_, reset_ring); +static ssize_t tcmu_free_kept_buf_store(struct config_item *item, const char *page, + size_t count) +{ + struct se_device *se_dev = container_of(to_config_group(item), + struct se_device, + dev_action_group); + struct tcmu_dev *udev = TCMU_DEV(se_dev); + struct tcmu_cmd *cmd; + u16 cmd_id; + int ret; + + if (!target_dev_configured(&udev->se_dev)) { + pr_err("Device is not configured.\n"); + return -EINVAL; + } + + ret = kstrtou16(page, 0, &cmd_id); + if (ret < 0) + return ret; + + mutex_lock(&udev->cmdr_lock); + + { + XA_STATE(xas, &udev->commands, cmd_id); + + xas_lock(&xas); + cmd = xas_load(&xas); + if (!cmd) { + pr_err("free_kept_buf: cmd_id %d not found\n", cmd_id); + count = -EINVAL; + xas_unlock(&xas); + goto out_unlock; + } + if (!test_bit(TCMU_CMD_BIT_KEEP_BUF, &cmd->flags)) { + pr_err("free_kept_buf: cmd_id %d was not completed with KEEP_BUF\n", + cmd_id); + count = -EINVAL; + xas_unlock(&xas); + goto out_unlock; + } + xas_store(&xas, NULL); + xas_unlock(&xas); + } + + tcmu_cmd_free_data(cmd, cmd->dbi_cnt); + tcmu_free_cmd(cmd); + /* + * We only freed data space, not ring space. Therefore we dont call + * run_tmr_queue, but call run_qfull_queue if tmr_list is empty. + */ + if (list_empty(&udev->tmr_queue)) + run_qfull_queue(udev, false); + +out_unlock: + mutex_unlock(&udev->cmdr_lock); + return count; +} +CONFIGFS_ATTR_WO(tcmu_, free_kept_buf); + static struct configfs_attribute *tcmu_attrib_attrs[] = { &tcmu_attr_cmd_time_out, &tcmu_attr_qfull_time_out, @@ -2951,6 +3078,7 @@ static struct configfs_attribute **tcmu_attrs; static struct configfs_attribute *tcmu_action_attrs[] = { &tcmu_attr_block_dev, &tcmu_attr_reset_ring, + &tcmu_attr_free_kept_buf, NULL, }; diff --git a/include/uapi/linux/target_core_user.h b/include/uapi/linux/target_core_user.h index 95b1597f16ae..27ace512babd 100644 --- a/include/uapi/linux/target_core_user.h +++ b/include/uapi/linux/target_core_user.h @@ -46,6 +46,7 @@ #define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0) /* Out-of-order completions */ #define TCMU_MAILBOX_FLAG_CAP_READ_LEN (1 << 1) /* Read data length */ #define TCMU_MAILBOX_FLAG_CAP_TMR (1 << 2) /* TMR notifications */ +#define TCMU_MAILBOX_FLAG_CAP_KEEP_BUF (1<<3) /* Keep buf after cmd completion */ struct tcmu_mailbox { __u16 version; @@ -75,6 +76,7 @@ struct tcmu_cmd_entry_hdr { __u8 kflags; #define TCMU_UFLAG_UNKNOWN_OP 0x1 #define TCMU_UFLAG_READ_LEN 0x2 +#define TCMU_UFLAG_KEEP_BUF 0x4 __u8 uflags; } __packed; -- cgit v1.2.3-70-g09d2 From 7e457e5efc2856e10623e28047a4d8c92ef0aa69 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 28 Jul 2021 13:53:52 +0200 Subject: scsi: target: core: Avoid using lun_tg_pt_gp after unlock core_alua_state_lba_dependent() currently uses lun->lun_tg_pt_gp without holding the lun_tg_pt_gp_lock. The lock is taken in the caller, so obtain the needed tg_pt_gp_id there instead. Link: https://lore.kernel.org/r/20210728115353.2396-2-ddiss@suse.de Cc: Hannes Reinecke Reviewed-by: Mike Christie Signed-off-by: David Disseldorp Signed-off-by: Martin K. Petersen --- drivers/target/target_core_alua.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 3bb921345bce..e0036e72b351 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -460,7 +460,7 @@ static inline void core_alua_state_nonoptimized( static inline int core_alua_state_lba_dependent( struct se_cmd *cmd, - struct t10_alua_tg_pt_gp *tg_pt_gp) + u16 tg_pt_gp_id) { struct se_device *dev = cmd->se_dev; u64 segment_size, segment_mult, sectors, lba; @@ -511,8 +511,7 @@ static inline int core_alua_state_lba_dependent( } list_for_each_entry(map_mem, &cur_map->lba_map_mem_list, lba_map_mem_list) { - if (map_mem->lba_map_mem_alua_pg_id != - tg_pt_gp->tg_pt_gp_id) + if (map_mem->lba_map_mem_alua_pg_id != tg_pt_gp_id) continue; switch(map_mem->lba_map_mem_alua_state) { case ALUA_ACCESS_STATE_STANDBY: @@ -674,6 +673,7 @@ target_alua_state_check(struct se_cmd *cmd) struct se_lun *lun = cmd->se_lun; struct t10_alua_tg_pt_gp *tg_pt_gp; int out_alua_state, nonop_delay_msecs; + u16 tg_pt_gp_id; if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) return 0; @@ -698,8 +698,8 @@ target_alua_state_check(struct se_cmd *cmd) tg_pt_gp = lun->lun_tg_pt_gp; out_alua_state = tg_pt_gp->tg_pt_gp_alua_access_state; nonop_delay_msecs = tg_pt_gp->tg_pt_gp_nonop_delay_msecs; + tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id; - // XXX: keeps using tg_pt_gp witout reference after unlock spin_unlock(&lun->lun_tg_pt_gp_lock); /* * Process ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED in a separate conditional @@ -727,7 +727,7 @@ target_alua_state_check(struct se_cmd *cmd) return TCM_CHECK_CONDITION_NOT_READY; break; case ALUA_ACCESS_STATE_LBA_DEPENDENT: - if (core_alua_state_lba_dependent(cmd, tg_pt_gp)) + if (core_alua_state_lba_dependent(cmd, tg_pt_gp_id)) return TCM_CHECK_CONDITION_NOT_READY; break; /* -- cgit v1.2.3-70-g09d2 From 35410f86242694fde04ca3ff70c327755e067e6a Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 28 Jul 2021 13:53:53 +0200 Subject: scsi: target: sbp: Drop incorrect ASC/ASCQ usage The se_cmd scsi_asc and scsi_ascq members are only used for tracking ALUA SCSI sense detail between target_core_alua and translate_sense_reason(), so they're effectively always zero here. Link: https://lore.kernel.org/r/20210728115353.2396-3-ddiss@suse.de Cc: Chris Boot Reviewed-by: Mike Christie Signed-off-by: David Disseldorp Signed-off-by: Martin K. Petersen --- drivers/target/sbp/sbp_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 4d3ceee23622..b9f9fb5d7e63 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1389,8 +1389,8 @@ static void sbp_sense_mangle(struct sbp_target_request *req) (sense[0] & 0x80) | /* valid */ ((sense[2] & 0xe0) >> 1) | /* mark, eom, ili */ (sense[2] & 0x0f); /* sense_key */ - status[2] = se_cmd->scsi_asc; /* sense_code */ - status[3] = se_cmd->scsi_ascq; /* sense_qualifier */ + status[2] = 0; /* XXX sense_code */ + status[3] = 0; /* XXX sense_qualifier */ /* information */ status[4] = sense[3]; -- cgit v1.2.3-70-g09d2 From 40fd8845c025c33629e469f1383151096a21d524 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Wed, 28 Jul 2021 13:53:54 +0200 Subject: scsi: target: core: Drop unnecessary se_cmd ASC/ASCQ members These members are only used for ALUA sense detail propagation, which can just as easily be done via sense_reason_t. Link: https://lore.kernel.org/r/20210728115353.2396-4-ddiss@suse.de Reviewed-by: Mike Christie Signed-off-by: David Disseldorp Signed-off-by: Martin K. Petersen --- drivers/target/target_core_alua.c | 86 ++++++++++++---------------------- drivers/target/target_core_transport.c | 33 +++++++++---- include/target/target_core_base.h | 8 ++-- 3 files changed, 60 insertions(+), 67 deletions(-) diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index e0036e72b351..cb1de1ecaaa6 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -428,22 +428,6 @@ out: return rc; } -static inline void set_ascq(struct se_cmd *cmd, u8 alua_ascq) -{ - /* - * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; - * The ALUA additional sense code qualifier (ASCQ) is determined - * by the ALUA primary or secondary access state.. - */ - pr_debug("[%s]: ALUA TG Port not available, " - "SenseKey: NOT_READY, ASC/ASCQ: " - "0x04/0x%02x\n", - cmd->se_tfo->fabric_name, alua_ascq); - - cmd->scsi_asc = 0x04; - cmd->scsi_ascq = alua_ascq; -} - static inline void core_alua_state_nonoptimized( struct se_cmd *cmd, unsigned char *cdb, @@ -458,7 +442,7 @@ static inline void core_alua_state_nonoptimized( cmd->alua_nonop_delay = nonop_delay_msecs; } -static inline int core_alua_state_lba_dependent( +static inline sense_reason_t core_alua_state_lba_dependent( struct se_cmd *cmd, u16 tg_pt_gp_id) { @@ -506,8 +490,7 @@ static inline int core_alua_state_lba_dependent( } if (!cur_map) { spin_unlock(&dev->t10_alua.lba_map_lock); - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE); - return 1; + return TCM_ALUA_TG_PT_UNAVAILABLE; } list_for_each_entry(map_mem, &cur_map->lba_map_mem_list, lba_map_mem_list) { @@ -516,12 +499,10 @@ static inline int core_alua_state_lba_dependent( switch(map_mem->lba_map_mem_alua_state) { case ALUA_ACCESS_STATE_STANDBY: spin_unlock(&dev->t10_alua.lba_map_lock); - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); - return 1; + return TCM_ALUA_TG_PT_STANDBY; case ALUA_ACCESS_STATE_UNAVAILABLE: spin_unlock(&dev->t10_alua.lba_map_lock); - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE); - return 1; + return TCM_ALUA_TG_PT_UNAVAILABLE; default: break; } @@ -531,7 +512,7 @@ static inline int core_alua_state_lba_dependent( return 0; } -static inline int core_alua_state_standby( +static inline sense_reason_t core_alua_state_standby( struct se_cmd *cmd, unsigned char *cdb) { @@ -555,24 +536,21 @@ static inline int core_alua_state_standby( case SAI_READ_CAPACITY_16: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); - return 1; + return TCM_ALUA_TG_PT_STANDBY; } case MAINTENANCE_IN: switch (cdb[1] & 0x1f) { case MI_REPORT_TARGET_PGS: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); - return 1; + return TCM_ALUA_TG_PT_STANDBY; } case MAINTENANCE_OUT: switch (cdb[1]) { case MO_SET_TARGET_PGS: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); - return 1; + return TCM_ALUA_TG_PT_STANDBY; } case REQUEST_SENSE: case PERSISTENT_RESERVE_IN: @@ -581,14 +559,13 @@ static inline int core_alua_state_standby( case WRITE_BUFFER: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); - return 1; + return TCM_ALUA_TG_PT_STANDBY; } return 0; } -static inline int core_alua_state_unavailable( +static inline sense_reason_t core_alua_state_unavailable( struct se_cmd *cmd, unsigned char *cdb) { @@ -605,30 +582,27 @@ static inline int core_alua_state_unavailable( case MI_REPORT_TARGET_PGS: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE); - return 1; + return TCM_ALUA_TG_PT_UNAVAILABLE; } case MAINTENANCE_OUT: switch (cdb[1]) { case MO_SET_TARGET_PGS: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE); - return 1; + return TCM_ALUA_TG_PT_UNAVAILABLE; } case REQUEST_SENSE: case READ_BUFFER: case WRITE_BUFFER: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_UNAVAILABLE); - return 1; + return TCM_ALUA_TG_PT_UNAVAILABLE; } return 0; } -static inline int core_alua_state_transition( +static inline sense_reason_t core_alua_state_transition( struct se_cmd *cmd, unsigned char *cdb) { @@ -645,16 +619,14 @@ static inline int core_alua_state_transition( case MI_REPORT_TARGET_PGS: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_STATE_TRANSITION); - return 1; + return TCM_ALUA_STATE_TRANSITION; } case REQUEST_SENSE: case READ_BUFFER: case WRITE_BUFFER: return 0; default: - set_ascq(cmd, ASCQ_04H_ALUA_STATE_TRANSITION); - return 1; + return TCM_ALUA_STATE_TRANSITION; } return 0; @@ -674,6 +646,7 @@ target_alua_state_check(struct se_cmd *cmd) struct t10_alua_tg_pt_gp *tg_pt_gp; int out_alua_state, nonop_delay_msecs; u16 tg_pt_gp_id; + sense_reason_t rc = TCM_NO_SENSE; if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) return 0; @@ -687,8 +660,7 @@ target_alua_state_check(struct se_cmd *cmd) if (atomic_read(&lun->lun_tg_pt_secondary_offline)) { pr_debug("ALUA: Got secondary offline status for local" " target port\n"); - set_ascq(cmd, ASCQ_04H_ALUA_OFFLINE); - return TCM_CHECK_CONDITION_NOT_READY; + return TCM_ALUA_OFFLINE; } if (!lun->lun_tg_pt_gp) @@ -715,20 +687,16 @@ target_alua_state_check(struct se_cmd *cmd) core_alua_state_nonoptimized(cmd, cdb, nonop_delay_msecs); break; case ALUA_ACCESS_STATE_STANDBY: - if (core_alua_state_standby(cmd, cdb)) - return TCM_CHECK_CONDITION_NOT_READY; + rc = core_alua_state_standby(cmd, cdb); break; case ALUA_ACCESS_STATE_UNAVAILABLE: - if (core_alua_state_unavailable(cmd, cdb)) - return TCM_CHECK_CONDITION_NOT_READY; + rc = core_alua_state_unavailable(cmd, cdb); break; case ALUA_ACCESS_STATE_TRANSITION: - if (core_alua_state_transition(cmd, cdb)) - return TCM_CHECK_CONDITION_NOT_READY; + rc = core_alua_state_transition(cmd, cdb); break; case ALUA_ACCESS_STATE_LBA_DEPENDENT: - if (core_alua_state_lba_dependent(cmd, tg_pt_gp_id)) - return TCM_CHECK_CONDITION_NOT_READY; + rc = core_alua_state_lba_dependent(cmd, tg_pt_gp_id); break; /* * OFFLINE is a secondary ALUA target port group access state, that is @@ -738,10 +706,16 @@ target_alua_state_check(struct se_cmd *cmd) default: pr_err("Unknown ALUA access state: 0x%02x\n", out_alua_state); - return TCM_INVALID_CDB_FIELD; + rc = TCM_INVALID_CDB_FIELD; } - return 0; + if (rc && rc != TCM_INVALID_CDB_FIELD) { + pr_debug("[%s]: ALUA TG Port not available, " + "SenseKey: NOT_READY, ASC/rc: 0x04/%d\n", + cmd->se_tfo->fabric_name, rc); + } + + return rc; } /* diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 7e35eddd9eb7..065834480179 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2003,7 +2003,6 @@ void transport_generic_request_failure(struct se_cmd *cmd, case TCM_ADDRESS_OUT_OF_RANGE: case TCM_CHECK_CONDITION_ABORT_CMD: case TCM_CHECK_CONDITION_UNIT_ATTENTION: - case TCM_CHECK_CONDITION_NOT_READY: case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED: case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: @@ -2013,6 +2012,10 @@ void transport_generic_request_failure(struct se_cmd *cmd, case TCM_TOO_MANY_SEGMENT_DESCS: case TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE: case TCM_INVALID_FIELD_IN_COMMAND_IU: + case TCM_ALUA_TG_PT_STANDBY: + case TCM_ALUA_TG_PT_UNAVAILABLE: + case TCM_ALUA_STATE_TRANSITION: + case TCM_ALUA_OFFLINE: break; case TCM_OUT_OF_RESOURCES: cmd->scsi_status = SAM_STAT_TASK_SET_FULL; @@ -3277,9 +3280,6 @@ static const struct sense_detail sense_detail_table[] = { [TCM_CHECK_CONDITION_UNIT_ATTENTION] = { .key = UNIT_ATTENTION, }, - [TCM_CHECK_CONDITION_NOT_READY] = { - .key = NOT_READY, - }, [TCM_MISCOMPARE_VERIFY] = { .key = MISCOMPARE, .asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */ @@ -3340,6 +3340,26 @@ static const struct sense_detail sense_detail_table[] = { .asc = 0x0e, .ascq = 0x03, /* INVALID FIELD IN COMMAND INFORMATION UNIT */ }, + [TCM_ALUA_TG_PT_STANDBY] = { + .key = NOT_READY, + .asc = 0x04, + .ascq = ASCQ_04H_ALUA_TG_PT_STANDBY, + }, + [TCM_ALUA_TG_PT_UNAVAILABLE] = { + .key = NOT_READY, + .asc = 0x04, + .ascq = ASCQ_04H_ALUA_TG_PT_UNAVAILABLE, + }, + [TCM_ALUA_STATE_TRANSITION] = { + .key = NOT_READY, + .asc = 0x04, + .ascq = ASCQ_04H_ALUA_STATE_TRANSITION, + }, + [TCM_ALUA_OFFLINE] = { + .key = NOT_READY, + .asc = 0x04, + .ascq = ASCQ_04H_ALUA_OFFLINE, + }, }; /** @@ -3374,11 +3394,8 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) cmd->scsi_status = SAM_STAT_BUSY; return; } - } else if (sd->asc == 0) { - WARN_ON_ONCE(cmd->scsi_asc == 0); - asc = cmd->scsi_asc; - ascq = cmd->scsi_ascq; } else { + WARN_ON_ONCE(sd->asc == 0); asc = sd->asc; ascq = sd->ascq; } diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 85c16c266eac..f53e0f160695 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -171,7 +171,7 @@ enum tcm_sense_reason_table { TCM_WRITE_PROTECTED = R(0x0c), TCM_CHECK_CONDITION_ABORT_CMD = R(0x0d), TCM_CHECK_CONDITION_UNIT_ATTENTION = R(0x0e), - TCM_CHECK_CONDITION_NOT_READY = R(0x0f), + TCM_RESERVATION_CONFLICT = R(0x10), TCM_ADDRESS_OUT_OF_RANGE = R(0x11), TCM_OUT_OF_RESOURCES = R(0x12), @@ -188,6 +188,10 @@ enum tcm_sense_reason_table { TCM_INSUFFICIENT_REGISTRATION_RESOURCES = R(0x1d), TCM_LUN_BUSY = R(0x1e), TCM_INVALID_FIELD_IN_COMMAND_IU = R(0x1f), + TCM_ALUA_TG_PT_STANDBY = R(0x20), + TCM_ALUA_TG_PT_UNAVAILABLE = R(0x21), + TCM_ALUA_STATE_TRANSITION = R(0x22), + TCM_ALUA_OFFLINE = R(0x23), #undef R }; @@ -455,8 +459,6 @@ enum target_core_dif_check { struct se_cmd { /* SAM response code being sent to initiator */ u8 scsi_status; - u8 scsi_asc; - u8 scsi_ascq; u16 scsi_sense_length; unsigned unknown_data_length:1; bool state_active:1; -- cgit v1.2.3-70-g09d2 From 50741b70b0cbbafbd9199f5180e66c0c53783a4a Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Mon, 19 Jul 2021 12:03:18 +0530 Subject: cpuidle: pseries: Fixup CEDE0 latency only for POWER10 onwards Commit d947fb4c965c ("cpuidle: pseries: Fixup exit latency for CEDE(0)") sets the exit latency of CEDE(0) based on the latency values of the Extended CEDE states advertised by the platform On POWER9 LPARs, the firmwares advertise a very low value of 2us for CEDE1 exit latency on a Dedicated LPAR. The latency advertized by the PHYP hypervisor corresponds to the latency required to wakeup from the underlying hardware idle state. However the wakeup latency from the LPAR perspective should include 1. The time taken to transition the CPU from the Hypervisor into the LPAR post wakeup from platform idle state 2. Time taken to send the IPI from the source CPU (waker) to the idle target CPU (wakee). 1. can be measured via timer idle test, where we queue a timer, say for 1ms, and enter the CEDE state. When the timer fires, in the timer handler we compute how much extra timer over the expected 1ms have we consumed. On a a POWER9 LPAR the numbers are CEDE latency measured using a timer (numbers in ns) N Min Median Avg 90%ile 99%ile Max Stddev 400 2601 5677 5668.74 5917 6413 9299 455.01 1. and 2. combined can be determined by an IPI latency test where we send an IPI to an idle CPU and in the handler compute the time difference between when the IPI was sent and when the handler ran. We see the following numbers on POWER9 LPAR. CEDE latency measured using an IPI (numbers in ns) N Min Median Avg 90%ile 99%ile Max Stddev 400 711 7564 7369.43 8559 9514 9698 1200.01 Suppose, we consider the 99th percentile latency value measured using the IPI to be the wakeup latency, the value would be 9.5us This is in the ballpark of the default value of 10us. Hence, use the exit latency of CEDE(0) based on the latency values advertized by platform only from POWER10 onwards. The values advertized on POWER10 platforms is more realistic and informed by the latency measurements. For earlier platforms stick to the default value of 10us. The fix was suggested by Michael Ellerman. Fixes: d947fb4c965c ("cpuidle: pseries: Fixup exit latency for CEDE(0)") Reported-by: Enrico Joedecke Signed-off-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1626676399-15975-2-git-send-email-ego@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-pseries.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index a2b5c6f60cf0..e592280d8acf 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -419,7 +419,21 @@ static int pseries_idle_probe(void) cpuidle_state_table = shared_states; max_idle_state = ARRAY_SIZE(shared_states); } else { - fixup_cede0_latency(); + /* + * Use firmware provided latency values + * starting with POWER10 platforms. In the + * case that we are running on a POWER10 + * platform but in an earlier compat mode, we + * can still use the firmware provided values. + * + * However, on platforms prior to POWER10, we + * cannot rely on the accuracy of the firmware + * provided latency values. On such platforms, + * go with the conservative default estimate + * of 10us. + */ + if (cpu_has_feature(CPU_FTR_ARCH_31) || pvr_version_is(PVR_POWER10)) + fixup_cede0_latency(); cpuidle_state_table = dedicated_states; max_idle_state = NR_DEDICATED_STATES; } -- cgit v1.2.3-70-g09d2 From 71737a6c2a8f801622d2b71567d1ec1e4c5b40b8 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Mon, 19 Jul 2021 12:03:19 +0530 Subject: cpuidle: pseries: Do not cap the CEDE0 latency in fixup_cede0_latency() Currently in fixup_cede0_latency() code, we perform the fixup the CEDE(0) exit latency value only if minimum advertized extended CEDE latency values are less than 10us. This was done so as to not break the expected behaviour on POWER8 platforms where the advertised latency was higher than the default 10us, which would delay the SMT folding on the core. However, after the earlier patch "cpuidle/pseries: Fixup CEDE0 latency only for POWER10 onwards", we can be sure that the fixup of CEDE0 latency is going to happen only from POWER10 onwards. Hence unconditionally use the minimum exit latency provided by the platform. Signed-off-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1626676399-15975-3-git-send-email-ego@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-pseries.c | 59 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index e592280d8acf..bba449b77641 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -346,11 +346,9 @@ static int pseries_cpuidle_driver_init(void) static void __init fixup_cede0_latency(void) { struct xcede_latency_payload *payload; - u64 min_latency_us; + u64 min_xcede_latency_us = UINT_MAX; int i; - min_latency_us = dedicated_states[1].exit_latency; // CEDE latency - if (parse_cede_parameters()) return; @@ -358,42 +356,45 @@ static void __init fixup_cede0_latency(void) nr_xcede_records); payload = &xcede_latency_parameter.payload; + + /* + * The CEDE idle state maps to CEDE(0). While the hypervisor + * does not advertise CEDE(0) exit latency values, it does + * advertise the latency values of the extended CEDE states. + * We use the lowest advertised exit latency value as a proxy + * for the exit latency of CEDE(0). + */ for (i = 0; i < nr_xcede_records; i++) { struct xcede_latency_record *record = &payload->records[i]; + u8 hint = record->hint; u64 latency_tb = be64_to_cpu(record->latency_ticks); u64 latency_us = DIV_ROUND_UP_ULL(tb_to_ns(latency_tb), NSEC_PER_USEC); - if (latency_us == 0) - pr_warn("cpuidle: xcede record %d has an unrealistic latency of 0us.\n", i); - - if (latency_us < min_latency_us) - min_latency_us = latency_us; - } - - /* - * By default, we assume that CEDE(0) has exit latency 10us, - * since there is no way for us to query from the platform. - * - * However, if the wakeup latency of an Extended CEDE state is - * smaller than 10us, then we can be sure that CEDE(0) - * requires no more than that. - * - * Perform the fix-up. - */ - if (min_latency_us < dedicated_states[1].exit_latency) { /* - * We set a minimum of 1us wakeup latency for cede0 to - * distinguish it from snooze + * We expect the exit latency of an extended CEDE + * state to be non-zero, it to since it takes at least + * a few nanoseconds to wakeup the idle CPU and + * dispatch the virtual processor into the Linux + * Guest. + * + * So we consider only non-zero value for performing + * the fixup of CEDE(0) latency. */ - u64 cede0_latency = 1; + if (latency_us == 0) { + pr_warn("cpuidle: Skipping xcede record %d [hint=%d]. Exit latency = 0us\n", + i, hint); + continue; + } - if (min_latency_us > cede0_latency) - cede0_latency = min_latency_us - 1; + if (latency_us < min_xcede_latency_us) + min_xcede_latency_us = latency_us; + } - dedicated_states[1].exit_latency = cede0_latency; - dedicated_states[1].target_residency = 10 * (cede0_latency); + if (min_xcede_latency_us != UINT_MAX) { + dedicated_states[1].exit_latency = min_xcede_latency_us; + dedicated_states[1].target_residency = 10 * (min_xcede_latency_us); pr_info("cpuidle: Fixed up CEDE exit latency to %llu us\n", - cede0_latency); + min_xcede_latency_us); } } -- cgit v1.2.3-70-g09d2 From a6cae77f1bc89368a4e2822afcddc45c3062d499 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Thu, 29 Jul 2021 20:01:03 +0200 Subject: powerpc/stacktrace: Include linux/delay.h commit 7c6986ade69e ("powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()") introduces udelay() call without including the linux/delay.h header. This may happen to work on master but the header that declares the functionshould be included nonetheless. Fixes: 7c6986ade69e ("powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi()") Signed-off-by: Michal Suchanek Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210729180103.15578-1-msuchanek@suse.de --- arch/powerpc/kernel/stacktrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index 2b0d04a1b7d2..9e4a4a7af380 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -8,6 +8,7 @@ * Copyright 2018 Nick Piggin, Michael Ellerman, IBM Corp. */ +#include #include #include #include -- cgit v1.2.3-70-g09d2 From 4ffd3b800e9722ea44fc3755e72d026dd530dc4e Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:43 +0300 Subject: RDMA/hns: Don't skip IB creation flow for regular RC QP The call to internal QP creation function skips QP creation checks and misses the addition of such device QPs to the restrack DB. As a preparation to general allocation scheme, convert hns to use proper API. Link: https://lore.kernel.org/r/7b236c15f7d5abb368958297ac6962d8459cb824.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index a3305d196675..e0f59b8d7d5d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -758,7 +758,7 @@ static struct hns_roce_qp *hns_roce_v1_create_lp_qp(struct hns_roce_dev *hr_dev, init_attr.cap.max_recv_wr = HNS_ROCE_MIN_WQE_NUM; init_attr.cap.max_send_wr = HNS_ROCE_MIN_WQE_NUM; - qp = hns_roce_create_qp(pd, &init_attr, NULL); + qp = ib_create_qp(pd, &init_attr); if (IS_ERR(qp)) { dev_err(dev, "Create loop qp for mr free failed!"); return NULL; @@ -923,7 +923,7 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev) create_lp_qp_failed: for (i -= 1; i >= 0; i--) { hr_qp = free_mr->mr_free_qp[i]; - if (hns_roce_v1_destroy_qp(&hr_qp->ibqp, NULL)) + if (ib_destroy_qp(&hr_qp->ibqp)) dev_err(dev, "Destroy qp %d for mr free failed!\n", i); } @@ -953,7 +953,7 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev) if (!hr_qp) continue; - ret = hns_roce_v1_destroy_qp(&hr_qp->ibqp, NULL); + ret = ib_destroy_qp(&hr_qp->ibqp); if (ret) dev_err(dev, "Destroy qp %d for mr free failed(%d)!\n", i, ret); -- cgit v1.2.3-70-g09d2 From e66e49592b690d6abd537cc207b07a3db2f413d0 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:44 +0300 Subject: RDMA/hns: Don't overwrite supplied QP attributes QP attributes that were supplied by IB/core already have all parameters set when they are passed to the driver. The drivers are not supposed to change anything in struct ib_qp_init_attr. Fixes: 66d86e529dd5 ("RDMA/hns: Add UD support for HIP09") Link: https://lore.kernel.org/r/5987138875e8ade9aa339d4db6e1bd9694ed4591.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hns/hns_roce_qp.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index b101b7e578f2..c3e2fee16c0e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -1171,14 +1171,8 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, if (!hr_qp) return ERR_PTR(-ENOMEM); - if (init_attr->qp_type == IB_QPT_XRC_INI) - init_attr->recv_cq = NULL; - - if (init_attr->qp_type == IB_QPT_XRC_TGT) { + if (init_attr->qp_type == IB_QPT_XRC_TGT) hr_qp->xrcdn = to_hr_xrcd(init_attr->xrcd)->xrcdn; - init_attr->recv_cq = NULL; - init_attr->send_cq = NULL; - } if (init_attr->qp_type == IB_QPT_GSI) { hr_qp->port = init_attr->port_num - 1; -- cgit v1.2.3-70-g09d2 From f9193d266347fe9bed5c173e7a1bf96268142a79 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:45 +0300 Subject: RDMA/efa: Remove double QP type assignment The QP type is set by the IB/core and shouldn't be set in the driver. Fixes: 40909f664d27 ("RDMA/efa: Add EFA verbs implementation") Link: https://lore.kernel.org/r/838c40134c1590167b888ca06ad51071139ff2ae.1627040189.git.leonro@nvidia.com Acked-by: Gal Pressman Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/efa/efa_verbs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index b4cfb656ddd5..b1c4780e86be 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -727,7 +727,6 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, qp->qp_handle = create_qp_resp.qp_handle; qp->ibqp.qp_num = create_qp_resp.qp_num; - qp->ibqp.qp_type = init_attr->qp_type; qp->max_send_wr = init_attr->cap.max_send_wr; qp->max_recv_wr = init_attr->cap.max_recv_wr; qp->max_send_sge = init_attr->cap.max_send_sge; -- cgit v1.2.3-70-g09d2 From b0791dbf1214a9e539fa8507b4b7e50f5367b79a Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:46 +0300 Subject: RDMA/mlx5: Cancel pkey work before destroying device resources In the driver release flow, we are ensuring that notifier is disabled and no new works can be added to pkey_change_handler. It means that we can cancel that handler before destroying resources to make sure that our unwind routine is symmetrical to the allocation one. Link: https://lore.kernel.org/r/f2b1ea1bad952e4e7a48a6f731de9e0344986b29.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index cac0c52ed1d9..d2b9cba0028d 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2908,6 +2908,15 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev) struct mlx5_ib_resources *devr = &dev->devr; int port; + /* + * Make sure no change P_Key work items are still executing. + * + * At this stage, the mlx5_ib_event should be unregistered + * and it ensures that no new works are added. + */ + for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) + cancel_work_sync(&devr->ports[port].pkey_change_work); + mlx5_ib_destroy_srq(devr->s1, NULL); kfree(devr->s1); mlx5_ib_destroy_srq(devr->s0, NULL); @@ -2918,10 +2927,6 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev) kfree(devr->c0); mlx5_ib_dealloc_pd(devr->p0, NULL); kfree(devr->p0); - - /* Make sure no change P_Key work items are still executing */ - for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) - cancel_work_sync(&devr->ports[port].pkey_change_work); } static u32 get_core_cap_flags(struct ib_device *ibdev, -- cgit v1.2.3-70-g09d2 From 8c9e7f0325fe57ef55bacfa82d10857b4433fef3 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:47 +0300 Subject: RDMA/mlx5: Delete device resource mutex that didn't protect anything The dev->devr.mutex was intended to protect GSI QP pointer change in the struct mlx5_ib_port_resources when it is accessed from the pkey_change_work. However that pointer isn't changed during the runtime and once IB/core adds MAD, it stays stable. Link: https://lore.kernel.org/r/6e338c561033df20d92e1371fc6a7a0d93aad945.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/gsi.c | 34 +++++++++------------------------- drivers/infiniband/hw/mlx5/main.c | 9 +++++++-- drivers/infiniband/hw/mlx5/mlx5_ib.h | 2 -- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c index 7fcad9135276..e549d6fa4a41 100644 --- a/drivers/infiniband/hw/mlx5/gsi.c +++ b/drivers/infiniband/hw/mlx5/gsi.c @@ -116,8 +116,6 @@ int mlx5_ib_create_gsi(struct ib_pd *pd, struct mlx5_ib_qp *mqp, goto err_free_tx; } - mutex_lock(&dev->devr.mutex); - if (dev->devr.ports[port_num - 1].gsi) { mlx5_ib_warn(dev, "GSI QP already exists on port %d\n", port_num); @@ -167,15 +165,11 @@ int mlx5_ib_create_gsi(struct ib_pd *pd, struct mlx5_ib_qp *mqp, INIT_LIST_HEAD(&gsi->rx_qp->sig_mrs); dev->devr.ports[attr->port_num - 1].gsi = gsi; - - mutex_unlock(&dev->devr.mutex); - return 0; err_destroy_cq: ib_free_cq(gsi->cq); err_free_wrs: - mutex_unlock(&dev->devr.mutex); kfree(gsi->outstanding_wrs); err_free_tx: kfree(gsi->tx_qps); @@ -190,16 +184,13 @@ int mlx5_ib_destroy_gsi(struct mlx5_ib_qp *mqp) int qp_index; int ret; - mutex_lock(&dev->devr.mutex); ret = mlx5_ib_destroy_qp(gsi->rx_qp, NULL); if (ret) { mlx5_ib_warn(dev, "unable to destroy hardware GSI QP. error %d\n", ret); - mutex_unlock(&dev->devr.mutex); return ret; } dev->devr.ports[port_num - 1].gsi = NULL; - mutex_unlock(&dev->devr.mutex); gsi->rx_qp = NULL; for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) { @@ -339,23 +330,13 @@ err_destroy_qp: WARN_ON_ONCE(qp); } -static void setup_qps(struct mlx5_ib_gsi_qp *gsi) -{ - struct mlx5_ib_dev *dev = to_mdev(gsi->rx_qp->device); - u16 qp_index; - - mutex_lock(&dev->devr.mutex); - for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) - setup_qp(gsi, qp_index); - mutex_unlock(&dev->devr.mutex); -} - int mlx5_ib_gsi_modify_qp(struct ib_qp *qp, struct ib_qp_attr *attr, int attr_mask) { struct mlx5_ib_dev *dev = to_mdev(qp->device); struct mlx5_ib_qp *mqp = to_mqp(qp); struct mlx5_ib_gsi_qp *gsi = &mqp->gsi; + u16 qp_index; int ret; mlx5_ib_dbg(dev, "modifying GSI QP to state %d\n", attr->qp_state); @@ -366,8 +347,11 @@ int mlx5_ib_gsi_modify_qp(struct ib_qp *qp, struct ib_qp_attr *attr, return ret; } - if (to_mqp(gsi->rx_qp)->state == IB_QPS_RTS) - setup_qps(gsi); + if (to_mqp(gsi->rx_qp)->state != IB_QPS_RTS) + return 0; + + for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) + setup_qp(gsi, qp_index); return 0; } @@ -511,8 +495,8 @@ int mlx5_ib_gsi_post_recv(struct ib_qp *qp, const struct ib_recv_wr *wr, void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp *gsi) { - if (!gsi) - return; + u16 qp_index; - setup_qps(gsi); + for (qp_index = 0; qp_index < gsi->num_qps; ++qp_index) + setup_qp(gsi, qp_index); } diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index d2b9cba0028d..c00c56d52496 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2501,6 +2501,13 @@ static void pkey_change_handler(struct work_struct *work) container_of(work, struct mlx5_ib_port_resources, pkey_change_work); + if (!ports->gsi) + /* + * We got this event before device was fully configured + * and MAD registration code wasn't called/finished yet. + */ + return; + mlx5_ib_gsi_pkey_change(ports->gsi); } @@ -2795,8 +2802,6 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) if (!MLX5_CAP_GEN(dev->mdev, xrc)) return -EOPNOTSUPP; - mutex_init(&devr->mutex); - devr->p0 = rdma_zalloc_drv_obj(ibdev, ib_pd); if (!devr->p0) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 585fb00bdce8..0aa19cd90a57 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -795,8 +795,6 @@ struct mlx5_ib_resources { struct ib_srq *s0; struct ib_srq *s1; struct mlx5_ib_port_resources ports[2]; - /* Protects changes to the port resources */ - struct mutex mutex; }; struct mlx5_ib_counters { -- cgit v1.2.3-70-g09d2 From 0dc0da15ed7d1f50ec3ef0cdbb7f2975abefec1f Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:48 +0300 Subject: RDMA/mlx5: Rework custom driver QP type creation Starting from commit 2b1f747071c5 ("RDMA/core: Allow drivers to disable restrack DB") the restrack is able to handle non-standard QP types either. That change allows us to rewrite custom QP calls to their IB/core counterparts, so we will use general QP creation flow even for the driver QP types. Link: https://lore.kernel.org/r/51682ab82298748941f38bd23ee3bf77ef1cab7b.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/gsi.c | 15 ++------------- drivers/infiniband/hw/mlx5/main.c | 20 +++++++------------- drivers/infiniband/hw/mlx5/qp.c | 6 +++++- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c index e549d6fa4a41..541da52470cb 100644 --- a/drivers/infiniband/hw/mlx5/gsi.c +++ b/drivers/infiniband/hw/mlx5/gsi.c @@ -145,24 +145,13 @@ int mlx5_ib_create_gsi(struct ib_pd *pd, struct mlx5_ib_qp *mqp, hw_init_attr.cap.max_inline_data = 0; } - gsi->rx_qp = mlx5_ib_create_qp(pd, &hw_init_attr, NULL); + gsi->rx_qp = ib_create_qp(pd, &hw_init_attr); if (IS_ERR(gsi->rx_qp)) { mlx5_ib_warn(dev, "unable to create hardware GSI QP. error %ld\n", PTR_ERR(gsi->rx_qp)); ret = PTR_ERR(gsi->rx_qp); goto err_destroy_cq; } - gsi->rx_qp->device = pd->device; - gsi->rx_qp->pd = pd; - gsi->rx_qp->real_qp = gsi->rx_qp; - - gsi->rx_qp->qp_type = hw_init_attr.qp_type; - gsi->rx_qp->send_cq = hw_init_attr.send_cq; - gsi->rx_qp->recv_cq = hw_init_attr.recv_cq; - gsi->rx_qp->event_handler = hw_init_attr.event_handler; - spin_lock_init(&gsi->rx_qp->mr_lock); - INIT_LIST_HEAD(&gsi->rx_qp->rdma_mrs); - INIT_LIST_HEAD(&gsi->rx_qp->sig_mrs); dev->devr.ports[attr->port_num - 1].gsi = gsi; return 0; @@ -184,7 +173,7 @@ int mlx5_ib_destroy_gsi(struct mlx5_ib_qp *mqp) int qp_index; int ret; - ret = mlx5_ib_destroy_qp(gsi->rx_qp, NULL); + ret = ib_destroy_qp(gsi->rx_qp); if (ret) { mlx5_ib_warn(dev, "unable to destroy hardware GSI QP. error %d\n", ret); diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index c00c56d52496..7aa513edc6db 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -4073,7 +4073,7 @@ static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev) mlx5_ib_warn(dev, "mr cache cleanup failed\n"); if (dev->umrc.qp) - mlx5_ib_destroy_qp(dev->umrc.qp, NULL); + ib_destroy_qp(dev->umrc.qp); if (dev->umrc.cq) ib_free_cq(dev->umrc.cq); if (dev->umrc.pd) @@ -4126,23 +4126,17 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) init_attr->cap.max_send_sge = 1; init_attr->qp_type = MLX5_IB_QPT_REG_UMR; init_attr->port_num = 1; - qp = mlx5_ib_create_qp(pd, init_attr, NULL); + qp = ib_create_qp(pd, init_attr); if (IS_ERR(qp)) { mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n"); ret = PTR_ERR(qp); goto error_3; } - qp->device = &dev->ib_dev; - qp->real_qp = qp; - qp->uobject = NULL; - qp->qp_type = MLX5_IB_QPT_REG_UMR; - qp->send_cq = init_attr->send_cq; - qp->recv_cq = init_attr->recv_cq; attr->qp_state = IB_QPS_INIT; attr->port_num = 1; - ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_PKEY_INDEX | - IB_QP_PORT, NULL); + ret = ib_modify_qp(qp, attr, + IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT); if (ret) { mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n"); goto error_4; @@ -4152,7 +4146,7 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) attr->qp_state = IB_QPS_RTR; attr->path_mtu = IB_MTU_256; - ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL); + ret = ib_modify_qp(qp, attr, IB_QP_STATE); if (ret) { mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n"); goto error_4; @@ -4160,7 +4154,7 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) memset(attr, 0, sizeof(*attr)); attr->qp_state = IB_QPS_RTS; - ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL); + ret = ib_modify_qp(qp, attr, IB_QP_STATE); if (ret) { mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n"); goto error_4; @@ -4183,7 +4177,7 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev) return 0; error_4: - mlx5_ib_destroy_qp(qp, NULL); + ib_destroy_qp(qp); dev->umrc.qp = NULL; error_3: diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index a056b7a8e0c3..297aacc5d7f9 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -2673,7 +2673,6 @@ static int create_dct(struct mlx5_ib_dev *dev, struct ib_pd *pd, } qp->state = IB_QPS_RESET; - rdma_restrack_no_track(&qp->ibqp.res); return 0; } @@ -3012,6 +3011,7 @@ static int create_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, switch (qp->type) { case MLX5_IB_QPT_DCT: err = create_dct(dev, pd, qp, params); + rdma_restrack_no_track(&qp->ibqp.res); break; case MLX5_IB_QPT_DCI: err = create_dci(dev, pd, qp, params); @@ -3022,6 +3022,10 @@ static int create_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, case IB_QPT_GSI: err = mlx5_ib_create_gsi(pd, qp, params->attr); break; + case MLX5_IB_QPT_HW_GSI: + case MLX5_IB_QPT_REG_UMR: + rdma_restrack_no_track(&qp->ibqp.res); + fallthrough; default: if (params->udata) err = create_user_qp(dev, pd, qp, params); -- cgit v1.2.3-70-g09d2 From 44da3730e046a784d088157175d9418ba60661fc Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:49 +0300 Subject: RDMA/rdmavt: Decouple QP and SGE lists allocations The rdmavt QP has fields that are both needed for the control and data path. Such mixed declaration caused to the very specific allocation flow with kzalloc_node and SGE list embedded into the struct rvt_qp. This patch separates QP creation to two: regular memory allocation for the control path and specific code for the SGE list, while the access to the later is performed through derefenced pointer. Such pointer and its context are expected to be in the cache, so performance difference is expected to be negligible, if any exists. Link: https://lore.kernel.org/r/f66c1e20ccefba0db3c69c58ca9c897f062b4d1c.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rdmavt/qp.c | 13 ++++++++----- include/rdma/rdmavt_qp.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index e9f3d356b361..14900860985c 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -1078,7 +1078,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, int err; struct rvt_swqe *swq = NULL; size_t sz; - size_t sg_list_sz; + size_t sg_list_sz = 0; struct ib_qp *ret = ERR_PTR(-ENOMEM); struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device); void *priv = NULL; @@ -1126,8 +1126,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, if (!swq) return ERR_PTR(-ENOMEM); - sz = sizeof(*qp); - sg_list_sz = 0; if (init_attr->srq) { struct rvt_srq *srq = ibsrq_to_rvtsrq(init_attr->srq); @@ -1137,10 +1135,13 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, } else if (init_attr->cap.max_recv_sge > 1) sg_list_sz = sizeof(*qp->r_sg_list) * (init_attr->cap.max_recv_sge - 1); - qp = kzalloc_node(sz + sg_list_sz, GFP_KERNEL, - rdi->dparms.node); + qp = kzalloc_node(sizeof(*qp), GFP_KERNEL, rdi->dparms.node); if (!qp) goto bail_swq; + qp->r_sg_list = + kzalloc_node(sg_list_sz, GFP_KERNEL, rdi->dparms.node); + if (!qp->r_sg_list) + goto bail_qp; qp->allowed_ops = get_allowed_ops(init_attr->qp_type); RCU_INIT_POINTER(qp->next, NULL); @@ -1328,6 +1329,7 @@ bail_driver_priv: bail_qp: kfree(qp->s_ack_queue); + kfree(qp->r_sg_list); kfree(qp); bail_swq: @@ -1762,6 +1764,7 @@ int rvt_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) kvfree(qp->r_rq.kwq); rdi->driver_f.qp_priv_free(rdi, qp); kfree(qp->s_ack_queue); + kfree(qp->r_sg_list); rdma_destroy_ah_attr(&qp->remote_ah_attr); rdma_destroy_ah_attr(&qp->alt_ah_attr); free_ud_wq_attr(qp); diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h index 8275954f5ce6..2e58d5e6ac0e 100644 --- a/include/rdma/rdmavt_qp.h +++ b/include/rdma/rdmavt_qp.h @@ -444,7 +444,7 @@ struct rvt_qp { /* * This sge list MUST be last. Do not add anything below here. */ - struct rvt_sge r_sg_list[] /* verified SGEs */ + struct rvt_sge *r_sg_list /* verified SGEs */ ____cacheline_aligned_in_smp; }; -- cgit v1.2.3-70-g09d2 From 514aee660df493cd673154a6ba6bab745ec47b8c Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:50 +0300 Subject: RDMA: Globally allocate and release QP memory Convert QP object to follow IB/core general allocation scheme. That change allows us to make sure that restrack properly kref the memory. Link: https://lore.kernel.org/r/48e767124758aeecc433360ddd85eaa6325b34d9.1627040189.git.leonro@nvidia.com Reviewed-by: Gal Pressman #efa Tested-by: Gal Pressman Reviewed-by: Dennis Dalessandro #rdma and core Tested-by: Dennis Dalessandro Signed-off-by: Leon Romanovsky Tested-by: Tatyana Nikolova Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 28 ++++++-- drivers/infiniband/core/device.c | 2 + drivers/infiniband/core/restrack.c | 2 +- drivers/infiniband/core/verbs.c | 40 +++++------ drivers/infiniband/hw/bnxt_re/ib_verbs.c | 26 +++---- drivers/infiniband/hw/bnxt_re/ib_verbs.h | 7 +- drivers/infiniband/hw/bnxt_re/main.c | 1 + drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 5 +- drivers/infiniband/hw/cxgb4/provider.c | 1 + drivers/infiniband/hw/cxgb4/qp.c | 37 ++++------ drivers/infiniband/hw/efa/efa.h | 5 +- drivers/infiniband/hw/efa/efa_main.c | 1 + drivers/infiniband/hw/efa/efa_verbs.c | 28 +++----- drivers/infiniband/hw/hns/hns_roce_device.h | 5 +- drivers/infiniband/hw/hns/hns_roce_main.c | 1 + drivers/infiniband/hw/hns/hns_roce_qp.c | 28 +++----- drivers/infiniband/hw/irdma/utils.c | 3 - drivers/infiniband/hw/irdma/verbs.c | 31 ++++----- drivers/infiniband/hw/mlx4/main.c | 1 + drivers/infiniband/hw/mlx4/mlx4_ib.h | 5 +- drivers/infiniband/hw/mlx4/qp.c | 25 +++---- drivers/infiniband/hw/mlx5/gsi.c | 2 - drivers/infiniband/hw/mlx5/main.c | 1 + drivers/infiniband/hw/mlx5/mlx5_ib.h | 5 +- drivers/infiniband/hw/mlx5/qp.c | 56 +++++---------- drivers/infiniband/hw/mthca/mthca_provider.c | 77 ++++++++------------- drivers/infiniband/hw/ocrdma/ocrdma_main.c | 1 + drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 25 +++---- drivers/infiniband/hw/ocrdma/ocrdma_verbs.h | 5 +- drivers/infiniband/hw/qedr/main.c | 1 + drivers/infiniband/hw/qedr/qedr_roce_cm.c | 13 ++-- drivers/infiniband/hw/qedr/qedr_roce_cm.h | 5 +- drivers/infiniband/hw/qedr/verbs.c | 49 ++++--------- drivers/infiniband/hw/qedr/verbs.h | 4 +- drivers/infiniband/hw/usnic/usnic_ib_main.c | 1 + drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c | 34 ++++----- drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h | 10 +-- drivers/infiniband/hw/usnic/usnic_ib_verbs.c | 69 +++++++++---------- drivers/infiniband/hw/usnic/usnic_ib_verbs.h | 5 +- drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c | 1 + drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | 53 ++++++-------- drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h | 5 +- drivers/infiniband/sw/rdmavt/qp.c | 91 +++++++++---------------- drivers/infiniband/sw/rdmavt/qp.h | 5 +- drivers/infiniband/sw/rdmavt/vt.c | 9 +++ drivers/infiniband/sw/rxe/rxe_pool.c | 2 +- drivers/infiniband/sw/rxe/rxe_verbs.c | 48 ++++++------- drivers/infiniband/sw/rxe/rxe_verbs.h | 2 +- drivers/infiniband/sw/siw/siw_main.c | 1 + drivers/infiniband/sw/siw/siw_qp.c | 2 - drivers/infiniband/sw/siw/siw_verbs.c | 54 +++++++-------- drivers/infiniband/sw/siw/siw_verbs.h | 5 +- include/rdma/ib_verbs.h | 30 ++++++-- 53 files changed, 404 insertions(+), 549 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 647cca4e0240..fa2e0bbaf8c7 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -322,13 +322,14 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd, struct ib_uqp_object *uobj, const char *caller) { struct ib_qp *qp; + int ret; if (!dev->ops.create_qp) return ERR_PTR(-EOPNOTSUPP); - qp = dev->ops.create_qp(pd, attr, udata); - if (IS_ERR(qp)) - return qp; + qp = rdma_zalloc_drv_obj_numa(dev, ib_qp); + if (!qp) + return ERR_PTR(-ENOMEM); qp->device = dev; qp->pd = pd; @@ -337,14 +338,10 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd, qp->qp_type = attr->qp_type; qp->rwq_ind_tbl = attr->rwq_ind_tbl; - qp->send_cq = attr->send_cq; - qp->recv_cq = attr->recv_cq; qp->srq = attr->srq; - qp->rwq_ind_tbl = attr->rwq_ind_tbl; qp->event_handler = attr->event_handler; qp->port = attr->port_num; - atomic_set(&qp->usecnt, 0); spin_lock_init(&qp->mr_lock); INIT_LIST_HEAD(&qp->rdma_mrs); INIT_LIST_HEAD(&qp->sig_mrs); @@ -352,8 +349,25 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd, rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP); WARN_ONCE(!udata && !caller, "Missing kernel QP owner"); rdma_restrack_set_name(&qp->res, udata ? NULL : caller); + ret = dev->ops.create_qp(qp, attr, udata); + if (ret) + goto err_create; + + /* + * TODO: The mlx4 internally overwrites send_cq and recv_cq. + * Unfortunately, it is not an easy task to fix that driver. + */ + qp->send_cq = attr->send_cq; + qp->recv_cq = attr->recv_cq; + rdma_restrack_add(&qp->res); return qp; + +err_create: + rdma_restrack_put(&qp->res); + kfree(qp); + return ERR_PTR(ret); + } struct rdma_dev_addr; diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 9056f48bdca6..f4814bb7f082 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2654,6 +2654,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) SET_DEVICE_OP(dev_ops, get_hw_stats); SET_DEVICE_OP(dev_ops, get_link_layer); SET_DEVICE_OP(dev_ops, get_netdev); + SET_DEVICE_OP(dev_ops, get_numa_node); SET_DEVICE_OP(dev_ops, get_port_immutable); SET_DEVICE_OP(dev_ops, get_vector_affinity); SET_DEVICE_OP(dev_ops, get_vf_config); @@ -2710,6 +2711,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) SET_OBJ_SIZE(dev_ops, ib_cq); SET_OBJ_SIZE(dev_ops, ib_mw); SET_OBJ_SIZE(dev_ops, ib_pd); + SET_OBJ_SIZE(dev_ops, ib_qp); SET_OBJ_SIZE(dev_ops, ib_rwq_ind_table); SET_OBJ_SIZE(dev_ops, ib_srq); SET_OBJ_SIZE(dev_ops, ib_ucontext); diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c index 033207882c82..1f935d9f6178 100644 --- a/drivers/infiniband/core/restrack.c +++ b/drivers/infiniband/core/restrack.c @@ -343,7 +343,7 @@ void rdma_restrack_del(struct rdma_restrack_entry *res) rt = &dev->res[res->type]; old = xa_erase(&rt->xa, res->id); - if (res->type == RDMA_RESTRACK_MR || res->type == RDMA_RESTRACK_QP) + if (res->type == RDMA_RESTRACK_MR) return; WARN_ON(old != res); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 7036967e4c0b..a164609c2ee7 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1963,30 +1963,32 @@ int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata) rdma_rw_cleanup_mrs(qp); rdma_counter_unbind_qp(qp, true); - rdma_restrack_del(&qp->res); ret = qp->device->ops.destroy_qp(qp, udata); - if (!ret) { - if (alt_path_sgid_attr) - rdma_put_gid_attr(alt_path_sgid_attr); - if (av_sgid_attr) - rdma_put_gid_attr(av_sgid_attr); - if (pd) - atomic_dec(&pd->usecnt); - if (scq) - atomic_dec(&scq->usecnt); - if (rcq) - atomic_dec(&rcq->usecnt); - if (srq) - atomic_dec(&srq->usecnt); - if (ind_tbl) - atomic_dec(&ind_tbl->usecnt); - if (sec) - ib_destroy_qp_security_end(sec); - } else { + if (ret) { if (sec) ib_destroy_qp_security_abort(sec); + return ret; } + if (alt_path_sgid_attr) + rdma_put_gid_attr(alt_path_sgid_attr); + if (av_sgid_attr) + rdma_put_gid_attr(av_sgid_attr); + if (pd) + atomic_dec(&pd->usecnt); + if (scq) + atomic_dec(&scq->usecnt); + if (rcq) + atomic_dec(&rcq->usecnt); + if (srq) + atomic_dec(&srq->usecnt); + if (ind_tbl) + atomic_dec(&ind_tbl->usecnt); + if (sec) + ib_destroy_qp_security_end(sec); + + rdma_restrack_del(&qp->res); + kfree(qp); return ret; } EXPORT_SYMBOL(ib_destroy_qp_user); diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 283b6b81563c..634d1586a1fa 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -815,7 +815,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) { rc = bnxt_re_destroy_gsi_sqp(qp); if (rc) - goto sh_fail; + return rc; } mutex_lock(&rdev->qp_lock); @@ -826,10 +826,7 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) ib_umem_release(qp->rumem); ib_umem_release(qp->sumem); - kfree(qp); return 0; -sh_fail: - return rc; } static u8 __from_ib_qp_type(enum ib_qp_type type) @@ -1402,27 +1399,22 @@ static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev, return rc; } -struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, - struct ib_qp_init_attr *qp_init_attr, - struct ib_udata *udata) +int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr, + struct ib_udata *udata) { + struct ib_pd *ib_pd = ib_qp->pd; struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); struct bnxt_re_dev *rdev = pd->rdev; struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; - struct bnxt_re_qp *qp; + struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); int rc; rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr); if (!rc) { rc = -EINVAL; - goto exit; + goto fail; } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - rc = -ENOMEM; - goto exit; - } qp->rdev = rdev; rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata); if (rc) @@ -1465,16 +1457,14 @@ struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, mutex_unlock(&rdev->qp_lock); atomic_inc(&rdev->qp_count); - return &qp->ib_qp; + return 0; qp_destroy: bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); free_umem: ib_umem_release(qp->rumem); ib_umem_release(qp->sumem); fail: - kfree(qp); -exit: - return ERR_PTR(rc); + return rc; } static u8 __from_ib_qp_state(enum ib_qp_state state) diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h index d68671cc6173..b5c6e0f4f877 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h @@ -78,9 +78,9 @@ struct bnxt_re_srq { }; struct bnxt_re_qp { + struct ib_qp ib_qp; struct list_head list; struct bnxt_re_dev *rdev; - struct ib_qp ib_qp; spinlock_t sq_lock; /* protect sq */ spinlock_t rq_lock; /* protect rq */ struct bnxt_qplib_qp qplib_qp; @@ -179,9 +179,8 @@ int bnxt_re_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); int bnxt_re_destroy_srq(struct ib_srq *srq, struct ib_udata *udata); int bnxt_re_post_srq_recv(struct ib_srq *srq, const struct ib_recv_wr *recv_wr, const struct ib_recv_wr **bad_recv_wr); -struct ib_qp *bnxt_re_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *qp_init_attr, - struct ib_udata *udata); +int bnxt_re_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *qp_init_attr, + struct ib_udata *udata); int bnxt_re_modify_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_udata *udata); int bnxt_re_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index d5674026512a..3edf66818e4b 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -709,6 +709,7 @@ static const struct ib_device_ops bnxt_re_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, bnxt_re_ah, ib_ah), INIT_RDMA_OBJ_SIZE(ib_cq, bnxt_re_cq, ib_cq), INIT_RDMA_OBJ_SIZE(ib_pd, bnxt_re_pd, ib_pd), + INIT_RDMA_OBJ_SIZE(ib_qp, bnxt_re_qp, ib_qp), INIT_RDMA_OBJ_SIZE(ib_srq, bnxt_re_srq, ib_srq), INIT_RDMA_OBJ_SIZE(ib_ucontext, bnxt_re_ucontext, ib_uctx), }; diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 3883af3d2312..6a2a415ec791 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -989,9 +989,8 @@ int c4iw_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata); int c4iw_create_srq(struct ib_srq *srq, struct ib_srq_init_attr *attrs, struct ib_udata *udata); int c4iw_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata); -struct ib_qp *c4iw_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata); +int c4iw_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata); int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index 881d515eb15a..e7337662aff8 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -499,6 +499,7 @@ static const struct ib_device_ops c4iw_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_cq, c4iw_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_mw, c4iw_mw, ibmw), INIT_RDMA_OBJ_SIZE(ib_pd, c4iw_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, c4iw_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, c4iw_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, c4iw_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index a81fa7a56edb..d20b4ef2c853 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -2103,16 +2103,15 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) ucontext ? &ucontext->uctx : &rhp->rdev.uctx, !qhp->srq); c4iw_put_wr_wait(qhp->wr_waitp); - - kfree(qhp); return 0; } -struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, - struct ib_udata *udata) +int c4iw_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata) { + struct ib_pd *pd = qp->pd; struct c4iw_dev *rhp; - struct c4iw_qp *qhp; + struct c4iw_qp *qhp = to_c4iw_qp(qp); struct c4iw_pd *php; struct c4iw_cq *schp; struct c4iw_cq *rchp; @@ -2124,44 +2123,36 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, struct c4iw_mm_entry *sq_key_mm, *rq_key_mm = NULL, *sq_db_key_mm; struct c4iw_mm_entry *rq_db_key_mm = NULL, *ma_sync_key_mm = NULL; - pr_debug("ib_pd %p\n", pd); - if (attrs->qp_type != IB_QPT_RC || attrs->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; php = to_c4iw_pd(pd); rhp = php->rhp; schp = get_chp(rhp, ((struct c4iw_cq *)attrs->send_cq)->cq.cqid); rchp = get_chp(rhp, ((struct c4iw_cq *)attrs->recv_cq)->cq.cqid); if (!schp || !rchp) - return ERR_PTR(-EINVAL); + return -EINVAL; if (attrs->cap.max_inline_data > T4_MAX_SEND_INLINE) - return ERR_PTR(-EINVAL); + return -EINVAL; if (!attrs->srq) { if (attrs->cap.max_recv_wr > rhp->rdev.hw_queue.t4_max_rq_size) - return ERR_PTR(-E2BIG); + return -E2BIG; rqsize = attrs->cap.max_recv_wr + 1; if (rqsize < 8) rqsize = 8; } if (attrs->cap.max_send_wr > rhp->rdev.hw_queue.t4_max_sq_size) - return ERR_PTR(-E2BIG); + return -E2BIG; sqsize = attrs->cap.max_send_wr + 1; if (sqsize < 8) sqsize = 8; - qhp = kzalloc(sizeof(*qhp), GFP_KERNEL); - if (!qhp) - return ERR_PTR(-ENOMEM); - qhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL); - if (!qhp->wr_waitp) { - ret = -ENOMEM; - goto err_free_qhp; - } + if (!qhp->wr_waitp) + return -ENOMEM; qhp->wq.sq.size = sqsize; qhp->wq.sq.memsize = @@ -2339,7 +2330,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, qhp->wq.sq.qid, qhp->wq.sq.size, qhp->wq.sq.memsize, attrs->cap.max_send_wr, qhp->wq.rq.qid, qhp->wq.rq.size, qhp->wq.rq.memsize, attrs->cap.max_recv_wr); - return &qhp->ibqp; + return 0; err_free_ma_sync_key: kfree(ma_sync_key_mm); err_free_rq_db_key: @@ -2359,9 +2350,7 @@ err_destroy_qp: ucontext ? &ucontext->uctx : &rhp->rdev.uctx, !attrs->srq); err_free_wr_wait: c4iw_put_wr_wait(qhp->wr_waitp); -err_free_qhp: - kfree(qhp); - return ERR_PTR(ret); + return ret; } int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h index 2b8ca099b381..1a1e60eee1dc 100644 --- a/drivers/infiniband/hw/efa/efa.h +++ b/drivers/infiniband/hw/efa/efa.h @@ -132,9 +132,8 @@ int efa_query_pkey(struct ib_device *ibdev, u32 port, u16 index, int efa_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); int efa_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata); -struct ib_qp *efa_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata); int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, struct ib_udata *udata); diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c index 203e6ddcacbc..997947d77de6 100644 --- a/drivers/infiniband/hw/efa/efa_main.c +++ b/drivers/infiniband/hw/efa/efa_main.c @@ -271,6 +271,7 @@ static const struct ib_device_ops efa_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, efa_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, efa_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, efa_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, efa_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, efa_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index b1c4780e86be..e5f9d90aad5e 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -450,7 +450,6 @@ int efa_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) qp->rq_size, DMA_TO_DEVICE); } - kfree(qp); return 0; } @@ -609,17 +608,16 @@ static int efa_qp_validate_attr(struct efa_dev *dev, return 0; } -struct ib_qp *efa_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { struct efa_com_create_qp_params create_qp_params = {}; struct efa_com_create_qp_result create_qp_resp; - struct efa_dev *dev = to_edev(ibpd->device); + struct efa_dev *dev = to_edev(ibqp->device); struct efa_ibv_create_qp_resp resp = {}; struct efa_ibv_create_qp cmd = {}; + struct efa_qp *qp = to_eqp(ibqp); struct efa_ucontext *ucontext; - struct efa_qp *qp; int err; ucontext = rdma_udata_to_drv_context(udata, struct efa_ucontext, @@ -664,14 +662,8 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, goto err_out; } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - err = -ENOMEM; - goto err_out; - } - create_qp_params.uarn = ucontext->uarn; - create_qp_params.pd = to_epd(ibpd)->pdn; + create_qp_params.pd = to_epd(ibqp->pd)->pdn; if (init_attr->qp_type == IB_QPT_UD) { create_qp_params.qp_type = EFA_ADMIN_QP_TYPE_UD; @@ -682,7 +674,7 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, "Unsupported qp type %d driver qp type %d\n", init_attr->qp_type, cmd.driver_qp_type); err = -EOPNOTSUPP; - goto err_free_qp; + goto err_out; } ibdev_dbg(&dev->ibdev, "Create QP: qp type %d driver qp type %#x\n", @@ -700,7 +692,7 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, qp->rq_size, DMA_TO_DEVICE); if (!qp->rq_cpu_addr) { err = -ENOMEM; - goto err_free_qp; + goto err_out; } ibdev_dbg(&dev->ibdev, @@ -746,7 +738,7 @@ struct ib_qp *efa_create_qp(struct ib_pd *ibpd, ibdev_dbg(&dev->ibdev, "Created qp[%d]\n", qp->ibqp.qp_num); - return &qp->ibqp; + return 0; err_remove_mmap_entries: efa_qp_user_mmap_entries_remove(qp); @@ -756,11 +748,9 @@ err_free_mapped: if (qp->rq_size) efa_free_mapped(dev, qp->rq_cpu_addr, qp->rq_dma_addr, qp->rq_size, DMA_TO_DEVICE); -err_free_qp: - kfree(qp); err_out: atomic64_inc(&dev->stats.create_qp_err); - return ERR_PTR(err); + return err; } static const struct { diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 991f65269fa6..0c3eb1163977 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -1216,9 +1216,8 @@ int hns_roce_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata); int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata); int hns_roce_dealloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata); -struct ib_qp *hns_roce_create_qp(struct ib_pd *ib_pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int hns_roce_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); void init_flush_work(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp); diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 078a97193f0e..23b88a5a372f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -454,6 +454,7 @@ static const struct ib_device_ops hns_roce_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, hns_roce_cq, ib_cq), INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, hns_roce_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index c3e2fee16c0e..fd0f71acd470 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -959,8 +959,6 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, struct ib_device *ibdev = &hr_dev->ib_dev; int ret; - hr_qp->ibqp.qp_type = init_attr->qp_type; - if (init_attr->cap.max_inline_data > hr_dev->caps.max_sq_inline) init_attr->cap.max_inline_data = hr_dev->caps.max_sq_inline; @@ -1121,8 +1119,6 @@ void hns_roce_qp_destroy(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, free_qp_buf(hr_dev, hr_qp); free_kernel_wrid(hr_qp); free_qp_db(hr_dev, hr_qp, udata); - - kfree(hr_qp); } static int check_qp_type(struct hns_roce_dev *hr_dev, enum ib_qp_type type, @@ -1154,22 +1150,18 @@ out: return -EOPNOTSUPP; } -struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +int hns_roce_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { - struct ib_device *ibdev = pd ? pd->device : init_attr->xrcd->device; + struct ib_device *ibdev = qp->device; struct hns_roce_dev *hr_dev = to_hr_dev(ibdev); - struct hns_roce_qp *hr_qp; + struct hns_roce_qp *hr_qp = to_hr_qp(qp); + struct ib_pd *pd = qp->pd; int ret; ret = check_qp_type(hr_dev, init_attr->qp_type, !!udata); if (ret) - return ERR_PTR(ret); - - hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL); - if (!hr_qp) - return ERR_PTR(-ENOMEM); + return ret; if (init_attr->qp_type == IB_QPT_XRC_TGT) hr_qp->xrcdn = to_hr_xrcd(init_attr->xrcd)->xrcdn; @@ -1180,15 +1172,11 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, } ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, hr_qp); - if (ret) { + if (ret) ibdev_err(ibdev, "Create QP type 0x%x failed(%d)\n", init_attr->qp_type, ret); - kfree(hr_qp); - return ERR_PTR(ret); - } - - return &hr_qp->ibqp; + return ret; } int to_hr_qp_type(int qp_type) diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 5bbe44e54f9a..e94470991fe0 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -1141,10 +1141,7 @@ void irdma_free_qp_rsrc(struct irdma_qp *iwqp) iwqp->kqp.dma_mem.va, iwqp->kqp.dma_mem.pa); iwqp->kqp.dma_mem.va = NULL; kfree(iwqp->kqp.sq_wrid_mem); - iwqp->kqp.sq_wrid_mem = NULL; kfree(iwqp->kqp.rq_wrid_mem); - iwqp->kqp.rq_wrid_mem = NULL; - kfree(iwqp); } /** diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 9712f6902ba8..9b8c451e2426 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -792,18 +792,19 @@ static int irdma_validate_qp_attrs(struct ib_qp_init_attr *init_attr, /** * irdma_create_qp - create qp - * @ibpd: ptr of pd + * @ibqp: ptr of qp * @init_attr: attributes for qp * @udata: user data for create qp */ -static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +static int irdma_create_qp(struct ib_qp *ibqp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { + struct ib_pd *ibpd = ibqp->pd; struct irdma_pd *iwpd = to_iwpd(ibpd); struct irdma_device *iwdev = to_iwdev(ibpd->device); struct irdma_pci_f *rf = iwdev->rf; - struct irdma_qp *iwqp; + struct irdma_qp *iwqp = to_iwqp(ibqp); struct irdma_create_qp_req req; struct irdma_create_qp_resp uresp = {}; u32 qp_num = 0; @@ -820,7 +821,7 @@ static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, err_code = irdma_validate_qp_attrs(init_attr, iwdev); if (err_code) - return ERR_PTR(err_code); + return err_code; sq_size = init_attr->cap.max_send_wr; rq_size = init_attr->cap.max_recv_wr; @@ -833,10 +834,6 @@ static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, init_info.qp_uk_init_info.max_rq_frag_cnt = init_attr->cap.max_recv_sge; init_info.qp_uk_init_info.max_inline_data = init_attr->cap.max_inline_data; - iwqp = kzalloc(sizeof(*iwqp), GFP_KERNEL); - if (!iwqp) - return ERR_PTR(-ENOMEM); - qp = &iwqp->sc_qp; qp->qp_uk.back_qp = iwqp; qp->qp_uk.lock = &iwqp->lock; @@ -849,10 +846,8 @@ static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, iwqp->q2_ctx_mem.size, &iwqp->q2_ctx_mem.pa, GFP_KERNEL); - if (!iwqp->q2_ctx_mem.va) { - err_code = -ENOMEM; - goto error; - } + if (!iwqp->q2_ctx_mem.va) + return -ENOMEM; init_info.q2 = iwqp->q2_ctx_mem.va; init_info.q2_pa = iwqp->q2_ctx_mem.pa; @@ -1001,17 +996,16 @@ static struct ib_qp *irdma_create_qp(struct ib_pd *ibpd, if (err_code) { ibdev_dbg(&iwdev->ibdev, "VERBS: copy_to_udata failed\n"); irdma_destroy_qp(&iwqp->ibqp, udata); - return ERR_PTR(err_code); + return err_code; } } init_completion(&iwqp->free_qp); - return &iwqp->ibqp; + return 0; error: irdma_free_qp_rsrc(iwqp); - - return ERR_PTR(err_code); + return err_code; } static int irdma_get_ib_acc_flags(struct irdma_qp *iwqp) @@ -4406,6 +4400,7 @@ static const struct ib_device_ops irdma_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, irdma_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, irdma_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_mw, irdma_mr, ibmw), + INIT_RDMA_OBJ_SIZE(ib_qp, irdma_qp, ibqp), }; /** diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index ae4c91b612ce..f367f4a4abff 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -2577,6 +2577,7 @@ static const struct ib_device_ops mlx4_ib_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, mlx4_ib_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, mlx4_ib_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, mlx4_ib_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, mlx4_ib_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, mlx4_ib_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx4_ib_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index e856cf23a0a1..c60f6e9ac640 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -792,9 +792,8 @@ void mlx4_ib_free_srq_wqe(struct mlx4_ib_srq *srq, int wqe_index); int mlx4_ib_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, const struct ib_recv_wr **bad_wr); -struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int mlx4_ib_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata); void mlx4_ib_drain_sq(struct ib_qp *qp); void mlx4_ib_drain_rq(struct ib_qp *qp); diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 4a2ef7daaded..8662f462e2a5 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1578,24 +1578,19 @@ static int _mlx4_ib_create_qp(struct ib_pd *pd, struct mlx4_ib_qp *qp, return 0; } -struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) { - struct ib_device *device = pd ? pd->device : init_attr->xrcd->device; +int mlx4_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) +{ + struct ib_device *device = ibqp->device; struct mlx4_ib_dev *dev = to_mdev(device); - struct mlx4_ib_qp *qp; + struct mlx4_ib_qp *qp = to_mqp(ibqp); + struct ib_pd *pd = ibqp->pd; int ret; - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) - return ERR_PTR(-ENOMEM); - mutex_init(&qp->mutex); ret = _mlx4_ib_create_qp(pd, qp, init_attr, udata); - if (ret) { - kfree(qp); - return ERR_PTR(ret); - } + if (ret) + return ret; if (init_attr->qp_type == IB_QPT_GSI && !(init_attr->create_flags & MLX4_IB_QP_CREATE_ROCE_V2_GSI)) { @@ -1618,7 +1613,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, init_attr->create_flags &= ~MLX4_IB_QP_CREATE_ROCE_V2_GSI; } } - return &qp->ibqp; + return 0; } static int _mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) @@ -1646,8 +1641,6 @@ static int _mlx4_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) } kfree(mqp->sqp); - kfree(mqp); - return 0; } diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c index 541da52470cb..3ad8f637c589 100644 --- a/drivers/infiniband/hw/mlx5/gsi.c +++ b/drivers/infiniband/hw/mlx5/gsi.c @@ -193,8 +193,6 @@ int mlx5_ib_destroy_gsi(struct mlx5_ib_qp *mqp) kfree(gsi->outstanding_wrs); kfree(gsi->tx_qps); - kfree(mqp); - return 0; } diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 7aa513edc6db..46f28514cf3a 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -3805,6 +3805,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_counters, mlx5_ib_mcounters, ibcntrs), INIT_RDMA_OBJ_SIZE(ib_cq, mlx5_ib_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, mlx5_ib_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, mlx5_ib_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index 0aa19cd90a57..bf20a388eabe 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -1219,9 +1219,8 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, const struct ib_recv_wr **bad_wr); int mlx5_ib_enable_lb(struct mlx5_ib_dev *dev, bool td, bool qp); void mlx5_ib_disable_lb(struct mlx5_ib_dev *dev, bool td, bool qp); -struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int mlx5_ib_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 297aacc5d7f9..9d20c838974f 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -3114,7 +3114,6 @@ static int mlx5_ib_destroy_dct(struct mlx5_ib_qp *mqp) } kfree(mqp->dct.in); - kfree(mqp); return 0; } @@ -3152,25 +3151,23 @@ static int check_ucmd_data(struct mlx5_ib_dev *dev, return ret ? 0 : -EINVAL; } -struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr, - struct ib_udata *udata) +int mlx5_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr, + struct ib_udata *udata) { struct mlx5_create_qp_params params = {}; - struct mlx5_ib_dev *dev; - struct mlx5_ib_qp *qp; + struct mlx5_ib_dev *dev = to_mdev(ibqp->device); + struct mlx5_ib_qp *qp = to_mqp(ibqp); + struct ib_pd *pd = ibqp->pd; enum ib_qp_type type; int err; - dev = pd ? to_mdev(pd->device) : - to_mdev(to_mxrcd(attr->xrcd)->ibxrcd.device); - err = check_qp_type(dev, attr, &type); if (err) - return ERR_PTR(err); + return err; err = check_valid_flow(dev, pd, attr, udata); if (err) - return ERR_PTR(err); + return err; params.udata = udata; params.uidx = MLX5_IB_DEFAULT_UIDX; @@ -3180,49 +3177,43 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr, if (udata) { err = process_udata_size(dev, ¶ms); if (err) - return ERR_PTR(err); + return err; err = check_ucmd_data(dev, ¶ms); if (err) - return ERR_PTR(err); + return err; params.ucmd = kzalloc(params.ucmd_size, GFP_KERNEL); if (!params.ucmd) - return ERR_PTR(-ENOMEM); + return -ENOMEM; err = ib_copy_from_udata(params.ucmd, udata, params.inlen); if (err) goto free_ucmd; } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - err = -ENOMEM; - goto free_ucmd; - } - mutex_init(&qp->mutex); qp->type = type; if (udata) { err = process_vendor_flags(dev, qp, params.ucmd, attr); if (err) - goto free_qp; + goto free_ucmd; err = get_qp_uidx(qp, ¶ms); if (err) - goto free_qp; + goto free_ucmd; } err = process_create_flags(dev, qp, attr); if (err) - goto free_qp; + goto free_ucmd; err = check_qp_attr(dev, qp, attr); if (err) - goto free_qp; + goto free_ucmd; err = create_qp(dev, pd, qp, ¶ms); if (err) - goto free_qp; + goto free_ucmd; kfree(params.ucmd); params.ucmd = NULL; @@ -3237,7 +3228,7 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attr, if (err) goto destroy_qp; - return &qp->ibqp; + return 0; destroy_qp: switch (qp->type) { @@ -3248,22 +3239,12 @@ destroy_qp: mlx5_ib_destroy_gsi(qp); break; default: - /* - * These lines below are temp solution till QP allocation - * will be moved to be under IB/core responsiblity. - */ - qp->ibqp.send_cq = attr->send_cq; - qp->ibqp.recv_cq = attr->recv_cq; - qp->ibqp.pd = pd; destroy_qp_common(dev, qp, udata); } - qp = NULL; -free_qp: - kfree(qp); free_ucmd: kfree(params.ucmd); - return ERR_PTR(err); + return err; } int mlx5_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) @@ -3278,9 +3259,6 @@ int mlx5_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) return mlx5_ib_destroy_dct(mqp); destroy_qp_common(dev, mqp, udata); - - kfree(mqp); - return 0; } diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index adf4fcf0fee4..ceee23ebc0f2 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -459,52 +459,45 @@ static int mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata) return 0; } -static struct ib_qp *mthca_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +static int mthca_create_qp(struct ib_qp *ibqp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { struct mthca_ucontext *context = rdma_udata_to_drv_context( udata, struct mthca_ucontext, ibucontext); struct mthca_create_qp ucmd; - struct mthca_qp *qp; + struct mthca_qp *qp = to_mqp(ibqp); + struct mthca_dev *dev = to_mdev(ibqp->device); int err; if (init_attr->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; switch (init_attr->qp_type) { case IB_QPT_RC: case IB_QPT_UC: case IB_QPT_UD: { - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) - return ERR_PTR(-ENOMEM); - if (udata) { - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { - kfree(qp); - return ERR_PTR(-EFAULT); - } + if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) + return -EFAULT; - err = mthca_map_user_db(to_mdev(pd->device), &context->uar, + err = mthca_map_user_db(dev, &context->uar, context->db_tab, - ucmd.sq_db_index, ucmd.sq_db_page); - if (err) { - kfree(qp); - return ERR_PTR(err); - } + ucmd.sq_db_index, + ucmd.sq_db_page); + if (err) + return err; - err = mthca_map_user_db(to_mdev(pd->device), &context->uar, + err = mthca_map_user_db(dev, &context->uar, context->db_tab, - ucmd.rq_db_index, ucmd.rq_db_page); + ucmd.rq_db_index, + ucmd.rq_db_page); if (err) { - mthca_unmap_user_db(to_mdev(pd->device), - &context->uar, + mthca_unmap_user_db(dev, &context->uar, context->db_tab, ucmd.sq_db_index); - kfree(qp); - return ERR_PTR(err); + return err; } qp->mr.ibmr.lkey = ucmd.lkey; @@ -512,20 +505,16 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, qp->rq.db_index = ucmd.rq_db_index; } - err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd), + err = mthca_alloc_qp(dev, to_mpd(ibqp->pd), to_mcq(init_attr->send_cq), to_mcq(init_attr->recv_cq), init_attr->qp_type, init_attr->sq_sig_type, &init_attr->cap, qp, udata); if (err && udata) { - mthca_unmap_user_db(to_mdev(pd->device), - &context->uar, - context->db_tab, + mthca_unmap_user_db(dev, &context->uar, context->db_tab, ucmd.sq_db_index); - mthca_unmap_user_db(to_mdev(pd->device), - &context->uar, - context->db_tab, + mthca_unmap_user_db(dev, &context->uar, context->db_tab, ucmd.rq_db_index); } @@ -535,34 +524,28 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, case IB_QPT_SMI: case IB_QPT_GSI: { - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) - return ERR_PTR(-ENOMEM); qp->sqp = kzalloc(sizeof(struct mthca_sqp), GFP_KERNEL); - if (!qp->sqp) { - kfree(qp); - return ERR_PTR(-ENOMEM); - } + if (!qp->sqp) + return -ENOMEM; qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1; - err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd), + err = mthca_alloc_sqp(dev, to_mpd(ibqp->pd), to_mcq(init_attr->send_cq), to_mcq(init_attr->recv_cq), init_attr->sq_sig_type, &init_attr->cap, - qp->ibqp.qp_num, init_attr->port_num, - qp, udata); + qp->ibqp.qp_num, init_attr->port_num, qp, + udata); break; } default: /* Don't support raw QPs */ - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } if (err) { kfree(qp->sqp); - kfree(qp); - return ERR_PTR(err); + return err; } init_attr->cap.max_send_wr = qp->sq.max; @@ -571,7 +554,7 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, init_attr->cap.max_recv_sge = qp->rq.max_gs; init_attr->cap.max_inline_data = qp->max_inline_data; - return &qp->ibqp; + return 0; } static int mthca_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) @@ -594,7 +577,6 @@ static int mthca_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) } mthca_free_qp(to_mdev(qp->device), to_mqp(qp)); kfree(to_mqp(qp)->sqp); - kfree(to_mqp(qp)); return 0; } @@ -1121,6 +1103,7 @@ static const struct ib_device_ops mthca_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, mthca_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, mthca_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, mthca_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, mthca_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, mthca_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index f329db0c591f..7abf6cf1e937 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -185,6 +185,7 @@ static const struct ib_device_ops ocrdma_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, ocrdma_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, ocrdma_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, ocrdma_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, ocrdma_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, ocrdma_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 58619ce64d0d..735123d0e9ec 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -1288,19 +1288,19 @@ static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev, } } -struct ib_qp *ocrdma_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata) +int ocrdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata) { int status; + struct ib_pd *ibpd = ibqp->pd; struct ocrdma_pd *pd = get_ocrdma_pd(ibpd); - struct ocrdma_qp *qp; - struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device); + struct ocrdma_qp *qp = get_ocrdma_qp(ibqp); + struct ocrdma_dev *dev = get_ocrdma_dev(ibqp->device); struct ocrdma_create_qp_ureq ureq; u16 dpp_credit_lmt, dpp_offset; if (attrs->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; status = ocrdma_check_qp_params(ibpd, dev, attrs, udata); if (status) @@ -1309,12 +1309,7 @@ struct ib_qp *ocrdma_create_qp(struct ib_pd *ibpd, memset(&ureq, 0, sizeof(ureq)); if (udata) { if (ib_copy_from_udata(&ureq, udata, sizeof(ureq))) - return ERR_PTR(-EFAULT); - } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - status = -ENOMEM; - goto gen_err; + return -EFAULT; } ocrdma_set_qp_init_params(qp, pd, attrs); if (udata == NULL) @@ -1349,7 +1344,7 @@ struct ib_qp *ocrdma_create_qp(struct ib_pd *ibpd, ocrdma_store_gsi_qp_cq(dev, attrs); qp->ibqp.qp_num = qp->id; mutex_unlock(&dev->dev_lock); - return &qp->ibqp; + return 0; cpy_err: ocrdma_del_qpn_map(dev, qp); @@ -1359,10 +1354,9 @@ mbx_err: mutex_unlock(&dev->dev_lock); kfree(qp->wqe_wr_id_tbl); kfree(qp->rqe_wr_id_tbl); - kfree(qp); pr_err("%s(%d) error=%d\n", __func__, dev->id, status); gen_err: - return ERR_PTR(status); + return status; } int _ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, @@ -1731,7 +1725,6 @@ int ocrdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) kfree(qp->wqe_wr_id_tbl); kfree(qp->rqe_wr_id_tbl); - kfree(qp); return 0; } diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h index b1c5fad81603..b73d742a520c 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.h @@ -75,9 +75,8 @@ int ocrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, int ocrdma_resize_cq(struct ib_cq *, int cqe, struct ib_udata *); int ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata); -struct ib_qp *ocrdma_create_qp(struct ib_pd *, - struct ib_qp_init_attr *attrs, - struct ib_udata *); +int ocrdma_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata); int _ocrdma_modify_qp(struct ib_qp *, struct ib_qp_attr *attr, int attr_mask); int ocrdma_modify_qp(struct ib_qp *, struct ib_qp_attr *attr, diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c index de98e0604f91..755930be01b8 100644 --- a/drivers/infiniband/hw/qedr/main.c +++ b/drivers/infiniband/hw/qedr/main.c @@ -233,6 +233,7 @@ static const struct ib_device_ops qedr_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, qedr_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, qedr_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, qedr_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, qedr_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, qedr_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_xrcd, qedr_xrcd, ibxrcd), INIT_RDMA_OBJ_SIZE(ib_ucontext, qedr_ucontext, ibucontext), diff --git a/drivers/infiniband/hw/qedr/qedr_roce_cm.c b/drivers/infiniband/hw/qedr/qedr_roce_cm.c index 13e5e6bbec99..05307c1488b8 100644 --- a/drivers/infiniband/hw/qedr/qedr_roce_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_roce_cm.c @@ -319,20 +319,19 @@ err1: return rc; } -struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev, - struct ib_qp_init_attr *attrs, - struct qedr_qp *qp) +int qedr_create_gsi_qp(struct qedr_dev *dev, struct ib_qp_init_attr *attrs, + struct qedr_qp *qp) { int rc; rc = qedr_check_gsi_qp_attrs(dev, attrs); if (rc) - return ERR_PTR(rc); + return rc; rc = qedr_ll2_start(dev, attrs, qp); if (rc) { DP_ERR(dev, "create gsi qp: failed on ll2 start. rc=%d\n", rc); - return ERR_PTR(rc); + return rc; } /* create QP */ @@ -359,7 +358,7 @@ struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev, DP_DEBUG(dev, QEDR_MSG_GSI, "created GSI QP %p\n", qp); - return &qp->ibqp; + return 0; err: kfree(qp->rqe_wr_id); @@ -368,7 +367,7 @@ err: if (rc) DP_ERR(dev, "create gsi qp: failed destroy on create\n"); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } int qedr_destroy_gsi_qp(struct qedr_dev *dev) diff --git a/drivers/infiniband/hw/qedr/qedr_roce_cm.h b/drivers/infiniband/hw/qedr/qedr_roce_cm.h index d46dcd3f6424..f3432f035ec6 100644 --- a/drivers/infiniband/hw/qedr/qedr_roce_cm.h +++ b/drivers/infiniband/hw/qedr/qedr_roce_cm.h @@ -50,9 +50,8 @@ int qedr_gsi_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, const struct ib_recv_wr **bad_wr); int qedr_gsi_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, const struct ib_send_wr **bad_wr); -struct ib_qp *qedr_create_gsi_qp(struct qedr_dev *dev, - struct ib_qp_init_attr *attrs, - struct qedr_qp *qp); +int qedr_create_gsi_qp(struct qedr_dev *dev, struct ib_qp_init_attr *attrs, + struct qedr_qp *qp); void qedr_store_gsi_qp_cq(struct qedr_dev *dev, struct qedr_qp *qp, struct ib_qp_init_attr *attrs); int qedr_destroy_gsi_qp(struct qedr_dev *dev); diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index b72ef24db657..16d4c0228d76 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -2239,34 +2239,30 @@ static int qedr_free_qp_resources(struct qedr_dev *dev, struct qedr_qp *qp, return 0; } -struct ib_qp *qedr_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata) +int qedr_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata) { struct qedr_xrcd *xrcd = NULL; - struct qedr_pd *pd = NULL; - struct qedr_dev *dev; - struct qedr_qp *qp; - struct ib_qp *ibqp; + struct ib_pd *ibpd = ibqp->pd; + struct qedr_pd *pd = get_qedr_pd(ibpd); + struct qedr_dev *dev = get_qedr_dev(ibqp->device); + struct qedr_qp *qp = get_qedr_qp(ibqp); int rc = 0; if (attrs->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; - if (attrs->qp_type == IB_QPT_XRC_TGT) { + if (attrs->qp_type == IB_QPT_XRC_TGT) xrcd = get_qedr_xrcd(attrs->xrcd); - dev = get_qedr_dev(xrcd->ibxrcd.device); - } else { + else pd = get_qedr_pd(ibpd); - dev = get_qedr_dev(ibpd->device); - } DP_DEBUG(dev, QEDR_MSG_QP, "create qp: called from %s, pd=%p\n", udata ? "user library" : "kernel", pd); rc = qedr_check_qp_attrs(ibpd, dev, attrs, udata); if (rc) - return ERR_PTR(rc); + return rc; DP_DEBUG(dev, QEDR_MSG_QP, "create qp: called from %s, event_handler=%p, eepd=%p sq_cq=%p, sq_icid=%d, rq_cq=%p, rq_icid=%d\n", @@ -2276,20 +2272,10 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd, get_qedr_cq(attrs->recv_cq), attrs->recv_cq ? get_qedr_cq(attrs->recv_cq)->icid : 0); - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - DP_ERR(dev, "create qp: failed allocating memory\n"); - return ERR_PTR(-ENOMEM); - } - qedr_set_common_qp_params(dev, qp, pd, attrs); - if (attrs->qp_type == IB_QPT_GSI) { - ibqp = qedr_create_gsi_qp(dev, attrs, qp); - if (IS_ERR(ibqp)) - kfree(qp); - return ibqp; - } + if (attrs->qp_type == IB_QPT_GSI) + return qedr_create_gsi_qp(dev, attrs, qp); if (udata || xrcd) rc = qedr_create_user_qp(dev, qp, ibpd, udata, attrs); @@ -2297,7 +2283,7 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd, rc = qedr_create_kernel_qp(dev, qp, ibpd, attrs); if (rc) - goto out_free_qp; + return rc; qp->ibqp.qp_num = qp->qp_id; @@ -2307,14 +2293,11 @@ struct ib_qp *qedr_create_qp(struct ib_pd *ibpd, goto out_free_qp_resources; } - return &qp->ibqp; + return 0; out_free_qp_resources: qedr_free_qp_resources(dev, qp, udata); -out_free_qp: - kfree(qp); - - return ERR_PTR(-EFAULT); + return -EFAULT; } static enum ib_qp_state qedr_get_ibqp_state(enum qed_roce_qp_state qp_state) @@ -2874,8 +2857,6 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) if (rdma_protocol_iwarp(&dev->ibdev, 1)) qedr_iw_qp_rem_ref(&qp->ibqp); - else - kfree(qp); return 0; } diff --git a/drivers/infiniband/hw/qedr/verbs.h b/drivers/infiniband/hw/qedr/verbs.h index 34ad47515861..031687dafc61 100644 --- a/drivers/infiniband/hw/qedr/verbs.h +++ b/drivers/infiniband/hw/qedr/verbs.h @@ -56,8 +56,8 @@ int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, int qedr_resize_cq(struct ib_cq *, int cqe, struct ib_udata *); int qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata); int qedr_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags); -struct ib_qp *qedr_create_qp(struct ib_pd *, struct ib_qp_init_attr *attrs, - struct ib_udata *); +int qedr_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata); int qedr_modify_qp(struct ib_qp *, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); int qedr_query_qp(struct ib_qp *, struct ib_qp_attr *qp_attr, diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c index c49f9e19d926..228e9a36dad0 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_main.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c @@ -360,6 +360,7 @@ static const struct ib_device_ops usnic_dev_ops = { .reg_user_mr = usnic_ib_reg_mr, INIT_RDMA_OBJ_SIZE(ib_pd, usnic_ib_pd, ibpd), INIT_RDMA_OBJ_SIZE(ib_cq, usnic_ib_cq, ibcq), + INIT_RDMA_OBJ_SIZE(ib_qp, usnic_ib_qp_grp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, usnic_ib_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c index 0cdb156e165e..3b60fa9cb58d 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c @@ -665,13 +665,12 @@ static int qp_grp_id_from_flow(struct usnic_ib_qp_grp_flow *qp_flow, return 0; } -struct usnic_ib_qp_grp * -usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, - struct usnic_ib_pd *pd, - struct usnic_vnic_res_spec *res_spec, - struct usnic_transport_spec *transport_spec) +int usnic_ib_qp_grp_create(struct usnic_ib_qp_grp *qp_grp, + struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, + struct usnic_ib_pd *pd, + struct usnic_vnic_res_spec *res_spec, + struct usnic_transport_spec *transport_spec) { - struct usnic_ib_qp_grp *qp_grp; int err; enum usnic_transport_type transport = transport_spec->trans_type; struct usnic_ib_qp_grp_flow *qp_flow; @@ -684,20 +683,15 @@ usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, usnic_err("Spec does not meet minimum req for transport %d\n", transport); log_spec(res_spec); - return ERR_PTR(err); + return err; } - qp_grp = kzalloc(sizeof(*qp_grp), GFP_ATOMIC); - if (!qp_grp) - return NULL; - qp_grp->res_chunk_list = alloc_res_chunk_list(vf->vnic, res_spec, qp_grp); - if (IS_ERR_OR_NULL(qp_grp->res_chunk_list)) { - err = qp_grp->res_chunk_list ? - PTR_ERR(qp_grp->res_chunk_list) : -ENOMEM; - goto out_free_qp_grp; - } + if (IS_ERR_OR_NULL(qp_grp->res_chunk_list)) + return qp_grp->res_chunk_list ? + PTR_ERR(qp_grp->res_chunk_list) : + -ENOMEM; err = qp_grp_and_vf_bind(vf, pd, qp_grp); if (err) @@ -724,7 +718,7 @@ usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, usnic_ib_sysfs_qpn_add(qp_grp); - return qp_grp; + return 0; out_release_flow: release_and_remove_flow(qp_flow); @@ -732,10 +726,7 @@ out_qp_grp_vf_unbind: qp_grp_and_vf_unbind(qp_grp); out_free_res: free_qp_grp_res(qp_grp->res_chunk_list); -out_free_qp_grp: - kfree(qp_grp); - - return ERR_PTR(err); + return err; } void usnic_ib_qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp) @@ -748,7 +739,6 @@ void usnic_ib_qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp) usnic_ib_sysfs_qpn_remove(qp_grp); qp_grp_and_vf_unbind(qp_grp); free_qp_grp_res(qp_grp->res_chunk_list); - kfree(qp_grp); } struct usnic_vnic_res_chunk* diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h index a8a2314c9531..62e732be6736 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.h @@ -89,11 +89,11 @@ extern const struct usnic_vnic_res_spec min_transport_spec[USNIC_TRANSPORT_MAX]; const char *usnic_ib_qp_grp_state_to_string(enum ib_qp_state state); int usnic_ib_qp_grp_dump_hdr(char *buf, int buf_sz); int usnic_ib_qp_grp_dump_rows(void *obj, char *buf, int buf_sz); -struct usnic_ib_qp_grp * -usnic_ib_qp_grp_create(struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, - struct usnic_ib_pd *pd, - struct usnic_vnic_res_spec *res_spec, - struct usnic_transport_spec *trans_spec); +int usnic_ib_qp_grp_create(struct usnic_ib_qp_grp *qp, + struct usnic_fwd_dev *ufdev, struct usnic_ib_vf *vf, + struct usnic_ib_pd *pd, + struct usnic_vnic_res_spec *res_spec, + struct usnic_transport_spec *trans_spec); void usnic_ib_qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp); int usnic_ib_qp_grp_modify(struct usnic_ib_qp_grp *qp_grp, enum ib_qp_state new_state, diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c index 57d210ca855a..06a4e9d4545d 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c @@ -168,30 +168,31 @@ static int usnic_ib_fill_create_qp_resp(struct usnic_ib_qp_grp *qp_grp, return 0; } -static struct usnic_ib_qp_grp* -find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, - struct usnic_ib_pd *pd, - struct usnic_transport_spec *trans_spec, - struct usnic_vnic_res_spec *res_spec) +static int +find_free_vf_and_create_qp_grp(struct ib_qp *qp, + struct usnic_transport_spec *trans_spec, + struct usnic_vnic_res_spec *res_spec) { + struct usnic_ib_dev *us_ibdev = to_usdev(qp->device); + struct usnic_ib_pd *pd = to_upd(qp->pd); struct usnic_ib_vf *vf; struct usnic_vnic *vnic; - struct usnic_ib_qp_grp *qp_grp; + struct usnic_ib_qp_grp *qp_grp = to_uqp_grp(qp); struct device *dev, **dev_list; - int i; + int i, ret; BUG_ON(!mutex_is_locked(&us_ibdev->usdev_lock)); if (list_empty(&us_ibdev->vf_dev_list)) { usnic_info("No vfs to allocate\n"); - return NULL; + return -ENOMEM; } if (usnic_ib_share_vf) { /* Try to find resouces on a used vf which is in pd */ dev_list = usnic_uiom_get_dev_list(pd->umem_pd); if (IS_ERR(dev_list)) - return ERR_CAST(dev_list); + return PTR_ERR(dev_list); for (i = 0; dev_list[i]; i++) { dev = dev_list[i]; vf = dev_get_drvdata(dev); @@ -202,10 +203,10 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, dev_name(&us_ibdev->ib_dev.dev), pci_name(usnic_vnic_get_pdev( vnic))); - qp_grp = usnic_ib_qp_grp_create(us_ibdev->ufdev, - vf, pd, - res_spec, - trans_spec); + ret = usnic_ib_qp_grp_create(qp_grp, + us_ibdev->ufdev, + vf, pd, res_spec, + trans_spec); spin_unlock(&vf->lock); goto qp_grp_check; @@ -223,9 +224,9 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, vnic = vf->vnic; if (vf->qp_grp_ref_cnt == 0 && usnic_vnic_check_room(vnic, res_spec) == 0) { - qp_grp = usnic_ib_qp_grp_create(us_ibdev->ufdev, vf, - pd, res_spec, - trans_spec); + ret = usnic_ib_qp_grp_create(qp_grp, us_ibdev->ufdev, + vf, pd, res_spec, + trans_spec); spin_unlock(&vf->lock); goto qp_grp_check; @@ -235,16 +236,15 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev, usnic_info("No free qp grp found on %s\n", dev_name(&us_ibdev->ib_dev.dev)); - return ERR_PTR(-ENOMEM); + return -ENOMEM; qp_grp_check: - if (IS_ERR_OR_NULL(qp_grp)) { + if (ret) { usnic_err("Failed to allocate qp_grp\n"); if (usnic_ib_share_vf) usnic_uiom_free_dev_list(dev_list); - return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); } - return qp_grp; + return ret; } static void qp_grp_destroy(struct usnic_ib_qp_grp *qp_grp) @@ -458,13 +458,12 @@ int usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) return 0; } -struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +int usnic_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { int err; struct usnic_ib_dev *us_ibdev; - struct usnic_ib_qp_grp *qp_grp; + struct usnic_ib_qp_grp *qp_grp = to_uqp_grp(ibqp); struct usnic_ib_ucontext *ucontext = rdma_udata_to_drv_context( udata, struct usnic_ib_ucontext, ibucontext); int cq_cnt; @@ -474,29 +473,29 @@ struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd, usnic_dbg("\n"); - us_ibdev = to_usdev(pd->device); + us_ibdev = to_usdev(ibqp->device); if (init_attr->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; err = ib_copy_from_udata(&cmd, udata, sizeof(cmd)); if (err) { usnic_err("%s: cannot copy udata for create_qp\n", dev_name(&us_ibdev->ib_dev.dev)); - return ERR_PTR(-EINVAL); + return -EINVAL; } err = create_qp_validate_user_data(cmd); if (err) { usnic_err("%s: Failed to validate user data\n", dev_name(&us_ibdev->ib_dev.dev)); - return ERR_PTR(-EINVAL); + return -EINVAL; } if (init_attr->qp_type != IB_QPT_UD) { usnic_err("%s asked to make a non-UD QP: %d\n", dev_name(&us_ibdev->ib_dev.dev), init_attr->qp_type); - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } trans_spec = cmd.spec; @@ -504,13 +503,9 @@ struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd, cq_cnt = (init_attr->send_cq == init_attr->recv_cq) ? 1 : 2; res_spec = min_transport_spec[trans_spec.trans_type]; usnic_vnic_res_spec_update(&res_spec, USNIC_VNIC_RES_TYPE_CQ, cq_cnt); - qp_grp = find_free_vf_and_create_qp_grp(us_ibdev, to_upd(pd), - &trans_spec, - &res_spec); - if (IS_ERR_OR_NULL(qp_grp)) { - err = qp_grp ? PTR_ERR(qp_grp) : -ENOMEM; + err = find_free_vf_and_create_qp_grp(ibqp, &trans_spec, &res_spec); + if (err) goto out_release_mutex; - } err = usnic_ib_fill_create_qp_resp(qp_grp, udata); if (err) { @@ -522,13 +517,13 @@ struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd, list_add_tail(&qp_grp->link, &ucontext->qp_grp_list); usnic_ib_log_vf(qp_grp->vf); mutex_unlock(&us_ibdev->usdev_lock); - return &qp_grp->ibqp; + return 0; out_release_qp_grp: qp_grp_destroy(qp_grp); out_release_mutex: mutex_unlock(&us_ibdev->usdev_lock); - return ERR_PTR(err); + return err; } int usnic_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata) diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h index 6b82d0f2d184..6ca9ee0dddbe 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.h +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.h @@ -50,9 +50,8 @@ int usnic_ib_query_gid(struct ib_device *ibdev, u32 port, int index, union ib_gid *gid); int usnic_ib_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata); int usnic_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata); -struct ib_qp *usnic_ib_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int usnic_ib_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int usnic_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata); int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index 8ed8bc24c69f..b39175837d58 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c @@ -185,6 +185,7 @@ static const struct ib_device_ops pvrdma_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, pvrdma_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, pvrdma_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, pvrdma_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, pvrdma_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_ucontext, pvrdma_ucontext, ibucontext), }; diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c index 67769b715126..f83cd4a9d992 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c @@ -182,18 +182,17 @@ static int pvrdma_set_sq_size(struct pvrdma_dev *dev, struct ib_qp_cap *req_cap, /** * pvrdma_create_qp - create queue pair - * @pd: protection domain + * @ibqp: queue pair * @init_attr: queue pair attributes * @udata: user data * - * @return: the ib_qp pointer on success, otherwise returns an errno. + * @return: the 0 on success, otherwise returns an errno. */ -struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +int pvrdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { - struct pvrdma_qp *qp = NULL; - struct pvrdma_dev *dev = to_vdev(pd->device); + struct pvrdma_qp *qp = to_vqp(ibqp); + struct pvrdma_dev *dev = to_vdev(ibqp->device); union pvrdma_cmd_req req; union pvrdma_cmd_resp rsp; struct pvrdma_cmd_create_qp *cmd = &req.create_qp; @@ -209,7 +208,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, dev_warn(&dev->pdev->dev, "invalid create queuepair flags %#x\n", init_attr->create_flags); - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } if (init_attr->qp_type != IB_QPT_RC && @@ -217,22 +216,22 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, init_attr->qp_type != IB_QPT_GSI) { dev_warn(&dev->pdev->dev, "queuepair type %d not supported\n", init_attr->qp_type); - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } if (is_srq && !dev->dsr->caps.max_srq) { dev_warn(&dev->pdev->dev, "SRQs not supported by device\n"); - return ERR_PTR(-EINVAL); + return -EINVAL; } if (!atomic_add_unless(&dev->num_qps, 1, dev->dsr->caps.max_qp)) - return ERR_PTR(-ENOMEM); + return -ENOMEM; switch (init_attr->qp_type) { case IB_QPT_GSI: if (init_attr->port_num == 0 || - init_attr->port_num > pd->device->phys_port_cnt) { + init_attr->port_num > ibqp->device->phys_port_cnt) { dev_warn(&dev->pdev->dev, "invalid queuepair attrs\n"); ret = -EINVAL; goto err_qp; @@ -240,12 +239,6 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, fallthrough; case IB_QPT_RC: case IB_QPT_UD: - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - ret = -ENOMEM; - goto err_qp; - } - spin_lock_init(&qp->sq.lock); spin_lock_init(&qp->rq.lock); mutex_init(&qp->mutex); @@ -275,9 +268,9 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, if (!is_srq) { /* set qp->sq.wqe_cnt, shift, buf_size.. */ - qp->rumem = - ib_umem_get(pd->device, ucmd.rbuf_addr, - ucmd.rbuf_size, 0); + qp->rumem = ib_umem_get(ibqp->device, + ucmd.rbuf_addr, + ucmd.rbuf_size, 0); if (IS_ERR(qp->rumem)) { ret = PTR_ERR(qp->rumem); goto err_qp; @@ -288,7 +281,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, qp->srq = to_vsrq(init_attr->srq); } - qp->sumem = ib_umem_get(pd->device, ucmd.sbuf_addr, + qp->sumem = ib_umem_get(ibqp->device, ucmd.sbuf_addr, ucmd.sbuf_size, 0); if (IS_ERR(qp->sumem)) { if (!is_srq) @@ -306,12 +299,12 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, qp->npages_recv = 0; qp->npages = qp->npages_send + qp->npages_recv; } else { - ret = pvrdma_set_sq_size(to_vdev(pd->device), + ret = pvrdma_set_sq_size(to_vdev(ibqp->device), &init_attr->cap, qp); if (ret) goto err_qp; - ret = pvrdma_set_rq_size(to_vdev(pd->device), + ret = pvrdma_set_rq_size(to_vdev(ibqp->device), &init_attr->cap, qp); if (ret) goto err_qp; @@ -362,7 +355,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, memset(cmd, 0, sizeof(*cmd)); cmd->hdr.cmd = PVRDMA_CMD_CREATE_QP; - cmd->pd_handle = to_vpd(pd)->pd_handle; + cmd->pd_handle = to_vpd(ibqp->pd)->pd_handle; cmd->send_cq_handle = to_vcq(init_attr->send_cq)->cq_handle; cmd->recv_cq_handle = to_vcq(init_attr->recv_cq)->cq_handle; if (is_srq) @@ -418,11 +411,11 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, dev_warn(&dev->pdev->dev, "failed to copy back udata\n"); __pvrdma_destroy_qp(dev, qp); - return ERR_PTR(-EINVAL); + return -EINVAL; } } - return &qp->ibqp; + return 0; err_pdir: pvrdma_page_dir_cleanup(dev, &qp->pdir); @@ -430,10 +423,8 @@ err_umem: ib_umem_release(qp->rumem); ib_umem_release(qp->sumem); err_qp: - kfree(qp); atomic_dec(&dev->num_qps); - - return ERR_PTR(ret); + return ret; } static void _pvrdma_free_qp(struct pvrdma_qp *qp) @@ -454,8 +445,6 @@ static void _pvrdma_free_qp(struct pvrdma_qp *qp) pvrdma_page_dir_cleanup(dev, &qp->pdir); - kfree(qp); - atomic_dec(&dev->num_qps); } diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h index 544b94d97c3a..78807b23d831 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h @@ -390,9 +390,8 @@ int pvrdma_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, int pvrdma_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); int pvrdma_destroy_srq(struct ib_srq *srq, struct ib_udata *udata); -struct ib_qp *pvrdma_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int pvrdma_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int pvrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); int pvrdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 14900860985c..da2d94a5a9c2 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -1058,7 +1058,7 @@ static int alloc_ud_wq_attr(struct rvt_qp *qp, int node) /** * rvt_create_qp - create a queue pair for a device - * @ibpd: the protection domain who's device we create the queue pair for + * @ibqp: the queue pair * @init_attr: the attributes of the queue pair * @udata: user data for libibverbs.so * @@ -1066,47 +1066,45 @@ static int alloc_ud_wq_attr(struct rvt_qp *qp, int node) * unique idea of what queue pair numbers mean. For instance there is a reserved * range for PSM. * - * Return: the queue pair on success, otherwise returns an errno. + * Return: 0 on success, otherwise returns an errno. * * Called by the ib_create_qp() core verbs function. */ -struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) +int rvt_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) { - struct rvt_qp *qp; - int err; + struct rvt_qp *qp = ibqp_to_rvtqp(ibqp); + int ret = -ENOMEM; struct rvt_swqe *swq = NULL; size_t sz; size_t sg_list_sz = 0; - struct ib_qp *ret = ERR_PTR(-ENOMEM); - struct rvt_dev_info *rdi = ib_to_rvt(ibpd->device); + struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); void *priv = NULL; size_t sqsize; u8 exclude_prefix = 0; if (!rdi) - return ERR_PTR(-EINVAL); + return -EINVAL; if (init_attr->create_flags & ~IB_QP_CREATE_NETDEV_USE) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; if (init_attr->cap.max_send_sge > rdi->dparms.props.max_send_sge || init_attr->cap.max_send_wr > rdi->dparms.props.max_qp_wr) - return ERR_PTR(-EINVAL); + return -EINVAL; /* Check receive queue parameters if no SRQ is specified. */ if (!init_attr->srq) { if (init_attr->cap.max_recv_sge > rdi->dparms.props.max_recv_sge || init_attr->cap.max_recv_wr > rdi->dparms.props.max_qp_wr) - return ERR_PTR(-EINVAL); + return -EINVAL; if (init_attr->cap.max_send_sge + init_attr->cap.max_send_wr + init_attr->cap.max_recv_sge + init_attr->cap.max_recv_wr == 0) - return ERR_PTR(-EINVAL); + return -EINVAL; } sqsize = init_attr->cap.max_send_wr + 1 + @@ -1115,8 +1113,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, case IB_QPT_SMI: case IB_QPT_GSI: if (init_attr->port_num == 0 || - init_attr->port_num > ibpd->device->phys_port_cnt) - return ERR_PTR(-EINVAL); + init_attr->port_num > ibqp->device->phys_port_cnt) + return -EINVAL; fallthrough; case IB_QPT_UC: case IB_QPT_RC: @@ -1124,7 +1122,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, sz = struct_size(swq, sg_list, init_attr->cap.max_send_sge); swq = vzalloc_node(array_size(sz, sqsize), rdi->dparms.node); if (!swq) - return ERR_PTR(-ENOMEM); + return -ENOMEM; if (init_attr->srq) { struct rvt_srq *srq = ibsrq_to_rvtsrq(init_attr->srq); @@ -1135,9 +1133,6 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, } else if (init_attr->cap.max_recv_sge > 1) sg_list_sz = sizeof(*qp->r_sg_list) * (init_attr->cap.max_recv_sge - 1); - qp = kzalloc_node(sizeof(*qp), GFP_KERNEL, rdi->dparms.node); - if (!qp) - goto bail_swq; qp->r_sg_list = kzalloc_node(sg_list_sz, GFP_KERNEL, rdi->dparms.node); if (!qp->r_sg_list) @@ -1166,7 +1161,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, */ priv = rdi->driver_f.qp_priv_alloc(rdi, qp); if (IS_ERR(priv)) { - ret = priv; + ret = PTR_ERR(priv); goto bail_qp; } qp->priv = priv; @@ -1180,12 +1175,10 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, qp->r_rq.max_sge = init_attr->cap.max_recv_sge; sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) + sizeof(struct rvt_rwqe); - err = rvt_alloc_rq(&qp->r_rq, qp->r_rq.size * sz, + ret = rvt_alloc_rq(&qp->r_rq, qp->r_rq.size * sz, rdi->dparms.node, udata); - if (err) { - ret = ERR_PTR(err); + if (ret) goto bail_driver_priv; - } } /* @@ -1206,40 +1199,35 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, qp->s_max_sge = init_attr->cap.max_send_sge; if (init_attr->sq_sig_type == IB_SIGNAL_REQ_WR) qp->s_flags = RVT_S_SIGNAL_REQ_WR; - err = alloc_ud_wq_attr(qp, rdi->dparms.node); - if (err) { - ret = (ERR_PTR(err)); + ret = alloc_ud_wq_attr(qp, rdi->dparms.node); + if (ret) goto bail_rq_rvt; - } if (init_attr->create_flags & IB_QP_CREATE_NETDEV_USE) exclude_prefix = RVT_AIP_QP_PREFIX; - err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table, + ret = alloc_qpn(rdi, &rdi->qp_dev->qpn_table, init_attr->qp_type, init_attr->port_num, exclude_prefix); - if (err < 0) { - ret = ERR_PTR(err); + if (ret < 0) goto bail_rq_wq; - } - qp->ibqp.qp_num = err; + + qp->ibqp.qp_num = ret; if (init_attr->create_flags & IB_QP_CREATE_NETDEV_USE) qp->ibqp.qp_num |= RVT_AIP_QP_BASE; qp->port_num = init_attr->port_num; rvt_init_qp(rdi, qp, init_attr->qp_type); if (rdi->driver_f.qp_priv_init) { - err = rdi->driver_f.qp_priv_init(rdi, qp, init_attr); - if (err) { - ret = ERR_PTR(err); + ret = rdi->driver_f.qp_priv_init(rdi, qp, init_attr); + if (ret) goto bail_rq_wq; - } } break; default: /* Don't support raw QPs */ - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; } init_attr->cap.max_inline_data = 0; @@ -1252,28 +1240,24 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, if (!qp->r_rq.wq) { __u64 offset = 0; - err = ib_copy_to_udata(udata, &offset, + ret = ib_copy_to_udata(udata, &offset, sizeof(offset)); - if (err) { - ret = ERR_PTR(err); + if (ret) goto bail_qpn; - } } else { u32 s = sizeof(struct rvt_rwq) + qp->r_rq.size * sz; qp->ip = rvt_create_mmap_info(rdi, s, udata, qp->r_rq.wq); if (IS_ERR(qp->ip)) { - ret = ERR_CAST(qp->ip); + ret = PTR_ERR(qp->ip); goto bail_qpn; } - err = ib_copy_to_udata(udata, &qp->ip->offset, + ret = ib_copy_to_udata(udata, &qp->ip->offset, sizeof(qp->ip->offset)); - if (err) { - ret = ERR_PTR(err); + if (ret) goto bail_ip; - } } qp->pid = current->pid; } @@ -1281,7 +1265,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, spin_lock(&rdi->n_qps_lock); if (rdi->n_qps_allocated == rdi->dparms.props.max_qp) { spin_unlock(&rdi->n_qps_lock); - ret = ERR_PTR(-ENOMEM); + ret = ENOMEM; goto bail_ip; } @@ -1307,9 +1291,7 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, spin_unlock_irq(&rdi->pending_lock); } - ret = &qp->ibqp; - - return ret; + return 0; bail_ip: if (qp->ip) @@ -1330,11 +1312,7 @@ bail_driver_priv: bail_qp: kfree(qp->s_ack_queue); kfree(qp->r_sg_list); - kfree(qp); - -bail_swq: vfree(swq); - return ret; } @@ -1769,7 +1747,6 @@ int rvt_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) rdma_destroy_ah_attr(&qp->alt_ah_attr); free_ud_wq_attr(qp); vfree(qp->s_wq); - kfree(qp); return 0; } diff --git a/drivers/infiniband/sw/rdmavt/qp.h b/drivers/infiniband/sw/rdmavt/qp.h index 2cdba1283bf6..bceb77c28c71 100644 --- a/drivers/infiniband/sw/rdmavt/qp.h +++ b/drivers/infiniband/sw/rdmavt/qp.h @@ -52,9 +52,8 @@ int rvt_driver_qp_init(struct rvt_dev_info *rdi); void rvt_qp_exit(struct rvt_dev_info *rdi); -struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata); +int rvt_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, + struct ib_udata *udata); int rvt_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); int rvt_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata); diff --git a/drivers/infiniband/sw/rdmavt/vt.c b/drivers/infiniband/sw/rdmavt/vt.c index ac17209816cd..d4526f38427e 100644 --- a/drivers/infiniband/sw/rdmavt/vt.c +++ b/drivers/infiniband/sw/rdmavt/vt.c @@ -131,6 +131,13 @@ static int rvt_query_device(struct ib_device *ibdev, return 0; } +static int rvt_get_numa_node(struct ib_device *ibdev) +{ + struct rvt_dev_info *rdi = ib_to_rvt(ibdev); + + return rdi->dparms.node; +} + static int rvt_modify_device(struct ib_device *device, int device_modify_mask, struct ib_device_modify *device_modify) @@ -380,6 +387,7 @@ static const struct ib_device_ops rvt_dev_ops = { .destroy_srq = rvt_destroy_srq, .detach_mcast = rvt_detach_mcast, .get_dma_mr = rvt_get_dma_mr, + .get_numa_node = rvt_get_numa_node, .get_port_immutable = rvt_get_port_immutable, .map_mr_sg = rvt_map_mr_sg, .mmap = rvt_mmap, @@ -406,6 +414,7 @@ static const struct ib_device_ops rvt_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, rvt_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, rvt_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, rvt_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, rvt_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, rvt_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, rvt_ucontext, ibucontext), }; diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c index 0b8e7c6255a2..ffa8420b4765 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.c +++ b/drivers/infiniband/sw/rxe/rxe_pool.c @@ -41,7 +41,7 @@ struct rxe_type_info rxe_type_info[RXE_NUM_TYPES] = { .size = sizeof(struct rxe_qp), .elem_offset = offsetof(struct rxe_qp, pelem), .cleanup = rxe_qp_cleanup, - .flags = RXE_POOL_INDEX, + .flags = RXE_POOL_INDEX | RXE_POOL_NO_ALLOC, .min_index = RXE_MIN_QP_INDEX, .max_index = RXE_MAX_QP_INDEX, }, diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index f7b1a1f64c13..267b5a9c345d 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -391,59 +391,52 @@ static int rxe_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, return err; } -static struct ib_qp *rxe_create_qp(struct ib_pd *ibpd, - struct ib_qp_init_attr *init, - struct ib_udata *udata) +static int rxe_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init, + struct ib_udata *udata) { int err; - struct rxe_dev *rxe = to_rdev(ibpd->device); - struct rxe_pd *pd = to_rpd(ibpd); - struct rxe_qp *qp; + struct rxe_dev *rxe = to_rdev(ibqp->device); + struct rxe_pd *pd = to_rpd(ibqp->pd); + struct rxe_qp *qp = to_rqp(ibqp); struct rxe_create_qp_resp __user *uresp = NULL; if (udata) { if (udata->outlen < sizeof(*uresp)) - return ERR_PTR(-EINVAL); + return -EINVAL; uresp = udata->outbuf; } if (init->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; err = rxe_qp_chk_init(rxe, init); if (err) - goto err1; - - qp = rxe_alloc(&rxe->qp_pool); - if (!qp) { - err = -ENOMEM; - goto err1; - } + return err; if (udata) { - if (udata->inlen) { - err = -EINVAL; - goto err2; - } + if (udata->inlen) + return -EINVAL; + qp->is_user = true; } else { qp->is_user = false; } - rxe_add_index(qp); + err = rxe_add_to_pool(&rxe->qp_pool, qp); + if (err) + return err; - err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibpd, udata); + rxe_add_index(qp); + err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibqp->pd, udata); if (err) - goto err3; + goto qp_init; - return &qp->ibqp; + return 0; -err3: +qp_init: rxe_drop_index(qp); -err2: rxe_drop_ref(qp); -err1: - return ERR_PTR(err); + return err; } static int rxe_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, @@ -1145,6 +1138,7 @@ static const struct ib_device_ops rxe_dev_ops = { INIT_RDMA_OBJ_SIZE(ib_ah, rxe_ah, ibah), INIT_RDMA_OBJ_SIZE(ib_cq, rxe_cq, ibcq), INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd), + INIT_RDMA_OBJ_SIZE(ib_qp, rxe_qp, ibqp), INIT_RDMA_OBJ_SIZE(ib_srq, rxe_srq, ibsrq), INIT_RDMA_OBJ_SIZE(ib_ucontext, rxe_ucontext, ibuc), INIT_RDMA_OBJ_SIZE(ib_mw, rxe_mw, ibmw), diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index 959a3260fcab..ac2a2148027f 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -210,8 +210,8 @@ struct rxe_resp_info { }; struct rxe_qp { - struct rxe_pool_entry pelem; struct ib_qp ibqp; + struct rxe_pool_entry pelem; struct ib_qp_attr attr; unsigned int valid; unsigned int mtu; diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c index cf55326f2ab4..9093e6a80b26 100644 --- a/drivers/infiniband/sw/siw/siw_main.c +++ b/drivers/infiniband/sw/siw/siw_main.c @@ -297,6 +297,7 @@ static const struct ib_device_ops siw_device_ops = { INIT_RDMA_OBJ_SIZE(ib_cq, siw_cq, base_cq), INIT_RDMA_OBJ_SIZE(ib_pd, siw_pd, base_pd), + INIT_RDMA_OBJ_SIZE(ib_qp, siw_qp, base_qp), INIT_RDMA_OBJ_SIZE(ib_srq, siw_srq, base_srq), INIT_RDMA_OBJ_SIZE(ib_ucontext, siw_ucontext, base_ucontext), }; diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c index ddb2e66f9f13..7e01f2438afc 100644 --- a/drivers/infiniband/sw/siw/siw_qp.c +++ b/drivers/infiniband/sw/siw/siw_qp.c @@ -1344,6 +1344,4 @@ void siw_free_qp(struct kref *ref) siw_put_tx_cpu(qp->tx_cpu); atomic_dec(&sdev->num_qp); - siw_dbg_qp(qp, "free QP\n"); - kfree_rcu(qp, rcu); } diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index 3f175f220a22..1b36350601fa 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -285,16 +285,16 @@ siw_mmap_entry_insert(struct siw_ucontext *uctx, * * Create QP of requested size on given device. * - * @pd: Protection Domain + * @qp: Queue pait * @attrs: Initial QP attributes. * @udata: used to provide QP ID, SQ and RQ size back to user. */ -struct ib_qp *siw_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *attrs, - struct ib_udata *udata) +int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, + struct ib_udata *udata) { - struct siw_qp *qp = NULL; + struct ib_pd *pd = ibqp->pd; + struct siw_qp *qp = to_siw_qp(ibqp); struct ib_device *base_dev = pd->device; struct siw_device *sdev = to_siw_dev(base_dev); struct siw_ucontext *uctx = @@ -307,17 +307,16 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, siw_dbg(base_dev, "create new QP\n"); if (attrs->create_flags) - return ERR_PTR(-EOPNOTSUPP); + return -EOPNOTSUPP; if (atomic_inc_return(&sdev->num_qp) > SIW_MAX_QP) { siw_dbg(base_dev, "too many QP's\n"); - rv = -ENOMEM; - goto err_out; + return -ENOMEM; } if (attrs->qp_type != IB_QPT_RC) { siw_dbg(base_dev, "only RC QP's supported\n"); rv = -EOPNOTSUPP; - goto err_out; + goto err_atomic; } if ((attrs->cap.max_send_wr > SIW_MAX_QP_WR) || (attrs->cap.max_recv_wr > SIW_MAX_QP_WR) || @@ -325,13 +324,13 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, (attrs->cap.max_recv_sge > SIW_MAX_SGE)) { siw_dbg(base_dev, "QP size error\n"); rv = -EINVAL; - goto err_out; + goto err_atomic; } if (attrs->cap.max_inline_data > SIW_MAX_INLINE) { siw_dbg(base_dev, "max inline send: %d > %d\n", attrs->cap.max_inline_data, (int)SIW_MAX_INLINE); rv = -EINVAL; - goto err_out; + goto err_atomic; } /* * NOTE: we allow for zero element SQ and RQ WQE's SGL's @@ -340,19 +339,15 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, if (attrs->cap.max_send_wr + attrs->cap.max_recv_wr == 0) { siw_dbg(base_dev, "QP must have send or receive queue\n"); rv = -EINVAL; - goto err_out; + goto err_atomic; } if (!attrs->send_cq || (!attrs->recv_cq && !attrs->srq)) { siw_dbg(base_dev, "send CQ or receive CQ invalid\n"); rv = -EINVAL; - goto err_out; - } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - rv = -ENOMEM; - goto err_out; + goto err_atomic; } + init_rwsem(&qp->state_lock); spin_lock_init(&qp->sq_lock); spin_lock_init(&qp->rq_lock); @@ -360,7 +355,7 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, rv = siw_qp_add(sdev, qp); if (rv) - goto err_out; + goto err_atomic; num_sqe = attrs->cap.max_send_wr; num_rqe = attrs->cap.max_recv_wr; @@ -482,23 +477,20 @@ struct ib_qp *siw_create_qp(struct ib_pd *pd, list_add_tail(&qp->devq, &sdev->qp_list); spin_unlock_irqrestore(&sdev->lock, flags); - return &qp->base_qp; + return 0; err_out_xa: xa_erase(&sdev->qp_xa, qp_id(qp)); -err_out: - if (qp) { - if (uctx) { - rdma_user_mmap_entry_remove(qp->sq_entry); - rdma_user_mmap_entry_remove(qp->rq_entry); - } - vfree(qp->sendq); - vfree(qp->recvq); - kfree(qp); + if (uctx) { + rdma_user_mmap_entry_remove(qp->sq_entry); + rdma_user_mmap_entry_remove(qp->rq_entry); } - atomic_dec(&sdev->num_qp); + vfree(qp->sendq); + vfree(qp->recvq); - return ERR_PTR(rv); +err_atomic: + atomic_dec(&sdev->num_qp); + return rv; } /* diff --git a/drivers/infiniband/sw/siw/siw_verbs.h b/drivers/infiniband/sw/siw/siw_verbs.h index 67ac08886a70..09964234f8d3 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.h +++ b/drivers/infiniband/sw/siw/siw_verbs.h @@ -50,9 +50,8 @@ int siw_query_gid(struct ib_device *base_dev, u32 port, int idx, union ib_gid *gid); int siw_alloc_pd(struct ib_pd *base_pd, struct ib_udata *udata); int siw_dealloc_pd(struct ib_pd *base_pd, struct ib_udata *udata); -struct ib_qp *siw_create_qp(struct ib_pd *base_pd, - struct ib_qp_init_attr *attr, - struct ib_udata *udata); +int siw_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attr, + struct ib_udata *udata); int siw_query_qp(struct ib_qp *base_qp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr); int siw_verbs_modify_qp(struct ib_qp *base_qp, struct ib_qp_attr *attr, diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 371df1c80aeb..6737582e9e2e 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -2268,8 +2268,13 @@ struct iw_cm_conn_param; !__same_type(((struct drv_struct *)NULL)->member, \ struct ib_struct))) -#define rdma_zalloc_drv_obj_gfp(ib_dev, ib_type, gfp) \ - ((struct ib_type *)kzalloc(ib_dev->ops.size_##ib_type, gfp)) +#define rdma_zalloc_drv_obj_gfp(ib_dev, ib_type, gfp) \ + ((struct ib_type *)rdma_zalloc_obj(ib_dev, ib_dev->ops.size_##ib_type, \ + gfp, false)) + +#define rdma_zalloc_drv_obj_numa(ib_dev, ib_type) \ + ((struct ib_type *)rdma_zalloc_obj(ib_dev, ib_dev->ops.size_##ib_type, \ + GFP_KERNEL, true)) #define rdma_zalloc_drv_obj(ib_dev, ib_type) \ rdma_zalloc_drv_obj_gfp(ib_dev, ib_type, GFP_KERNEL) @@ -2435,9 +2440,8 @@ struct ib_device_ops { struct ib_udata *udata); int (*query_srq)(struct ib_srq *srq, struct ib_srq_attr *srq_attr); int (*destroy_srq)(struct ib_srq *srq, struct ib_udata *udata); - struct ib_qp *(*create_qp)(struct ib_pd *pd, - struct ib_qp_init_attr *qp_init_attr, - struct ib_udata *udata); + int (*create_qp)(struct ib_qp *qp, struct ib_qp_init_attr *qp_init_attr, + struct ib_udata *udata); int (*modify_qp)(struct ib_qp *qp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_udata *udata); int (*query_qp)(struct ib_qp *qp, struct ib_qp_attr *qp_attr, @@ -2635,11 +2639,18 @@ struct ib_device_ops { int (*query_ucontext)(struct ib_ucontext *context, struct uverbs_attr_bundle *attrs); + /* + * Provide NUMA node. This API exists for rdmavt/hfi1 only. + * Everyone else relies on Linux memory management model. + */ + int (*get_numa_node)(struct ib_device *dev); + DECLARE_RDMA_OBJ_SIZE(ib_ah); DECLARE_RDMA_OBJ_SIZE(ib_counters); DECLARE_RDMA_OBJ_SIZE(ib_cq); DECLARE_RDMA_OBJ_SIZE(ib_mw); DECLARE_RDMA_OBJ_SIZE(ib_pd); + DECLARE_RDMA_OBJ_SIZE(ib_qp); DECLARE_RDMA_OBJ_SIZE(ib_rwq_ind_table); DECLARE_RDMA_OBJ_SIZE(ib_srq); DECLARE_RDMA_OBJ_SIZE(ib_ucontext); @@ -2746,6 +2757,15 @@ struct ib_device { u32 lag_flags; }; +static inline void *rdma_zalloc_obj(struct ib_device *dev, size_t size, + gfp_t gfp, bool is_numa_aware) +{ + if (is_numa_aware && dev->ops.get_numa_node) + return kzalloc_node(size, gfp, dev->ops.get_numa_node(dev)); + + return kzalloc(size, gfp); +} + struct ib_client_nl_info; struct ib_client { const char *name; -- cgit v1.2.3-70-g09d2 From 20da44dfe8eff5b61685e394dec690a5d9dc36ce Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Fri, 23 Jul 2021 14:39:51 +0300 Subject: RDMA/mlx5: Drop in-driver verbs object creations There is no real value in bypassing IB/core APIs for creating standard objects with standard types. The open-coded variant didn't have any restrack task management calls and caused to such objects to be not present when running rdmatoool. Link: https://lore.kernel.org/r/f745590e5fb7d56f90fdb25f64ee3983ba17e1e4.1627040189.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/verbs.c | 7 +-- drivers/infiniband/hw/mlx5/main.c | 92 +++++++++------------------------------ 2 files changed, 25 insertions(+), 74 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index a164609c2ee7..89c6987cb5eb 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1035,7 +1035,8 @@ struct ib_srq *ib_create_srq_user(struct ib_pd *pd, } if (srq->srq_type == IB_SRQT_XRC) { srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd; - atomic_inc(&srq->ext.xrc.xrcd->usecnt); + if (srq->ext.xrc.xrcd) + atomic_inc(&srq->ext.xrc.xrcd->usecnt); } atomic_inc(&pd->usecnt); @@ -1046,7 +1047,7 @@ struct ib_srq *ib_create_srq_user(struct ib_pd *pd, if (ret) { rdma_restrack_put(&srq->res); atomic_dec(&srq->pd->usecnt); - if (srq->srq_type == IB_SRQT_XRC) + if (srq->srq_type == IB_SRQT_XRC && srq->ext.xrc.xrcd) atomic_dec(&srq->ext.xrc.xrcd->usecnt); if (ib_srq_has_cq(srq->srq_type)) atomic_dec(&srq->ext.cq->usecnt); @@ -1090,7 +1091,7 @@ int ib_destroy_srq_user(struct ib_srq *srq, struct ib_udata *udata) return ret; atomic_dec(&srq->pd->usecnt); - if (srq->srq_type == IB_SRQT_XRC) + if (srq->srq_type == IB_SRQT_XRC && srq->ext.xrc.xrcd) atomic_dec(&srq->ext.xrc.xrcd->usecnt); if (ib_srq_has_cq(srq->srq_type)) atomic_dec(&srq->ext.cq->usecnt); diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 46f28514cf3a..60dfc666d33a 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -2802,31 +2802,16 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) if (!MLX5_CAP_GEN(dev->mdev, xrc)) return -EOPNOTSUPP; - devr->p0 = rdma_zalloc_drv_obj(ibdev, ib_pd); - if (!devr->p0) - return -ENOMEM; - - devr->p0->device = ibdev; - devr->p0->uobject = NULL; - atomic_set(&devr->p0->usecnt, 0); + devr->p0 = ib_alloc_pd(ibdev, 0); + if (IS_ERR(devr->p0)) + return PTR_ERR(devr->p0); - ret = mlx5_ib_alloc_pd(devr->p0, NULL); - if (ret) - goto error0; - - devr->c0 = rdma_zalloc_drv_obj(ibdev, ib_cq); - if (!devr->c0) { - ret = -ENOMEM; + devr->c0 = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr); + if (IS_ERR(devr->c0)) { + ret = PTR_ERR(devr->c0); goto error1; } - devr->c0->device = &dev->ib_dev; - atomic_set(&devr->c0->usecnt, 0); - - ret = mlx5_ib_create_cq(devr->c0, &cq_attr, NULL); - if (ret) - goto err_create_cq; - ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0); if (ret) goto error2; @@ -2841,45 +2826,22 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) attr.srq_type = IB_SRQT_XRC; attr.ext.cq = devr->c0; - devr->s0 = rdma_zalloc_drv_obj(ibdev, ib_srq); - if (!devr->s0) { - ret = -ENOMEM; - goto error4; - } - - devr->s0->device = &dev->ib_dev; - devr->s0->pd = devr->p0; - devr->s0->srq_type = IB_SRQT_XRC; - devr->s0->ext.cq = devr->c0; - ret = mlx5_ib_create_srq(devr->s0, &attr, NULL); - if (ret) + devr->s0 = ib_create_srq(devr->p0, &attr); + if (IS_ERR(devr->s0)) { + ret = PTR_ERR(devr->s0); goto err_create; - - atomic_inc(&devr->s0->ext.cq->usecnt); - atomic_inc(&devr->p0->usecnt); - atomic_set(&devr->s0->usecnt, 0); + } memset(&attr, 0, sizeof(attr)); attr.attr.max_sge = 1; attr.attr.max_wr = 1; attr.srq_type = IB_SRQT_BASIC; - devr->s1 = rdma_zalloc_drv_obj(ibdev, ib_srq); - if (!devr->s1) { - ret = -ENOMEM; - goto error5; - } - - devr->s1->device = &dev->ib_dev; - devr->s1->pd = devr->p0; - devr->s1->srq_type = IB_SRQT_BASIC; - devr->s1->ext.cq = devr->c0; - ret = mlx5_ib_create_srq(devr->s1, &attr, NULL); - if (ret) + devr->s1 = ib_create_srq(devr->p0, &attr); + if (IS_ERR(devr->s1)) { + ret = PTR_ERR(devr->s1); goto error6; - - atomic_inc(&devr->p0->usecnt); - atomic_set(&devr->s1->usecnt, 0); + } for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) INIT_WORK(&devr->ports[port].pkey_change_work, @@ -2888,23 +2850,15 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev) return 0; error6: - kfree(devr->s1); -error5: - mlx5_ib_destroy_srq(devr->s0, NULL); + ib_destroy_srq(devr->s0); err_create: - kfree(devr->s0); -error4: mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0); error3: mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0); error2: - mlx5_ib_destroy_cq(devr->c0, NULL); -err_create_cq: - kfree(devr->c0); + ib_destroy_cq(devr->c0); error1: - mlx5_ib_dealloc_pd(devr->p0, NULL); -error0: - kfree(devr->p0); + ib_dealloc_pd(devr->p0); return ret; } @@ -2922,16 +2876,12 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev) for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) cancel_work_sync(&devr->ports[port].pkey_change_work); - mlx5_ib_destroy_srq(devr->s1, NULL); - kfree(devr->s1); - mlx5_ib_destroy_srq(devr->s0, NULL); - kfree(devr->s0); + ib_destroy_srq(devr->s1); + ib_destroy_srq(devr->s0); mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0); mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0); - mlx5_ib_destroy_cq(devr->c0, NULL); - kfree(devr->c0); - mlx5_ib_dealloc_pd(devr->p0, NULL); - kfree(devr->p0); + ib_destroy_cq(devr->c0); + ib_dealloc_pd(devr->p0); } static u32 get_core_cap_flags(struct ib_device *ibdev, -- cgit v1.2.3-70-g09d2 From 4f993264fe2965c344f223d854ccbb549b16ed71 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Tue, 3 Aug 2021 08:15:43 +0800 Subject: f2fs: introduce discard_unit mount option As James Z reported in bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=213877 [1.] One-line summary of the problem: Mount multiple SMR block devices exceed certain number cause system non-response [2.] Full description of the problem/report: Created some F2FS on SMR devices (mkfs.f2fs -m), then mounted in sequence. Each device is the same Model: HGST HSH721414AL (Size 14TB). Empirically, found that when the amount of SMR device * 1.5Gb > System RAM, the system ran out of memory and hung. No dmesg output. For example, 24 SMR Disk need 24*1.5GB = 36GB. A system with 32G RAM can only mount 21 devices, the 22nd device will be a reproducible cause of system hang. The number of SMR devices with other FS mounted on this system does not interfere with the result above. [3.] Keywords (i.e., modules, networking, kernel): F2FS, SMR, Memory [4.] Kernel information [4.1.] Kernel version (uname -a): Linux 5.13.4-200.fc34.x86_64 #1 SMP Tue Jul 20 20:27:29 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux [4.2.] Kernel .config file: Default Fedora 34 with f2fs-tools-1.14.0-2.fc34.x86_64 [5.] Most recent kernel version which did not have the bug: None [6.] Output of Oops.. message (if applicable) with symbolic information resolved (see Documentation/admin-guide/oops-tracing.rst) None [7.] A small shell script or example program which triggers the problem (if possible) mount /dev/sdX /mnt/0X [8.] Memory consumption With 24 * 14T SMR Block device with F2FS free -g total used free shared buff/cache available Mem: 46 36 0 0 10 10 Swap: 0 0 0 With 3 * 14T SMR Block device with F2FS free -g total used free shared buff/cache available Mem: 7 5 0 0 1 1 Swap: 7 0 7 The root cause is, there are three bitmaps: - cur_valid_map - ckpt_valid_map - discard_map and each of them will cost ~500MB memory, {cur, ckpt}_valid_map are necessary, but discard_map is optional, since this bitmap will only be useful in mountpoint that small discard is enabled. For a blkzoned device such as SMR or ZNS devices, f2fs will only issue discard for a section(zone) when all blocks of that section are invalid, so, for such device, we don't need small discard functionality at all. This patch introduces a new mountoption "discard_unit=block|segment| section" to support issuing discard with different basic unit which is aligned to block, segment or section, so that user can specify "discard_unit=segment" or "discard_unit=section" to disable small discard functionality. Note that this mount option can not be changed by remount() due to related metadata need to be initialized during mount(). In order to save memory, let's use "discard_unit=section" for blkzoned device by default. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/filesystems/f2fs.rst | 8 ++++ fs/f2fs/f2fs.h | 16 ++++++++ fs/f2fs/segment.c | 82 ++++++++++++++++++++++++-------------- fs/f2fs/super.c | 54 +++++++++++++++++++++++-- fs/f2fs/sysfs.c | 2 + 5 files changed, 130 insertions(+), 32 deletions(-) diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index ff9e7cc97c65..8f251a662542 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -312,6 +312,14 @@ inlinecrypt When possible, encrypt/decrypt the contents of encrypted Documentation/block/inline-encryption.rst. atgc Enable age-threshold garbage collection, it provides high effectiveness and efficiency on background GC. +discard_unit=%s Control discard unit, the argument can be "block", "segment" + and "section", issued discard command's offset/size will be + aligned to the unit, by default, "discard_unit=block" is set, + so that small discard functionality is enabled. + For blkzoned device, "discard_unit=section" will be set by + default, it is helpful for large sized SMR or ZNS devices to + reduce memory cost by getting rid of fs metadata supports small + discard. ======================== ============================================================ Debugfs Entries diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 8459b6d5a2f8..8d4665a7a0fb 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -139,6 +139,11 @@ struct f2fs_mount_info { int fsync_mode; /* fsync policy */ int fs_mode; /* fs mode: LFS or ADAPTIVE */ int bggc_mode; /* bggc mode: off, on or sync */ + int discard_unit; /* + * discard command's offset/size should + * be aligned to this unit: block, + * segment or section + */ struct fscrypt_dummy_policy dummy_enc_policy; /* test dummy encryption */ block_t unusable_cap_perc; /* percentage for cap */ block_t unusable_cap; /* Amount of space allowed to be @@ -1299,6 +1304,12 @@ enum { */ }; +enum { + DISCARD_UNIT_BLOCK, /* basic discard unit is block */ + DISCARD_UNIT_SEGMENT, /* basic discard unit is segment */ + DISCARD_UNIT_SECTION, /* basic discard unit is section */ +}; + static inline int f2fs_test_bit(unsigned int nr, char *addr); static inline void f2fs_set_bit(unsigned int nr, char *addr); static inline void f2fs_clear_bit(unsigned int nr, char *addr); @@ -4365,6 +4376,11 @@ static inline bool is_journalled_quota(struct f2fs_sb_info *sbi) return false; } +static inline bool f2fs_block_unit_discard(struct f2fs_sb_info *sbi) +{ + return F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK; +} + #define EFSBADCRC EBADMSG /* Bad CRC detected */ #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 0f976cefe425..80f26158e304 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1893,7 +1893,8 @@ static int f2fs_issue_discard(struct f2fs_sb_info *sbi, se = get_seg_entry(sbi, GET_SEGNO(sbi, i)); offset = GET_BLKOFF_FROM_SEG0(sbi, i); - if (!f2fs_test_and_set_bit(offset, se->discard_map)) + if (f2fs_block_unit_discard(sbi) && + !f2fs_test_and_set_bit(offset, se->discard_map)) sbi->discard_blks--; } @@ -1918,7 +1919,8 @@ static bool add_discard_addrs(struct f2fs_sb_info *sbi, struct cp_control *cpc, struct list_head *head = &SM_I(sbi)->dcc_info->entry_list; int i; - if (se->valid_blocks == max_blocks || !f2fs_hw_support_discard(sbi)) + if (se->valid_blocks == max_blocks || !f2fs_hw_support_discard(sbi) || + !f2fs_block_unit_discard(sbi)) return false; if (!force) { @@ -2003,14 +2005,18 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi, unsigned int start = 0, end = -1; unsigned int secno, start_segno; bool force = (cpc->reason & CP_DISCARD); - bool need_align = f2fs_lfs_mode(sbi) && __is_large_section(sbi); + bool section_alignment = F2FS_OPTION(sbi).discard_unit == + DISCARD_UNIT_SECTION; + + if (f2fs_lfs_mode(sbi) && __is_large_section(sbi)) + section_alignment = true; mutex_lock(&dirty_i->seglist_lock); while (1) { int i; - if (need_align && end != -1) + if (section_alignment && end != -1) end--; start = find_next_bit(prefree_map, MAIN_SEGS(sbi), end + 1); if (start >= MAIN_SEGS(sbi)) @@ -2018,7 +2024,7 @@ void f2fs_clear_prefree_segments(struct f2fs_sb_info *sbi, end = find_next_zero_bit(prefree_map, MAIN_SEGS(sbi), start + 1); - if (need_align) { + if (section_alignment) { start = rounddown(start, sbi->segs_per_sec); end = roundup(end, sbi->segs_per_sec); } @@ -2056,6 +2062,9 @@ next: } mutex_unlock(&dirty_i->seglist_lock); + if (!f2fs_block_unit_discard(sbi)) + goto wakeup; + /* send small discards */ list_for_each_entry_safe(entry, this, head, list) { unsigned int cur_pos = 0, next_pos, len, total_len = 0; @@ -2089,6 +2098,7 @@ skip: dcc->nr_discards -= total_len; } +wakeup: wake_up_discard_thread(sbi, false); } @@ -2108,6 +2118,11 @@ static int create_discard_cmd_control(struct f2fs_sb_info *sbi) return -ENOMEM; dcc->discard_granularity = DEFAULT_DISCARD_GRANULARITY; + if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT) + dcc->discard_granularity = sbi->blocks_per_seg; + else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION) + dcc->discard_granularity = BLKS_PER_SEC(sbi); + INIT_LIST_HEAD(&dcc->entry_list); for (i = 0; i < MAX_PLIST_NUM; i++) INIT_LIST_HEAD(&dcc->pend_list[i]); @@ -2255,7 +2270,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) del = 0; } - if (!f2fs_test_and_set_bit(offset, se->discard_map)) + if (f2fs_block_unit_discard(sbi) && + !f2fs_test_and_set_bit(offset, se->discard_map)) sbi->discard_blks--; /* @@ -2297,7 +2313,8 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) } } - if (f2fs_test_and_clear_bit(offset, se->discard_map)) + if (f2fs_block_unit_discard(sbi) && + f2fs_test_and_clear_bit(offset, se->discard_map)) sbi->discard_blks++; } if (!f2fs_test_bit(offset, se->ckpt_valid_map)) @@ -4282,6 +4299,7 @@ static int build_sit_info(struct f2fs_sb_info *sbi) unsigned int sit_segs, start; char *src_bitmap, *bitmap; unsigned int bitmap_size, main_bitmap_size, sit_bitmap_size; + unsigned int discard_map = f2fs_block_unit_discard(sbi) ? 1 : 0; /* allocate memory for SIT information */ sit_i = f2fs_kzalloc(sbi, sizeof(struct sit_info), GFP_KERNEL); @@ -4304,9 +4322,9 @@ static int build_sit_info(struct f2fs_sb_info *sbi) return -ENOMEM; #ifdef CONFIG_F2FS_CHECK_FS - bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * 4; + bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * (3 + discard_map); #else - bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * 3; + bitmap_size = MAIN_SEGS(sbi) * SIT_VBLOCK_MAP_SIZE * (2 + discard_map); #endif sit_i->bitmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); if (!sit_i->bitmap) @@ -4326,8 +4344,10 @@ static int build_sit_info(struct f2fs_sb_info *sbi) bitmap += SIT_VBLOCK_MAP_SIZE; #endif - sit_i->sentries[start].discard_map = bitmap; - bitmap += SIT_VBLOCK_MAP_SIZE; + if (discard_map) { + sit_i->sentries[start].discard_map = bitmap; + bitmap += SIT_VBLOCK_MAP_SIZE; + } } sit_i->tmp_map = f2fs_kzalloc(sbi, SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); @@ -4489,17 +4509,19 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) if (IS_NODESEG(se->type)) total_node_blocks += se->valid_blocks; - /* build discard map only one time */ - if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) { - memset(se->discard_map, 0xff, - SIT_VBLOCK_MAP_SIZE); - } else { - memcpy(se->discard_map, - se->cur_valid_map, - SIT_VBLOCK_MAP_SIZE); - sbi->discard_blks += - sbi->blocks_per_seg - - se->valid_blocks; + if (f2fs_block_unit_discard(sbi)) { + /* build discard map only one time */ + if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) { + memset(se->discard_map, 0xff, + SIT_VBLOCK_MAP_SIZE); + } else { + memcpy(se->discard_map, + se->cur_valid_map, + SIT_VBLOCK_MAP_SIZE); + sbi->discard_blks += + sbi->blocks_per_seg - + se->valid_blocks; + } } if (__is_large_section(sbi)) @@ -4535,13 +4557,15 @@ static int build_sit_entries(struct f2fs_sb_info *sbi) if (IS_NODESEG(se->type)) total_node_blocks += se->valid_blocks; - if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) { - memset(se->discard_map, 0xff, SIT_VBLOCK_MAP_SIZE); - } else { - memcpy(se->discard_map, se->cur_valid_map, - SIT_VBLOCK_MAP_SIZE); - sbi->discard_blks += old_valid_blocks; - sbi->discard_blks -= se->valid_blocks; + if (f2fs_block_unit_discard(sbi)) { + if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) { + memset(se->discard_map, 0xff, SIT_VBLOCK_MAP_SIZE); + } else { + memcpy(se->discard_map, se->cur_valid_map, + SIT_VBLOCK_MAP_SIZE); + sbi->discard_blks += old_valid_blocks; + sbi->discard_blks -= se->valid_blocks; + } } if (__is_large_section(sbi)) { diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 3617aa5f0477..a4fed184b811 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -155,6 +155,7 @@ enum { Opt_atgc, Opt_gc_merge, Opt_nogc_merge, + Opt_discard_unit, Opt_err, }; @@ -231,6 +232,7 @@ static match_table_t f2fs_tokens = { {Opt_atgc, "atgc"}, {Opt_gc_merge, "gc_merge"}, {Opt_nogc_merge, "nogc_merge"}, + {Opt_discard_unit, "discard_unit=%s"}, {Opt_err, NULL}, }; @@ -1173,6 +1175,25 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) case Opt_nogc_merge: clear_opt(sbi, GC_MERGE); break; + case Opt_discard_unit: + name = match_strdup(&args[0]); + if (!name) + return -ENOMEM; + if (!strcmp(name, "block")) { + F2FS_OPTION(sbi).discard_unit = + DISCARD_UNIT_BLOCK; + } else if (!strcmp(name, "segment")) { + F2FS_OPTION(sbi).discard_unit = + DISCARD_UNIT_SEGMENT; + } else if (!strcmp(name, "section")) { + F2FS_OPTION(sbi).discard_unit = + DISCARD_UNIT_SECTION; + } else { + kfree(name); + return -EINVAL; + } + kfree(name); + break; default: f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value", p); @@ -1211,6 +1232,14 @@ default_check: return -EINVAL; } #endif + if (f2fs_sb_has_blkzoned(sbi)) { + if (F2FS_OPTION(sbi).discard_unit != + DISCARD_UNIT_SECTION) { + f2fs_info(sbi, "Zoned block device doesn't need small discard, set discard_unit=section by default"); + F2FS_OPTION(sbi).discard_unit = + DISCARD_UNIT_SECTION; + } + } #ifdef CONFIG_F2FS_FS_COMPRESSION if (f2fs_test_compress_extension(sbi)) { @@ -1925,6 +1954,14 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) if (test_opt(sbi, ATGC)) seq_puts(seq, ",atgc"); + + if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK) + seq_printf(seq, ",discard_unit=%s", "block"); + else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SEGMENT) + seq_printf(seq, ",discard_unit=%s", "segment"); + else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION) + seq_printf(seq, ",discard_unit=%s", "section"); + return 0; } @@ -1961,10 +1998,13 @@ static void default_options(struct f2fs_sb_info *sbi) sbi->sb->s_flags |= SB_LAZYTIME; set_opt(sbi, FLUSH_MERGE); set_opt(sbi, DISCARD); - if (f2fs_sb_has_blkzoned(sbi)) + if (f2fs_sb_has_blkzoned(sbi)) { F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; - else + F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; + } else { F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; + F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK; + } #ifdef CONFIG_F2FS_FS_XATTR set_opt(sbi, XATTR_USER); @@ -2066,6 +2106,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); + bool block_unit_discard = f2fs_block_unit_discard(sbi); #ifdef CONFIG_QUOTA int i, j; #endif @@ -2166,6 +2207,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } + if (block_unit_discard != f2fs_block_unit_discard(sbi)) { + err = -EINVAL; + f2fs_warn(sbi, "switch discard_unit option is not allowed"); + goto restore_opts; + } + if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) { err = -EINVAL; f2fs_warn(sbi, "disabling checkpoint not compatible with read-only"); @@ -3778,7 +3825,8 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) /* adjust parameters according to the volume size */ if (sm_i->main_segments <= SMALL_VOLUME_SEGMENTS) { F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_REUSE; - sm_i->dcc_info->discard_granularity = 1; + if (f2fs_block_unit_discard(sbi)) + sm_i->dcc_info->discard_granularity = 1; sm_i->ipu_policy = 1 << F2FS_IPU_FORCE; } diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index b1725620c07d..f98afd9f9380 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -428,6 +428,8 @@ out: if (!strcmp(a->attr.name, "discard_granularity")) { if (t == 0 || t > MAX_PLIST_NUM) return -EINVAL; + if (!f2fs_block_unit_discard(sbi)) + return -EINVAL; if (t == *ui) return count; *ui = t; -- cgit v1.2.3-70-g09d2 From 0f6b56ec958d49e2b3dc955cdac6b62702c04b72 Mon Sep 17 00:00:00 2001 From: Daeho Jeong Date: Mon, 2 Aug 2021 21:22:45 -0700 Subject: f2fs: add sysfs node to control ra_pages for fadvise seq file fadvise() allows the user to expand the readahead window to double with POSIX_FADV_SEQUENTIAL, now. But, in some use cases, it is not that sufficient and we need to meet the need in a restricted way. We can control the multiplier value of bdi device readahead between 2 (default) and 256 for POSIX_FADV_SEQUENTIAL advise option. Signed-off-by: Daeho Jeong Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++ fs/f2fs/f2fs.h | 5 +++++ fs/f2fs/file.c | 30 ++++++++++++++++++++++++++++++ fs/f2fs/super.c | 1 + fs/f2fs/sysfs.c | 10 ++++++++++ 5 files changed, 52 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 845c4be535b0..73211f77d11e 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -507,3 +507,9 @@ Date: July 2021 Contact: "Daeho Jeong" Description: You can control for which gc mode the "gc_reclaimed_segments" node shows. Refer to the description of the modes in "gc_reclaimed_segments". + +What: /sys/fs/f2fs//seq_file_ra_mul +Date: July 2021 +Contact: "Daeho Jeong" +Description: You can control the multiplier value of bdi device readahead window size + between 2 (default) and 256 for POSIX_FADV_SEQUENTIAL advise option. diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 8d4665a7a0fb..1b4c482d08e2 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1749,6 +1749,8 @@ struct f2fs_sb_info { unsigned int gc_segment_mode; /* GC state for reclaimed segments */ unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */ + unsigned long seq_file_ra_mul; /* multiplier for ra_pages of seq. files in fadvise */ + #ifdef CONFIG_F2FS_FS_COMPRESSION struct kmem_cache *page_array_slab; /* page array entry */ unsigned int page_array_slab_size; /* default page array slab size */ @@ -4003,6 +4005,9 @@ void f2fs_destroy_extent_cache(void); /* * sysfs.c */ +#define MIN_RA_MUL 2 +#define MAX_RA_MUL 256 + int __init f2fs_init_sysfs(void); void f2fs_exit_sysfs(void); int f2fs_register_sysfs(struct f2fs_sb_info *sbi); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index e931782abdab..7d8ee60f6c1f 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" @@ -4344,6 +4345,34 @@ out: return ret; } +static int f2fs_file_fadvise(struct file *filp, loff_t offset, loff_t len, + int advice) +{ + struct inode *inode; + struct address_space *mapping; + struct backing_dev_info *bdi; + + if (advice == POSIX_FADV_SEQUENTIAL) { + inode = file_inode(filp); + if (S_ISFIFO(inode->i_mode)) + return -ESPIPE; + + mapping = filp->f_mapping; + if (!mapping || len < 0) + return -EINVAL; + + bdi = inode_to_bdi(mapping->host); + filp->f_ra.ra_pages = bdi->ra_pages * + F2FS_I_SB(inode)->seq_file_ra_mul; + spin_lock(&filp->f_lock); + filp->f_mode &= ~FMODE_RANDOM; + spin_unlock(&filp->f_lock); + return 0; + } + + return generic_fadvise(filp, offset, len, advice); +} + #ifdef CONFIG_COMPAT struct compat_f2fs_gc_range { u32 sync; @@ -4472,4 +4501,5 @@ const struct file_operations f2fs_file_operations = { #endif .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, + .fadvise = f2fs_file_fadvise, }; diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index a4fed184b811..84cd085020cd 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3466,6 +3466,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi) sbi->next_victim_seg[FG_GC] = NULL_SEGNO; sbi->max_victim_search = DEF_MAX_VICTIM_SEARCH; sbi->migration_granularity = sbi->segs_per_sec; + sbi->seq_file_ra_mul = MIN_RA_MUL; sbi->dir_level = DEF_DIR_LEVEL; sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index f98afd9f9380..0954761341d7 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -540,6 +540,14 @@ out: return count; } + if (!strcmp(a->attr.name, "seq_file_ra_mul")) { + if (t >= MIN_RA_MUL && t <= MAX_RA_MUL) + sbi->seq_file_ra_mul = t; + else + return -EINVAL; + return count; + } + *ui = (unsigned int)t; return count; @@ -765,6 +773,7 @@ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_cou F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, seq_file_ra_mul, seq_file_ra_mul); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs); @@ -840,6 +849,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(atgc_candidate_count), ATTR_LIST(atgc_age_weight), ATTR_LIST(atgc_age_threshold), + ATTR_LIST(seq_file_ra_mul), ATTR_LIST(gc_segment_mode), ATTR_LIST(gc_reclaimed_segments), NULL, -- cgit v1.2.3-70-g09d2 From 5f6bb7e32283b8e3339b7adc00638234ac199cc4 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:32 +0300 Subject: RDMA/mlx5: Delete not-available udata check XRC_TGT QPs are created through kernel verbs and don't have udata at all. Fixes: 6eefa839c4dd ("RDMA/mlx5: Protect from kernel crash if XRC_TGT doesn't have udata") Fixes: e383085c2425 ("RDMA/mlx5: Set ECE options during QP create") Link: https://lore.kernel.org/r/b68228597e730675020aa5162745390a2d39d3a2.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/qp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 9d20c838974f..556b5e7acd46 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -1906,7 +1906,6 @@ static int get_atomic_mode(struct mlx5_ib_dev *dev, static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, struct mlx5_create_qp_params *params) { - struct mlx5_ib_create_qp *ucmd = params->ucmd; struct ib_qp_init_attr *attr = params->attr; u32 uidx = params->uidx; struct mlx5_ib_resources *devr = &dev->devr; @@ -1926,8 +1925,6 @@ static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, if (!in) return -ENOMEM; - if (MLX5_CAP_GEN(mdev, ece_support) && ucmd) - MLX5_SET(create_qp_in, in, ece, ucmd->ece_options); qpc = MLX5_ADDR_OF(create_qp_in, in, qpc); MLX5_SET(qpc, qpc, st, MLX5_QP_ST_XRC); -- cgit v1.2.3-70-g09d2 From 8fc3beebf623092e446f4c88fca1699c868ca86d Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:33 +0300 Subject: RDMA/core: Delete duplicated and unreachable code The ib_create_named_qp() is kernel verb and no kernel users exist that use XRC_INI QP. Hence such QP path is not reachable. In addition, delete duplicated assignments of QP attributes from the initialization structure. Link: https://lore.kernel.org/r/1b4c0d1def5f8f6d26839e14d19da950cc4a0b05.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 1 + drivers/infiniband/core/verbs.c | 22 ++++------------------ 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index fa2e0bbaf8c7..c870adecd3a4 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -341,6 +341,7 @@ _ib_create_qp(struct ib_device *dev, struct ib_pd *pd, qp->srq = attr->srq; qp->event_handler = attr->event_handler; qp->port = attr->port_num; + qp->qp_context = attr->qp_context; spin_lock_init(&qp->mr_lock); INIT_LIST_HEAD(&qp->rdma_mrs); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 89c6987cb5eb..635642a3ecbc 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1257,28 +1257,14 @@ struct ib_qp *ib_create_named_qp(struct ib_pd *pd, return xrc_qp; } - qp->event_handler = qp_init_attr->event_handler; - qp->qp_context = qp_init_attr->qp_context; - if (qp_init_attr->qp_type == IB_QPT_XRC_INI) { - qp->recv_cq = NULL; - qp->srq = NULL; - } else { - qp->recv_cq = qp_init_attr->recv_cq; - if (qp_init_attr->recv_cq) - atomic_inc(&qp_init_attr->recv_cq->usecnt); - qp->srq = qp_init_attr->srq; - if (qp->srq) - atomic_inc(&qp_init_attr->srq->usecnt); - } - - qp->send_cq = qp_init_attr->send_cq; - qp->xrcd = NULL; + if (qp_init_attr->recv_cq) + atomic_inc(&qp_init_attr->recv_cq->usecnt); + if (qp->srq) + atomic_inc(&qp_init_attr->srq->usecnt); atomic_inc(&pd->usecnt); if (qp_init_attr->send_cq) atomic_inc(&qp_init_attr->send_cq->usecnt); - if (qp_init_attr->rwq_ind_tbl) - atomic_inc(&qp->rwq_ind_tbl->usecnt); if (qp_init_attr->cap.max_rdma_ctxs) { ret = rdma_rw_init_mrs(qp, qp_init_attr); -- cgit v1.2.3-70-g09d2 From 20e2bcc4c2a8ede2fe6e335b9eea357bcfbe79bb Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:34 +0300 Subject: RDMA/core: Remove protection from wrong in-kernel API usage The ib_create_named_qp() is kernel verb that is not used for user supplied attributes. In such case, it is ULP responsibility to provide valid QP attributes. In-kernel API shouldn't check it, exactly like other functions that don't check device capabilities. Link: https://lore.kernel.org/r/b9b9e981d1af148b750750196e686199dbbf61f8.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/verbs.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 635642a3ecbc..2090f3c9f689 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1219,16 +1219,6 @@ struct ib_qp *ib_create_named_qp(struct ib_pd *pd, struct ib_qp *qp; int ret; - if (qp_init_attr->rwq_ind_tbl && - (qp_init_attr->recv_cq || - qp_init_attr->srq || qp_init_attr->cap.max_recv_wr || - qp_init_attr->cap.max_recv_sge)) - return ERR_PTR(-EINVAL); - - if ((qp_init_attr->create_flags & IB_QP_CREATE_INTEGRITY_EN) && - !(device->attrs.device_cap_flags & IB_DEVICE_INTEGRITY_HANDOVER)) - return ERR_PTR(-EINVAL); - /* * If the callers is using the RDMA API calculate the resources * needed for the RDMA READ/WRITE operations. -- cgit v1.2.3-70-g09d2 From 8da9fe4e4fa7d561df0f3fe65bfa6dbf78aa7590 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:35 +0300 Subject: RDMA/core: Reorganize create QP low-level functions The low-level create QP function grew to be larger than any sensible inline function should be. The inline attribute is not really needed for that function and can be implemented as exported symbol. Link: https://lore.kernel.org/r/2c08709d86f876c3dfb77684357b2a939e570ca4.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 58 ++--------------------------- drivers/infiniband/core/verbs.c | 74 ++++++++++++++++++++++++++++++++----- include/rdma/ib_verbs.h | 16 ++++++-- 3 files changed, 81 insertions(+), 67 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index c870adecd3a4..d28ced053222 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -316,60 +316,10 @@ struct ib_device *ib_device_get_by_index(const struct net *net, u32 index); void nldev_init(void); void nldev_exit(void); -static inline struct ib_qp * -_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, - struct ib_qp_init_attr *attr, struct ib_udata *udata, - struct ib_uqp_object *uobj, const char *caller) -{ - struct ib_qp *qp; - int ret; - - if (!dev->ops.create_qp) - return ERR_PTR(-EOPNOTSUPP); - - qp = rdma_zalloc_drv_obj_numa(dev, ib_qp); - if (!qp) - return ERR_PTR(-ENOMEM); - - qp->device = dev; - qp->pd = pd; - qp->uobject = uobj; - qp->real_qp = qp; - - qp->qp_type = attr->qp_type; - qp->rwq_ind_tbl = attr->rwq_ind_tbl; - qp->srq = attr->srq; - qp->event_handler = attr->event_handler; - qp->port = attr->port_num; - qp->qp_context = attr->qp_context; - - spin_lock_init(&qp->mr_lock); - INIT_LIST_HEAD(&qp->rdma_mrs); - INIT_LIST_HEAD(&qp->sig_mrs); - - rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP); - WARN_ONCE(!udata && !caller, "Missing kernel QP owner"); - rdma_restrack_set_name(&qp->res, udata ? NULL : caller); - ret = dev->ops.create_qp(qp, attr, udata); - if (ret) - goto err_create; - - /* - * TODO: The mlx4 internally overwrites send_cq and recv_cq. - * Unfortunately, it is not an easy task to fix that driver. - */ - qp->send_cq = attr->send_cq; - qp->recv_cq = attr->recv_cq; - - rdma_restrack_add(&qp->res); - return qp; - -err_create: - rdma_restrack_put(&qp->res); - kfree(qp); - return ERR_PTR(ret); - -} +struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, + struct ib_qp_init_attr *attr, + struct ib_udata *udata, struct ib_uqp_object *uobj, + const char *caller); struct rdma_dev_addr; int rdma_resolve_ip_route(struct sockaddr *src_addr, diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 2090f3c9f689..a7717df83273 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1201,19 +1201,75 @@ static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp, } /** - * ib_create_named_qp - Creates a kernel QP associated with the specified protection - * domain. + * _ib_create_qp - Creates a QP associated with the specified protection domain + * @dev: IB device * @pd: The protection domain associated with the QP. - * @qp_init_attr: A list of initial attributes required to create the + * @attr: A list of initial attributes required to create the * QP. If QP creation succeeds, then the attributes are updated to * the actual capabilities of the created QP. + * @udata: User data + * @uobj: uverbs obect * @caller: caller's build-time module name - * - * NOTE: for user qp use ib_create_qp_user with valid udata! */ -struct ib_qp *ib_create_named_qp(struct ib_pd *pd, - struct ib_qp_init_attr *qp_init_attr, - const char *caller) +struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, + struct ib_qp_init_attr *attr, + struct ib_udata *udata, struct ib_uqp_object *uobj, + const char *caller) +{ + struct ib_qp *qp; + int ret; + + if (!dev->ops.create_qp) + return ERR_PTR(-EOPNOTSUPP); + + qp = rdma_zalloc_drv_obj_numa(dev, ib_qp); + if (!qp) + return ERR_PTR(-ENOMEM); + + qp->device = dev; + qp->pd = pd; + qp->uobject = uobj; + qp->real_qp = qp; + + qp->qp_type = attr->qp_type; + qp->rwq_ind_tbl = attr->rwq_ind_tbl; + qp->srq = attr->srq; + qp->event_handler = attr->event_handler; + qp->port = attr->port_num; + qp->qp_context = attr->qp_context; + + spin_lock_init(&qp->mr_lock); + INIT_LIST_HEAD(&qp->rdma_mrs); + INIT_LIST_HEAD(&qp->sig_mrs); + + rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP); + WARN_ONCE(!udata && !caller, "Missing kernel QP owner"); + rdma_restrack_set_name(&qp->res, udata ? NULL : caller); + ret = dev->ops.create_qp(qp, attr, udata); + if (ret) + goto err_create; + + /* + * TODO: The mlx4 internally overwrites send_cq and recv_cq. + * Unfortunately, it is not an easy task to fix that driver. + */ + qp->send_cq = attr->send_cq; + qp->recv_cq = attr->recv_cq; + + rdma_restrack_add(&qp->res); + return qp; + +err_create: + rdma_restrack_put(&qp->res); + kfree(qp); + return ERR_PTR(ret); + +} +EXPORT_SYMBOL(_ib_create_qp); + +struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, + struct ib_qp_init_attr *qp_init_attr, + const char *caller) { struct ib_device *device = pd ? pd->device : qp_init_attr->xrcd->device; struct ib_qp *qp; @@ -1280,7 +1336,7 @@ err: return ERR_PTR(ret); } -EXPORT_SYMBOL(ib_create_named_qp); +EXPORT_SYMBOL(ib_create_qp_kernel); static const struct { int valid; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 6737582e9e2e..aa7806335cba 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -3688,13 +3688,21 @@ static inline int ib_post_srq_recv(struct ib_srq *srq, bad_recv_wr ? : &dummy); } -struct ib_qp *ib_create_named_qp(struct ib_pd *pd, - struct ib_qp_init_attr *qp_init_attr, - const char *caller); +struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, + struct ib_qp_init_attr *qp_init_attr, + const char *caller); +/** + * ib_create_qp - Creates a kernel QP associated with the specific protection + * domain. + * @pd: The protection domain associated with the QP. + * @init_attr: A list of initial attributes required to create the + * QP. If QP creation succeeds, then the attributes are updated to + * the actual capabilities of the created QP. + */ static inline struct ib_qp *ib_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *init_attr) { - return ib_create_named_qp(pd, init_attr, KBUILD_MODNAME); + return ib_create_qp_kernel(pd, init_attr, KBUILD_MODNAME); } /** -- cgit v1.2.3-70-g09d2 From 00a79d6b996d46e9077b0d02a19c87b99305b94a Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:36 +0300 Subject: RDMA/core: Configure selinux QP during creation All QP creation flows called ib_create_qp_security(), but differently. This caused to the need to provide exclusion conditions for the XRC_TGT, because such QP already had selinux configuration call. In order to fix it, move ib_create_qp_security() to the general QP creation routine. Link: https://lore.kernel.org/r/4d7cd6f5828aca37fb62283e6b126b73ab86b18c.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/uverbs_cmd.c | 7 ------- drivers/infiniband/core/uverbs_std_types_qp.c | 6 ------ drivers/infiniband/core/verbs.c | 11 +++++++---- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 8c8ca7bce3ca..b5153200b8a8 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1447,10 +1447,6 @@ static int create_qp(struct uverbs_attr_bundle *attrs, } if (cmd->qp_type != IB_QPT_XRC_TGT) { - ret = ib_create_qp_security(qp, device); - if (ret) - goto err_cb; - atomic_inc(&pd->usecnt); if (attr.send_cq) atomic_inc(&attr.send_cq->usecnt); @@ -1502,9 +1498,6 @@ static int create_qp(struct uverbs_attr_bundle *attrs, resp.response_length = uverbs_response_length(attrs, sizeof(resp)); return uverbs_response(attrs, &resp, sizeof(resp)); -err_cb: - ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs)); - err_put: if (!IS_ERR(xrcd_uobj)) uobj_put_read(xrcd_uobj); diff --git a/drivers/infiniband/core/uverbs_std_types_qp.c b/drivers/infiniband/core/uverbs_std_types_qp.c index c00cfb5ed387..92812f6a21b0 100644 --- a/drivers/infiniband/core/uverbs_std_types_qp.c +++ b/drivers/infiniband/core/uverbs_std_types_qp.c @@ -280,12 +280,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)( obj->uevent.uobject.object = qp; uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_CREATE_QP_HANDLE); - if (attr.qp_type != IB_QPT_XRC_TGT) { - ret = ib_create_qp_security(qp, device); - if (ret) - return ret; - } - set_caps(&attr, &cap, false); ret = uverbs_copy_to_struct_or_zero(attrs, UVERBS_ATTR_CREATE_QP_RESP_CAP, &cap, diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index a7717df83273..1f0f0beebe22 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1216,6 +1216,7 @@ struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, struct ib_udata *udata, struct ib_uqp_object *uobj, const char *caller) { + struct ib_udata dummy = {}; struct ib_qp *qp; int ret; @@ -1256,9 +1257,15 @@ struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, qp->send_cq = attr->send_cq; qp->recv_cq = attr->recv_cq; + ret = ib_create_qp_security(qp, dev); + if (ret) + goto err_security; + rdma_restrack_add(&qp->res); return qp; +err_security: + qp->device->ops.destroy_qp(qp, udata ? &dummy : NULL); err_create: rdma_restrack_put(&qp->res); kfree(qp); @@ -1288,10 +1295,6 @@ struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, if (IS_ERR(qp)) return qp; - ret = ib_create_qp_security(qp, device); - if (ret) - goto err; - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { struct ib_qp *xrc_qp = create_xrc_qp_user(qp, qp_init_attr); -- cgit v1.2.3-70-g09d2 From 5507f67d08cdd947714647caa5c60f96b719fcb7 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:37 +0300 Subject: RDMA/core: Properly increment and decrement QP usecnts The QP usecnts were incremented through QP attributes structure while decreased through QP itself. Rely on the ib_creat_qp_user() code that initialized all QP parameters prior returning to the user and increment exactly like destroy does. Link: https://lore.kernel.org/r/25d256a3bb1fc480b77d7fe439817b993de48610.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 2 + drivers/infiniband/core/uverbs_cmd.c | 13 +----- drivers/infiniband/core/uverbs_std_types_qp.c | 13 +----- drivers/infiniband/core/verbs.c | 60 +++++++++++++++------------ 4 files changed, 39 insertions(+), 49 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index d28ced053222..d8f464b43dbc 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -320,6 +320,8 @@ struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, struct ib_qp_init_attr *attr, struct ib_udata *udata, struct ib_uqp_object *uobj, const char *caller); +void ib_qp_usecnt_inc(struct ib_qp *qp); +void ib_qp_usecnt_dec(struct ib_qp *qp); struct rdma_dev_addr; int rdma_resolve_ip_route(struct sockaddr *src_addr, diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b5153200b8a8..62cafd768d89 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1445,18 +1445,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs, ret = PTR_ERR(qp); goto err_put; } + ib_qp_usecnt_inc(qp); - if (cmd->qp_type != IB_QPT_XRC_TGT) { - atomic_inc(&pd->usecnt); - if (attr.send_cq) - atomic_inc(&attr.send_cq->usecnt); - if (attr.recv_cq) - atomic_inc(&attr.recv_cq->usecnt); - if (attr.srq) - atomic_inc(&attr.srq->usecnt); - if (ind_tbl) - atomic_inc(&ind_tbl->usecnt); - } else { + if (cmd->qp_type == IB_QPT_XRC_TGT) { /* It is done in _ib_create_qp for other QP types */ qp->uobject = obj; } diff --git a/drivers/infiniband/core/uverbs_std_types_qp.c b/drivers/infiniband/core/uverbs_std_types_qp.c index 92812f6a21b0..a0e734735ba5 100644 --- a/drivers/infiniband/core/uverbs_std_types_qp.c +++ b/drivers/infiniband/core/uverbs_std_types_qp.c @@ -258,18 +258,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)( ret = PTR_ERR(qp); goto err_put; } + ib_qp_usecnt_inc(qp); - if (attr.qp_type != IB_QPT_XRC_TGT) { - atomic_inc(&pd->usecnt); - if (attr.send_cq) - atomic_inc(&attr.send_cq->usecnt); - if (attr.recv_cq) - atomic_inc(&attr.recv_cq->usecnt); - if (attr.srq) - atomic_inc(&attr.srq->usecnt); - if (attr.rwq_ind_tbl) - atomic_inc(&attr.rwq_ind_tbl->usecnt); - } else { + if (attr.qp_type == IB_QPT_XRC_TGT) { obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject); atomic_inc(&obj->uxrcd->refcnt); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 1f0f0beebe22..a568155b63f5 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1274,6 +1274,36 @@ err_create: } EXPORT_SYMBOL(_ib_create_qp); +void ib_qp_usecnt_inc(struct ib_qp *qp) +{ + if (qp->pd) + atomic_inc(&qp->pd->usecnt); + if (qp->send_cq) + atomic_inc(&qp->send_cq->usecnt); + if (qp->recv_cq) + atomic_inc(&qp->recv_cq->usecnt); + if (qp->srq) + atomic_inc(&qp->srq->usecnt); + if (qp->rwq_ind_tbl) + atomic_inc(&qp->rwq_ind_tbl->usecnt); +} +EXPORT_SYMBOL(ib_qp_usecnt_inc); + +void ib_qp_usecnt_dec(struct ib_qp *qp) +{ + if (qp->rwq_ind_tbl) + atomic_dec(&qp->rwq_ind_tbl->usecnt); + if (qp->srq) + atomic_dec(&qp->srq->usecnt); + if (qp->recv_cq) + atomic_dec(&qp->recv_cq->usecnt); + if (qp->send_cq) + atomic_dec(&qp->send_cq->usecnt); + if (qp->pd) + atomic_dec(&qp->pd->usecnt); +} +EXPORT_SYMBOL(ib_qp_usecnt_dec); + struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr, const char *caller) @@ -1306,14 +1336,7 @@ struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, return xrc_qp; } - if (qp_init_attr->recv_cq) - atomic_inc(&qp_init_attr->recv_cq->usecnt); - if (qp->srq) - atomic_inc(&qp_init_attr->srq->usecnt); - - atomic_inc(&pd->usecnt); - if (qp_init_attr->send_cq) - atomic_inc(&qp_init_attr->send_cq->usecnt); + ib_qp_usecnt_inc(qp); if (qp_init_attr->cap.max_rdma_ctxs) { ret = rdma_rw_init_mrs(qp, qp_init_attr); @@ -1971,10 +1994,6 @@ int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata) { const struct ib_gid_attr *alt_path_sgid_attr = qp->alt_path_sgid_attr; const struct ib_gid_attr *av_sgid_attr = qp->av_sgid_attr; - struct ib_pd *pd; - struct ib_cq *scq, *rcq; - struct ib_srq *srq; - struct ib_rwq_ind_table *ind_tbl; struct ib_qp_security *sec; int ret; @@ -1986,11 +2005,6 @@ int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata) if (qp->real_qp != qp) return __ib_destroy_shared_qp(qp); - pd = qp->pd; - scq = qp->send_cq; - rcq = qp->recv_cq; - srq = qp->srq; - ind_tbl = qp->rwq_ind_tbl; sec = qp->qp_sec; if (sec) ib_destroy_qp_security_begin(sec); @@ -2010,16 +2024,8 @@ int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata) rdma_put_gid_attr(alt_path_sgid_attr); if (av_sgid_attr) rdma_put_gid_attr(av_sgid_attr); - if (pd) - atomic_dec(&pd->usecnt); - if (scq) - atomic_dec(&scq->usecnt); - if (rcq) - atomic_dec(&rcq->usecnt); - if (srq) - atomic_dec(&srq->usecnt); - if (ind_tbl) - atomic_dec(&ind_tbl->usecnt); + + ib_qp_usecnt_dec(qp); if (sec) ib_destroy_qp_security_end(sec); -- cgit v1.2.3-70-g09d2 From d2b10794fc1312f856d67d0a6454aaa3ae96c595 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Tue, 3 Aug 2021 21:20:38 +0300 Subject: RDMA/core: Create clean QP creations interface for uverbs Unify create QP creation interface to make clean approach to create XRC_TGT and regular QPs. Link: https://lore.kernel.org/r/5cd50e7d8ad9112545a1a61dea62799a5cb3224a.1628014762.git.leonro@nvidia.com Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 9 ++-- drivers/infiniband/core/uverbs_cmd.c | 13 +---- drivers/infiniband/core/uverbs_std_types_qp.c | 10 +--- drivers/infiniband/core/verbs.c | 72 ++++++++++++++++----------- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index d8f464b43dbc..f66f48d860ec 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -316,10 +316,11 @@ struct ib_device *ib_device_get_by_index(const struct net *net, u32 index); void nldev_init(void); void nldev_exit(void); -struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, - struct ib_qp_init_attr *attr, - struct ib_udata *udata, struct ib_uqp_object *uobj, - const char *caller); +struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd, + struct ib_qp_init_attr *attr, + struct ib_udata *udata, + struct ib_uqp_object *uobj, const char *caller); + void ib_qp_usecnt_inc(struct ib_qp *qp); void ib_qp_usecnt_dec(struct ib_qp *qp); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 62cafd768d89..740e6b2efe0e 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1435,23 +1435,14 @@ static int create_qp(struct uverbs_attr_bundle *attrs, attr.source_qpn = cmd->source_qpn; } - if (cmd->qp_type == IB_QPT_XRC_TGT) - qp = ib_create_qp(pd, &attr); - else - qp = _ib_create_qp(device, pd, &attr, &attrs->driver_udata, obj, - NULL); - + qp = ib_create_qp_user(device, pd, &attr, &attrs->driver_udata, obj, + KBUILD_MODNAME); if (IS_ERR(qp)) { ret = PTR_ERR(qp); goto err_put; } ib_qp_usecnt_inc(qp); - if (cmd->qp_type == IB_QPT_XRC_TGT) { - /* It is done in _ib_create_qp for other QP types */ - qp->uobject = obj; - } - obj->uevent.uobject.object = qp; obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file); if (obj->uevent.event_file) diff --git a/drivers/infiniband/core/uverbs_std_types_qp.c b/drivers/infiniband/core/uverbs_std_types_qp.c index a0e734735ba5..dd1075466f61 100644 --- a/drivers/infiniband/core/uverbs_std_types_qp.c +++ b/drivers/infiniband/core/uverbs_std_types_qp.c @@ -248,12 +248,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)( set_caps(&attr, &cap, true); mutex_init(&obj->mcast_lock); - if (attr.qp_type == IB_QPT_XRC_TGT) - qp = ib_create_qp(pd, &attr); - else - qp = _ib_create_qp(device, pd, &attr, &attrs->driver_udata, obj, - NULL); - + qp = ib_create_qp_user(device, pd, &attr, &attrs->driver_udata, obj, + KBUILD_MODNAME); if (IS_ERR(qp)) { ret = PTR_ERR(qp); goto err_put; @@ -264,8 +260,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QP_CREATE)( obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject); atomic_inc(&obj->uxrcd->refcnt); - /* It is done in _ib_create_qp for other QP types */ - qp->uobject = obj; } obj->uevent.uobject.object = qp; diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index a568155b63f5..89a2b21976d6 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1200,21 +1200,10 @@ static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp, return qp; } -/** - * _ib_create_qp - Creates a QP associated with the specified protection domain - * @dev: IB device - * @pd: The protection domain associated with the QP. - * @attr: A list of initial attributes required to create the - * QP. If QP creation succeeds, then the attributes are updated to - * the actual capabilities of the created QP. - * @udata: User data - * @uobj: uverbs obect - * @caller: caller's build-time module name - */ -struct ib_qp *_ib_create_qp(struct ib_device *dev, struct ib_pd *pd, - struct ib_qp_init_attr *attr, - struct ib_udata *udata, struct ib_uqp_object *uobj, - const char *caller) +static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd, + struct ib_qp_init_attr *attr, + struct ib_udata *udata, + struct ib_uqp_object *uobj, const char *caller) { struct ib_udata dummy = {}; struct ib_qp *qp; @@ -1272,7 +1261,43 @@ err_create: return ERR_PTR(ret); } -EXPORT_SYMBOL(_ib_create_qp); + +/** + * ib_create_qp_user - Creates a QP associated with the specified protection + * domain. + * @dev: IB device + * @pd: The protection domain associated with the QP. + * @attr: A list of initial attributes required to create the + * QP. If QP creation succeeds, then the attributes are updated to + * the actual capabilities of the created QP. + * @udata: User data + * @uobj: uverbs obect + * @caller: caller's build-time module name + */ +struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd, + struct ib_qp_init_attr *attr, + struct ib_udata *udata, + struct ib_uqp_object *uobj, const char *caller) +{ + struct ib_qp *qp, *xrc_qp; + + if (attr->qp_type == IB_QPT_XRC_TGT) + qp = create_qp(dev, pd, attr, NULL, NULL, caller); + else + qp = create_qp(dev, pd, attr, udata, uobj, NULL); + if (attr->qp_type != IB_QPT_XRC_TGT || IS_ERR(qp)) + return qp; + + xrc_qp = create_xrc_qp_user(qp, attr); + if (IS_ERR(xrc_qp)) { + ib_destroy_qp(qp); + return xrc_qp; + } + + xrc_qp->uobject = uobj; + return xrc_qp; +} +EXPORT_SYMBOL(ib_create_qp_user); void ib_qp_usecnt_inc(struct ib_qp *qp) { @@ -1308,7 +1333,7 @@ struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr, const char *caller) { - struct ib_device *device = pd ? pd->device : qp_init_attr->xrcd->device; + struct ib_device *device = pd->device; struct ib_qp *qp; int ret; @@ -1321,21 +1346,10 @@ struct ib_qp *ib_create_qp_kernel(struct ib_pd *pd, if (qp_init_attr->cap.max_rdma_ctxs) rdma_rw_init_qp(device, qp_init_attr); - qp = _ib_create_qp(device, pd, qp_init_attr, NULL, NULL, caller); + qp = create_qp(device, pd, qp_init_attr, NULL, NULL, caller); if (IS_ERR(qp)) return qp; - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { - struct ib_qp *xrc_qp = - create_xrc_qp_user(qp, qp_init_attr); - - if (IS_ERR(xrc_qp)) { - ret = PTR_ERR(xrc_qp); - goto err; - } - return xrc_qp; - } - ib_qp_usecnt_inc(qp); if (qp_init_attr->cap.max_rdma_ctxs) { -- cgit v1.2.3-70-g09d2 From 1094795eb9f2b17678d944eb38d45af8f8f67362 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 29 Jul 2021 16:58:00 +0100 Subject: perf tools: Add WARN_ONCE equivalent for UI warnings Currently WARN_ONCE prints to stderr and corrupts the TUI. Add equivalent methods for UI warnings. Signed-off-by: James Clark Reviewed-by: Leo Yan Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20210729155805.2830-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/debug.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 48f631966067..f99468a7f681 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -22,6 +22,13 @@ extern int debug_data_convert; eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__) #define pr_warning(fmt, ...) \ eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning_once(fmt, ...) ({ \ + static int __warned; \ + if (unlikely(!__warned)) { \ + pr_warning(fmt, ##__VA_ARGS__); \ + __warned = 1; \ + } \ +}) #define pr_info(fmt, ...) \ eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__) #define pr_debug(fmt, ...) \ @@ -55,6 +62,13 @@ void trace_event(union perf_event *event); int ui__error(const char *format, ...) __printf(1, 2); int ui__warning(const char *format, ...) __printf(1, 2); +#define ui__warning_once(format, ...) ({ \ + static int __warned; \ + if (unlikely(!__warned)) { \ + ui__warning(format, ##__VA_ARGS__); \ + __warned = 1; \ + } \ +}) void pr_stat(const char *fmt, ...); -- cgit v1.2.3-70-g09d2 From 3d8b92472ae7ba91d759cadb4670bd492ef97d04 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 29 Jul 2021 16:58:01 +0100 Subject: perf annotate: Re-add annotate_warned functionality Setting annotate_warned to true on errors was removed in commit ee51d851392e ("perf annotate: Introduce strerror for handling symbol__disassemble() errors") which means when 'perf annotate --skip-missing' is used warnings are shown multiple times for the same DSO. Setting this again restores the original behavior of only one warning each. Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20210729155805.2830-3-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 1 + tools/perf/ui/gtk/annotate.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 701130ad43a2..ef4da4295bf7 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -966,6 +966,7 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel, err = symbol__annotate2(ms, evsel, opts, &browser.arch); if (err) { char msg[BUFSIZ]; + ms->map->dso->annotate_warned = true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s:\n%s", sym->name, msg); goto out_free_offsets; diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index 94167bfed722..0a50e962f9a3 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -177,6 +177,7 @@ static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel, err = symbol__annotate(ms, evsel, &annotation__default_options, NULL); if (err) { char msg[BUFSIZ]; + ms->map->dso->annotate_warned = true; symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); ui__error("Couldn't annotate %s: %s\n", sym->name, msg); return -1; -- cgit v1.2.3-70-g09d2 From 243c3a3eb4e03201dec36f2edfc4fe604d8b9078 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 29 Jul 2021 16:58:02 +0100 Subject: perf annotate: Add disassembly warnings for annotate --stdio Currently 'perf annotate --stdio' (and --stdio2) will exit without printing anything if there are disassembly errors. Apply the same error handler that's used for TUI and GTK modes. This makes comparing disassembly across the different modes more consistent. Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20210729155805.2830-4-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index cb280de3369f..d43f6b5e5169 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2789,9 +2789,17 @@ int symbol__tty_annotate2(struct map_symbol *ms, struct evsel *evsel, struct rb_root source_line = RB_ROOT; struct hists *hists = evsel__hists(evsel); char buf[1024]; + int err; + + err = symbol__annotate2(ms, evsel, opts, NULL); + if (err) { + char msg[BUFSIZ]; - if (symbol__annotate2(ms, evsel, opts, NULL) < 0) + dso->annotate_warned = true; + symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); + ui__error("Couldn't annotate %s:\n%s", sym->name, msg); return -1; + } if (opts->print_lines) { srcline_full_filename = opts->full_path; @@ -2815,9 +2823,17 @@ int symbol__tty_annotate(struct map_symbol *ms, struct evsel *evsel, struct dso *dso = ms->map->dso; struct symbol *sym = ms->sym; struct rb_root source_line = RB_ROOT; + int err; + + err = symbol__annotate(ms, evsel, opts, NULL); + if (err) { + char msg[BUFSIZ]; - if (symbol__annotate(ms, evsel, opts, NULL) < 0) + dso->annotate_warned = true; + symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); + ui__error("Couldn't annotate %s:\n%s", sym->name, msg); return -1; + } symbol__calc_percent(sym, evsel); -- cgit v1.2.3-70-g09d2 From 115520495015591d6a98a5965644cfffd218e399 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 29 Jul 2021 16:58:03 +0100 Subject: perf tools: Add flag for tracking warnings of missing DSOs Auxtrace support may need DSOs for decoding (for example Arm Coresight). If one of these is missing it would make sense to warn once for each one that's missing, but not flood the output with every address as there could be thousands of lookups. This flag will allow tracking whether a warning was shown for each DSO. Signed-off-by: James Clark Reviewed-by: Leo Yan Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20210729155805.2830-5-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 52e7101c5609..83723ba11dc8 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -170,6 +170,7 @@ struct dso { u8 has_srcline:1; u8 hit:1; u8 annotate_warned:1; + u8 auxtrace_warned:1; u8 short_name_allocated:1; u8 long_name_allocated:1; u8 is_64_bit:1; -- cgit v1.2.3-70-g09d2 From f3c33cbd9221e543bb4dd3c9028aef758fa2aa0e Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 29 Jul 2021 16:58:04 +0100 Subject: perf cs-etm: Improve Coresight zero timestamp warning Only show the warning if the user hasn't already set timeless mode and improve the text because there was ambiguity around the meaning of '...' Change the warning to a UI warning instead of printing straight to stderr because this corrupts the UI when perf report TUI is used. The UI warning function also handles printing to stderr when in perf script mode. Suggested-by: Leo Yan Signed-off-by: James Clark Reviewed-by: Leo Yan Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Leo Yan Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http://lore.kernel.org/lkml/20210729155805.2830-6-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 9c9039ae6989..84cca3fc05a5 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -328,8 +328,11 @@ cs_etm_decoder__do_hard_timestamp(struct cs_etm_queue *etmq, * underflow. */ packet_queue->cs_timestamp = 0; - WARN_ONCE(true, "Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR - ". Decoding may be improved with --itrace=Z...\n", indx); + if (!cs_etm__etmq_is_timeless(etmq)) + pr_warning_once("Zero Coresight timestamp found at Idx:%" OCSD_TRC_IDX_STR + ". Decoding may be improved by prepending 'Z' to your current --itrace arguments.\n", + indx); + } else if (packet_queue->instr_count > elem->timestamp) { /* * Sanity check that the elem->timestamp - packet_queue->instr_count would not -- cgit v1.2.3-70-g09d2 From a8bd29bd49c4156ea0ec5a97812333e2aeef44e7 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Thu, 29 Jul 2021 23:37:54 +0000 Subject: PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pciconfig_read() syscall reads PCI configuration space using hardware-dependent config accessors. If the read fails on PCI, most accessors don't return an error; they pretend the read was successful and got ~0 data from the device, so the syscall returns success with ~0 data in the buffer. When the accessor does return an error, pciconfig_read() normally fills the user's buffer with ~0 and returns an error in errno. But after e4585da22ad0 ("pci syscall.c: Switch to refcounting API"), we don't fill the buffer with ~0 for the EPERM "user lacks CAP_SYS_ADMIN" error. Userspace may rely on the ~0 data to detect errors, but after e4585da22ad0, that would not detect CAP_SYS_ADMIN errors. Restore the original behaviour of filling the buffer with ~0 when the CAP_SYS_ADMIN check fails. [bhelgaas: commit log, fold in Nathan's fix https://lore.kernel.org/r/20210803200836.500658-1-nathan@kernel.org] Fixes: e4585da22ad0 ("pci syscall.c: Switch to refcounting API") Link: https://lore.kernel.org/r/20210729233755.1509616-1-kw@linux.com Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org --- drivers/pci/syscall.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index 8b003c890b87..c9f03418e71e 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -22,8 +22,10 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn, long err; int cfg_ret; + err = -EPERM; + dev = NULL; if (!capable(CAP_SYS_ADMIN)) - return -EPERM; + goto error; err = -ENODEV; dev = pci_get_domain_bus_and_slot(0, bus, dfn); -- cgit v1.2.3-70-g09d2 From d6b1715999fc2e215d35f581fb7471bc9c6f16e9 Mon Sep 17 00:00:00 2001 From: Krzysztof Wilczyński Date: Thu, 29 Jul 2021 23:37:55 +0000 Subject: PCI: Return int from pciconfig_read() syscall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change pciconfig_read() syscall "err" return value from long to int. This makes it consistent with pciconfig_write(). [bhelgaas: commit log] Link: https://lore.kernel.org/r/20210729233755.1509616-2-kw@linux.com Signed-off-by: Krzysztof Wilczyński Signed-off-by: Bjorn Helgaas --- drivers/pci/syscall.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index c9f03418e71e..61a6fe3cde21 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -19,8 +19,7 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn, u8 byte; u16 word; u32 dword; - long err; - int cfg_ret; + int err, cfg_ret; err = -EPERM; dev = NULL; -- cgit v1.2.3-70-g09d2 From d08c8b855140e9f5240b3ffd1b8b9d435675e281 Mon Sep 17 00:00:00 2001 From: Wasim Khan Date: Thu, 29 Jul 2021 14:17:47 +0200 Subject: PCI: Add ACS quirks for NXP LX2xx0 and LX2xx2 platforms Root Ports in NXP LX2xx0 and LX2xx2, where each Root Port is a Root Complex with unique segment numbers, do provide isolation features to disable peer transactions and validate bus numbers in requests, but do not provide an actual PCIe ACS capability. Add ACS quirks for NXP LX2xx0 A/C/E/N and LX2xx2 A/C/E/N platforms. LX2xx0A : without security features + CAN-FD LX2160A (0x8d81) - 16 cores LX2120A (0x8da1) - 12 cores LX2080A (0x8d83) - 8 cores LX2xx0C : security features + CAN-FD LX2160C (0x8d80) - 16 cores LX2120C (0x8da0) - 12 cores LX2080C (0x8d82) - 8 cores LX2xx0E : security features + CAN LX2160E (0x8d90) - 16 cores LX2120E (0x8db0) - 12 cores LX2080E (0x8d92) - 8 cores LX2xx0N : without security features + CAN LX2160N (0x8d91) - 16 cores LX2120N (0x8db1) - 12 cores LX2080N (0x8d93) - 8 cores LX2xx2A : without security features + CAN-FD LX2162A (0x8d89) - 16 cores LX2122A (0x8da9) - 12 cores LX2082A (0x8d8b) - 8 cores LX2xx2C : security features + CAN-FD LX2162C (0x8d88) - 16 cores LX2122C (0x8da8) - 12 cores LX2082C (0x8d8a) - 8 cores LX2xx2E : security features + CAN LX2162E (0x8d98) - 16 cores LX2122E (0x8db8) - 12 cores LX2082E (0x8d9a) - 8 cores LX2xx2N : without security features + CAN LX2162N (0x8d99) - 16 cores LX2122N (0x8db9) - 12 cores LX2082N (0x8d9b) - 8 cores [bhelgaas: put PCI_VENDOR_ID_NXP definition next to PCI_VENDOR_ID_FREESCALE as a clue that they share the same Device ID namespace] Link: https://lore.kernel.org/r/20210729121747.1823086-1-wasim.khan@oss.nxp.com Link: https://lore.kernel.org/r/20210803180021.3252886-1-wasim.khan@oss.nxp.com Signed-off-by: Wasim Khan Signed-off-by: Bjorn Helgaas --- drivers/pci/quirks.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/pci_ids.h | 3 ++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6d74386eadc2..207d089a8d37 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -4614,6 +4614,18 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } +/* + * Each of these NXP Root Ports is in a Root Complex with a unique segment + * number and does provide isolation features to disable peer transactions + * and validate bus numbers in requests, but does not provide an ACS + * capability. + */ +static int pci_quirk_nxp_rp_acs(struct pci_dev *dev, u16 acs_flags) +{ + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); +} + static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags) { if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) @@ -4860,6 +4872,39 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs }, + /* NXP root ports, xx=16, 12, or 08 cores */ + /* LX2xx0A : without security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d81, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da1, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d83, pci_quirk_nxp_rp_acs }, + /* LX2xx0C : security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d80, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da0, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d82, pci_quirk_nxp_rp_acs }, + /* LX2xx0E : security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d90, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db0, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d92, pci_quirk_nxp_rp_acs }, + /* LX2xx0N : without security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d91, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db1, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d93, pci_quirk_nxp_rp_acs }, + /* LX2xx2A : without security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d89, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da9, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d8b, pci_quirk_nxp_rp_acs }, + /* LX2xx2C : security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d88, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da8, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d8a, pci_quirk_nxp_rp_acs }, + /* LX2xx2E : security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d98, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db8, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d9a, pci_quirk_nxp_rp_acs }, + /* LX2xx2N : without security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d99, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db9, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs }, /* Zhaoxin Root/Downstream Ports */ { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, { 0 } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4bac1831de80..1a9b8589391c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2451,7 +2451,8 @@ #define PCI_VENDOR_ID_TDI 0x192E #define PCI_DEVICE_ID_TDI_EHCI 0x0101 -#define PCI_VENDOR_ID_FREESCALE 0x1957 +#define PCI_VENDOR_ID_FREESCALE 0x1957 /* duplicate: NXP */ +#define PCI_VENDOR_ID_NXP 0x1957 /* duplicate: FREESCALE */ #define PCI_DEVICE_ID_MPC8308 0xc006 #define PCI_DEVICE_ID_MPC8315E 0x00b4 #define PCI_DEVICE_ID_MPC8315 0x00b5 -- cgit v1.2.3-70-g09d2 From d04691d373e75c83424b85c0e68e4a3f9370c10d Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 3 Aug 2021 14:15:47 -0700 Subject: cpuidle: pseries: Mark pseries_idle_proble() as __init After commit 7cbd631d4dec ("cpuidle: pseries: Fixup CEDE0 latency only for POWER10 onwards"), pseries_idle_probe() is no longer inlined when compiling with clang, which causes a modpost warning: WARNING: modpost: vmlinux.o(.text+0xc86a54): Section mismatch in reference from the function pseries_idle_probe() to the function .init.text:fixup_cede0_latency() The function pseries_idle_probe() references the function __init fixup_cede0_latency(). This is often because pseries_idle_probe lacks a __init annotation or the annotation of fixup_cede0_latency is wrong. pseries_idle_probe() is a non-init function, which calls fixup_cede0_latency(), which is an init function, explaining the mismatch. pseries_idle_probe() is only called from pseries_processor_idle_init(), which is an init function, so mark pseries_idle_probe() as __init so there is no more warning. Fixes: 054e44ba99ae ("cpuidle: pseries: Add function to parse extended CEDE records") Signed-off-by: Nathan Chancellor Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210803211547.1093820-1-nathan@kernel.org --- drivers/cpuidle/cpuidle-pseries.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index bba449b77641..7e7ab5597d7a 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c @@ -403,7 +403,7 @@ static void __init fixup_cede0_latency(void) * pseries_idle_probe() * Choose state table for shared versus dedicated partition */ -static int pseries_idle_probe(void) +static int __init pseries_idle_probe(void) { if (cpuidle_disable != IDLE_NO_OVERRIDE) -- cgit v1.2.3-70-g09d2 From 156ca4e650bfb9a4259b427069caa11b5a4df3d4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 29 Jul 2021 23:19:35 +0900 Subject: powerpc: remove unused zInstall target from arch/powerpc/boot/Makefile Commit c913e5f95e54 ("powerpc/boot: Don't install zImage.* from make install") added the zInstall target to arch/powerpc/boot/Makefile, but you cannot use it since the corresponding hook is missing in arch/powerpc/Makefile. It has never worked since its addition. Nobody has complained about it for 7 years, which means this code was unneeded. With this removal, the install.sh will be passed in with 4 parameters. Simplify the shell script. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210729141937.445051-1-masahiroy@kernel.org --- arch/powerpc/boot/Makefile | 6 +----- arch/powerpc/boot/install.sh | 13 ------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index e312ea802aa6..a702f9d1ec0d 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -448,11 +448,7 @@ $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" -# Install the vmlinux and other built boot targets. -zInstall: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) - sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $^ - -PHONY += install zInstall +PHONY += install # anything not in $(targets) clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh index b6a256bc96ee..658c93ca7437 100644 --- a/arch/powerpc/boot/install.sh +++ b/arch/powerpc/boot/install.sh @@ -15,7 +15,6 @@ # $2 - kernel image file # $3 - kernel map file # $4 - default install path (blank if root directory) -# $5 and more - kernel boot files; zImage*, uImage, cuImage.*, etc. # # Bail with error code if anything goes wrong @@ -41,15 +40,3 @@ fi cat $2 > $4/$image_name cp $3 $4/System.map - -# Copy all the bootable image files -path=$4 -shift 4 -while [ $# -ne 0 ]; do - image_name=`basename $1` - if [ -f $path/$image_name ]; then - mv $path/$image_name $path/$image_name.old - fi - cat $1 > $path/$image_name - shift -done; -- cgit v1.2.3-70-g09d2 From 9bef456b20581e630ef9a13555ca04fed65a859d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 29 Jul 2021 23:19:36 +0900 Subject: powerpc: make the install target not depend on any build artifact The install target should not depend on any build artifact. The reason is explained in commit 19514fc665ff ("arm, kbuild: make "make install" not depend on vmlinux"). Change the PowerPC installation code in a similar way. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210729141937.445051-2-masahiroy@kernel.org --- arch/powerpc/boot/Makefile | 2 +- arch/powerpc/boot/install.sh | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index a702f9d1ec0d..0d165bd98b61 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -445,7 +445,7 @@ $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) $(Q)rm -f $@; ln $< $@ # Only install the vmlinux -install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) +install: sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" PHONY += install diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh index 658c93ca7437..14473150ddb4 100644 --- a/arch/powerpc/boot/install.sh +++ b/arch/powerpc/boot/install.sh @@ -20,6 +20,20 @@ # Bail with error code if anything goes wrong set -e +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist +verify "$2" +verify "$3" + # User may have a custom install script if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi -- cgit v1.2.3-70-g09d2 From 86ff0bce2e9665c8b074930fe6caed615da070c1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 29 Jul 2021 23:19:37 +0900 Subject: powerpc: move the install rule to arch/powerpc/Makefile Currently, the install target in arch/powerpc/Makefile descends into arch/powerpc/boot/Makefile to invoke the shell script, but there is no good reason to do so. arch/powerpc/Makefile can run the shell script directly. Signed-off-by: Masahiro Yamada Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210729141937.445051-3-masahiroy@kernel.org --- arch/powerpc/Makefile | 3 ++- arch/powerpc/boot/Makefile | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6505d66f1193..9aaf1abbc641 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -407,7 +407,8 @@ endef PHONY += install install: - $(Q)$(MAKE) $(build)=$(boot) install + sh -x $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" vmlinux \ + System.map "$(INSTALL_PATH)" archclean: $(Q)$(MAKE) $(clean)=$(boot) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 0d165bd98b61..10c0fb306f15 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -444,12 +444,6 @@ $(obj)/zImage: $(addprefix $(obj)/, $(image-y)) $(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y)) $(Q)rm -f $@; ln $< $@ -# Only install the vmlinux -install: - sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" - -PHONY += install - # anything not in $(targets) clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ -- cgit v1.2.3-70-g09d2 From a4bec516b9c0823d7e2bb8c8928c98b535cf9adf Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Wed, 28 Jul 2021 23:26:05 +0530 Subject: powerpc/cacheinfo: Lookup cache by dt node and thread-group id Currently the cacheinfo code on powerpc indexes the "cache" objects (modelling the L1/L2/L3 caches) where the key is device-tree node corresponding to that cache. On some of the POWER server platforms thread-groups within the core share different sets of caches (Eg: On SMT8 POWER9 systems, threads 0,2,4,6 of a core share L1 cache and threads 1,3,5,7 of the same core share another L1 cache). On such platforms, there is a single device-tree node corresponding to that cache and the cache-configuration within the threads of the core is indicated via "ibm,thread-groups" device-tree property. Since the current code is not aware of the "ibm,thread-groups" property, on the aforementoined systems, cacheinfo code still treats all the threads in the core to be sharing the cache because of the single device-tree node (In the earlier example, the cacheinfo code would says CPUs 0-7 share L1 cache). In this patch, we make the powerpc cacheinfo code aware of the "ibm,thread-groups" property. We indexe the "cache" objects by the key-pair (device-tree node, thread-group id). For any CPUX, for a given level of cache, the thread-group id is defined to be the first CPU in the "ibm,thread-groups" cache-group containing CPUX. For levels of cache which are not represented in "ibm,thread-groups" property, the thread-group id is -1. [parth: Remove "static" keyword for the definition of "thread_group_l1_cache_map" and "thread_group_l2_cache_map" to get rid of the compile error.] Signed-off-by: Gautham R. Shenoy Signed-off-by: Parth Shah Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210728175607.591679-2-parth@linux.ibm.com --- arch/powerpc/include/asm/smp.h | 3 ++ arch/powerpc/kernel/cacheinfo.c | 80 +++++++++++++++++++++++++++++------------ arch/powerpc/kernel/smp.c | 4 +-- 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 03b3d010cbab..1259040cc3a4 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -33,6 +33,9 @@ extern bool coregroup_enabled; extern int cpu_to_chip_id(int cpu); extern int *chip_id_lookup_table; +DECLARE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); +DECLARE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); + #ifdef CONFIG_SMP struct smp_ops_t { diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 6f903e9aa20b..5a6925d87424 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -120,6 +120,7 @@ struct cache { struct cpumask shared_cpu_map; /* online CPUs using this cache */ int type; /* split cache disambiguation */ int level; /* level not explicit in device tree */ + int group_id; /* id of the group of threads that share this cache */ struct list_head list; /* global list of cache objects */ struct cache *next_local; /* next cache of >= level */ }; @@ -142,22 +143,24 @@ static const char *cache_type_string(const struct cache *cache) } static void cache_init(struct cache *cache, int type, int level, - struct device_node *ofnode) + struct device_node *ofnode, int group_id) { cache->type = type; cache->level = level; cache->ofnode = of_node_get(ofnode); + cache->group_id = group_id; INIT_LIST_HEAD(&cache->list); list_add(&cache->list, &cache_list); } -static struct cache *new_cache(int type, int level, struct device_node *ofnode) +static struct cache *new_cache(int type, int level, + struct device_node *ofnode, int group_id) { struct cache *cache; cache = kzalloc(sizeof(*cache), GFP_KERNEL); if (cache) - cache_init(cache, type, level, ofnode); + cache_init(cache, type, level, ofnode, group_id); return cache; } @@ -309,20 +312,24 @@ static struct cache *cache_find_first_sibling(struct cache *cache) return cache; list_for_each_entry(iter, &cache_list, list) - if (iter->ofnode == cache->ofnode && iter->next_local == cache) + if (iter->ofnode == cache->ofnode && + iter->group_id == cache->group_id && + iter->next_local == cache) return iter; return cache; } -/* return the first cache on a local list matching node */ -static struct cache *cache_lookup_by_node(const struct device_node *node) +/* return the first cache on a local list matching node and thread-group id */ +static struct cache *cache_lookup_by_node_group(const struct device_node *node, + int group_id) { struct cache *cache = NULL; struct cache *iter; list_for_each_entry(iter, &cache_list, list) { - if (iter->ofnode != node) + if (iter->ofnode != node || + iter->group_id != group_id) continue; cache = cache_find_first_sibling(iter); break; @@ -352,14 +359,15 @@ static int cache_is_unified_d(const struct device_node *np) CACHE_TYPE_UNIFIED_D : CACHE_TYPE_UNIFIED; } -static struct cache *cache_do_one_devnode_unified(struct device_node *node, int level) +static struct cache *cache_do_one_devnode_unified(struct device_node *node, int group_id, + int level) { pr_debug("creating L%d ucache for %pOFP\n", level, node); - return new_cache(cache_is_unified_d(node), level, node); + return new_cache(cache_is_unified_d(node), level, node, group_id); } -static struct cache *cache_do_one_devnode_split(struct device_node *node, +static struct cache *cache_do_one_devnode_split(struct device_node *node, int group_id, int level) { struct cache *dcache, *icache; @@ -367,8 +375,8 @@ static struct cache *cache_do_one_devnode_split(struct device_node *node, pr_debug("creating L%d dcache and icache for %pOFP\n", level, node); - dcache = new_cache(CACHE_TYPE_DATA, level, node); - icache = new_cache(CACHE_TYPE_INSTRUCTION, level, node); + dcache = new_cache(CACHE_TYPE_DATA, level, node, group_id); + icache = new_cache(CACHE_TYPE_INSTRUCTION, level, node, group_id); if (!dcache || !icache) goto err; @@ -382,31 +390,32 @@ err: return NULL; } -static struct cache *cache_do_one_devnode(struct device_node *node, int level) +static struct cache *cache_do_one_devnode(struct device_node *node, int group_id, int level) { struct cache *cache; if (cache_node_is_unified(node)) - cache = cache_do_one_devnode_unified(node, level); + cache = cache_do_one_devnode_unified(node, group_id, level); else - cache = cache_do_one_devnode_split(node, level); + cache = cache_do_one_devnode_split(node, group_id, level); return cache; } static struct cache *cache_lookup_or_instantiate(struct device_node *node, + int group_id, int level) { struct cache *cache; - cache = cache_lookup_by_node(node); + cache = cache_lookup_by_node_group(node, group_id); WARN_ONCE(cache && cache->level != level, "cache level mismatch on lookup (got %d, expected %d)\n", cache->level, level); if (!cache) - cache = cache_do_one_devnode(node, level); + cache = cache_do_one_devnode(node, group_id, level); return cache; } @@ -443,7 +452,27 @@ static void do_subsidiary_caches_debugcheck(struct cache *cache) of_node_get_device_type(cache->ofnode)); } -static void do_subsidiary_caches(struct cache *cache) +/* + * If sub-groups of threads in a core containing @cpu_id share the + * L@level-cache (information obtained via "ibm,thread-groups" + * device-tree property), then we identify the group by the first + * thread-sibling in the group. We define this to be the group-id. + * + * In the absence of any thread-group information for L@level-cache, + * this function returns -1. + */ +static int get_group_id(unsigned int cpu_id, int level) +{ + if (has_big_cores && level == 1) + return cpumask_first(per_cpu(thread_group_l1_cache_map, + cpu_id)); + else if (thread_group_shares_l2 && level == 2) + return cpumask_first(per_cpu(thread_group_l2_cache_map, + cpu_id)); + return -1; +} + +static void do_subsidiary_caches(struct cache *cache, unsigned int cpu_id) { struct device_node *subcache_node; int level = cache->level; @@ -452,9 +481,11 @@ static void do_subsidiary_caches(struct cache *cache) while ((subcache_node = of_find_next_cache_node(cache->ofnode))) { struct cache *subcache; + int group_id; level++; - subcache = cache_lookup_or_instantiate(subcache_node, level); + group_id = get_group_id(cpu_id, level); + subcache = cache_lookup_or_instantiate(subcache_node, group_id, level); of_node_put(subcache_node); if (!subcache) break; @@ -468,6 +499,7 @@ static struct cache *cache_chain_instantiate(unsigned int cpu_id) { struct device_node *cpu_node; struct cache *cpu_cache = NULL; + int group_id; pr_debug("creating cache object(s) for CPU %i\n", cpu_id); @@ -476,11 +508,13 @@ static struct cache *cache_chain_instantiate(unsigned int cpu_id) if (!cpu_node) goto out; - cpu_cache = cache_lookup_or_instantiate(cpu_node, 1); + group_id = get_group_id(cpu_id, 1); + + cpu_cache = cache_lookup_or_instantiate(cpu_node, group_id, 1); if (!cpu_cache) goto out; - do_subsidiary_caches(cpu_cache); + do_subsidiary_caches(cpu_cache, cpu_id); cache_cpu_set(cpu_cache, cpu_id); out: @@ -848,13 +882,15 @@ static struct cache *cache_lookup_by_cpu(unsigned int cpu_id) { struct device_node *cpu_node; struct cache *cache; + int group_id; cpu_node = of_get_cpu_node(cpu_id, NULL); WARN_ONCE(!cpu_node, "no OF node found for CPU %i\n", cpu_id); if (!cpu_node) return NULL; - cache = cache_lookup_by_node(cpu_node); + group_id = get_group_id(cpu_id, 1); + cache = cache_lookup_by_node_group(cpu_node, group_id); of_node_put(cpu_node); return cache; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 447b78a87c8f..a7fcac44a8e2 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -122,14 +122,14 @@ static struct thread_groups_list tgl[NR_CPUS] __initdata; * On big-cores system, thread_group_l1_cache_map for each CPU corresponds to * the set its siblings that share the L1-cache. */ -static DEFINE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); +DEFINE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); /* * On some big-cores system, thread_group_l2_cache_map for each CPU * corresponds to the set its siblings within the core that share the * L2-cache. */ -static DEFINE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); +DEFINE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; -- cgit v1.2.3-70-g09d2 From 69aa8e078545bc14d84a8b4b3cb914ac8f9f280e Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Wed, 28 Jul 2021 23:26:06 +0530 Subject: powerpc/cacheinfo: Remove the redundant get_shared_cpu_map() The helper function get_shared_cpu_map() was added in 'commit 500fe5f550ec ("powerpc/cacheinfo: Report the correct shared_cpu_map on big-cores")' and subsequently expanded upon in 'commit 0be47634db0b ("powerpc/cacheinfo: Print correct cache-sibling map/list for L2 cache")' in order to help report the correct groups of threads sharing these caches on big-core systems where groups of threads within a core can share different sets of caches. Now that powerpc/cacheinfo is aware of "ibm,thread-groups" property, cache->shared_cpu_map contains the correct set of thread-siblings sharing the cache. Hence we no longer need the functions get_shared_cpu_map(). This patch removes this function. We also remove the helper function index_dir_to_cpu() which was only called by get_shared_cpu_map(). With these functions removed, we can still see the correct cache-sibling map/list for L1 and L2 caches on systems with L1 and L2 caches distributed among groups of threads in a core. With this patch, on a SMT8 POWER10 system where the L1 and L2 caches are split between the two groups of threads in a core, for CPUs 8,9, the L1-Data, L1-Instruction, L2, L3 cache CPU sibling list is as follows: $ grep . /sys/devices/system/cpu/cpu[89]/cache/index[0123]/shared_cpu_list /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list:8,10,12,14 /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list:8,10,12,14 /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list:8,10,12,14 /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list:8-15 /sys/devices/system/cpu/cpu9/cache/index0/shared_cpu_list:9,11,13,15 /sys/devices/system/cpu/cpu9/cache/index1/shared_cpu_list:9,11,13,15 /sys/devices/system/cpu/cpu9/cache/index2/shared_cpu_list:9,11,13,15 /sys/devices/system/cpu/cpu9/cache/index3/shared_cpu_list:8-15 $ ppc64_cpu --smt=4 $ grep . /sys/devices/system/cpu/cpu[89]/cache/index[0123]/shared_cpu_list /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list:8,10 /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list:8,10 /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list:8,10 /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list:8-11 /sys/devices/system/cpu/cpu9/cache/index0/shared_cpu_list:9,11 /sys/devices/system/cpu/cpu9/cache/index1/shared_cpu_list:9,11 /sys/devices/system/cpu/cpu9/cache/index2/shared_cpu_list:9,11 /sys/devices/system/cpu/cpu9/cache/index3/shared_cpu_list:8-11 $ ppc64_cpu --smt=2 $ grep . /sys/devices/system/cpu/cpu[89]/cache/index[0123]/shared_cpu_list /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list:8-9 /sys/devices/system/cpu/cpu9/cache/index0/shared_cpu_list:9 /sys/devices/system/cpu/cpu9/cache/index1/shared_cpu_list:9 /sys/devices/system/cpu/cpu9/cache/index2/shared_cpu_list:9 /sys/devices/system/cpu/cpu9/cache/index3/shared_cpu_list:8-9 $ ppc64_cpu --smt=1 $ grep . /sys/devices/system/cpu/cpu[89]/cache/index[0123]/shared_cpu_list /sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list:8 /sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list:8 Signed-off-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210728175607.591679-3-parth@linux.ibm.com --- arch/powerpc/kernel/cacheinfo.c | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 5a6925d87424..20d91693eac1 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -675,45 +675,6 @@ static ssize_t level_show(struct kobject *k, struct kobj_attribute *attr, char * static struct kobj_attribute cache_level_attr = __ATTR(level, 0444, level_show, NULL); -static unsigned int index_dir_to_cpu(struct cache_index_dir *index) -{ - struct kobject *index_dir_kobj = &index->kobj; - struct kobject *cache_dir_kobj = index_dir_kobj->parent; - struct kobject *cpu_dev_kobj = cache_dir_kobj->parent; - struct device *dev = kobj_to_dev(cpu_dev_kobj); - - return dev->id; -} - -/* - * On big-core systems, each core has two groups of CPUs each of which - * has its own L1-cache. The thread-siblings which share l1-cache with - * @cpu can be obtained via cpu_smallcore_mask(). - * - * On some big-core systems, the L2 cache is shared only between some - * groups of siblings. This is already parsed and encoded in - * cpu_l2_cache_mask(). - * - * TODO: cache_lookup_or_instantiate() needs to be made aware of the - * "ibm,thread-groups" property so that cache->shared_cpu_map - * reflects the correct siblings on platforms that have this - * device-tree property. This helper function is only a stop-gap - * solution so that we report the correct siblings to the - * userspace via sysfs. - */ -static const struct cpumask *get_shared_cpu_map(struct cache_index_dir *index, struct cache *cache) -{ - if (has_big_cores) { - int cpu = index_dir_to_cpu(index); - if (cache->level == 1) - return cpu_smallcore_mask(cpu); - if (cache->level == 2 && thread_group_shares_l2) - return cpu_l2_cache_mask(cpu); - } - - return &cache->shared_cpu_map; -} - static ssize_t show_shared_cpumap(struct kobject *k, struct kobj_attribute *attr, char *buf, bool list) { @@ -724,7 +685,7 @@ show_shared_cpumap(struct kobject *k, struct kobj_attribute *attr, char *buf, bo index = kobj_to_cache_index_dir(k); cache = index->cache; - mask = get_shared_cpu_map(index, cache); + mask = &cache->shared_cpu_map; return cpumap_print_to_pagebuf(list, buf, mask); } -- cgit v1.2.3-70-g09d2 From e9ef81e1079b0c4c374fba0f9affa7129c7c913b Mon Sep 17 00:00:00 2001 From: Parth Shah Date: Wed, 28 Jul 2021 23:26:07 +0530 Subject: powerpc/smp: Use existing L2 cache_map cpumask to find L3 cache siblings On POWER10 systems, the "ibm,thread-groups" property "2" indicates the cpus in thread-group share both L2 and L3 caches. Hence, use cache_property = 2 itself to find both the L2 and L3 cache siblings. Hence, create a new thread_group_l3_cache_map to keep list of L3 siblings, but fill the mask using same property "2" array. Signed-off-by: Parth Shah Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210728175607.591679-4-parth@linux.ibm.com --- arch/powerpc/include/asm/smp.h | 3 ++ arch/powerpc/kernel/cacheinfo.c | 3 ++ arch/powerpc/kernel/smp.c | 66 ++++++++++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 1259040cc3a4..7ef1cd8168a0 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -35,6 +35,7 @@ extern int *chip_id_lookup_table; DECLARE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); DECLARE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); +DECLARE_PER_CPU(cpumask_var_t, thread_group_l3_cache_map); #ifdef CONFIG_SMP @@ -144,6 +145,7 @@ extern int cpu_to_core_id(int cpu); extern bool has_big_cores; extern bool thread_group_shares_l2; +extern bool thread_group_shares_l3; #define cpu_smt_mask cpu_smt_mask #ifdef CONFIG_SCHED_SMT @@ -198,6 +200,7 @@ extern void __cpu_die(unsigned int cpu); #define hard_smp_processor_id() get_hard_smp_processor_id(0) #define smp_setup_cpu_maps() #define thread_group_shares_l2 0 +#define thread_group_shares_l3 0 static inline void inhibit_secondary_onlining(void) {} static inline void uninhibit_secondary_onlining(void) {} static inline const struct cpumask *cpu_sibling_mask(int cpu) diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 20d91693eac1..cf1be75b7833 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -469,6 +469,9 @@ static int get_group_id(unsigned int cpu_id, int level) else if (thread_group_shares_l2 && level == 2) return cpumask_first(per_cpu(thread_group_l2_cache_map, cpu_id)); + else if (thread_group_shares_l3 && level == 3) + return cpumask_first(per_cpu(thread_group_l3_cache_map, + cpu_id)); return -1; } diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a7fcac44a8e2..f2abd88e0c25 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -78,6 +78,7 @@ struct task_struct *secondary_current; bool has_big_cores; bool coregroup_enabled; bool thread_group_shares_l2; +bool thread_group_shares_l3; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); DEFINE_PER_CPU(cpumask_var_t, cpu_smallcore_map); @@ -101,7 +102,7 @@ enum { #define MAX_THREAD_LIST_SIZE 8 #define THREAD_GROUP_SHARE_L1 1 -#define THREAD_GROUP_SHARE_L2 2 +#define THREAD_GROUP_SHARE_L2_L3 2 struct thread_groups { unsigned int property; unsigned int nr_groups; @@ -131,6 +132,12 @@ DEFINE_PER_CPU(cpumask_var_t, thread_group_l1_cache_map); */ DEFINE_PER_CPU(cpumask_var_t, thread_group_l2_cache_map); +/* + * On P10, thread_group_l3_cache_map for each CPU is equal to the + * thread_group_l2_cache_map + */ +DEFINE_PER_CPU(cpumask_var_t, thread_group_l3_cache_map); + /* SMP operations for this machine */ struct smp_ops_t *smp_ops; @@ -889,19 +896,41 @@ out: return tg; } +static int update_mask_from_threadgroup(cpumask_var_t *mask, struct thread_groups *tg, int cpu, int cpu_group_start) +{ + int first_thread = cpu_first_thread_sibling(cpu); + int i; + + zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cpu)); + + for (i = first_thread; i < first_thread + threads_per_core; i++) { + int i_group_start = get_cpu_thread_group_start(i, tg); + + if (unlikely(i_group_start == -1)) { + WARN_ON_ONCE(1); + return -ENODATA; + } + + if (i_group_start == cpu_group_start) + cpumask_set_cpu(i, *mask); + } + + return 0; +} + static int __init init_thread_group_cache_map(int cpu, int cache_property) { - int first_thread = cpu_first_thread_sibling(cpu); - int i, cpu_group_start = -1, err = 0; + int cpu_group_start = -1, err = 0; struct thread_groups *tg = NULL; cpumask_var_t *mask = NULL; if (cache_property != THREAD_GROUP_SHARE_L1 && - cache_property != THREAD_GROUP_SHARE_L2) + cache_property != THREAD_GROUP_SHARE_L2_L3) return -EINVAL; tg = get_thread_groups(cpu, cache_property, &err); + if (!tg) return err; @@ -912,25 +941,18 @@ static int __init init_thread_group_cache_map(int cpu, int cache_property) return -ENODATA; } - if (cache_property == THREAD_GROUP_SHARE_L1) + if (cache_property == THREAD_GROUP_SHARE_L1) { mask = &per_cpu(thread_group_l1_cache_map, cpu); - else if (cache_property == THREAD_GROUP_SHARE_L2) + update_mask_from_threadgroup(mask, tg, cpu, cpu_group_start); + } + else if (cache_property == THREAD_GROUP_SHARE_L2_L3) { mask = &per_cpu(thread_group_l2_cache_map, cpu); - - zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cpu)); - - for (i = first_thread; i < first_thread + threads_per_core; i++) { - int i_group_start = get_cpu_thread_group_start(i, tg); - - if (unlikely(i_group_start == -1)) { - WARN_ON_ONCE(1); - return -ENODATA; - } - - if (i_group_start == cpu_group_start) - cpumask_set_cpu(i, *mask); + update_mask_from_threadgroup(mask, tg, cpu, cpu_group_start); + mask = &per_cpu(thread_group_l3_cache_map, cpu); + update_mask_from_threadgroup(mask, tg, cpu, cpu_group_start); } + return 0; } @@ -1020,14 +1042,16 @@ static int __init init_big_cores(void) has_big_cores = true; for_each_possible_cpu(cpu) { - int err = init_thread_group_cache_map(cpu, THREAD_GROUP_SHARE_L2); + int err = init_thread_group_cache_map(cpu, THREAD_GROUP_SHARE_L2_L3); if (err) return err; } thread_group_shares_l2 = true; - pr_debug("L2 cache only shared by the threads in the small core\n"); + thread_group_shares_l3 = true; + pr_debug("L2/L3 cache only shared by the threads in the small core\n"); + return 0; } -- cgit v1.2.3-70-g09d2 From cf9c615cde49fb5d2480549c8c955a0a387798d3 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 21 Jul 2021 00:15:04 +1000 Subject: powerpc/64s/perf: Always use SIAR for kernel interrupts If an interrupt is taken in kernel mode, always use SIAR for it rather than looking at regs_sipr. This prevents samples piling up around interrupt enable (hard enable or interrupt replay via soft enable) in PMUs / modes where the PR sample indication is not in synch with SIAR. This results in better sampling of interrupt entry and exit in particular. Signed-off-by: Nicholas Piggin Tested-by: Athira Rajeev Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210720141504.420110-1-npiggin@gmail.com --- arch/powerpc/perf/core-book3s.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index bb0ee716de91..91203ed9d0ff 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -340,6 +340,13 @@ static inline void perf_read_regs(struct pt_regs *regs) * If the PMU doesn't update the SIAR for non marked events use * pt_regs. * + * If regs is a kernel interrupt, always use SIAR. Some PMUs have an + * issue with regs_sipr not being in synch with SIAR in interrupt entry + * and return sequences, which can result in regs_sipr being true for + * kernel interrupts and SIAR, which has the effect of causing samples + * to pile up at mtmsrd MSR[EE] 0->1 or pending irq replay around + * interrupt entry/exit. + * * If the PMU has HV/PR flags then check to see if they * place the exception in userspace. If so, use pt_regs. In * continuous sampling mode the SIAR and the PMU exception are @@ -356,6 +363,8 @@ static inline void perf_read_regs(struct pt_regs *regs) use_siar = 1; else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING)) use_siar = 0; + else if (!user_mode(regs)) + use_siar = 1; else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs)) use_siar = 0; else -- cgit v1.2.3-70-g09d2 From 91803392c732c43b5cf440e885ea89be7f5fecef Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 4 Aug 2021 08:38:38 +0800 Subject: f2fs: fix to stop filesystem update once CP failed During f2fs_write_checkpoint(), once we failed in f2fs_flush_nat_entries() or do_checkpoint(), metadata of filesystem such as prefree bitmap, nat/sit version bitmap won't be recovered, it may cause f2fs image to be inconsistent, let's just set CP error flag to avoid further updates until we figure out a scheme to rollback all metadatas in such condition. Reported-by: Yangtao Li Signed-off-by: Yangtao Li Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 12 +++++++++--- fs/f2fs/f2fs.h | 2 +- fs/f2fs/segment.c | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 6c208108d69c..7f6745f4630e 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -1639,8 +1639,11 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* write cached NAT/SIT entries to NAT/SIT area */ err = f2fs_flush_nat_entries(sbi, cpc); - if (err) + if (err) { + f2fs_err(sbi, "f2fs_flush_nat_entries failed err:%d, stop checkpoint", err); + f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); goto stop; + } f2fs_flush_sit_entries(sbi, cpc); @@ -1648,10 +1651,13 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_save_inmem_curseg(sbi); err = do_checkpoint(sbi, cpc); - if (err) + if (err) { + f2fs_err(sbi, "do_checkpoint failed err:%d, stop checkpoint", err); + f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); f2fs_release_discard_addrs(sbi); - else + } else { f2fs_clear_prefree_segments(sbi, cpc); + } f2fs_restore_inmem_curseg(sbi); stop: diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1b4c482d08e2..d24fd5045712 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -547,7 +547,7 @@ enum { */ }; -#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO count */ +#define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO or flush count */ /* congestion wait timeout value, default: 20ms */ #define DEFAULT_IO_TIMEOUT (msecs_to_jiffies(20)) diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 80f26158e304..ca9876a6d396 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -776,11 +776,22 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi) return 0; for (i = 1; i < sbi->s_ndevs; i++) { + int count = DEFAULT_RETRY_IO_COUNT; + if (!f2fs_test_bit(i, (char *)&sbi->dirty_device)) continue; - ret = __submit_flush_wait(sbi, FDEV(i).bdev); - if (ret) + + do { + ret = __submit_flush_wait(sbi, FDEV(i).bdev); + if (ret) + congestion_wait(BLK_RW_ASYNC, + DEFAULT_IO_TIMEOUT); + } while (ret && --count); + + if (ret) { + f2fs_stop_checkpoint(sbi, false); break; + } spin_lock(&sbi->dev_lock); f2fs_clear_bit(i, (char *)&sbi->dirty_device); -- cgit v1.2.3-70-g09d2 From 13e47bebbe83f58ddc41d2987567e97c5068a1ec Mon Sep 17 00:00:00 2001 From: Tong Tiangen Date: Fri, 2 Jul 2021 04:54:21 +0000 Subject: riscv: Implement thread_struct whitelist for hardened usercopy This whitelists the FPU register state portion of the thread_struct for copying to userspace, instead of the default entire struct. Signed-off-by: Tong Tiangen Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/processor.h | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 8fcceb8eda07..1af859b9d5bf 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -72,6 +72,7 @@ config RISCV select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU + select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_VMAP_STACK if MMU && 64BIT select HAVE_ASM_MODVERSIONS select HAVE_CONTEXT_TRACKING diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index 021ed64ee608..46b492c78cbb 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -37,6 +37,14 @@ struct thread_struct { unsigned long bad_cause; }; +/* Whitelist the fstate from the task_struct for hardened usercopy */ +static inline void arch_thread_struct_whitelist(unsigned long *offset, + unsigned long *size) +{ + *offset = offsetof(struct thread_struct, fstate); + *size = sizeof_field(struct thread_struct, fstate); +} + #define INIT_THREAD { \ .sp = sizeof(init_stack) + (long)&init_stack, \ } -- cgit v1.2.3-70-g09d2 From dc1cff969101afd08601e90463b44bd572e62dd4 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Jul 2021 18:04:53 -0400 Subject: KVM: X86: MMU: Tune PTE_LIST_EXT to be bigger Currently rmap array element only contains 3 entries. However for EPT=N there could have a lot of guest pages that got tens of even hundreds of rmap entry. A normal distribution of a 6G guest (even if idle) shows this with rmap count statistics: Rmap_Count: 0 1 2-3 4-7 8-15 16-31 32-63 64-127 128-255 256-511 512-1023 Level=4K: 3089171 49005 14016 1363 235 212 15 7 0 0 0 Level=2M: 5951 227 0 0 0 0 0 0 0 0 0 Level=1G: 32 0 0 0 0 0 0 0 0 0 0 If we do some more fork some pages will grow even larger rmap counts. This patch makes PTE_LIST_EXT bigger so it'll be more efficient for the general use case of EPT=N as we do list reference less and the loops over PTE_LIST_EXT will be slightly more efficient; but still not too large so less waste when array not full. It should not affecting EPT=Y since EPT normally only has zero or one rmap entry for each page, so no array is even allocated. With a test case to fork 500 child and recycle them ("./rmap_fork 500" [1]), this patch speeds up fork time of about 29%. Before: 473.90 (+-5.93%) After: 366.10 (+-4.94%) [1] https://github.com/xzpeter/clibs/commit/825436f825453de2ea5aaee4bdb1c92281efe5b3 Signed-off-by: Peter Xu Message-Id: <20210730220455.26054-6-peterx@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index e702361b4409..69ad8189d7eb 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -137,8 +137,8 @@ module_param(dbg, bool, 0644); #include -/* make pte_list_desc fit well in cache line */ -#define PTE_LIST_EXT 3 +/* make pte_list_desc fit well in cache lines */ +#define PTE_LIST_EXT 15 struct pte_list_desc { u64 *sptes[PTE_LIST_EXT]; -- cgit v1.2.3-70-g09d2 From 13236e25ebab91b3e42ddedf5354b569ace1b555 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Jul 2021 18:06:02 -0400 Subject: KVM: X86: Optimize pte_list_desc with per-array counter Add a counter field into pte_list_desc, so as to simplify the add/remove/loop logic. E.g., we don't need to loop over the array any more for most reasons. This will make more sense after we've switched the array size to be larger otherwise the counter will be a waste. Initially I wanted to store a tail pointer at the head of the array list so we don't need to traverse the list at least for pushing new ones (if without the counter we traverse both the list and the array). However that'll need slightly more change without a huge lot benefit, e.g., after we grow entry numbers per array the list traversing is not so expensive. So let's be simple but still try to get as much benefit as we can with just these extra few lines of changes (not to mention the code looks easier too without looping over arrays). I used the same a test case to fork 500 child and recycle them ("./rmap_fork 500" [1]), this patch further speeds up the total fork time of about 4%, which is a total of 33% of vanilla kernel: Vanilla: 473.90 (+-5.93%) 3->15 slots: 366.10 (+-4.94%) Add counter: 351.00 (+-3.70%) [1] https://github.com/xzpeter/clibs/commit/825436f825453de2ea5aaee4bdb1c92281efe5b3 Signed-off-by: Peter Xu Message-Id: <20210730220602.26327-1-peterx@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 69ad8189d7eb..f1eb2fdfa473 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -138,11 +138,21 @@ module_param(dbg, bool, 0644); #include /* make pte_list_desc fit well in cache lines */ -#define PTE_LIST_EXT 15 +#define PTE_LIST_EXT 14 +/* + * Slight optimization of cacheline layout, by putting `more' and `spte_count' + * at the start; then accessing it will only use one single cacheline for + * either full (entries==PTE_LIST_EXT) case or entries<=6. + */ struct pte_list_desc { - u64 *sptes[PTE_LIST_EXT]; struct pte_list_desc *more; + /* + * Stores number of entries stored in the pte_list_desc. No need to be + * u64 but just for easier alignment. When PTE_LIST_EXT, means full. + */ + u64 spte_count; + u64 *sptes[PTE_LIST_EXT]; }; struct kvm_shadow_walk_iterator { @@ -901,7 +911,7 @@ static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte, struct kvm_rmap_head *rmap_head) { struct pte_list_desc *desc; - int i, count = 0; + int count = 0; if (!rmap_head->val) { rmap_printk("%p %llx 0->1\n", spte, *spte); @@ -911,24 +921,24 @@ static int pte_list_add(struct kvm_vcpu *vcpu, u64 *spte, desc = mmu_alloc_pte_list_desc(vcpu); desc->sptes[0] = (u64 *)rmap_head->val; desc->sptes[1] = spte; + desc->spte_count = 2; rmap_head->val = (unsigned long)desc | 1; ++count; } else { rmap_printk("%p %llx many->many\n", spte, *spte); desc = (struct pte_list_desc *)(rmap_head->val & ~1ul); - while (desc->sptes[PTE_LIST_EXT-1]) { + while (desc->spte_count == PTE_LIST_EXT) { count += PTE_LIST_EXT; - if (!desc->more) { desc->more = mmu_alloc_pte_list_desc(vcpu); desc = desc->more; + desc->spte_count = 0; break; } desc = desc->more; } - for (i = 0; desc->sptes[i]; ++i) - ++count; - desc->sptes[i] = spte; + count += desc->spte_count; + desc->sptes[desc->spte_count++] = spte; } return count; } @@ -938,13 +948,12 @@ pte_list_desc_remove_entry(struct kvm_rmap_head *rmap_head, struct pte_list_desc *desc, int i, struct pte_list_desc *prev_desc) { - int j; + int j = desc->spte_count - 1; - for (j = PTE_LIST_EXT - 1; !desc->sptes[j] && j > i; --j) - ; desc->sptes[i] = desc->sptes[j]; desc->sptes[j] = NULL; - if (j != 0) + desc->spte_count--; + if (desc->spte_count) return; if (!prev_desc && !desc->more) rmap_head->val = 0; @@ -977,7 +986,7 @@ static void __pte_list_remove(u64 *spte, struct kvm_rmap_head *rmap_head) desc = (struct pte_list_desc *)(rmap_head->val & ~1ul); prev_desc = NULL; while (desc) { - for (i = 0; i < PTE_LIST_EXT && desc->sptes[i]; ++i) { + for (i = 0; i < desc->spte_count; ++i) { if (desc->sptes[i] == spte) { pte_list_desc_remove_entry(rmap_head, desc, i, prev_desc); -- cgit v1.2.3-70-g09d2 From a75b540451d20ef1aebaa09d183ddc5c44c6f86a Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Fri, 30 Jul 2021 18:06:05 -0400 Subject: KVM: X86: Optimize zapping rmap Using rmap_get_first() and rmap_remove() for zapping a huge rmap list could be slow. The easy way is to travers the rmap list, collecting the a/d bits and free the slots along the way. Provide a pte_list_destroy() and do exactly that. Signed-off-by: Peter Xu Message-Id: <20210730220605.26377-1-peterx@redhat.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index f1eb2fdfa473..232ced2e7bf8 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1007,6 +1007,34 @@ static void pte_list_remove(struct kvm_rmap_head *rmap_head, u64 *sptep) __pte_list_remove(sptep, rmap_head); } +/* Return true if rmap existed, false otherwise */ +static bool pte_list_destroy(struct kvm_rmap_head *rmap_head) +{ + struct pte_list_desc *desc, *next; + int i; + + if (!rmap_head->val) + return false; + + if (!(rmap_head->val & 1)) { + mmu_spte_clear_track_bits((u64 *)rmap_head->val); + goto out; + } + + desc = (struct pte_list_desc *)(rmap_head->val & ~1ul); + + for (; desc; desc = next) { + for (i = 0; i < desc->spte_count; i++) + mmu_spte_clear_track_bits(desc->sptes[i]); + next = desc->more; + mmu_free_pte_list_desc(desc); + } +out: + /* rmap_head is meaningless now, remember to reset it */ + rmap_head->val = 0; + return true; +} + static struct kvm_rmap_head *__gfn_to_rmap(gfn_t gfn, int level, const struct kvm_memory_slot *slot) { @@ -1398,18 +1426,7 @@ static bool rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) static bool kvm_zap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, const struct kvm_memory_slot *slot) { - u64 *sptep; - struct rmap_iterator iter; - bool flush = false; - - while ((sptep = rmap_get_first(rmap_head, &iter))) { - rmap_printk("spte %p %llx.\n", sptep, *sptep); - - pte_list_remove(rmap_head, sptep); - flush = true; - } - - return flush; + return pte_list_destroy(rmap_head); } static bool kvm_unmap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, -- cgit v1.2.3-70-g09d2 From e79f49c37ccf273c8aba733f803b3774ebfbe581 Mon Sep 17 00:00:00 2001 From: Like Xu Date: Wed, 28 Jul 2021 20:07:05 +0800 Subject: KVM: x86/pmu: Introduce pmc->is_paused to reduce the call time of perf interfaces Based on our observations, after any vm-exit associated with vPMU, there are at least two or more perf interfaces to be called for guest counter emulation, such as perf_event_{pause, read_value, period}(), and each one will {lock, unlock} the same perf_event_ctx. The frequency of calls becomes more severe when guest use counters in a multiplexed manner. Holding a lock once and completing the KVM request operations in the perf context would introduce a set of impractical new interfaces. So we can further optimize the vPMU implementation by avoiding repeated calls to these interfaces in the KVM context for at least one pattern: After we call perf_event_pause() once, the event will be disabled and its internal count will be reset to 0. So there is no need to pause it again or read its value. Once the event is paused, event period will not be updated until the next time it's resumed or reprogrammed. And there is also no need to call perf_event_period twice for a non-running counter, considering the perf_event for a running counter is never paused. Based on this implementation, for the following common usage of sampling 4 events using perf on a 4u8g guest: echo 0 > /proc/sys/kernel/watchdog echo 25 > /proc/sys/kernel/perf_cpu_time_max_percent echo 10000 > /proc/sys/kernel/perf_event_max_sample_rate echo 0 > /proc/sys/kernel/perf_cpu_time_max_percent for i in `seq 1 1 10` do taskset -c 0 perf record \ -e cpu-cycles -e instructions -e branch-instructions -e cache-misses \ /root/br_instr a done the average latency of the guest NMI handler is reduced from 37646.7 ns to 32929.3 ns (~1.14x speed up) on the Intel ICX server. Also, in addition to collecting more samples, no loss of sampling accuracy was observed compared to before the optimization. Signed-off-by: Like Xu Message-Id: <20210728120705.6855-1-likexu@tencent.com> Signed-off-by: Paolo Bonzini Acked-by: Peter Zijlstra --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/pmu.c | 5 ++++- arch/x86/kvm/pmu.h | 2 +- arch/x86/kvm/vmx/pmu_intel.c | 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 99f37781a6fc..a079880d4cd5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -482,6 +482,7 @@ struct kvm_pmc { * ctrl value for fixed counters. */ u64 current_config; + bool is_paused; }; struct kvm_pmu { diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 827886c12c16..0772bad9165c 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -137,18 +137,20 @@ static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type, pmc->perf_event = event; pmc_to_pmu(pmc)->event_count++; clear_bit(pmc->idx, pmc_to_pmu(pmc)->reprogram_pmi); + pmc->is_paused = false; } static void pmc_pause_counter(struct kvm_pmc *pmc) { u64 counter = pmc->counter; - if (!pmc->perf_event) + if (!pmc->perf_event || pmc->is_paused) return; /* update counter, reset event value to avoid redundant accumulation */ counter += perf_event_pause(pmc->perf_event, true); pmc->counter = counter & pmc_bitmask(pmc); + pmc->is_paused = true; } static bool pmc_resume_counter(struct kvm_pmc *pmc) @@ -163,6 +165,7 @@ static bool pmc_resume_counter(struct kvm_pmc *pmc) /* reuse perf_event to serve as pmc_reprogram_counter() does*/ perf_event_enable(pmc->perf_event); + pmc->is_paused = false; clear_bit(pmc->idx, (unsigned long *)&pmc_to_pmu(pmc)->reprogram_pmi); return true; diff --git a/arch/x86/kvm/pmu.h b/arch/x86/kvm/pmu.h index 67e753edfa22..0e4f2b1fa9fb 100644 --- a/arch/x86/kvm/pmu.h +++ b/arch/x86/kvm/pmu.h @@ -55,7 +55,7 @@ static inline u64 pmc_read_counter(struct kvm_pmc *pmc) u64 counter, enabled, running; counter = pmc->counter; - if (pmc->perf_event) + if (pmc->perf_event && !pmc->is_paused) counter += perf_event_read_value(pmc->perf_event, &enabled, &running); /* FIXME: Scaling needed? */ diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c index 9efc1a6b8693..10cc4f65c4ef 100644 --- a/arch/x86/kvm/vmx/pmu_intel.c +++ b/arch/x86/kvm/vmx/pmu_intel.c @@ -437,13 +437,13 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) !(msr & MSR_PMC_FULL_WIDTH_BIT)) data = (s64)(s32)data; pmc->counter += data - pmc_read_counter(pmc); - if (pmc->perf_event) + if (pmc->perf_event && !pmc->is_paused) perf_event_period(pmc->perf_event, get_sample_period(pmc, data)); return 0; } else if ((pmc = get_fixed_pmc(pmu, msr))) { pmc->counter += data - pmc_read_counter(pmc); - if (pmc->perf_event) + if (pmc->perf_event && !pmc->is_paused) perf_event_period(pmc->perf_event, get_sample_period(pmc, data)); return 0; -- cgit v1.2.3-70-g09d2 From d277f6e88c88729b1d57d40bbfb00d0bfc961972 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 3 Aug 2021 15:56:55 -0600 Subject: PCI: of: Don't fail devm_pci_alloc_host_bridge() on missing 'ranges' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 669cbc708122 ("PCI: Move DT resource setup into devm_pci_alloc_host_bridge()") made devm_pci_alloc_host_bridge() fail on any DT resource parsing errors, but Broadcom iProc uses devm_pci_alloc_host_bridge() on BCMA bus devices that don't have DT resources. In particular, there is no 'ranges' property. Fix iProc by making 'ranges' optional. If 'ranges' is required by a platform, there's going to be more errors latter on if it is missing. Link: https://lore.kernel.org/r/20210803215656.3803204-1-robh@kernel.org Fixes: 669cbc708122 ("PCI: Move DT resource setup into devm_pci_alloc_host_bridge()") Reported-by: Rafał Miłecki Tested-by: Rafał Miłecki Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Acked-by: Bjorn Helgaas Cc: Srinath Mannam Cc: Roman Bacik Cc: Bharat Gooty Cc: Abhishek Shah Cc: Jitendra Bhivare Cc: Ray Jui Cc: Florian Fainelli Cc: BCM Kernel Feedback Cc: Scott Branden Cc: Bjorn Helgaas Cc: Lorenzo Pieralisi --- drivers/pci/of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index a143b02b2dcd..d84381ce82b5 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -310,7 +310,7 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev, /* Check for ranges property */ err = of_pci_range_parser_init(&parser, dev_node); if (err) - goto failed; + return 0; dev_dbg(dev, "Parsing ranges property...\n"); for_each_of_pci_range(&parser, &range) { -- cgit v1.2.3-70-g09d2 From aeaea8969b402e0081210cc9144404d13996efed Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 3 Aug 2021 15:56:56 -0600 Subject: PCI: iproc: Fix BCMA probe resource handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 7ef1c871da16 ("PCI: iproc: Use pci_parse_request_of_pci_ranges()"), calling devm_request_pci_bus_resources() was dropped from the common iProc probe code, but is still needed for BCMA bus probing. Without it, there will be lots of warnings like this: pci 0000:00:00.0: BAR 8: no space for [mem size 0x00c00000] pci 0000:00:00.0: BAR 8: failed to assign [mem size 0x00c00000] Add back calling devm_request_pci_bus_resources() and adding the resources to pci_host_bridge.windows for BCMA bus probe. Link: https://lore.kernel.org/r/20210803215656.3803204-2-robh@kernel.org Fixes: 7ef1c871da16 ("PCI: iproc: Use pci_parse_request_of_pci_ranges()") Reported-by: Rafał Miłecki Tested-by: Rafał Miłecki Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Cc: Srinath Mannam Cc: Roman Bacik Cc: Bharat Gooty Cc: Abhishek Shah Cc: Jitendra Bhivare Cc: Ray Jui Cc: Florian Fainelli Cc: BCM Kernel Feedback Cc: Scott Branden Cc: Lorenzo Pieralisi Cc: "Krzysztof Wilczyński" Cc: Bjorn Helgaas --- drivers/pci/controller/pcie-iproc-bcma.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/pci/controller/pcie-iproc-bcma.c b/drivers/pci/controller/pcie-iproc-bcma.c index 56b8ee7bf330..f918c713afb0 100644 --- a/drivers/pci/controller/pcie-iproc-bcma.c +++ b/drivers/pci/controller/pcie-iproc-bcma.c @@ -35,7 +35,6 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev) { struct device *dev = &bdev->dev; struct iproc_pcie *pcie; - LIST_HEAD(resources); struct pci_host_bridge *bridge; int ret; @@ -60,19 +59,16 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev) pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1; pcie->mem.name = "PCIe MEM space"; pcie->mem.flags = IORESOURCE_MEM; - pci_add_resource(&resources, &pcie->mem); + pci_add_resource(&bridge->windows, &pcie->mem); + ret = devm_request_pci_bus_resources(dev, &bridge->windows); + if (ret) + return ret; pcie->map_irq = iproc_pcie_bcma_map_irq; - ret = iproc_pcie_setup(pcie, &resources); - if (ret) { - dev_err(dev, "PCIe controller setup failed\n"); - pci_free_resource_list(&resources); - return ret; - } - bcma_set_drvdata(bdev, pcie); - return 0; + + return iproc_pcie_setup(pcie, &bridge->windows); } static void iproc_pcie_bcma_remove(struct bcma_device *bdev) -- cgit v1.2.3-70-g09d2 From e1e71c168813564be0f6ea3d6740a059ca42d177 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 4 Aug 2021 13:22:58 +0200 Subject: fuse: fix use after free in fuse_read_interrupt() There is a potential race between fuse_read_interrupt() and fuse_request_end(). TASK1 in fuse_read_interrupt(): delete req->intr_entry (while holding fiq->lock) TASK2 in fuse_request_end(): req->intr_entry is empty -> skip fiq->lock wake up TASK3 TASK3 request is freed TASK1 in fuse_read_interrupt(): dereference req->in.h.unique ***BAM*** Fix by always grabbing fiq->lock if the request was ever interrupted (FR_INTERRUPTED set) thereby serializing with concurrent fuse_read_interrupt() calls. FR_INTERRUPTED is set before the request is queued on fiq->interrupts. Dequeing the request is done with list_del_init() but FR_INTERRUPTED is not cleared in this case. Reported-by: lijiazi Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 1c8f79b3dd06..dde341a6388a 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -288,10 +288,10 @@ void fuse_request_end(struct fuse_req *req) /* * test_and_set_bit() implies smp_mb() between bit - * changing and below intr_entry check. Pairs with + * changing and below FR_INTERRUPTED check. Pairs with * smp_mb() from queue_interrupt(). */ - if (!list_empty(&req->intr_entry)) { + if (test_bit(FR_INTERRUPTED, &req->flags)) { spin_lock(&fiq->lock); list_del_init(&req->intr_entry); spin_unlock(&fiq->lock); -- cgit v1.2.3-70-g09d2 From 84c215075b5723ab946708a6c74c26bd3c51114c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 4 Aug 2021 13:22:58 +0200 Subject: fuse: name fs_context consistently Naming convention under fs/fuse/: struct fuse_conn *fc; struct fs_context *fsc; Signed-off-by: Miklos Szeredi --- fs/fuse/control.c | 10 ++++----- fs/fuse/inode.c | 60 ++++++++++++++++++++++++++--------------------------- fs/fuse/virtio_fs.c | 12 +++++------ 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index cc7e94d73c6c..000d2e5627e9 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -328,7 +328,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc) drop_nlink(d_inode(fuse_control_sb->s_root)); } -static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fctx) +static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fsc) { static const struct tree_descr empty_descr = {""}; struct fuse_conn *fc; @@ -354,18 +354,18 @@ static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fctx) return 0; } -static int fuse_ctl_get_tree(struct fs_context *fc) +static int fuse_ctl_get_tree(struct fs_context *fsc) { - return get_tree_single(fc, fuse_ctl_fill_super); + return get_tree_single(fsc, fuse_ctl_fill_super); } static const struct fs_context_operations fuse_ctl_context_ops = { .get_tree = fuse_ctl_get_tree, }; -static int fuse_ctl_init_fs_context(struct fs_context *fc) +static int fuse_ctl_init_fs_context(struct fs_context *fsc) { - fc->ops = &fuse_ctl_context_ops; + fsc->ops = &fuse_ctl_context_ops; return 0; } diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index b9beb39a4a18..d1b1b17b321c 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -138,12 +138,12 @@ static void fuse_evict_inode(struct inode *inode) } } -static int fuse_reconfigure(struct fs_context *fc) +static int fuse_reconfigure(struct fs_context *fsc) { - struct super_block *sb = fc->root->d_sb; + struct super_block *sb = fsc->root->d_sb; sync_filesystem(sb); - if (fc->sb_flags & SB_MANDLOCK) + if (fsc->sb_flags & SB_MANDLOCK) return -EINVAL; return 0; @@ -573,38 +573,38 @@ static const struct fs_parameter_spec fuse_fs_parameters[] = { {} }; -static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) +static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) { struct fs_parse_result result; - struct fuse_fs_context *ctx = fc->fs_private; + struct fuse_fs_context *ctx = fsc->fs_private; int opt; - if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { + if (fsc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { /* * Ignore options coming from mount(MS_REMOUNT) for backward * compatibility. */ - if (fc->oldapi) + if (fsc->oldapi) return 0; - return invalfc(fc, "No changes allowed in reconfigure"); + return invalfc(fsc, "No changes allowed in reconfigure"); } - opt = fs_parse(fc, fuse_fs_parameters, param, &result); + opt = fs_parse(fsc, fuse_fs_parameters, param, &result); if (opt < 0) return opt; switch (opt) { case OPT_SOURCE: - if (fc->source) - return invalfc(fc, "Multiple sources specified"); - fc->source = param->string; + if (fsc->source) + return invalfc(fsc, "Multiple sources specified"); + fsc->source = param->string; param->string = NULL; break; case OPT_SUBTYPE: if (ctx->subtype) - return invalfc(fc, "Multiple subtypes specified"); + return invalfc(fsc, "Multiple subtypes specified"); ctx->subtype = param->string; param->string = NULL; return 0; @@ -616,22 +616,22 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) case OPT_ROOTMODE: if (!fuse_valid_type(result.uint_32)) - return invalfc(fc, "Invalid rootmode"); + return invalfc(fsc, "Invalid rootmode"); ctx->rootmode = result.uint_32; ctx->rootmode_present = true; break; case OPT_USER_ID: - ctx->user_id = make_kuid(fc->user_ns, result.uint_32); + ctx->user_id = make_kuid(fsc->user_ns, result.uint_32); if (!uid_valid(ctx->user_id)) - return invalfc(fc, "Invalid user_id"); + return invalfc(fsc, "Invalid user_id"); ctx->user_id_present = true; break; case OPT_GROUP_ID: - ctx->group_id = make_kgid(fc->user_ns, result.uint_32); + ctx->group_id = make_kgid(fsc->user_ns, result.uint_32); if (!gid_valid(ctx->group_id)) - return invalfc(fc, "Invalid group_id"); + return invalfc(fsc, "Invalid group_id"); ctx->group_id_present = true; break; @@ -649,7 +649,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) case OPT_BLKSIZE: if (!ctx->is_bdev) - return invalfc(fc, "blksize only supported for fuseblk"); + return invalfc(fsc, "blksize only supported for fuseblk"); ctx->blksize = result.uint_32; break; @@ -660,9 +660,9 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param) return 0; } -static void fuse_free_fc(struct fs_context *fc) +static void fuse_free_fsc(struct fs_context *fsc) { - struct fuse_fs_context *ctx = fc->fs_private; + struct fuse_fs_context *ctx = fsc->fs_private; if (ctx) { kfree(ctx->subtype); @@ -1566,9 +1566,9 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) return err; } -static int fuse_get_tree(struct fs_context *fc) +static int fuse_get_tree(struct fs_context *fsc) { - struct fuse_fs_context *ctx = fc->fs_private; + struct fuse_fs_context *ctx = fsc->fs_private; if (!ctx->fd_present || !ctx->rootmode_present || !ctx->user_id_present || !ctx->group_id_present) @@ -1576,14 +1576,14 @@ static int fuse_get_tree(struct fs_context *fc) #ifdef CONFIG_BLOCK if (ctx->is_bdev) - return get_tree_bdev(fc, fuse_fill_super); + return get_tree_bdev(fsc, fuse_fill_super); #endif - return get_tree_nodev(fc, fuse_fill_super); + return get_tree_nodev(fsc, fuse_fill_super); } static const struct fs_context_operations fuse_context_ops = { - .free = fuse_free_fc, + .free = fuse_free_fsc, .parse_param = fuse_parse_param, .reconfigure = fuse_reconfigure, .get_tree = fuse_get_tree, @@ -1592,7 +1592,7 @@ static const struct fs_context_operations fuse_context_ops = { /* * Set up the filesystem mount context. */ -static int fuse_init_fs_context(struct fs_context *fc) +static int fuse_init_fs_context(struct fs_context *fsc) { struct fuse_fs_context *ctx; @@ -1605,14 +1605,14 @@ static int fuse_init_fs_context(struct fs_context *fc) ctx->legacy_opts_show = true; #ifdef CONFIG_BLOCK - if (fc->fs_type == &fuseblk_fs_type) { + if (fsc->fs_type == &fuseblk_fs_type) { ctx->is_bdev = true; ctx->destroy = true; } #endif - fc->fs_private = ctx; - fc->ops = &fuse_context_ops; + fsc->fs_private = ctx; + fsc->ops = &fuse_context_ops; return 0; } diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 8f52cdaa8445..0ad89c6629d7 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -97,14 +97,14 @@ static const struct fs_parameter_spec virtio_fs_parameters[] = { {} }; -static int virtio_fs_parse_param(struct fs_context *fc, +static int virtio_fs_parse_param(struct fs_context *fsc, struct fs_parameter *param) { struct fs_parse_result result; - struct fuse_fs_context *ctx = fc->fs_private; + struct fuse_fs_context *ctx = fsc->fs_private; int opt; - opt = fs_parse(fc, virtio_fs_parameters, param, &result); + opt = fs_parse(fsc, virtio_fs_parameters, param, &result); if (opt < 0) return opt; @@ -119,9 +119,9 @@ static int virtio_fs_parse_param(struct fs_context *fc, return 0; } -static void virtio_fs_free_fc(struct fs_context *fc) +static void virtio_fs_free_fsc(struct fs_context *fsc) { - struct fuse_fs_context *ctx = fc->fs_private; + struct fuse_fs_context *ctx = fsc->fs_private; kfree(ctx); } @@ -1488,7 +1488,7 @@ out_err: } static const struct fs_context_operations virtio_fs_context_ops = { - .free = virtio_fs_free_fc, + .free = virtio_fs_free_fsc, .parse_param = virtio_fs_parse_param, .get_tree = virtio_fs_get_tree, }; -- cgit v1.2.3-70-g09d2 From badc741459f42f51e244533ce1df1cd9ac5ac6d7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 4 Aug 2021 13:22:58 +0200 Subject: fuse: move option checking into fuse_fill_super() Checking whether the "fd=", "rootmode=", "user_id=" and "group_id=" mount options are present can be moved from fuse_get_tree() into fuse_fill_super() where the value of the options are consumed. This relaxes semantics of reusing a fuse blockdev mount using the device name. Before this patch presence of these options were enforced but values ignored, after this patch these options are completely ignored in this case. Signed-off-by: Miklos Szeredi --- fs/fuse/inode.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d1b1b17b321c..54379a0c86d3 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1514,6 +1514,10 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) struct fuse_conn *fc; struct fuse_mount *fm; + if (!ctx->fd_present || !ctx->rootmode_present || + !ctx->user_id_present || !ctx->group_id_present) + return -EINVAL; + err = -EINVAL; file = fget(ctx->fd); if (!file) @@ -1570,14 +1574,9 @@ static int fuse_get_tree(struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; - if (!ctx->fd_present || !ctx->rootmode_present || - !ctx->user_id_present || !ctx->group_id_present) - return -EINVAL; - -#ifdef CONFIG_BLOCK - if (ctx->is_bdev) + if (IS_ENABLED(CONFIG_BLOCK) && ctx->is_bdev) { return get_tree_bdev(fsc, fuse_fill_super); -#endif + } return get_tree_nodev(fsc, fuse_fill_super); } -- cgit v1.2.3-70-g09d2 From ceb1412c1c8ca5b28c4252bdb15f2f1f17b4a1b0 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Wed, 23 Jun 2021 15:35:21 +0530 Subject: PCI: tegra194: Fix handling BME_CHGED event In tegra_pcie_ep_hard_irq(), APPL_INTR_STATUS_L0 is stored in val and again APPL_INTR_STATUS_L1_0_0 is also stored in val. So when execution reaches "if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT)", val is not correct. Link: https://lore.kernel.org/r/20210623100525.19944-2-omp@nvidia.com Signed-off-by: Om Prakash Singh Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Helgaas Acked-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-tegra194.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 3ec7b29d5dc7..fd14e2f45bba 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -497,19 +497,19 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg) struct tegra_pcie_dw *pcie = arg; struct dw_pcie_ep *ep = &pcie->pci.ep; int spurious = 1; - u32 val, tmp; + u32 status_l0, status_l1, link_status; - val = appl_readl(pcie, APPL_INTR_STATUS_L0); - if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); - appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0); + status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0); + if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0); - if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE) + if (status_l1 & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE) pex_ep_event_hot_rst_done(pcie); - if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) { - tmp = appl_readl(pcie, APPL_LINK_STATUS); - if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP) { + if (status_l1 & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) { + link_status = appl_readl(pcie, APPL_LINK_STATUS); + if (link_status & APPL_LINK_STATUS_RDLH_LINK_UP) { dev_dbg(pcie->dev, "Link is up with Host\n"); dw_pcie_ep_linkup(ep); } @@ -518,11 +518,11 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg) spurious = 0; } - if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_15); - appl_writel(pcie, val, APPL_INTR_STATUS_L1_15); + if (status_l0 & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_15); + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_15); - if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED) + if (status_l1 & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED) return IRQ_WAKE_THREAD; spurious = 0; @@ -530,8 +530,8 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg) if (spurious) { dev_warn(pcie->dev, "Random interrupt (STATUS = 0x%08X)\n", - val); - appl_writel(pcie, val, APPL_INTR_STATUS_L0); + status_l0); + appl_writel(pcie, status_l0, APPL_INTR_STATUS_L0); } return IRQ_HANDLED; -- cgit v1.2.3-70-g09d2 From 43537cf7e351264a1f05ed42ad402942bfc9140e Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Wed, 23 Jun 2021 15:35:22 +0530 Subject: PCI: tegra194: Fix MSI-X programming Lower order MSI-X address is programmed in MSIX_ADDR_MATCH_HIGH_OFF DBI register instead of higher order address. This patch fixes this programming mistake. Link: https://lore.kernel.org/r/20210623100525.19944-3-omp@nvidia.com Signed-off-by: Om Prakash Singh Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Helgaas Acked-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-tegra194.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index fd14e2f45bba..55c8afb9a899 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1763,7 +1763,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) val = (ep->msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK); val |= MSIX_ADDR_MATCH_LOW_OFF_EN; dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_LOW_OFF, val); - val = (lower_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK); + val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK); dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val); ret = dw_pcie_ep_init_complete(ep); -- cgit v1.2.3-70-g09d2 From 834c5cf2b5876f2fa0441a80826a84d4a64f932f Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Wed, 23 Jun 2021 15:35:23 +0530 Subject: PCI: tegra194: Disable interrupts before entering L2 In suspend_noirq() call if link doesn't goto L2, PERST# is asserted to bring link to detect state. However, this is causing surprise link down AER error. Since Kernel is executing noirq suspend calls, AER interrupt is not processed. PME and AER are shared interrupts and PCIe subsystem driver enables wake capability of PME irq during suspend. So this AER will cause suspend failure due to pending AER interrupt. After PCIe link is in L2, interrupts are not expected since PCIe controller will be in reset state. Disable PCIe interrupts before going to L2 state to avoid pending AER interrupt. Link: https://lore.kernel.org/r/20210623100525.19944-4-omp@nvidia.com Signed-off-by: Om Prakash Singh Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Helgaas Acked-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-tegra194.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 55c8afb9a899..f2e49dda2c83 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1493,6 +1493,16 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie) return; } + /* + * PCIe controller exits from L2 only if reset is applied, so + * controller doesn't handle interrupts. But in cases where + * L2 entry fails, PERST# is asserted which can trigger surprise + * link down AER. However this function call happens in + * suspend_noirq(), so AER interrupt will not be processed. + * Disable all interrupts to avoid such a scenario. + */ + appl_writel(pcie, 0x0, APPL_INTR_EN_L0_0); + if (tegra_pcie_try_link_l2(pcie)) { dev_info(pcie->dev, "Link didn't transition to L2 state\n"); /* -- cgit v1.2.3-70-g09d2 From de2bbf2b71bb994b2bbe5965e25dc06df83c5128 Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Wed, 23 Jun 2021 15:35:24 +0530 Subject: PCI: tegra194: Don't allow suspend when Tegra PCIe is in EP mode When Tegra PCIe is in endpoint mode it should be available for root port. PCIe link up by root port fails if it is in suspend state. So, don't allow Tegra to suspend when endpoint mode is enabled. Link: https://lore.kernel.org/r/20210623100525.19944-5-omp@nvidia.com Signed-off-by: Om Prakash Singh Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Helgaas Acked-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-tegra194.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index f2e49dda2c83..2d86e947bf1f 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -2246,6 +2246,11 @@ static int tegra_pcie_dw_resume_early(struct device *dev) struct tegra_pcie_dw *pcie = dev_get_drvdata(dev); u32 val; + if (pcie->mode == DW_PCIE_EP_TYPE) { + dev_err(dev, "Suspend is not supported in EP mode"); + return -ENOTSUPP; + } + if (!pcie->link_state) return 0; -- cgit v1.2.3-70-g09d2 From f62750e6918d2ac39ffe019249d2247ff0ac308d Mon Sep 17 00:00:00 2001 From: Om Prakash Singh Date: Wed, 23 Jun 2021 15:35:25 +0530 Subject: PCI: tegra194: Cleanup unused code Remove unused code from function tegra_pcie_config_ep. Link: https://lore.kernel.org/r/20210623100525.19944-6-omp@nvidia.com Signed-off-by: Om Prakash Singh Signed-off-by: Lorenzo Pieralisi Reviewed-by: Bjorn Helgaas Acked-by: Vidya Sagar --- drivers/pci/controller/dwc/pcie-tegra194.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 2d86e947bf1f..904976913081 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1945,13 +1945,6 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie, return ret; } - name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_ep_work", - pcie->cid); - if (!name) { - dev_err(dev, "Failed to create PCIe EP work thread string\n"); - return -ENOMEM; - } - pm_runtime_enable(dev); ret = dw_pcie_ep_init(ep); -- cgit v1.2.3-70-g09d2 From eb48d154cd0dade56a0e244f0cfa198ea2925ed3 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 2 Aug 2021 13:38:29 +0100 Subject: arm64: Move .hyp.rodata outside of the _sdata.._edata range The HYP rodata section is currently lumped together with the BSS, which isn't exactly what is expected (it gets registered with kmemleak, for example). Move it away so that it is actually marked RO. As an added benefit, it isn't registered with kmemleak anymore. Fixes: 380e18ade4a5 ("KVM: arm64: Introduce a BSS section for use at Hyp") Suggested-by: Catalin Marinas Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org #5.13 Acked-by: Catalin Marinas Link: https://lore.kernel.org/r/20210802123830.2195174-2-maz@kernel.org --- arch/arm64/kernel/vmlinux.lds.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 709d2c433c5e..f6b1a88245db 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -181,6 +181,8 @@ SECTIONS /* everything from this point to __init_begin will be marked RO NX */ RO_DATA(PAGE_SIZE) + HYPERVISOR_DATA_SECTIONS + idmap_pg_dir = .; . += IDMAP_DIR_SIZE; idmap_pg_end = .; @@ -260,8 +262,6 @@ SECTIONS _sdata = .; RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) - HYPERVISOR_DATA_SECTIONS - /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback -- cgit v1.2.3-70-g09d2 From 47e6223c841e029bfc23c3ce594dac5525cebaf8 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 2 Aug 2021 13:38:30 +0100 Subject: KVM: arm64: Unregister HYP sections from kmemleak in protected mode Booting a KVM host in protected mode with kmemleak quickly results in a pretty bad crash, as kmemleak doesn't know that the HYP sections have been taken away. This is specially true for the BSS section, which is part of the kernel BSS section and registered at boot time by kmemleak itself. Unregister the HYP part of the BSS before making that section HYP-private. The rest of the HYP-specific data is obtained via the page allocator or lives in other sections, none of which is subjected to kmemleak. Fixes: 90134ac9cabb ("KVM: arm64: Protect the .hyp sections from the host") Reviewed-by: Quentin Perret Reviewed-by: Catalin Marinas Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org # 5.13 Link: https://lore.kernel.org/r/20210802123830.2195174-3-maz@kernel.org --- arch/arm64/kvm/arm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e9a2b8f27792..52242f32c4be 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1982,6 +1983,12 @@ static int finalize_hyp_mode(void) if (ret) return ret; + /* + * Exclude HYP BSS from kmemleak so that it doesn't get peeked + * at, which would end badly once the section is inaccessible. + * None of other sections should ever be introspected. + */ + kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); ret = pkvm_mark_hyp_section(__hyp_bss); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 8165c6ae8e3a264601f02fc17e5545d027584a2f Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Thu, 8 Jul 2021 09:59:47 +0800 Subject: riscv: Allow forced irq threading The timer interrupt and the perf interrupt on riscv are with IRQF_PERCPU, so it's safe to allow forced interrupt threading. Signed-off-by: Kefeng Wang Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 1af859b9d5bf..1fc5a95df3f4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -98,6 +98,7 @@ config RISCV select HAVE_STACKPROTECTOR select HAVE_SYSCALL_TRACEPOINTS select IRQ_DOMAIN + select IRQ_FORCED_THREADING select MODULES_USE_ELF_RELA if MODULES select MODULE_SECTIONS if MODULES select OF -- cgit v1.2.3-70-g09d2 From bcf11b5e99b27472ea61231a64e29ad7dd31f0da Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Thu, 8 Jul 2021 09:59:48 +0800 Subject: riscv: Enable idle generic idle loop Enable generic idle loop to support for hlt/nohlt command line options to override default idle loop behavior. Signed-off-by: Kefeng Wang Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 1fc5a95df3f4..95cb9efa9213 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -48,6 +48,7 @@ config RISCV select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_EARLY_IOREMAP select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO + select GENERIC_IDLE_POLL_SETUP select GENERIC_IOREMAP select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_SHOW -- cgit v1.2.3-70-g09d2 From ecd4916c7261edccb2382c9931535e238875a44d Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Thu, 8 Jul 2021 09:59:49 +0800 Subject: riscv: Enable GENERIC_IRQ_SHOW_LEVEL The interrupt controllers on riscv support both edge and level triggered interrupts, it's useful to provide that information in /proc/interrupts. Signed-off-by: Kefeng Wang Signed-off-by: Palmer Dabbelt --- arch/riscv/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 95cb9efa9213..387cf68a5d52 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -52,6 +52,7 @@ config RISCV select GENERIC_IOREMAP select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_SHOW + select GENERIC_IRQ_SHOW_LEVEL select GENERIC_LIB_DEVMEM_IS_ALLOWED select GENERIC_PCI_IOMAP select GENERIC_PTDUMP if MMU -- cgit v1.2.3-70-g09d2 From f35ef8e4ea0a2b2b35a2c7009fc07b6d80a2b2f3 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 28 Jul 2021 23:52:11 +0200 Subject: dt-bindings: remoteproc: qcom: adsp: Add SDM660 ADSP Add a compatible string for SDM660 ADSP. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210728215212.18217-1-konrad.dybcio@somainline.org [bjorn: Use the -pas suffix] Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml index c597ccced623..0c112f3264a9 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml @@ -28,6 +28,7 @@ properties: - qcom,sc8180x-adsp-pas - qcom,sc8180x-cdsp-pas - qcom,sc8180x-mpss-pas + - qcom,sdm660-adsp-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sdx55-mpss-pas -- cgit v1.2.3-70-g09d2 From a0a77028c85ad1f6f36c3ceea21b30dc43721665 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Wed, 28 Jul 2021 23:52:12 +0200 Subject: remoteproc: q6v5_pas: Add sdm660 ADSP PIL compatible This chipset seems to work fine with the "generic" configuration. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210728215212.18217-2-konrad.dybcio@somainline.org [bjorn: Use "-pas" suffix for remoteprocs using TrustZone] Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index a79bee901e9b..401b1ec90785 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -833,6 +833,7 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, + { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init}, { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init}, { .compatible = "qcom,sdx55-mpss-pas", .data = &sdx55_mpss_resource}, -- cgit v1.2.3-70-g09d2 From 1ca70b24afb999376bee3cf3b4a52732988fa0d7 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Tue, 20 Jul 2021 11:15:42 -0700 Subject: MAINTAINERS: add Nick as Reviewer for compiler_attributes.h $ ./scripts/get_maintainer.pl --rolestats --git-blame -f \ include/linux/compiler_attributes.h ... Nick Desaulniers (supporter:CLANG/LLVM BUILD SUPPORT,authored lines:43/331=13%,commits:8/15=53%) It's also important for me to stay up on which compiler attributes clang is missing. Signed-off-by: Nick Desaulniers Signed-off-by: Miguel Ojeda --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0cce91cd5624..30724a8cf304 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4575,6 +4575,7 @@ F: drivers/platform/x86/compal-laptop.c COMPILER ATTRIBUTES M: Miguel Ojeda +R: Nick Desaulniers S: Maintained F: include/linux/compiler_attributes.h -- cgit v1.2.3-70-g09d2 From 9f2a5aebb03c19180e3be75ed7263c6ab510b75e Mon Sep 17 00:00:00 2001 From: Drew Fustini Date: Mon, 12 Jul 2021 23:30:18 -0700 Subject: dt-bindings: riscv: add starfive jh7100 bindings Add DT binding documentation for the StarFive JH7100 Soc [1] and the BeagleV Starlight JH7100 board [2]. [1] https://github.com/starfive-tech/beaglev_doc [2] https://github.com/beagleboard/beaglev-starlight Signed-off-by: Drew Fustini Reviewed-by: Rob Herring Reviewed-by: Bin Meng Signed-off-by: Palmer Dabbelt --- .../devicetree/bindings/riscv/starfive.yaml | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/starfive.yaml diff --git a/Documentation/devicetree/bindings/riscv/starfive.yaml b/Documentation/devicetree/bindings/riscv/starfive.yaml new file mode 100644 index 000000000000..5b36243fd674 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/starfive.yaml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/starfive.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive SoC-based boards + +maintainers: + - Michael Zhu + - Drew Fustini + +description: + StarFive SoC-based boards + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - items: + - const: beagle,beaglev-starlight-jh7100-r0 + - const: starfive,jh7100 + +additionalProperties: true + +... -- cgit v1.2.3-70-g09d2 From d4bf15a7ce172d186d400d606adf4f34a59130d6 Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Wed, 4 Aug 2021 11:29:46 +0800 Subject: f2fs: reduce the scope of setting fsck tag when de->name_len is zero I recently found a case where de->name_len is 0 in f2fs_fill_dentries() easily reproduced, and finally set the fsck flag. Thread A Thread B - f2fs_readdir - f2fs_read_inline_dir - ctx->pos = d.max - f2fs_add_dentry - f2fs_add_inline_entry - do_convert_inline_dir - f2fs_add_regular_entry - f2fs_readdir - f2fs_fill_dentries - set_sbi_flag(sbi, SBI_NEED_FSCK) Process A opens the folder, and has been reading without closing it. During this period, Process B created a file under the folder (occupying multiple f2fs_dir_entry, exceeding the d.max of the inline dir). After creation, process A uses the d.max of inline dir to read it again, and it will read that de->name_len is 0. And Chao pointed out that w/o inline conversion, the race condition still can happen as below: dir_entry1: A dir_entry2: B dir_entry3: C free slot: _ ctx->pos: ^ Thread A is traversing directory, ctx-pos moves to below position after readdir() by thread A: AAAABBBB___ ^ Then thread B delete dir_entry2, and create dir_entry3. Thread A calls readdir() to lookup dirents starting from middle of new dirent slots as below: AAAACCCCCC_ ^ In these scenarios, the file system is not damaged, and it's hard to avoid it. But we can bypass tagging FSCK flag if: a) bit_pos (:= ctx->pos % d->max) is non-zero and b) before bit_pos moves to first valid dir_entry. Fixes: ddf06b753a85 ("f2fs: fix to trigger fsck if dirent.name_len is zero") Signed-off-by: Yangtao Li [Chao: clean up description] Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/dir.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 456651682daf..c250bf46ef5e 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -1000,6 +1000,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode); struct blk_plug plug; bool readdir_ra = sbi->readdir_ra == 1; + bool found_valid_dirent = false; int err = 0; bit_pos = ((unsigned long)ctx->pos % d->max); @@ -1014,13 +1015,15 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, de = &d->dentry[bit_pos]; if (de->name_len == 0) { + if (found_valid_dirent || !bit_pos) { + printk_ratelimited( + "%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.", + KERN_WARNING, sbi->sb->s_id, + le32_to_cpu(de->ino)); + set_sbi_flag(sbi, SBI_NEED_FSCK); + } bit_pos++; ctx->pos = start_pos + bit_pos; - printk_ratelimited( - "%sF2FS-fs (%s): invalid namelen(0), ino:%u, run fsck to fix.", - KERN_WARNING, sbi->sb->s_id, - le32_to_cpu(de->ino)); - set_sbi_flag(sbi, SBI_NEED_FSCK); continue; } @@ -1063,6 +1066,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d, f2fs_ra_node_page(sbi, le32_to_cpu(de->ino)); ctx->pos = start_pos + bit_pos; + found_valid_dirent = true; } out: if (readdir_ra) -- cgit v1.2.3-70-g09d2 From 946e1052cdcc7e585ee5d1e72528ca49fb295243 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 18 Jul 2021 19:33:09 -0700 Subject: openrisc: don't printk() unconditionally Don't call printk() when CONFIG_PRINTK is not set. Fixes the following build errors: or1k-linux-ld: arch/openrisc/kernel/entry.o: in function `_external_irq_handler': (.text+0x804): undefined reference to `printk' (.text+0x804): relocation truncated to fit: R_OR1K_INSN_REL_26 against undefined symbol `printk' Fixes: 9d02a4283e9c ("OpenRISC: Boot code") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Jonas Bonn Cc: Stefan Kristiansson Cc: Stafford Horne Cc: openrisc@lists.librecores.org Signed-off-by: Stafford Horne --- arch/openrisc/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index bc657e55c15f..98e4f97db515 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -547,6 +547,7 @@ EXCEPTION_ENTRY(_external_irq_handler) l.bnf 1f // ext irq enabled, all ok. l.nop +#ifdef CONFIG_PRINTK l.addi r1,r1,-0x8 l.movhi r3,hi(42f) l.ori r3,r3,lo(42f) @@ -560,6 +561,7 @@ EXCEPTION_ENTRY(_external_irq_handler) .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r" .align 4 .previous +#endif l.ori r4,r4,SPR_SR_IEE // fix the bug // l.sw PT_SR(r1),r4 -- cgit v1.2.3-70-g09d2 From 11648cbb7b335b7eb54e1ff973fb938939616f46 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 15 Jul 2021 19:23:38 -0700 Subject: openrisc: rename or32 code & comments to or1k From Documentation/openrisc/todo.rst, rename "or32" in the source code to "or1k" since this is the name that has been settled on. Signed-off-by: Randy Dunlap Cc: Jonas Bonn Cc: Stefan Kristiansson Cc: Stafford Horne Cc: openrisc@lists.librecores.org Signed-off-by: Stafford Horne --- arch/openrisc/include/asm/pgtable.h | 6 +++--- arch/openrisc/include/asm/thread_info.h | 2 +- arch/openrisc/kernel/entry.S | 4 ++-- arch/openrisc/kernel/head.S | 6 +++--- arch/openrisc/kernel/setup.c | 4 ++-- arch/openrisc/lib/Makefile | 2 +- arch/openrisc/mm/fault.c | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h index 4ac591c9ca33..cdd657f80bfa 100644 --- a/arch/openrisc/include/asm/pgtable.h +++ b/arch/openrisc/include/asm/pgtable.h @@ -12,7 +12,7 @@ * et al. */ -/* or32 pgtable.h - macros and functions to manipulate page tables +/* or1k pgtable.h - macros and functions to manipulate page tables * * Based on: * include/asm-cris/pgtable.h @@ -29,14 +29,14 @@ /* * The Linux memory management assumes a three-level page table setup. On - * or32, we use that, but "fold" the mid level into the top-level page + * or1k, we use that, but "fold" the mid level into the top-level page * table. Since the MMU TLB is software loaded through an interrupt, it * supports any page table structure, so we could have used a three-level * setup, but for the amounts of memory we normally use, a two-level is * probably more efficient. * * This file contains the functions and defines necessary to modify and use - * the or32 page table tree. + * the or1k page table tree. */ extern void paging_init(void); diff --git a/arch/openrisc/include/asm/thread_info.h b/arch/openrisc/include/asm/thread_info.h index 4f9d2a261455..659834ab87fa 100644 --- a/arch/openrisc/include/asm/thread_info.h +++ b/arch/openrisc/include/asm/thread_info.h @@ -25,7 +25,7 @@ /* THREAD_SIZE is the size of the task_struct/kernel_stack combo. * normally, the stack is found by doing something like p + THREAD_SIZE - * in or32, a page is 8192 bytes, which seems like a sane size + * in or1k, a page is 8192 bytes, which seems like a sane size */ #define THREAD_SIZE_ORDER 0 diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index 98e4f97db515..8c8ac3451425 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -326,7 +326,7 @@ EXCEPTION_ENTRY(_data_page_fault_handler) 1: l.ori r6,r0,0x0 // !write access 2: - /* call fault.c handler in or32/mm/fault.c */ + /* call fault.c handler in openrisc/mm/fault.c */ l.jal do_page_fault l.nop l.j _ret_from_exception @@ -348,7 +348,7 @@ EXCEPTION_ENTRY(_insn_page_fault_handler) /* r4 set be EXCEPTION_HANDLE */ // effective address of fault l.ori r6,r0,0x0 // !write access - /* call fault.c handler in or32/mm/fault.c */ + /* call fault.c handler in openrisc/mm/fault.c */ l.jal do_page_fault l.nop l.j _ret_from_exception diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S index af355e3f4619..15f1b38dfe03 100644 --- a/arch/openrisc/kernel/head.S +++ b/arch/openrisc/kernel/head.S @@ -599,7 +599,7 @@ flush_tlb: l.jal _flush_tlb l.nop -/* The MMU needs to be enabled before or32_early_setup is called */ +/* The MMU needs to be enabled before or1k_early_setup is called */ enable_mmu: /* @@ -641,9 +641,9 @@ enable_mmu: /* magic number mismatch, set fdt pointer to null */ l.or r25,r0,r0 _fdt_found: - /* pass fdt pointer to or32_early_setup in r3 */ + /* pass fdt pointer to or1k_early_setup in r3 */ l.or r3,r0,r25 - LOAD_SYMBOL_2_GPR(r24, or32_early_setup) + LOAD_SYMBOL_2_GPR(r24, or1k_early_setup) l.jalr r24 l.nop diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index 8ae2da6ac097..7eddcac0ef2f 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -209,7 +209,7 @@ void __init setup_cpuinfo(void) } /** - * or32_early_setup + * or1k_early_setup * * Handles the pointer to the device tree that this kernel is to use * for establishing the available platform devices. @@ -217,7 +217,7 @@ void __init setup_cpuinfo(void) * Falls back on built-in device tree in case null pointer is passed. */ -void __init or32_early_setup(void *fdt) +void __init or1k_early_setup(void *fdt) { if (fdt) pr_info("FDT at %p\n", fdt); diff --git a/arch/openrisc/lib/Makefile b/arch/openrisc/lib/Makefile index 79775aaa6baa..53327406b483 100644 --- a/arch/openrisc/lib/Makefile +++ b/arch/openrisc/lib/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only # -# Makefile for or32 specific library files.. +# Makefile for or1k specific library files.. # obj-y := delay.o string.o memset.o memcpy.o diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c index ca97d9baab51..c730d1a51686 100644 --- a/arch/openrisc/mm/fault.c +++ b/arch/openrisc/mm/fault.c @@ -28,7 +28,7 @@ unsigned long pte_misses; /* updated by do_page_fault() */ unsigned long pte_errors; /* updated by do_page_fault() */ /* __PHX__ :: - check the vmalloc_fault in do_page_fault() - * - also look into include/asm-or32/mmu_context.h + * - also look into include/asm/mmu_context.h */ volatile pgd_t *current_pgd[NR_CPUS]; -- cgit v1.2.3-70-g09d2 From 62dd1fc8cc6b22e3e568be46ebdb817e66f5d6a5 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 5 Aug 2021 05:57:27 +0200 Subject: fuse: move fget() to fuse_get_tree() Affected call chains: fuse_get_tree -> get_tree_(bdev|nodev) -> fuse_fill_super Needed for following patch. Signed-off-by: Miklos Szeredi --- fs/fuse/fuse_i.h | 1 + fs/fuse/inode.c | 44 +++++++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 07829ce78695..a78480933ebe 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -489,6 +489,7 @@ struct fuse_dev { struct fuse_fs_context { int fd; + struct file *file; unsigned int rootmode; kuid_t user_id; kgid_t group_id; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 54379a0c86d3..3d64a68c52f7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1509,38 +1509,33 @@ EXPORT_SYMBOL_GPL(fuse_fill_super_common); static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; - struct file *file; int err; struct fuse_conn *fc; struct fuse_mount *fm; - if (!ctx->fd_present || !ctx->rootmode_present || + if (!ctx->file || !ctx->rootmode_present || !ctx->user_id_present || !ctx->group_id_present) return -EINVAL; - err = -EINVAL; - file = fget(ctx->fd); - if (!file) - goto err; - /* * Require mount to happen from the same user namespace which * opened /dev/fuse to prevent potential attacks. */ - if ((file->f_op != &fuse_dev_operations) || - (file->f_cred->user_ns != sb->s_user_ns)) - goto err_fput; - ctx->fudptr = &file->private_data; + err = -EINVAL; + if ((ctx->file->f_op != &fuse_dev_operations) || + (ctx->file->f_cred->user_ns != sb->s_user_ns)) + goto err; + ctx->fudptr = &ctx->file->private_data; fc = kmalloc(sizeof(*fc), GFP_KERNEL); err = -ENOMEM; if (!fc) - goto err_fput; + goto err; fm = kzalloc(sizeof(*fm), GFP_KERNEL); if (!fm) { kfree(fc); - goto err_fput; + goto err; } fuse_conn_init(fc, fm, sb->s_user_ns, &fuse_dev_fiq_ops, NULL); @@ -1551,12 +1546,8 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) err = fuse_fill_super_common(sb, ctx); if (err) goto err_put_conn; - /* - * atomic_dec_and_test() in fput() provides the necessary - * memory barrier for file->private_data to be visible on all - * CPUs after this - */ - fput(file); + /* file->private_data shall be visible on all CPUs after this */ + smp_mb(); fuse_send_init(get_fuse_mount_super(sb)); return 0; @@ -1564,8 +1555,6 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) fuse_conn_put(fc); kfree(fm); sb->s_fs_info = NULL; - err_fput: - fput(file); err: return err; } @@ -1573,12 +1562,21 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) static int fuse_get_tree(struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; + int err; + + if (ctx->fd_present) + ctx->file = fget(ctx->fd); if (IS_ENABLED(CONFIG_BLOCK) && ctx->is_bdev) { - return get_tree_bdev(fsc, fuse_fill_super); + err = get_tree_bdev(fsc, fuse_fill_super); + goto out_fput; } - return get_tree_nodev(fsc, fuse_fill_super); + err = get_tree_nodev(fsc, fuse_fill_super); +out_fput: + if (ctx->file) + fput(ctx->file); + return err; } static const struct fs_context_operations fuse_context_ops = { -- cgit v1.2.3-70-g09d2 From 5d5b74aa9c766f0dd37d5cc1a2a7a94586130501 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 5 Aug 2021 05:57:27 +0200 Subject: fuse: allow sharing existing sb Make it possible to create a new mount from a already working server. Here's a detailed description of the problem from Jakob: "The background for this question is occasional problems we see with our fuse filesystem [1] and mount namespaces. On a usual client, we have system-wide, autofs managed mountpoints. When a new mount namespace is created (which can be done unprivileged in combination with user namespaces), it can happen that a mountpoint is used inside the new namespace but idle in the root mount namespace. So autofs unmounts the parent, system-wide mountpoint. But the fuse module stays active and still serves mountpoint in the child mount namespace. Because the fuse daemon also blocks other system wide resources corresponding to the mountpoint, this situation effectively prevents new mounts until the child mount namespaces closes. [1] https://github.com/cvmfs/cvmfs" Reported-by: Jakob Blomer Signed-off-by: Miklos Szeredi --- fs/fuse/inode.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 3d64a68c52f7..a3e7fb484938 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1559,9 +1559,26 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc) return err; } +/* + * This is the path where user supplied an already initialized fuse dev. In + * this case never create a new super if the old one is gone. + */ +static int fuse_set_no_super(struct super_block *sb, struct fs_context *fsc) +{ + return -ENOTCONN; +} + +static int fuse_test_super(struct super_block *sb, struct fs_context *fsc) +{ + + return fsc->sget_key == get_fuse_conn_super(sb); +} + static int fuse_get_tree(struct fs_context *fsc) { struct fuse_fs_context *ctx = fsc->fs_private; + struct fuse_dev *fud; + struct super_block *sb; int err; if (ctx->fd_present) @@ -1571,8 +1588,27 @@ static int fuse_get_tree(struct fs_context *fsc) err = get_tree_bdev(fsc, fuse_fill_super); goto out_fput; } + /* + * While block dev mount can be initialized with a dummy device fd + * (found by device name), normal fuse mounts can't + */ + if (!ctx->file) + return -EINVAL; - err = get_tree_nodev(fsc, fuse_fill_super); + /* + * Allow creating a fuse mount with an already initialized fuse + * connection + */ + fud = READ_ONCE(ctx->file->private_data); + if (ctx->file->f_op == &fuse_dev_operations && fud) { + fsc->sget_key = fud->fc; + sb = sget_fc(fsc, fuse_test_super, fuse_set_no_super); + err = PTR_ERR_OR_ZERO(sb); + if (!IS_ERR(sb)) + fsc->root = dget(sb->s_root); + } else { + err = get_tree_nodev(fsc, fuse_fill_super); + } out_fput: if (ctx->file) fput(ctx->file); -- cgit v1.2.3-70-g09d2 From 319afe68567b923e25140e744e7f05e3e5d889c1 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 4 Aug 2021 12:48:41 -0400 Subject: KVM: xen: do not use struct gfn_to_hva_cache gfn_to_hva_cache is not thread-safe, so it is usually used only within a vCPU (whose code is protected by vcpu->mutex). The Xen interface implementation has such a cache in kvm->arch, but it is not really used except to store the location of the shared info page. Replace shinfo_set and shinfo_cache with just the value that is passed via KVM_XEN_ATTR_TYPE_SHARED_INFO; the only complication is that the initialization value is not zero anymore and therefore kvm_xen_init_vm needs to be introduced. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 3 +-- arch/x86/kvm/x86.c | 1 + arch/x86/kvm/xen.c | 23 ++++++++++++----------- arch/x86/kvm/xen.h | 5 +++++ 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index a079880d4cd5..6a73ff7db5f9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1003,9 +1003,8 @@ struct msr_bitmap_range { /* Xen emulation context */ struct kvm_xen { bool long_mode; - bool shinfo_set; u8 upcall_vector; - struct gfn_to_hva_cache shinfo_cache; + gfn_t shinfo_gfn; }; enum kvm_irqchip_mode { diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 348452bb16bc..3cedc7cc132a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -11162,6 +11162,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) kvm_hv_init_vm(kvm); kvm_page_track_init(kvm); kvm_mmu_init_vm(kvm); + kvm_xen_init_vm(kvm); return static_call(kvm_x86_vm_init)(kvm); } diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index ae17250e1efe..9ea9c3dabe37 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -25,15 +25,14 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn) { gpa_t gpa = gfn_to_gpa(gfn); int wc_ofs, sec_hi_ofs; - int ret; + int ret = 0; int idx = srcu_read_lock(&kvm->srcu); - ret = kvm_gfn_to_hva_cache_init(kvm, &kvm->arch.xen.shinfo_cache, - gpa, PAGE_SIZE); - if (ret) + if (kvm_is_error_hva(gfn_to_hva(kvm, gfn))) { + ret = -EFAULT; goto out; - - kvm->arch.xen.shinfo_set = true; + } + kvm->arch.xen.shinfo_gfn = gfn; /* Paranoia checks on the 32-bit struct layout */ BUILD_BUG_ON(offsetof(struct compat_shared_info, wc) != 0x900); @@ -245,7 +244,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) case KVM_XEN_ATTR_TYPE_SHARED_INFO: if (data->u.shared_info.gfn == GPA_INVALID) { - kvm->arch.xen.shinfo_set = false; + kvm->arch.xen.shinfo_gfn = GPA_INVALID; r = 0; break; } @@ -283,10 +282,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) break; case KVM_XEN_ATTR_TYPE_SHARED_INFO: - if (kvm->arch.xen.shinfo_set) - data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_cache.gpa); - else - data->u.shared_info.gfn = GPA_INVALID; + data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_gfn); r = 0; break; @@ -646,6 +642,11 @@ int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc) return 0; } +void kvm_xen_init_vm(struct kvm *kvm) +{ + kvm->arch.xen.shinfo_gfn = GPA_INVALID; +} + void kvm_xen_destroy_vm(struct kvm *kvm) { if (kvm->arch.xen_hvm_config.msr) diff --git a/arch/x86/kvm/xen.h b/arch/x86/kvm/xen.h index 463a7844a8ca..cc0cf5f37450 100644 --- a/arch/x86/kvm/xen.h +++ b/arch/x86/kvm/xen.h @@ -21,6 +21,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data); int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data); int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data); int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc); +void kvm_xen_init_vm(struct kvm *kvm); void kvm_xen_destroy_vm(struct kvm *kvm); static inline bool kvm_xen_msr_enabled(struct kvm *kvm) @@ -50,6 +51,10 @@ static inline int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data) return 1; } +static inline void kvm_xen_init_vm(struct kvm *kvm) +{ +} + static inline void kvm_xen_destroy_vm(struct kvm *kvm) { } -- cgit v1.2.3-70-g09d2 From 730d070ae9f12fff5d44fe8fb0547ae37d100da8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 3 Aug 2021 16:15:45 +0200 Subject: MIPS: Replace deprecated CPU-hotplug functions. The functions get_online_cpus() and put_online_cpus() have been deprecated during the CPU hotplug rework. They map directly to cpus_read_lock() and cpus_read_unlock(). Replace deprecated CPU-hotplug functions with the official version. The behavior remains unchanged. Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Thomas Bogendoerfer --- arch/mips/kernel/mips-mt-fpaff.c | 10 +++++----- arch/mips/kernel/process.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 6c590ef27648..67e130d3f038 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -76,13 +76,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) return -EFAULT; - get_online_cpus(); + cpus_read_lock(); rcu_read_lock(); p = find_process_by_pid(pid); if (!p) { rcu_read_unlock(); - put_online_cpus(); + cpus_read_unlock(); return -ESRCH; } @@ -147,7 +147,7 @@ out_free_cpus_allowed: free_cpumask_var(cpus_allowed); out_put_task: put_task_struct(p); - put_online_cpus(); + cpus_read_unlock(); return retval; } @@ -166,7 +166,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, if (len < real_len) return -EINVAL; - get_online_cpus(); + cpus_read_lock(); rcu_read_lock(); retval = -ESRCH; @@ -182,7 +182,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, out_unlock: rcu_read_unlock(); - put_online_cpus(); + cpus_read_unlock(); if (retval) return retval; if (copy_to_user(user_mask_ptr, &mask, real_len)) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 73c8e7990a97..95aa86fa6077 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -859,10 +859,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) * scheduled in then it will already have picked up the new FP mode * whilst doing so. */ - get_online_cpus(); + cpus_read_lock(); for_each_cpu_and(cpu, &process_cpus, cpu_online_mask) work_on_cpu(cpu, prepare_for_fp_mode_switch, NULL); - put_online_cpus(); + cpus_read_unlock(); return 0; } -- cgit v1.2.3-70-g09d2 From ad548993a66c498267695edd8b19a682be0e3a8b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 4 Aug 2021 17:02:16 -0700 Subject: MIPS: loongson2ef: don't build serial.o unconditionally LOONGSON_UART_BASE depends on EARLY_PRINTK || SERIAL_8250, but when neither of these Kconfig symbols is set, the kernel build has errors: ../arch/mips/loongson2ef/common/serial.c: In function 'serial_init': ../arch/mips/loongson2ef/common/serial.c:66:25: error: 'loongson_uart_base' undeclared (first use in this function) 66 | loongson_uart_base; ../arch/mips/loongson2ef/common/serial.c:66:25: note: each undeclared identifier is reported only once for each function it appears in ../arch/mips/loongson2ef/common/serial.c:68:41: error: '_loongson_uart_base' undeclared (first use in this function) 68 | (void __iomem *)_loongson_uart_base; Fix this by building serial.o only when one (or both) of these Kconfig symbols is enabled. Tested with: (a) EARLY_PRINTK=y, SERIAL_8250 not set; (b) EARLY_PRINTK=y, SERIAL_8250=y; (c) EARLY_PRINTK=y, SERIAL_8250=m. (d) EARLY_PRINTK not set, SERIAL_8250=y; (e) EARLY_PRINTK not set, SERIAL_8250=m; (f) EARLY_PRINTK not set, SERIAL_8250 not set. Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Jiaxun Yang Cc: Thomas Bogendoerfer Cc: linux-mips@vger.kernel.org Signed-off-by: Thomas Bogendoerfer --- arch/mips/loongson2ef/common/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mips/loongson2ef/common/Makefile b/arch/mips/loongson2ef/common/Makefile index d5ab3e543ea3..30ea8b5ca685 100644 --- a/arch/mips/loongson2ef/common/Makefile +++ b/arch/mips/loongson2ef/common/Makefile @@ -4,12 +4,14 @@ # obj-y += setup.o init.o env.o time.o reset.o irq.o \ - bonito-irq.o mem.o machtype.o platform.o serial.o + bonito-irq.o mem.o machtype.o platform.o obj-$(CONFIG_PCI) += pci.o # # Serial port support # +obj-$(CONFIG_LOONGSON_UART_BASE) += serial.o +obj-$(CONFIG_EARLY_PRINTK) += serial.o obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o obj-$(CONFIG_LOONGSON_MC146818) += rtc.o -- cgit v1.2.3-70-g09d2 From cb95ea79b3fc772c5873a7a4532ab4c14a455da2 Mon Sep 17 00:00:00 2001 From: Rui Wang Date: Thu, 29 Jul 2021 17:31:52 +0800 Subject: MIPS: locking/atomic: Fix atomic{_64,}_sub_if_positive This looks like a typo and that caused atomic64 test failed. Signed-off-by: Rui Wang Signed-off-by: Thomas Bogendoerfer --- arch/mips/include/asm/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 95e1f7f3597f..a0b9e7c1e4fc 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -206,7 +206,7 @@ ATOMIC_OPS(atomic64, xor, s64, ^=, xor, lld, scd) * The function returns the old value of @v minus @i. */ #define ATOMIC_SIP_OP(pfx, type, op, ll, sc) \ -static __inline__ int arch_##pfx##_sub_if_positive(type i, pfx##_t * v) \ +static __inline__ type arch_##pfx##_sub_if_positive(type i, pfx##_t * v) \ { \ type temp, result; \ \ -- cgit v1.2.3-70-g09d2 From fcb461e2bc8b83b7eaca20cb2221e8b940f2189c Mon Sep 17 00:00:00 2001 From: Evan Wang Date: Thu, 22 Jul 2021 16:40:38 +0200 Subject: PCI: aardvark: Fix checking for PIO status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is an issue that when PCIe switch is connected to an Armada 3700 board, there will be lots of warnings about PIO errors when reading the config space. According to Aardvark PIO read and write sequence in HW specification, the current way to check PIO status has the following issues: 1) For PIO read operation, it reports the error message, which should be avoided according to HW specification. 2) For PIO read and write operations, it only checks PIO operation complete status, which is not enough, and error status should also be checked. This patch aligns the code with Aardvark PIO read and write sequence in HW specification on PIO status check and fix the warnings when reading config space. [pali: Fix CRS handling when CRSSVE is not enabled] Link: https://lore.kernel.org/r/20210722144041.12661-2-pali@kernel.org Tested-by: Victor Gu Signed-off-by: Evan Wang Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Reviewed-by: Victor Gu Reviewed-by: Marek Behún Cc: stable@vger.kernel.org # b1bd5714472c ("PCI: aardvark: Indicate error in 'val' when config read fails") --- drivers/pci/controller/pci-aardvark.c | 62 ++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index c95ebe808f92..8bd060e084f1 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -58,6 +58,7 @@ #define PIO_COMPLETION_STATUS_CRS 2 #define PIO_COMPLETION_STATUS_CA 4 #define PIO_NON_POSTED_REQ BIT(10) +#define PIO_ERR_STATUS BIT(11) #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) @@ -472,7 +473,7 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); } -static void advk_pcie_check_pio_status(struct advk_pcie *pcie) +static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val) { struct device *dev = &pcie->pdev->dev; u32 reg; @@ -483,14 +484,49 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) status = (reg & PIO_COMPLETION_STATUS_MASK) >> PIO_COMPLETION_STATUS_SHIFT; - if (!status) - return; - + /* + * According to HW spec, the PIO status check sequence as below: + * 1) even if COMPLETION_STATUS(bit9:7) indicates successful, + * it still needs to check Error Status(bit11), only when this bit + * indicates no error happen, the operation is successful. + * 2) value Unsupported Request(1) of COMPLETION_STATUS(bit9:7) only + * means a PIO write error, and for PIO read it is successful with + * a read value of 0xFFFFFFFF. + * 3) value Completion Retry Status(CRS) of COMPLETION_STATUS(bit9:7) + * only means a PIO write error, and for PIO read it is successful + * with a read value of 0xFFFF0001. + * 4) value Completer Abort (CA) of COMPLETION_STATUS(bit9:7) means + * error for both PIO read and PIO write operation. + * 5) other errors are indicated as 'unknown'. + */ switch (status) { + case PIO_COMPLETION_STATUS_OK: + if (reg & PIO_ERR_STATUS) { + strcomp_status = "COMP_ERR"; + break; + } + /* Get the read result */ + if (val) + *val = advk_readl(pcie, PIO_RD_DATA); + /* No error */ + strcomp_status = NULL; + break; case PIO_COMPLETION_STATUS_UR: strcomp_status = "UR"; break; case PIO_COMPLETION_STATUS_CRS: + /* PCIe r4.0, sec 2.3.2, says: + * If CRS Software Visibility is not enabled, the Root Complex + * must re-issue the Configuration Request as a new Request. + * A Root Complex implementation may choose to limit the number + * of Configuration Request/CRS Completion Status loops before + * determining that something is wrong with the target of the + * Request and taking appropriate action, e.g., complete the + * Request to the host as a failed transaction. + * + * To simplify implementation do not re-issue the Configuration + * Request and complete the Request as a failed transaction. + */ strcomp_status = "CRS"; break; case PIO_COMPLETION_STATUS_CA: @@ -501,6 +537,9 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) break; } + if (!strcomp_status) + return 0; + if (reg & PIO_NON_POSTED_REQ) str_posted = "Non-posted"; else @@ -508,6 +547,8 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n", str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); + + return -EFAULT; } static int advk_pcie_wait_pio(struct advk_pcie *pcie) @@ -745,10 +786,13 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, return PCIBIOS_SET_FAILED; } - advk_pcie_check_pio_status(pcie); + /* Check PIO status and get the read result */ + ret = advk_pcie_check_pio_status(pcie, val); + if (ret < 0) { + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; + } - /* Get the read result */ - *val = advk_readl(pcie, PIO_RD_DATA); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) @@ -812,7 +856,9 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (ret < 0) return PCIBIOS_SET_FAILED; - advk_pcie_check_pio_status(pcie); + ret = advk_pcie_check_pio_status(pcie, NULL); + if (ret < 0) + return PCIBIOS_SET_FAILED; return PCIBIOS_SUCCESSFUL; } -- cgit v1.2.3-70-g09d2 From 02bcec3ea5591720114f586960490b04b093a09e Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 22 Jul 2021 16:40:39 +0200 Subject: PCI: aardvark: Increase polling delay to 1.5s while waiting for PIO response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Measurements in different conditions showed that aardvark hardware PIO response can take up to 1.44s. Increase wait timeout from 1ms to 1.5s to ensure that we do not miss responses from hardware. After 1.44s hardware returns errors (e.g. Completer abort). The previous two patches fixed checking for PIO status, so now we can use it to also catch errors which are reported by hardware after 1.44s. After applying this patch, kernel can detect and print PIO errors to dmesg: [ 6.879999] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100004 [ 6.896436] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100004 [ 6.913049] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100010 [ 6.929663] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100010 [ 6.953558] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100014 [ 6.970170] advk-pcie d0070000.pcie: Non-posted PIO Response Status: CA, 0xe00 @ 0x100014 [ 6.994328] advk-pcie d0070000.pcie: Posted PIO Response Status: COMP_ERR, 0x804 @ 0x100004 Without this patch kernel prints only a generic error to dmesg: [ 5.246847] advk-pcie d0070000.pcie: config read/write timed out Link: https://lore.kernel.org/r/20210722144041.12661-3-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marek Behún Cc: stable@vger.kernel.org # 7fbcb5da811b ("PCI: aardvark: Don't rely on jiffies while holding spinlock") --- drivers/pci/controller/pci-aardvark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 8bd060e084f1..5b9e4e79c3ae 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -167,7 +167,7 @@ #define PCIE_CONFIG_WR_TYPE0 0xa #define PCIE_CONFIG_WR_TYPE1 0xb -#define PIO_RETRY_CNT 500 +#define PIO_RETRY_CNT 750000 /* 1.5 s */ #define PIO_RETRY_DELAY 2 /* 2 us*/ #define LINK_WAIT_MAX_RETRIES 10 -- cgit v1.2.3-70-g09d2 From e902bb7c24a7099d0eb0eb4cba06f2d91e9299f3 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 22 Jul 2021 16:40:40 +0200 Subject: PCI: pci-bridge-emul: Add PCIe Root Capabilities Register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 16-bit Root Capabilities register is at offset 0x1e in the PCIe Capability. Rename current 'rsvd' struct member to 'rootcap'. Link: https://lore.kernel.org/r/20210722144041.12661-4-pali@kernel.org Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Reviewed-by: Marek Behún --- drivers/pci/pci-bridge-emul.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h index b31883022a8e..49bbd37ee318 100644 --- a/drivers/pci/pci-bridge-emul.h +++ b/drivers/pci/pci-bridge-emul.h @@ -54,7 +54,7 @@ struct pci_bridge_emul_pcie_conf { __le16 slotctl; __le16 slotsta; __le16 rootctl; - __le16 rsvd; + __le16 rootcap; __le32 rootsta; __le32 devcap2; __le16 devctl2; -- cgit v1.2.3-70-g09d2 From 43f5c77bcbd27cce70bf33c2b86d6726ce95dd66 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 22 Jul 2021 16:40:41 +0200 Subject: PCI: aardvark: Fix reporting CRS value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set CRSVIS flag in emulated root PCI bridge to indicate support for Completion Retry Status. Add check for CRSSVE flag from root PCI brige when issuing Configuration Read Request via PIO to correctly returns fabricated CRS value as it is required by PCIe spec. Link: https://lore.kernel.org/r/20210722144041.12661-5-pali@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár Signed-off-by: Lorenzo Pieralisi Cc: stable@vger.kernel.org # e0d9d30b7354 ("PCI: pci-bridge-emul: Fix big-endian support") --- drivers/pci/controller/pci-aardvark.c | 67 ++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 5b9e4e79c3ae..0c32283b3276 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -178,6 +178,8 @@ #define MSI_IRQ_NUM 32 +#define CFG_RD_CRS_VAL 0xffff0001 + struct advk_pcie { struct platform_device *pdev; void __iomem *base; @@ -473,7 +475,7 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); } -static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val) +static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val) { struct device *dev = &pcie->pdev->dev; u32 reg; @@ -515,9 +517,30 @@ static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val) strcomp_status = "UR"; break; case PIO_COMPLETION_STATUS_CRS: + if (allow_crs && val) { + /* PCIe r4.0, sec 2.3.2, says: + * If CRS Software Visibility is enabled: + * For a Configuration Read Request that includes both + * bytes of the Vendor ID field of a device Function's + * Configuration Space Header, the Root Complex must + * complete the Request to the host by returning a + * read-data value of 0001h for the Vendor ID field and + * all '1's for any additional bytes included in the + * request. + * + * So CRS in this case is not an error status. + */ + *val = CFG_RD_CRS_VAL; + strcomp_status = NULL; + break; + } /* PCIe r4.0, sec 2.3.2, says: * If CRS Software Visibility is not enabled, the Root Complex * must re-issue the Configuration Request as a new Request. + * If CRS Software Visibility is enabled: For a Configuration + * Write Request or for any other Configuration Read Request, + * the Root Complex must re-issue the Configuration Request as + * a new Request. * A Root Complex implementation may choose to limit the number * of Configuration Request/CRS Completion Status loops before * determining that something is wrong with the target of the @@ -586,6 +609,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, case PCI_EXP_RTCTL: { u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE; + *value |= PCI_EXP_RTCAP_CRSVIS << 16; return PCI_BRIDGE_EMUL_HANDLED; } @@ -667,6 +691,7 @@ static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) { struct pci_bridge_emul *bridge = &pcie->bridge; + int ret; bridge->conf.vendor = cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); @@ -690,7 +715,15 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) bridge->data = pcie; bridge->ops = &advk_pci_bridge_emul_ops; - return pci_bridge_emul_init(bridge, 0); + /* PCIe config space can be initialized after pci_bridge_emul_init() */ + ret = pci_bridge_emul_init(bridge, 0); + if (ret < 0) + return ret; + + /* Indicates supports for Completion Retry Status */ + bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); + + return 0; } static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, @@ -742,6 +775,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct advk_pcie *pcie = bus->sysdata; + bool allow_crs; u32 reg; int ret; @@ -754,7 +788,24 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, return pci_bridge_emul_conf_read(&pcie->bridge, where, size, val); + /* + * Completion Retry Status is possible to return only when reading all + * 4 bytes from PCI_VENDOR_ID and PCI_DEVICE_ID registers at once and + * CRSSVE flag on Root Bridge is enabled. + */ + allow_crs = (where == PCI_VENDOR_ID) && (size == 4) && + (le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & + PCI_EXP_RTCTL_CRSSVE); + if (advk_pcie_pio_is_running(pcie)) { + /* + * If it is possible return Completion Retry Status so caller + * tries to issue the request again instead of failing. + */ + if (allow_crs) { + *val = CFG_RD_CRS_VAL; + return PCIBIOS_SUCCESSFUL; + } *val = 0xffffffff; return PCIBIOS_SET_FAILED; } @@ -782,12 +833,20 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, ret = advk_pcie_wait_pio(pcie); if (ret < 0) { + /* + * If it is possible return Completion Retry Status so caller + * tries to issue the request again instead of failing. + */ + if (allow_crs) { + *val = CFG_RD_CRS_VAL; + return PCIBIOS_SUCCESSFUL; + } *val = 0xffffffff; return PCIBIOS_SET_FAILED; } /* Check PIO status and get the read result */ - ret = advk_pcie_check_pio_status(pcie, val); + ret = advk_pcie_check_pio_status(pcie, allow_crs, val); if (ret < 0) { *val = 0xffffffff; return PCIBIOS_SET_FAILED; @@ -856,7 +915,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (ret < 0) return PCIBIOS_SET_FAILED; - ret = advk_pcie_check_pio_status(pcie, NULL); + ret = advk_pcie_check_pio_status(pcie, false, NULL); if (ret < 0) return PCIBIOS_SET_FAILED; -- cgit v1.2.3-70-g09d2 From 224d8031e482bb83e2166779f46c7bb1a5f4a888 Mon Sep 17 00:00:00 2001 From: Shunyong Yang Date: Wed, 14 Jul 2021 21:23:31 +0800 Subject: tools: PCI: Zero-initialize param The values in param may be random if they are not initialized, which may cause use_dma flag set even when "-d" option is not provided in command line. Initializing all members to 0 to solve this. Link: https://lore.kernel.org/r/20210714132331.5200-1-yang.shunyong@gmail.com Signed-off-by: Shunyong Yang Signed-off-by: Lorenzo Pieralisi Acked-by: Kishon Vijay Abraham I --- tools/pci/pcitest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index 0a1344c45213..441b54234635 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -40,7 +40,7 @@ struct pci_test { static int run_test(struct pci_test *test) { - struct pci_endpoint_test_xfer_param param; + struct pci_endpoint_test_xfer_param param = {}; int ret = -EINVAL; int fd; -- cgit v1.2.3-70-g09d2 From eff21f5da308265678e7e59821795e606f3e560f Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 4 May 2021 19:17:42 +0200 Subject: PCI: tegra: Fix OF node reference leak Commit 9e38e690ace3 ("PCI: tegra: Fix OF node reference leak") has fixed some node reference leaks in this function but missed some of them. In fact, having 'port' referenced in the 'rp' structure is not enough to prevent the leak, until 'rp' is actually added in the 'pcie->ports' list. Add the missing 'goto err_node_put' accordingly. Link: https://lore.kernel.org/r/55b11e9a7fa2987fbc0869d68ae59888954d65e2.1620148539.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Lorenzo Pieralisi Reviewed-by: Vidya Sagar --- drivers/pci/controller/pci-tegra.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 4aa103aaa366..8cc7197f968d 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -2188,13 +2188,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) rp->np = port; rp->base = devm_pci_remap_cfg_resource(dev, &rp->regs); - if (IS_ERR(rp->base)) - return PTR_ERR(rp->base); + if (IS_ERR(rp->base)) { + err = PTR_ERR(rp->base); + goto err_node_put; + } label = devm_kasprintf(dev, GFP_KERNEL, "pex-reset-%u", index); if (!label) { - dev_err(dev, "failed to create reset GPIO label\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_node_put; } /* @@ -2212,7 +2214,8 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie) } else { dev_err(dev, "failed to get reset GPIO: %ld\n", PTR_ERR(rp->reset_gpio)); - return PTR_ERR(rp->reset_gpio); + err = PTR_ERR(rp->reset_gpio); + goto err_node_put; } } -- cgit v1.2.3-70-g09d2 From 804b2b6f2a95d924f52c80c80a01b8fea73efb1e Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 4 May 2021 19:17:54 +0200 Subject: PCI: tegra: Use 'seq_puts' instead of 'seq_printf' As spotted by checkpatch, use 'seq_puts' instead of 'seq_printf' when possible. It is slightly more efficient. Link: https://lore.kernel.org/r/7bdedb342b9221169ab085540cf25d1992e8b97a.1620148539.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Lorenzo Pieralisi Reviewed-by: Vidya Sagar --- drivers/pci/controller/pci-tegra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 8cc7197f968d..099a148c6215 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -2546,7 +2546,7 @@ static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) if (list_empty(&pcie->ports)) return NULL; - seq_printf(s, "Index Status\n"); + seq_puts(s, "Index Status\n"); return seq_list_start(&pcie->ports, *pos); } @@ -2583,16 +2583,16 @@ static int tegra_pcie_ports_seq_show(struct seq_file *s, void *v) seq_printf(s, "%2u ", port->index); if (up) - seq_printf(s, "up"); + seq_puts(s, "up"); if (active) { if (up) - seq_printf(s, ", "); + seq_puts(s, ", "); - seq_printf(s, "active"); + seq_puts(s, "active"); } - seq_printf(s, "\n"); + seq_puts(s, "\n"); return 0; } -- cgit v1.2.3-70-g09d2 From fd44e8efccd4de1764d195958bcac3242c921ed7 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Tue, 4 May 2021 19:18:04 +0200 Subject: PCI: tegra: make const array err_msg static Don't populate the array err_msg on the stack but instead make it static. Makes the object code smaller by 64 bytes. While at it, add a missing const, as reported by checkpatch. Compiled with gcc 11.0.1 Before: $ size drivers/pci/controller/pci-tegra.o text data bss dec hex filename 25623 2844 32 28499 6f53 drivers/pci/controller/pci-tegra.o After: $ size drivers/pci/controller/pci-tegra.o text data bss dec hex filename 25559 2844 32 28435 6f13 drivers/pci/controller/pci-tegra.o Link: https://lore.kernel.org/r/5f3f35296b944b94546cc7d1e9cc6186484620d8.1620148539.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christophe JAILLET Signed-off-by: Lorenzo Pieralisi Reviewed-by: Vidya Sagar --- drivers/pci/controller/pci-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 099a148c6215..3f620ed33192 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -759,7 +759,7 @@ static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) static irqreturn_t tegra_pcie_isr(int irq, void *arg) { - const char *err_msg[] = { + static const char * const err_msg[] = { "Unknown", "AXI slave error", "AXI decode error", -- cgit v1.2.3-70-g09d2 From 9eec0792024983276871baeb201609abb07dd35d Mon Sep 17 00:00:00 2001 From: Weizhao Ouyang Date: Thu, 5 Aug 2021 17:58:23 +0800 Subject: coccinelle: api: rename kzfree to kfree_sensitive Commit 453431a54934 ("mm, treewide: rename kzfree() to kfree_sensitive()") renamed kzfree() to kfree_sensitive(), it should be applied to coccinelle. Signed-off-by: Weizhao Ouyang Signed-off-by: Julia Lawall Acked-by: Denis Efremov --- scripts/coccinelle/api/kvmalloc.cocci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/coccinelle/api/kvmalloc.cocci b/scripts/coccinelle/api/kvmalloc.cocci index c30dab718a49..5ddcb76b76b0 100644 --- a/scripts/coccinelle/api/kvmalloc.cocci +++ b/scripts/coccinelle/api/kvmalloc.cocci @@ -79,7 +79,7 @@ position p : script:python() { relevant(p) }; } else { ... when != krealloc(E, ...) when any -* \(kfree\|kzfree\)(E) +* \(kfree\|kfree_sensitive\)(E) ... } -- cgit v1.2.3-70-g09d2 From 9e4ae52cabd8aec21360a44b90c4ec6b287eb0d2 Mon Sep 17 00:00:00 2001 From: ErKun Yang Date: Thu, 8 Apr 2021 21:27:51 +0800 Subject: PCI: xgene-msi: Remove redundant dev_err() call in xgene_msi_probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit devm_ioremap_resource() internally calls __devm_ioremap_resource() which is where error checking and handling is actually taking place. i Therefore, the dev_err() call in xgene_msi_probe() is redundant. Remove it. Link: https://lore.kernel.org/r/20210408132751.1198171-1-yangerkun@huawei.com Reported-by: Hulk Robot Signed-off-by: ErKun Yang [lorenzo.pieralisi@arm.com: commit log] Signed-off-by: Lorenzo Pieralisi Reviewed-by: Krzysztof Wilczyński --- drivers/pci/controller/pci-xgene-msi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c index 1c34c897a7e2..369b50f626fd 100644 --- a/drivers/pci/controller/pci-xgene-msi.c +++ b/drivers/pci/controller/pci-xgene-msi.c @@ -451,7 +451,6 @@ static int xgene_msi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xgene_msi->msi_regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xgene_msi->msi_regs)) { - dev_err(&pdev->dev, "no reg space\n"); rc = PTR_ERR(xgene_msi->msi_regs); goto error; } -- cgit v1.2.3-70-g09d2 From 9ff80e2de36d0554e3a6da18a171719fe8663c17 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 25 Jul 2021 19:07:54 +0100 Subject: mfd: Don't use irq_create_mapping() to resolve a mapping Although irq_create_mapping() is able to deal with duplicate mappings, it really isn't supposed to be a substitute for irq_find_mapping(), and can result in allocations that take place in atomic context if the mapping didn't exist. Fix the handful of MFD drivers that use irq_create_mapping() in interrupt context by using irq_find_mapping() instead. Cc: Linus Walleij Cc: Lee Jones Cc: Maxime Coquelin Cc: Alexandre Torgue Signed-off-by: Marc Zyngier Signed-off-by: Lee Jones --- drivers/mfd/ab8500-core.c | 2 +- drivers/mfd/stmpe.c | 4 ++-- drivers/mfd/tc3589x.c | 2 +- drivers/mfd/wm8994-irq.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 30489670ea52..cca0aac26148 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -485,7 +485,7 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F) line += 1; - handle_nested_irq(irq_create_mapping(ab8500->domain, line)); + handle_nested_irq(irq_find_mapping(ab8500->domain, line)); } return 0; diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 1dd39483e7c1..58d09c615e67 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -1095,7 +1095,7 @@ static irqreturn_t stmpe_irq(int irq, void *data) if (variant->id_val == STMPE801_ID || variant->id_val == STMPE1600_ID) { - int base = irq_create_mapping(stmpe->domain, 0); + int base = irq_find_mapping(stmpe->domain, 0); handle_nested_irq(base); return IRQ_HANDLED; @@ -1123,7 +1123,7 @@ static irqreturn_t stmpe_irq(int irq, void *data) while (status) { int bit = __ffs(status); int line = bank * 8 + bit; - int nestedirq = irq_create_mapping(stmpe->domain, line); + int nestedirq = irq_find_mapping(stmpe->domain, line); handle_nested_irq(nestedirq); status &= ~(1 << bit); diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 7614f8fe0e91..13583cdb93b6 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c @@ -187,7 +187,7 @@ again: while (status) { int bit = __ffs(status); - int virq = irq_create_mapping(tc3589x->domain, bit); + int virq = irq_find_mapping(tc3589x->domain, bit); handle_nested_irq(virq); status &= ~(1 << bit); diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c index 6c3a619e2628..651a028bc519 100644 --- a/drivers/mfd/wm8994-irq.c +++ b/drivers/mfd/wm8994-irq.c @@ -154,7 +154,7 @@ static irqreturn_t wm8994_edge_irq(int irq, void *data) struct wm8994 *wm8994 = data; while (gpio_get_value_cansleep(wm8994->pdata.irq_gpio)) - handle_nested_irq(irq_create_mapping(wm8994->edge_irq, 0)); + handle_nested_irq(irq_find_mapping(wm8994->edge_irq, 0)); return IRQ_HANDLED; } -- cgit v1.2.3-70-g09d2 From 1e29cd9983eba1b596bc07f94d81d728007f8a25 Mon Sep 17 00:00:00 2001 From: Dinghao Liu Date: Thu, 8 Apr 2021 15:24:02 +0800 Subject: PCI: rcar: Fix runtime PM imbalance in rcar_pcie_ep_probe() pm_runtime_get_sync() will increase the runtime PM counter even it returns an error. Thus a pairing decrement is needed to prevent refcount leak. Fix this by replacing this API with pm_runtime_resume_and_get(), which will not change the runtime PM counter on error. Link: https://lore.kernel.org/r/20210408072402.15069-1-dinghao.liu@zju.edu.cn Signed-off-by: Dinghao Liu Signed-off-by: Lorenzo Pieralisi Reviewed-by: Geert Uytterhoeven --- drivers/pci/controller/pcie-rcar-ep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/pcie-rcar-ep.c b/drivers/pci/controller/pcie-rcar-ep.c index b4a288e24aaf..c91d85b15129 100644 --- a/drivers/pci/controller/pcie-rcar-ep.c +++ b/drivers/pci/controller/pcie-rcar-ep.c @@ -492,9 +492,9 @@ static int rcar_pcie_ep_probe(struct platform_device *pdev) pcie->dev = dev; pm_runtime_enable(dev); - err = pm_runtime_get_sync(dev); + err = pm_runtime_resume_and_get(dev); if (err < 0) { - dev_err(dev, "pm_runtime_get_sync failed\n"); + dev_err(dev, "pm_runtime_resume_and_get failed\n"); goto err_pm_disable; } -- cgit v1.2.3-70-g09d2 From 32679a7a6b69d9307e6d89b45d554873ca625896 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 17 Jul 2021 18:25:28 +0200 Subject: mfd: axp20x: Add supplied-from property to axp288_fuel_gauge cell The power-supply framework has the notion of one power-supply device being supplied by another. A typical example of this is a charger charging a battery. A tablet getting plugged in to charge (or plugged out) only results in events seen by the axp288_charger device / MFD cell. Which means that a change udev-event only gets send for the charger power-supply class device, not for the battery (the axp288_fuel_gauge device). The axp288_fuel_gauge does have an external_power_change'd callback which will generate a change udev-event when called. But before this commit this never got called because the power-supply core only calls this when a power-supply class device's supplier changes and the supplier link from axp288_charger to axp288_fuel_gauge was missing. Add a "supplied-from" property to axp288_fuel_gauge cell, pointing to the "axp288_charger" power-supply class device, so that the axp288_fuel_gauge's external_power_change'd callback gets called on axp288_charger state changes. Signed-off-by: Hans de Goede Reviewed-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index d0ac019850d1..8161a5dc68e8 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -700,6 +700,18 @@ static const struct resource axp288_charger_resources[] = { DEFINE_RES_IRQ(AXP288_IRQ_CBTO), }; +static const char * const axp288_fuel_gauge_suppliers[] = { "axp288_charger" }; + +static const struct property_entry axp288_fuel_gauge_properties[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", axp288_fuel_gauge_suppliers), + { } +}; + +static const struct software_node axp288_fuel_gauge_sw_node = { + .name = "axp288_fuel_gauge", + .properties = axp288_fuel_gauge_properties, +}; + static const struct mfd_cell axp288_cells[] = { { .name = "axp288_adc", @@ -717,6 +729,7 @@ static const struct mfd_cell axp288_cells[] = { .name = "axp288_fuel_gauge", .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), .resources = axp288_fuel_gauge_resources, + .swnode = &axp288_fuel_gauge_sw_node, }, { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp288_power_button_resources), -- cgit v1.2.3-70-g09d2 From 8f00b3c41ae772e7393602a1b2e3bda4269ae636 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 2 Aug 2021 10:03:32 +0200 Subject: mfd: db8500-prcmu: Rename register header Drop the ambition to support dbx500, the other SoCs in this series were never deleted and the support for them has been deleted. DB8500 is what we support. Signed-off-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/db8500-prcmu-regs.h | 226 ++++++++++++++++++++++++++++++++++++++++ drivers/mfd/db8500-prcmu.c | 2 +- drivers/mfd/dbx500-prcmu-regs.h | 226 ---------------------------------------- 3 files changed, 227 insertions(+), 227 deletions(-) create mode 100644 drivers/mfd/db8500-prcmu-regs.h delete mode 100644 drivers/mfd/dbx500-prcmu-regs.h diff --git a/drivers/mfd/db8500-prcmu-regs.h b/drivers/mfd/db8500-prcmu-regs.h new file mode 100644 index 000000000000..75fd1069372c --- /dev/null +++ b/drivers/mfd/db8500-prcmu-regs.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) STMicroelectronics 2009 + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Kumar Sanghvi + * Author: Sundar Iyer + * + * PRCM Unit registers + */ + +#ifndef __DB8500_PRCMU_REGS_H +#define __DB8500_PRCMU_REGS_H + +#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) + +#define PRCM_ACLK_MGT (0x004) +#define PRCM_SVAMMCSPCLK_MGT (0x008) +#define PRCM_SIAMMDSPCLK_MGT (0x00C) +#define PRCM_SGACLK_MGT (0x014) +#define PRCM_UARTCLK_MGT (0x018) +#define PRCM_MSP02CLK_MGT (0x01C) +#define PRCM_I2CCLK_MGT (0x020) +#define PRCM_SDMMCCLK_MGT (0x024) +#define PRCM_SLIMCLK_MGT (0x028) +#define PRCM_PER1CLK_MGT (0x02C) +#define PRCM_PER2CLK_MGT (0x030) +#define PRCM_PER3CLK_MGT (0x034) +#define PRCM_PER5CLK_MGT (0x038) +#define PRCM_PER6CLK_MGT (0x03C) +#define PRCM_PER7CLK_MGT (0x040) +#define PRCM_LCDCLK_MGT (0x044) +#define PRCM_BMLCLK_MGT (0x04C) +#define PRCM_HSITXCLK_MGT (0x050) +#define PRCM_HSIRXCLK_MGT (0x054) +#define PRCM_HDMICLK_MGT (0x058) +#define PRCM_APEATCLK_MGT (0x05C) +#define PRCM_APETRACECLK_MGT (0x060) +#define PRCM_MCDECLK_MGT (0x064) +#define PRCM_IPI2CCLK_MGT (0x068) +#define PRCM_DSIALTCLK_MGT (0x06C) +#define PRCM_DMACLK_MGT (0x074) +#define PRCM_B2R2CLK_MGT (0x078) +#define PRCM_TVCLK_MGT (0x07C) +#define PRCM_UNIPROCLK_MGT (0x278) +#define PRCM_SSPCLK_MGT (0x280) +#define PRCM_RNGCLK_MGT (0x284) +#define PRCM_UICCCLK_MGT (0x27C) +#define PRCM_MSP1CLK_MGT (0x288) + +#define PRCM_ARM_PLLDIVPS (prcmu_base + 0x118) +#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f +#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf + +#define PRCM_PLLARM_LOCKP (prcmu_base + 0x0a8) +#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 + +#define PRCM_ARM_CHGCLKREQ (prcmu_base + 0x114) +#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) +#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16) + +#define PRCM_PLLARM_ENABLE (prcmu_base + 0x98) +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 +#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 + +#define PRCM_ARMCLKFIX_MGT (prcmu_base + 0x0) +#define PRCM_A9PL_FORCE_CLKEN (prcmu_base + 0x19C) +#define PRCM_A9_RESETN_CLR (prcmu_base + 0x1f4) +#define PRCM_A9_RESETN_SET (prcmu_base + 0x1f0) +#define PRCM_ARM_LS_CLAMP (prcmu_base + 0x30c) +#define PRCM_SRAM_A9 (prcmu_base + 0x308) + +#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN BIT(0) +#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN BIT(1) + +/* CPU mailbox registers */ +#define PRCM_MBOX_CPU_VAL (prcmu_base + 0x0fc) +#define PRCM_MBOX_CPU_SET (prcmu_base + 0x100) +#define PRCM_MBOX_CPU_CLR (prcmu_base + 0x104) + +#define PRCM_HOSTACCESS_REQ (prcmu_base + 0x334) +#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 +#define PRCM_HOSTACCESS_REQ_WAKE_REQ BIT(16) +#define ARM_WAKEUP_MODEM 0x1 + +#define PRCM_ARM_IT1_CLR (prcmu_base + 0x48C) +#define PRCM_ARM_IT1_VAL (prcmu_base + 0x494) +#define PRCM_HOLD_EVT (prcmu_base + 0x174) + +#define PRCM_MOD_AWAKE_STATUS (prcmu_base + 0x4A0) +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE BIT(0) +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE BIT(1) +#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_VMODEM_OFF_ISO BIT(2) + +#define PRCM_ITSTATUS0 (prcmu_base + 0x148) +#define PRCM_ITSTATUS1 (prcmu_base + 0x150) +#define PRCM_ITSTATUS2 (prcmu_base + 0x158) +#define PRCM_ITSTATUS3 (prcmu_base + 0x160) +#define PRCM_ITSTATUS4 (prcmu_base + 0x168) +#define PRCM_ITSTATUS5 (prcmu_base + 0x484) +#define PRCM_ITCLEAR5 (prcmu_base + 0x488) +#define PRCM_ARMIT_MASKXP70_IT (prcmu_base + 0x1018) + +/* System reset register */ +#define PRCM_APE_SOFTRST (prcmu_base + 0x228) + +/* Level shifter and clamp control registers */ +#define PRCM_MMIP_LS_CLAMP_SET (prcmu_base + 0x420) +#define PRCM_MMIP_LS_CLAMP_CLR (prcmu_base + 0x424) + +#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP BIT(11) +#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI BIT(22) + +/* PRCMU clock/PLL/reset registers */ +#define PRCM_PLLSOC0_FREQ (prcmu_base + 0x080) +#define PRCM_PLLSOC1_FREQ (prcmu_base + 0x084) +#define PRCM_PLLARM_FREQ (prcmu_base + 0x088) +#define PRCM_PLLDDR_FREQ (prcmu_base + 0x08C) +#define PRCM_PLL_FREQ_D_SHIFT 0 +#define PRCM_PLL_FREQ_D_MASK BITS(0, 7) +#define PRCM_PLL_FREQ_N_SHIFT 8 +#define PRCM_PLL_FREQ_N_MASK BITS(8, 13) +#define PRCM_PLL_FREQ_R_SHIFT 16 +#define PRCM_PLL_FREQ_R_MASK BITS(16, 18) +#define PRCM_PLL_FREQ_SELDIV2 BIT(24) +#define PRCM_PLL_FREQ_DIV2EN BIT(25) + +#define PRCM_PLLDSI_FREQ (prcmu_base + 0x500) +#define PRCM_PLLDSI_ENABLE (prcmu_base + 0x504) +#define PRCM_PLLDSI_LOCKP (prcmu_base + 0x508) +#define PRCM_DSI_PLLOUT_SEL (prcmu_base + 0x530) +#define PRCM_DSITVCLK_DIV (prcmu_base + 0x52C) +#define PRCM_PLLDSI_LOCKP (prcmu_base + 0x508) +#define PRCM_APE_RESETN_SET (prcmu_base + 0x1E4) +#define PRCM_APE_RESETN_CLR (prcmu_base + 0x1E8) + +#define PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE BIT(0) + +#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 BIT(0) +#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3 BIT(1) + +#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT 0 +#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK BITS(0, 2) +#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT 8 +#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK BITS(8, 10) + +#define PRCM_DSI_PLLOUT_SEL_OFF 0 +#define PRCM_DSI_PLLOUT_SEL_PHI 1 +#define PRCM_DSI_PLLOUT_SEL_PHI_2 2 +#define PRCM_DSI_PLLOUT_SEL_PHI_4 3 + +#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT 0 +#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK BITS(0, 7) +#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT 8 +#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK BITS(8, 15) +#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT 16 +#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK BITS(16, 23) +#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN BIT(24) +#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN BIT(25) +#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN BIT(26) + +#define PRCM_APE_RESETN_DSIPLL_RESETN BIT(14) + +#define PRCM_CLKOCR (prcmu_base + 0x1CC) +#define PRCM_CLKOCR_CLKOUT0_REF_CLK (1 << 0) +#define PRCM_CLKOCR_CLKOUT0_MASK BITS(0, 13) +#define PRCM_CLKOCR_CLKOUT1_REF_CLK (1 << 16) +#define PRCM_CLKOCR_CLKOUT1_MASK BITS(16, 29) + +/* ePOD and memory power signal control registers */ +#define PRCM_EPOD_C_SET (prcmu_base + 0x410) +#define PRCM_SRAM_LS_SLEEP (prcmu_base + 0x304) + +/* Debug power control unit registers */ +#define PRCM_POWER_STATE_SET (prcmu_base + 0x254) + +/* Miscellaneous unit registers */ +#define PRCM_DSI_SW_RESET (prcmu_base + 0x324) +#define PRCM_GPIOCR (prcmu_base + 0x138) +#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 +#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 + +/* PRCMU HW semaphore */ +#define PRCM_SEM (prcmu_base + 0x400) +#define PRCM_SEM_PRCM_SEM BIT(0) + +#define PRCM_TCR (prcmu_base + 0x1C8) +#define PRCM_TCR_TENSEL_MASK BITS(0, 7) +#define PRCM_TCR_STOP_TIMERS BIT(16) +#define PRCM_TCR_DOZE_MODE BIT(17) + +#define PRCM_CLKOCR_CLKODIV0_SHIFT 0 +#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) +#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 +#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) +#define PRCM_CLKOCR_CLKODIV1_SHIFT 16 +#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) +#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 +#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) +#define PRCM_CLKOCR_CLK1TYPE BIT(28) + +#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) +#define PRCM_CLK_MGT_CLKPLLSW_SOC0 BIT(5) +#define PRCM_CLK_MGT_CLKPLLSW_SOC1 BIT(6) +#define PRCM_CLK_MGT_CLKPLLSW_DDR BIT(7) +#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) +#define PRCM_CLK_MGT_CLKEN BIT(8) +#define PRCM_CLK_MGT_CLK38 BIT(9) +#define PRCM_CLK_MGT_CLK38DIV BIT(11) +#define PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN BIT(12) + +/* GPIOCR register */ +#define PRCM_GPIOCR_SPI2_SELECT BIT(23) + +#define PRCM_DDR_SUBSYS_APE_MINBW (prcmu_base + 0x438) +#define PRCM_CGATING_BYPASS (prcmu_base + 0x134) +#define PRCM_CGATING_BYPASS_ICN2 BIT(6) + +/* Miscellaneous unit registers */ +#define PRCM_RESOUTN_SET (prcmu_base + 0x214) +#define PRCM_RESOUTN_CLR (prcmu_base + 0x218) + +/* System reset register */ +#define PRCM_APE_SOFTRST (prcmu_base + 0x228) + +#endif /* __DB8500_PRCMU_REGS_H */ diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dea4e4e8bed5..82058d11099f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -37,7 +37,7 @@ #include #include #include -#include "dbx500-prcmu-regs.h" +#include "db8500-prcmu-regs.h" /* Index of different voltages to be used when accessing AVSData */ #define PRCM_AVS_BASE 0x2FC diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h deleted file mode 100644 index 75fd1069372c..000000000000 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ /dev/null @@ -1,226 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) STMicroelectronics 2009 - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Kumar Sanghvi - * Author: Sundar Iyer - * - * PRCM Unit registers - */ - -#ifndef __DB8500_PRCMU_REGS_H -#define __DB8500_PRCMU_REGS_H - -#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) - -#define PRCM_ACLK_MGT (0x004) -#define PRCM_SVAMMCSPCLK_MGT (0x008) -#define PRCM_SIAMMDSPCLK_MGT (0x00C) -#define PRCM_SGACLK_MGT (0x014) -#define PRCM_UARTCLK_MGT (0x018) -#define PRCM_MSP02CLK_MGT (0x01C) -#define PRCM_I2CCLK_MGT (0x020) -#define PRCM_SDMMCCLK_MGT (0x024) -#define PRCM_SLIMCLK_MGT (0x028) -#define PRCM_PER1CLK_MGT (0x02C) -#define PRCM_PER2CLK_MGT (0x030) -#define PRCM_PER3CLK_MGT (0x034) -#define PRCM_PER5CLK_MGT (0x038) -#define PRCM_PER6CLK_MGT (0x03C) -#define PRCM_PER7CLK_MGT (0x040) -#define PRCM_LCDCLK_MGT (0x044) -#define PRCM_BMLCLK_MGT (0x04C) -#define PRCM_HSITXCLK_MGT (0x050) -#define PRCM_HSIRXCLK_MGT (0x054) -#define PRCM_HDMICLK_MGT (0x058) -#define PRCM_APEATCLK_MGT (0x05C) -#define PRCM_APETRACECLK_MGT (0x060) -#define PRCM_MCDECLK_MGT (0x064) -#define PRCM_IPI2CCLK_MGT (0x068) -#define PRCM_DSIALTCLK_MGT (0x06C) -#define PRCM_DMACLK_MGT (0x074) -#define PRCM_B2R2CLK_MGT (0x078) -#define PRCM_TVCLK_MGT (0x07C) -#define PRCM_UNIPROCLK_MGT (0x278) -#define PRCM_SSPCLK_MGT (0x280) -#define PRCM_RNGCLK_MGT (0x284) -#define PRCM_UICCCLK_MGT (0x27C) -#define PRCM_MSP1CLK_MGT (0x288) - -#define PRCM_ARM_PLLDIVPS (prcmu_base + 0x118) -#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f -#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf - -#define PRCM_PLLARM_LOCKP (prcmu_base + 0x0a8) -#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 - -#define PRCM_ARM_CHGCLKREQ (prcmu_base + 0x114) -#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) -#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16) - -#define PRCM_PLLARM_ENABLE (prcmu_base + 0x98) -#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 -#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 - -#define PRCM_ARMCLKFIX_MGT (prcmu_base + 0x0) -#define PRCM_A9PL_FORCE_CLKEN (prcmu_base + 0x19C) -#define PRCM_A9_RESETN_CLR (prcmu_base + 0x1f4) -#define PRCM_A9_RESETN_SET (prcmu_base + 0x1f0) -#define PRCM_ARM_LS_CLAMP (prcmu_base + 0x30c) -#define PRCM_SRAM_A9 (prcmu_base + 0x308) - -#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN BIT(0) -#define PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN BIT(1) - -/* CPU mailbox registers */ -#define PRCM_MBOX_CPU_VAL (prcmu_base + 0x0fc) -#define PRCM_MBOX_CPU_SET (prcmu_base + 0x100) -#define PRCM_MBOX_CPU_CLR (prcmu_base + 0x104) - -#define PRCM_HOSTACCESS_REQ (prcmu_base + 0x334) -#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 -#define PRCM_HOSTACCESS_REQ_WAKE_REQ BIT(16) -#define ARM_WAKEUP_MODEM 0x1 - -#define PRCM_ARM_IT1_CLR (prcmu_base + 0x48C) -#define PRCM_ARM_IT1_VAL (prcmu_base + 0x494) -#define PRCM_HOLD_EVT (prcmu_base + 0x174) - -#define PRCM_MOD_AWAKE_STATUS (prcmu_base + 0x4A0) -#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE BIT(0) -#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE BIT(1) -#define PRCM_MOD_AWAKE_STATUS_PRCM_MOD_VMODEM_OFF_ISO BIT(2) - -#define PRCM_ITSTATUS0 (prcmu_base + 0x148) -#define PRCM_ITSTATUS1 (prcmu_base + 0x150) -#define PRCM_ITSTATUS2 (prcmu_base + 0x158) -#define PRCM_ITSTATUS3 (prcmu_base + 0x160) -#define PRCM_ITSTATUS4 (prcmu_base + 0x168) -#define PRCM_ITSTATUS5 (prcmu_base + 0x484) -#define PRCM_ITCLEAR5 (prcmu_base + 0x488) -#define PRCM_ARMIT_MASKXP70_IT (prcmu_base + 0x1018) - -/* System reset register */ -#define PRCM_APE_SOFTRST (prcmu_base + 0x228) - -/* Level shifter and clamp control registers */ -#define PRCM_MMIP_LS_CLAMP_SET (prcmu_base + 0x420) -#define PRCM_MMIP_LS_CLAMP_CLR (prcmu_base + 0x424) - -#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP BIT(11) -#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI BIT(22) - -/* PRCMU clock/PLL/reset registers */ -#define PRCM_PLLSOC0_FREQ (prcmu_base + 0x080) -#define PRCM_PLLSOC1_FREQ (prcmu_base + 0x084) -#define PRCM_PLLARM_FREQ (prcmu_base + 0x088) -#define PRCM_PLLDDR_FREQ (prcmu_base + 0x08C) -#define PRCM_PLL_FREQ_D_SHIFT 0 -#define PRCM_PLL_FREQ_D_MASK BITS(0, 7) -#define PRCM_PLL_FREQ_N_SHIFT 8 -#define PRCM_PLL_FREQ_N_MASK BITS(8, 13) -#define PRCM_PLL_FREQ_R_SHIFT 16 -#define PRCM_PLL_FREQ_R_MASK BITS(16, 18) -#define PRCM_PLL_FREQ_SELDIV2 BIT(24) -#define PRCM_PLL_FREQ_DIV2EN BIT(25) - -#define PRCM_PLLDSI_FREQ (prcmu_base + 0x500) -#define PRCM_PLLDSI_ENABLE (prcmu_base + 0x504) -#define PRCM_PLLDSI_LOCKP (prcmu_base + 0x508) -#define PRCM_DSI_PLLOUT_SEL (prcmu_base + 0x530) -#define PRCM_DSITVCLK_DIV (prcmu_base + 0x52C) -#define PRCM_PLLDSI_LOCKP (prcmu_base + 0x508) -#define PRCM_APE_RESETN_SET (prcmu_base + 0x1E4) -#define PRCM_APE_RESETN_CLR (prcmu_base + 0x1E8) - -#define PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE BIT(0) - -#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 BIT(0) -#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3 BIT(1) - -#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT 0 -#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK BITS(0, 2) -#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT 8 -#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK BITS(8, 10) - -#define PRCM_DSI_PLLOUT_SEL_OFF 0 -#define PRCM_DSI_PLLOUT_SEL_PHI 1 -#define PRCM_DSI_PLLOUT_SEL_PHI_2 2 -#define PRCM_DSI_PLLOUT_SEL_PHI_4 3 - -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT 0 -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK BITS(0, 7) -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT 8 -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK BITS(8, 15) -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT 16 -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK BITS(16, 23) -#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN BIT(24) -#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN BIT(25) -#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN BIT(26) - -#define PRCM_APE_RESETN_DSIPLL_RESETN BIT(14) - -#define PRCM_CLKOCR (prcmu_base + 0x1CC) -#define PRCM_CLKOCR_CLKOUT0_REF_CLK (1 << 0) -#define PRCM_CLKOCR_CLKOUT0_MASK BITS(0, 13) -#define PRCM_CLKOCR_CLKOUT1_REF_CLK (1 << 16) -#define PRCM_CLKOCR_CLKOUT1_MASK BITS(16, 29) - -/* ePOD and memory power signal control registers */ -#define PRCM_EPOD_C_SET (prcmu_base + 0x410) -#define PRCM_SRAM_LS_SLEEP (prcmu_base + 0x304) - -/* Debug power control unit registers */ -#define PRCM_POWER_STATE_SET (prcmu_base + 0x254) - -/* Miscellaneous unit registers */ -#define PRCM_DSI_SW_RESET (prcmu_base + 0x324) -#define PRCM_GPIOCR (prcmu_base + 0x138) -#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 -#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 - -/* PRCMU HW semaphore */ -#define PRCM_SEM (prcmu_base + 0x400) -#define PRCM_SEM_PRCM_SEM BIT(0) - -#define PRCM_TCR (prcmu_base + 0x1C8) -#define PRCM_TCR_TENSEL_MASK BITS(0, 7) -#define PRCM_TCR_STOP_TIMERS BIT(16) -#define PRCM_TCR_DOZE_MODE BIT(17) - -#define PRCM_CLKOCR_CLKODIV0_SHIFT 0 -#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) -#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 -#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) -#define PRCM_CLKOCR_CLKODIV1_SHIFT 16 -#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) -#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 -#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) -#define PRCM_CLKOCR_CLK1TYPE BIT(28) - -#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) -#define PRCM_CLK_MGT_CLKPLLSW_SOC0 BIT(5) -#define PRCM_CLK_MGT_CLKPLLSW_SOC1 BIT(6) -#define PRCM_CLK_MGT_CLKPLLSW_DDR BIT(7) -#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) -#define PRCM_CLK_MGT_CLKEN BIT(8) -#define PRCM_CLK_MGT_CLK38 BIT(9) -#define PRCM_CLK_MGT_CLK38DIV BIT(11) -#define PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN BIT(12) - -/* GPIOCR register */ -#define PRCM_GPIOCR_SPI2_SELECT BIT(23) - -#define PRCM_DDR_SUBSYS_APE_MINBW (prcmu_base + 0x438) -#define PRCM_CGATING_BYPASS (prcmu_base + 0x134) -#define PRCM_CGATING_BYPASS_ICN2 BIT(6) - -/* Miscellaneous unit registers */ -#define PRCM_RESOUTN_SET (prcmu_base + 0x214) -#define PRCM_RESOUTN_CLR (prcmu_base + 0x218) - -/* System reset register */ -#define PRCM_APE_SOFTRST (prcmu_base + 0x228) - -#endif /* __DB8500_PRCMU_REGS_H */ -- cgit v1.2.3-70-g09d2 From 6b3ba1e77d8913ee6ffb3972e889bc35550ed95c Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Thu, 5 Aug 2021 21:30:24 +0800 Subject: f2fs: Kconfig: clean up config options about compression In fs/f2fs/Kconfig, F2FS_FS_LZ4HC depends on F2FS_FS_LZ4 and F2FS_FS_LZ4 depends on F2FS_FS_COMPRESSION, so no need to make F2FS_FS_LZ4HC depends on F2FS_FS_COMPRESSION explicitly, remove the redudant "depends on", do the similar thing for F2FS_FS_LZORLE. At the same time, it is better to move F2FS_FS_LZORLE next to F2FS_FS_LZO, it looks like a little more clear when make menuconfig, the location of "LZO-RLE compression support" is under "LZO compression support" instead of "F2FS compression feature". Without this patch: F2FS compression feature LZO compression support LZ4 compression support LZ4HC compression support ZSTD compression support LZO-RLE compression support With this patch: F2FS compression feature LZO compression support LZO-RLE compression support LZ4 compression support LZ4HC compression support ZSTD compression support Signed-off-by: Tiezhu Yang Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/Kconfig | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig index 7669de7b49ce..2ac026fc3564 100644 --- a/fs/f2fs/Kconfig +++ b/fs/f2fs/Kconfig @@ -105,6 +105,13 @@ config F2FS_FS_LZO help Support LZO compress algorithm, if unsure, say Y. +config F2FS_FS_LZORLE + bool "LZO-RLE compression support" + depends on F2FS_FS_LZO + default y + help + Support LZO-RLE compress algorithm, if unsure, say Y. + config F2FS_FS_LZ4 bool "LZ4 compression support" depends on F2FS_FS_COMPRESSION @@ -114,7 +121,6 @@ config F2FS_FS_LZ4 config F2FS_FS_LZ4HC bool "LZ4HC compression support" - depends on F2FS_FS_COMPRESSION depends on F2FS_FS_LZ4 default y help @@ -127,11 +133,3 @@ config F2FS_FS_ZSTD default y help Support ZSTD compress algorithm, if unsure, say Y. - -config F2FS_FS_LZORLE - bool "LZO-RLE compression support" - depends on F2FS_FS_COMPRESSION - depends on F2FS_FS_LZO - default y - help - Support LZO-RLE compress algorithm, if unsure, say Y. -- cgit v1.2.3-70-g09d2 From 94afd6d6e5253179c9b891d02081cc8355a11768 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Wed, 4 Aug 2021 10:23:48 +0800 Subject: f2fs: extent cache: support unaligned extent Compressed inode may suffer read performance issue due to it can not use extent cache, so I propose to add this unaligned extent support to improve it. Currently, it only works in readonly format f2fs image. Unaligned extent: in one compressed cluster, physical block number will be less than logical block number, so we add an extra physical block length in extent info in order to indicate such extent status. The idea is if one whole cluster blocks are contiguous physically, once its mapping info was readed at first time, we will cache an unaligned (or aligned) extent info entry in extent cache, it expects that the mapping info will be hitted when rereading cluster. Merge policy: - Aligned extents can be merged. - Aligned extent and unaligned extent can not be merged. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/compress.c | 24 ++++++++++++++++++++++++ fs/f2fs/data.c | 38 +++++++++++++++++++++++++++----------- fs/f2fs/extent_cache.c | 41 +++++++++++++++++++++++++++++++++++++++++ fs/f2fs/f2fs.h | 20 ++++++++++++++++++++ fs/f2fs/node.c | 20 ++++++++++++++++++++ 5 files changed, 132 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 455561826c7d..7dbfd6965b97 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1666,6 +1666,30 @@ void f2fs_put_page_dic(struct page *page) f2fs_put_dic(dic); } +/* + * check whether cluster blocks are contiguous, and add extent cache entry + * only if cluster blocks are logically and physically contiguous. + */ +unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) +{ + bool compressed = f2fs_data_blkaddr(dn) == COMPRESS_ADDR; + int i = compressed ? 1 : 0; + block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page, + dn->ofs_in_node + i); + + for (i += 1; i < F2FS_I(dn->inode)->i_cluster_size; i++) { + block_t blkaddr = data_blkaddr(dn->inode, dn->node_page, + dn->ofs_in_node + i); + + if (!__is_valid_data_blkaddr(blkaddr)) + break; + if (first_blkaddr + i - (compressed ? 1 : 0) != blkaddr) + return 0; + } + + return compressed ? i - 1 : i; +} + const struct address_space_operations f2fs_compress_aops = { .releasepage = f2fs_release_page, .invalidatepage = f2fs_invalidate_page, diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 948083c88d17..df5e8d8c654e 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1135,7 +1135,7 @@ int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index) int f2fs_get_block(struct dnode_of_data *dn, pgoff_t index) { - struct extent_info ei = {0, 0, 0}; + struct extent_info ei = {0, }; struct inode *inode = dn->inode; if (f2fs_lookup_extent_cache(inode, index, &ei)) { @@ -1152,7 +1152,7 @@ struct page *f2fs_get_read_data_page(struct inode *inode, pgoff_t index, struct address_space *mapping = inode->i_mapping; struct dnode_of_data dn; struct page *page; - struct extent_info ei = {0,0,0}; + struct extent_info ei = {0, }; int err; page = f2fs_grab_cache_page(mapping, index, for_write); @@ -1450,7 +1450,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int err = 0, ofs = 1; unsigned int ofs_in_node, last_ofs_in_node; blkcnt_t prealloc; - struct extent_info ei = {0,0,0}; + struct extent_info ei = {0, }; block_t blkaddr; unsigned int start_pgofs; @@ -2126,6 +2126,8 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, sector_t last_block_in_file; const unsigned blocksize = blks_to_bytes(inode, 1); struct decompress_io_ctx *dic = NULL; + struct extent_info ei = {0, }; + bool from_dnode = true; int i; int ret = 0; @@ -2156,6 +2158,12 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, if (f2fs_cluster_is_empty(cc)) goto out; + if (f2fs_lookup_extent_cache(inode, start_idx, &ei)) + from_dnode = false; + + if (!from_dnode) + goto skip_reading_dnode; + set_new_dnode(&dn, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(&dn, start_idx, LOOKUP_NODE); if (ret) @@ -2163,11 +2171,13 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, f2fs_bug_on(sbi, dn.data_blkaddr != COMPRESS_ADDR); +skip_reading_dnode: for (i = 1; i < cc->cluster_size; i++) { block_t blkaddr; - blkaddr = data_blkaddr(dn.inode, dn.node_page, - dn.ofs_in_node + i); + blkaddr = from_dnode ? data_blkaddr(dn.inode, dn.node_page, + dn.ofs_in_node + i) : + ei.blk + i - 1; if (!__is_valid_data_blkaddr(blkaddr)) break; @@ -2177,6 +2187,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, goto out_put_dnode; } cc->nr_cpages++; + + if (!from_dnode && i >= ei.c_len) + break; } /* nothing to decompress */ @@ -2196,8 +2209,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, block_t blkaddr; struct bio_post_read_ctx *ctx; - blkaddr = data_blkaddr(dn.inode, dn.node_page, - dn.ofs_in_node + i + 1); + blkaddr = from_dnode ? data_blkaddr(dn.inode, dn.node_page, + dn.ofs_in_node + i + 1) : + ei.blk + i; f2fs_wait_on_block_writeback(inode, blkaddr); @@ -2242,13 +2256,15 @@ submit_and_realloc: *last_block_in_bio = blkaddr; } - f2fs_put_dnode(&dn); + if (from_dnode) + f2fs_put_dnode(&dn); *bio_ret = bio; return 0; out_put_dnode: - f2fs_put_dnode(&dn); + if (from_dnode) + f2fs_put_dnode(&dn); out: for (i = 0; i < cc->cluster_size; i++) { if (cc->rpages[i]) { @@ -2543,7 +2559,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) struct page *page = fio->page; struct inode *inode = page->mapping->host; struct dnode_of_data dn; - struct extent_info ei = {0,0,0}; + struct extent_info ei = {0, }; struct node_info ni; bool ipu_force = false; int err = 0; @@ -3218,7 +3234,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, struct dnode_of_data dn; struct page *ipage; bool locked = false; - struct extent_info ei = {0,0,0}; + struct extent_info ei = {0, }; int err = 0; int flag; diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c index 3ebf976a682d..b120589d8517 100644 --- a/fs/f2fs/extent_cache.c +++ b/fs/f2fs/extent_cache.c @@ -661,6 +661,47 @@ static void f2fs_update_extent_tree_range(struct inode *inode, f2fs_mark_inode_dirty_sync(inode, true); } +#ifdef CONFIG_F2FS_FS_COMPRESSION +void f2fs_update_extent_tree_range_compressed(struct inode *inode, + pgoff_t fofs, block_t blkaddr, unsigned int llen, + unsigned int c_len) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct extent_tree *et = F2FS_I(inode)->extent_tree; + struct extent_node *en = NULL; + struct extent_node *prev_en = NULL, *next_en = NULL; + struct extent_info ei; + struct rb_node **insert_p = NULL, *insert_parent = NULL; + bool leftmost = false; + + trace_f2fs_update_extent_tree_range(inode, fofs, blkaddr, llen); + + /* it is safe here to check FI_NO_EXTENT w/o et->lock in ro image */ + if (is_inode_flag_set(inode, FI_NO_EXTENT)) + return; + + write_lock(&et->lock); + + en = (struct extent_node *)f2fs_lookup_rb_tree_ret(&et->root, + (struct rb_entry *)et->cached_en, fofs, + (struct rb_entry **)&prev_en, + (struct rb_entry **)&next_en, + &insert_p, &insert_parent, false, + &leftmost); + if (en) + goto unlock_out; + + set_extent_info(&ei, fofs, blkaddr, llen); + ei.c_len = c_len; + + if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en)) + __insert_extent_tree(sbi, et, &ei, + insert_p, insert_parent, leftmost); +unlock_out: + write_unlock(&et->lock); +} +#endif + unsigned int f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) { struct extent_tree *et, *next; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index d24fd5045712..e97b4d8c5efc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -580,6 +580,9 @@ struct extent_info { unsigned int fofs; /* start offset in a file */ unsigned int len; /* length of the extent */ u32 blk; /* start block address of the extent */ +#ifdef CONFIG_F2FS_FS_COMPRESSION + unsigned int c_len; /* physical extent length of compressed blocks */ +#endif }; struct extent_node { @@ -799,6 +802,9 @@ static inline void set_extent_info(struct extent_info *ei, unsigned int fofs, ei->fofs = fofs; ei->blk = blk; ei->len = len; +#ifdef CONFIG_F2FS_FS_COMPRESSION + ei->c_len = 0; +#endif } static inline bool __is_discard_mergeable(struct discard_info *back, @@ -823,6 +829,12 @@ static inline bool __is_discard_front_mergeable(struct discard_info *cur, static inline bool __is_extent_mergeable(struct extent_info *back, struct extent_info *front) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (back->c_len && back->len != back->c_len) + return false; + if (front->c_len && front->len != front->c_len) + return false; +#endif return (back->fofs + back->len == front->fofs && back->blk + back->len == front->blk); } @@ -4068,12 +4080,16 @@ int f2fs_write_multi_pages(struct compress_ctx *cc, struct writeback_control *wbc, enum iostat_type io_type); int f2fs_is_compressed_cluster(struct inode *inode, pgoff_t index); +void f2fs_update_extent_tree_range_compressed(struct inode *inode, + pgoff_t fofs, block_t blkaddr, unsigned int llen, + unsigned int c_len); int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, unsigned nr_pages, sector_t *last_block_in_bio, bool is_readahead, bool for_write); struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc); void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed); void f2fs_put_page_dic(struct page *page); +unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn); int f2fs_init_compress_ctx(struct compress_ctx *cc); void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); void f2fs_init_compress_info(struct f2fs_sb_info *sbi); @@ -4128,6 +4144,7 @@ static inline void f2fs_put_page_dic(struct page *page) { WARN_ON_ONCE(1); } +static inline unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn) { return 0; } static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { } static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; } @@ -4143,6 +4160,9 @@ static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) { } #define inc_compr_inode_stat(inode) do { } while (0) +static inline void f2fs_update_extent_tree_range_compressed(struct inode *inode, + pgoff_t fofs, block_t blkaddr, unsigned int llen, + unsigned int c_len) { } #endif static inline void set_compress_context(struct inode *inode) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 5840b82ce311..9d838a7929fb 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -841,6 +841,26 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) dn->ofs_in_node = offset[level]; dn->node_page = npage[level]; dn->data_blkaddr = f2fs_data_blkaddr(dn); + + if (is_inode_flag_set(dn->inode, FI_COMPRESSED_FILE) && + f2fs_sb_has_readonly(sbi)) { + unsigned int c_len = f2fs_cluster_blocks_are_contiguous(dn); + block_t blkaddr; + + if (!c_len) + goto out; + + blkaddr = f2fs_data_blkaddr(dn); + if (blkaddr == COMPRESS_ADDR) + blkaddr = data_blkaddr(dn->inode, dn->node_page, + dn->ofs_in_node + 1); + + f2fs_update_extent_tree_range_compressed(dn->inode, + index, blkaddr, + F2FS_I(dn->inode)->i_cluster_size, + c_len); + } +out: return 0; release_pages: -- cgit v1.2.3-70-g09d2 From e1f85d25638cce2c5535efb608adf7a6ee817794 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Mon, 12 Jul 2021 18:03:12 +0800 Subject: gpio: gpio-aspeed-sgpio: Add AST2600 sgpio support The maximum number of gpio pins of SoC is hardcoded as 80 and the gpio pin count mask for GPIO Configuration register is hardcode as GENMASK(9,6). However, AST2600 has 2 sgpio master interfaces, one of them supports up to 128 gpio pins and pin count mask of GPIO Configuration Register is 5 bits. The patch adds ast2600 compatibles, removes MAX_NR_HW_SGPIO and corresponding design to make the gpio input/output pin base are determined by ngpios. The patch also removed hardcoded pin mask and adds ast2400, ast2500, ast2600 platform data that include gpio pin count mask for GPIO Configuration Register. The original pin order is as follows: (suppose MAX_NR_HW_SGPIO is 80 and ngpios is 10 as well) Input: 0 1 2 3 ... 9 Output: 80 81 82 ... 89 The new pin order is as follows: Input: 0 2 4 6 ... 18 Output: 1 3 5 7 ... 19 SGPIO pin id and input/output pin mapping is as follows: SGPIO0(0,1), SGPIO1(2,3), ..., SGPIO79(158,159) For example: Access SGPIO5(10,11) Get SGPIO pin 5 (suppose sgpio chip id is 2) gpioget 2 10 Set SGPIO pin 5 (suppose sgpio chip id is 2) gpioset 2 11=1 gpioset 2 11=0 Signed-off-by: Steven Lee Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 101 ++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 54 deletions(-) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 64e54f8c30d2..8f6bacd23e13 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -17,23 +17,15 @@ #include #include -/* - * MAX_NR_HW_GPIO represents the number of actual hardware-supported GPIOs (ie, - * slots within the clocked serial GPIO data). Since each HW GPIO is both an - * input and an output, we provide MAX_NR_HW_GPIO * 2 lines on our gpiochip - * device. - * - * We use SGPIO_OUTPUT_OFFSET to define the split between the inputs and - * outputs; the inputs start at line 0, the outputs start at OUTPUT_OFFSET. - */ -#define MAX_NR_HW_SGPIO 80 -#define SGPIO_OUTPUT_OFFSET MAX_NR_HW_SGPIO - #define ASPEED_SGPIO_CTRL 0x54 -#define ASPEED_SGPIO_PINS_MASK GENMASK(9, 6) #define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16) #define ASPEED_SGPIO_ENABLE BIT(0) +#define ASPEED_SGPIO_PINS_SHIFT 6 + +struct aspeed_sgpio_pdata { + const u32 pin_mask; +}; struct aspeed_sgpio { struct gpio_chip chip; @@ -41,7 +33,6 @@ struct aspeed_sgpio { spinlock_t lock; void __iomem *base; int irq; - int n_sgpio; }; struct aspeed_sgpio_bank { @@ -75,7 +66,13 @@ static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = { .val_regs = 0x0038, .rdata_reg = 0x0078, .irq_regs = 0x003C, - .names = { "I", "J" }, + .names = { "I", "J", "K", "L" }, + }, + { + .val_regs = 0x0090, + .rdata_reg = 0x007C, + .irq_regs = 0x0094, + .names = { "M", "N", "O", "P" }, }, }; @@ -121,9 +118,9 @@ static void __iomem *bank_reg(struct aspeed_sgpio *gpio, } } -#define GPIO_BANK(x) ((x % SGPIO_OUTPUT_OFFSET) >> 5) -#define GPIO_OFFSET(x) ((x % SGPIO_OUTPUT_OFFSET) & 0x1f) -#define GPIO_BIT(x) BIT(GPIO_OFFSET(x)) +#define GPIO_BANK(x) ((x) >> 6) +#define GPIO_OFFSET(x) ((x) & GENMASK(5, 0)) +#define GPIO_BIT(x) BIT(GPIO_OFFSET(x) >> 1) static const struct aspeed_sgpio_bank *to_bank(unsigned int offset) { @@ -138,39 +135,25 @@ static const struct aspeed_sgpio_bank *to_bank(unsigned int offset) static int aspeed_sgpio_init_valid_mask(struct gpio_chip *gc, unsigned long *valid_mask, unsigned int ngpios) { - struct aspeed_sgpio *sgpio = gpiochip_get_data(gc); - int n = sgpio->n_sgpio; - int c = SGPIO_OUTPUT_OFFSET - n; - - WARN_ON(ngpios < MAX_NR_HW_SGPIO * 2); - - /* input GPIOs in the lower range */ - bitmap_set(valid_mask, 0, n); - bitmap_clear(valid_mask, n, c); - - /* output GPIOS above SGPIO_OUTPUT_OFFSET */ - bitmap_set(valid_mask, SGPIO_OUTPUT_OFFSET, n); - bitmap_clear(valid_mask, SGPIO_OUTPUT_OFFSET + n, c); - + bitmap_set(valid_mask, 0, ngpios); return 0; } static void aspeed_sgpio_irq_init_valid_mask(struct gpio_chip *gc, unsigned long *valid_mask, unsigned int ngpios) { - struct aspeed_sgpio *sgpio = gpiochip_get_data(gc); - int n = sgpio->n_sgpio; + unsigned int i; - WARN_ON(ngpios < MAX_NR_HW_SGPIO * 2); - - /* input GPIOs in the lower range */ - bitmap_set(valid_mask, 0, n); - bitmap_clear(valid_mask, n, ngpios - n); + /* input GPIOs are even bits */ + for (i = 0; i < ngpios; i++) { + if (i % 2) + clear_bit(i, valid_mask); + } } static bool aspeed_sgpio_is_input(unsigned int offset) { - return offset < SGPIO_OUTPUT_OFFSET; + return !(offset % 2); } static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset) @@ -466,9 +449,18 @@ static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio, return 0; } +static const struct aspeed_sgpio_pdata ast2400_sgpio_pdata = { + .pin_mask = GENMASK(9, 6), +}; + +static const struct aspeed_sgpio_pdata ast2600_sgpiom_pdata = { + .pin_mask = GENMASK(10, 6), +}; + static const struct of_device_id aspeed_sgpio_of_table[] = { - { .compatible = "aspeed,ast2400-sgpio" }, - { .compatible = "aspeed,ast2500-sgpio" }, + { .compatible = "aspeed,ast2400-sgpio", .data = &ast2400_sgpio_pdata, }, + { .compatible = "aspeed,ast2500-sgpio", .data = &ast2400_sgpio_pdata, }, + { .compatible = "aspeed,ast2600-sgpiom", .data = &ast2600_sgpiom_pdata, }, {} }; @@ -476,10 +468,11 @@ MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table); static int __init aspeed_sgpio_probe(struct platform_device *pdev) { + u32 nr_gpios, sgpio_freq, sgpio_clk_div, gpio_cnt_regval, pin_mask; + const struct aspeed_sgpio_pdata *pdata; struct aspeed_sgpio *gpio; - u32 nr_gpios, sgpio_freq, sgpio_clk_div; - int rc; unsigned long apb_freq; + int rc; gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) @@ -489,16 +482,17 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) if (IS_ERR(gpio->base)) return PTR_ERR(gpio->base); + pdata = device_get_match_data(&pdev->dev); + if (!pdata) + return -EINVAL; + + pin_mask = pdata->pin_mask; + rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios); if (rc < 0) { dev_err(&pdev->dev, "Could not read ngpios property\n"); return -EINVAL; - } else if (nr_gpios > MAX_NR_HW_SGPIO) { - dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: %d\n", - MAX_NR_HW_SGPIO, nr_gpios); - return -EINVAL; } - gpio->n_sgpio = nr_gpios; rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq); if (rc < 0) { @@ -531,15 +525,14 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) if (sgpio_clk_div > (1 << 16) - 1) return -EINVAL; - iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | - FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) | - ASPEED_SGPIO_ENABLE, - gpio->base + ASPEED_SGPIO_CTRL); + gpio_cnt_regval = ((nr_gpios / 8) << ASPEED_SGPIO_PINS_SHIFT) & pin_mask; + iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval | + ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL); spin_lock_init(&gpio->lock); gpio->chip.parent = &pdev->dev; - gpio->chip.ngpio = MAX_NR_HW_SGPIO * 2; + gpio->chip.ngpio = nr_gpios * 2; gpio->chip.init_valid_mask = aspeed_sgpio_init_valid_mask; gpio->chip.direction_input = aspeed_sgpio_dir_in; gpio->chip.direction_output = aspeed_sgpio_dir_out; -- cgit v1.2.3-70-g09d2 From 8a3581c666f97bec53baebf2ed77e4954be0384d Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Mon, 12 Jul 2021 18:03:13 +0800 Subject: gpio: gpio-aspeed-sgpio: Add set_config function AST SoC supports *retain pin state* function when wdt reset. The patch adds set_config function for handling sgpio reset tolerance register. Signed-off-by: Steven Lee Reviewed-by: Andrew Jeffery Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 54 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 8f6bacd23e13..9b809c28f842 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -36,9 +36,10 @@ struct aspeed_sgpio { }; struct aspeed_sgpio_bank { - uint16_t val_regs; - uint16_t rdata_reg; - uint16_t irq_regs; + u16 val_regs; + u16 rdata_reg; + u16 irq_regs; + u16 tolerance_regs; const char names[4][3]; }; @@ -54,24 +55,28 @@ static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = { .val_regs = 0x0000, .rdata_reg = 0x0070, .irq_regs = 0x0004, + .tolerance_regs = 0x0018, .names = { "A", "B", "C", "D" }, }, { .val_regs = 0x001C, .rdata_reg = 0x0074, .irq_regs = 0x0020, + .tolerance_regs = 0x0034, .names = { "E", "F", "G", "H" }, }, { .val_regs = 0x0038, .rdata_reg = 0x0078, .irq_regs = 0x003C, + .tolerance_regs = 0x0050, .names = { "I", "J", "K", "L" }, }, { .val_regs = 0x0090, .rdata_reg = 0x007C, .irq_regs = 0x0094, + .tolerance_regs = 0x00A8, .names = { "M", "N", "O", "P" }, }, }; @@ -84,6 +89,7 @@ enum aspeed_sgpio_reg { reg_irq_type1, reg_irq_type2, reg_irq_status, + reg_tolerance, }; #define GPIO_VAL_VALUE 0x00 @@ -112,6 +118,8 @@ static void __iomem *bank_reg(struct aspeed_sgpio *gpio, return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2; case reg_irq_status: return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; + case reg_tolerance: + return gpio->base + bank->tolerance_regs; default: /* acturally if code runs to here, it's an error case */ BUG(); @@ -453,6 +461,44 @@ static const struct aspeed_sgpio_pdata ast2400_sgpio_pdata = { .pin_mask = GENMASK(9, 6), }; +static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, + unsigned int offset, bool enable) +{ + struct aspeed_sgpio *gpio = gpiochip_get_data(chip); + unsigned long flags; + void __iomem *reg; + u32 val; + + reg = bank_reg(gpio, to_bank(offset), reg_tolerance); + + spin_lock_irqsave(&gpio->lock, flags); + + val = readl(reg); + + if (enable) + val |= GPIO_BIT(offset); + else + val &= ~GPIO_BIT(offset); + + writel(val, reg); + + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static int aspeed_sgpio_set_config(struct gpio_chip *chip, unsigned int offset, + unsigned long config) +{ + unsigned long param = pinconf_to_config_param(config); + u32 arg = pinconf_to_config_argument(config); + + if (param == PIN_CONFIG_PERSIST_STATE) + return aspeed_sgpio_reset_tolerance(chip, offset, arg); + + return -ENOTSUPP; +} + static const struct aspeed_sgpio_pdata ast2600_sgpiom_pdata = { .pin_mask = GENMASK(10, 6), }; @@ -541,7 +587,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) gpio->chip.free = NULL; gpio->chip.get = aspeed_sgpio_get; gpio->chip.set = aspeed_sgpio_set; - gpio->chip.set_config = NULL; + gpio->chip.set_config = aspeed_sgpio_set_config; gpio->chip.label = dev_name(&pdev->dev); gpio->chip.base = -1; -- cgit v1.2.3-70-g09d2 From 09ac953b65b167efdaac25c63f2f1786f4faa801 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Mon, 12 Jul 2021 18:03:14 +0800 Subject: gpio: gpio-aspeed-sgpio: Move irq_chip to aspeed-sgpio struct The current design initializes irq->chip from a global irqchip struct, which causes multiple sgpio devices use the same irq_chip. The patch moves irq_chip to aspeed_sgpio struct for initializing irq_chip from their private gpio struct. Signed-off-by: Steven Lee Reviewed-by: Andrew Jeffery Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 9b809c28f842..6b3695197c97 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -29,6 +29,7 @@ struct aspeed_sgpio_pdata { struct aspeed_sgpio { struct gpio_chip chip; + struct irq_chip intc; struct clk *pclk; spinlock_t lock; void __iomem *base; @@ -403,14 +404,6 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc) chained_irq_exit(ic, desc); } -static struct irq_chip aspeed_sgpio_irqchip = { - .name = "aspeed-sgpio", - .irq_ack = aspeed_sgpio_irq_ack, - .irq_mask = aspeed_sgpio_irq_mask, - .irq_unmask = aspeed_sgpio_irq_unmask, - .irq_set_type = aspeed_sgpio_set_type, -}; - static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio, struct platform_device *pdev) { @@ -433,8 +426,14 @@ static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio, iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status)); } + gpio->intc.name = dev_name(&pdev->dev); + gpio->intc.irq_ack = aspeed_sgpio_irq_ack; + gpio->intc.irq_mask = aspeed_sgpio_irq_mask; + gpio->intc.irq_unmask = aspeed_sgpio_irq_unmask; + gpio->intc.irq_set_type = aspeed_sgpio_set_type; + irq = &gpio->chip.irq; - irq->chip = &aspeed_sgpio_irqchip; + irq->chip = &gpio->intc; irq->init_valid_mask = aspeed_sgpio_irq_init_valid_mask; irq->handler = handle_bad_irq; irq->default_type = IRQ_TYPE_NONE; -- cgit v1.2.3-70-g09d2 From 1f857b675237d77590d439f16c5927ec3e4b1f0e Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Mon, 12 Jul 2021 18:03:15 +0800 Subject: gpio: gpio-aspeed-sgpio: Use generic device property APIs Replace all of_property_read_u32() with device_property_read_u32(). Signed-off-by: Steven Lee Acked-by: Andrew Jeffery Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 6b3695197c97..b3d05fc724f0 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -533,13 +533,13 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) pin_mask = pdata->pin_mask; - rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios); + rc = device_property_read_u32(&pdev->dev, "ngpios", &nr_gpios); if (rc < 0) { dev_err(&pdev->dev, "Could not read ngpios property\n"); return -EINVAL; } - rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq); + rc = device_property_read_u32(&pdev->dev, "bus-frequency", &sgpio_freq); if (rc < 0) { dev_err(&pdev->dev, "Could not read bus-frequency property\n"); return -EINVAL; -- cgit v1.2.3-70-g09d2 From f43837f4f63b1a58084d7147b8b34c0f3dd261f6 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Mon, 12 Jul 2021 18:03:16 +0800 Subject: gpio: gpio-aspeed-sgpio: Return error if ngpios is not multiple of 8. Add an else-if condition in the probe function to check whether ngpios is multiple of 8. Per AST datasheet, numbers of available serial GPIO pins in Serial GPIO Configuration Register must be n bytes. For instance, if n = 1, it means AST SoC supports 8 GPIO pins. Signed-off-by: Steven Lee Reviewed-by: Andrew Jeffery Reviewed-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index b3d05fc724f0..191b82a2560c 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -537,6 +537,10 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) if (rc < 0) { dev_err(&pdev->dev, "Could not read ngpios property\n"); return -EINVAL; + } else if (nr_gpios % 8) { + dev_err(&pdev->dev, "Number of GPIOs not multiple of 8: %d\n", + nr_gpios); + return -EINVAL; } rc = device_property_read_u32(&pdev->dev, "bus-frequency", &sgpio_freq); -- cgit v1.2.3-70-g09d2 From a065d5615fc83908ef21ed8159ffb63d816ff5de Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 28 Jul 2021 16:42:27 +0200 Subject: of: unify of_count_phandle_with_args() arguments with !CONFIG_OF Unify the declaration of of_count_phandle_with_args() between enabled and disabled OF by making constifying pointed device_node. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- include/linux/of.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/of.h b/include/linux/of.h index 9c2e71e202d1..dfeb065c3fad 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -896,7 +896,7 @@ static inline int of_parse_phandle_with_fixed_args(const struct device_node *np, return -ENOSYS; } -static inline int of_count_phandle_with_args(struct device_node *np, +static inline int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name) { -- cgit v1.2.3-70-g09d2 From e6ae9a833ef4043b940954b8dcac31493706b9d6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 28 Jul 2021 16:42:28 +0200 Subject: gpiolib: constify passed device_node pointer Several gpiolib functions receive pointer to struct device_node which is later passed to OF functions. These OF functions accept already pointer to const, so gpiolib can follow similar approach to indicate they are not modifying the struct device_node. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-devres.c | 2 +- drivers/gpio/gpiolib-of.c | 8 ++++---- include/linux/gpio/consumer.h | 8 ++++---- include/linux/of_gpio.h | 15 ++++++++------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/gpio/gpiolib-devres.c b/drivers/gpio/gpiolib-devres.c index 4a517e5dedf0..79da85d17b71 100644 --- a/drivers/gpio/gpiolib-devres.c +++ b/drivers/gpio/gpiolib-devres.c @@ -145,7 +145,7 @@ EXPORT_SYMBOL_GPL(devm_gpiod_get_index); * In case of error an ERR_PTR() is returned. */ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, - struct device_node *node, + const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index bbcc7c073f63..1e5a6f63b2fe 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -130,7 +130,7 @@ bool of_gpio_need_valid_mask(const struct gpio_chip *gc) return false; } -static void of_gpio_flags_quirks(struct device_node *np, +static void of_gpio_flags_quirks(const struct device_node *np, const char *propname, enum of_gpio_flags *flags, int index) @@ -236,7 +236,7 @@ static void of_gpio_flags_quirks(struct device_node *np, * value on the error condition. If @flags is not NULL the function also fills * in flags for the GPIO. */ -static struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, +static struct gpio_desc *of_get_named_gpiod_flags(const struct device_node *np, const char *propname, int index, enum of_gpio_flags *flags) { struct of_phandle_args gpiospec; @@ -275,7 +275,7 @@ out: return desc; } -int of_get_named_gpio_flags(struct device_node *np, const char *list_name, +int of_get_named_gpio_flags(const struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags) { struct gpio_desc *desc; @@ -303,7 +303,7 @@ EXPORT_SYMBOL_GPL(of_get_named_gpio_flags); * * In case of error an ERR_PTR() is returned. */ -struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, +struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label) diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 566feb56601f..bf945b776555 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -609,7 +609,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_OF_GPIO) struct device_node; -struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, +struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label); @@ -619,7 +619,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, struct device_node; static inline -struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, +struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label) @@ -633,7 +633,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, struct device_node; struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, - struct device_node *node, + const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label); @@ -644,7 +644,7 @@ struct device_node; static inline struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, - struct device_node *node, + const struct device_node *node, const char *propname, int index, enum gpiod_flags dflags, const char *label) diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index f821095218b0..8bf2ea859653 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -49,7 +49,7 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc) return container_of(gc, struct of_mm_gpio_chip, gc); } -extern int of_get_named_gpio_flags(struct device_node *np, +extern int of_get_named_gpio_flags(const struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags); extern int of_mm_gpiochip_add_data(struct device_node *np, @@ -67,7 +67,7 @@ extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc); #include /* Drivers may not strictly depend on the GPIO support, so let them link. */ -static inline int of_get_named_gpio_flags(struct device_node *np, +static inline int of_get_named_gpio_flags(const struct device_node *np, const char *list_name, int index, enum of_gpio_flags *flags) { if (flags) @@ -98,7 +98,8 @@ static inline int of_get_named_gpio_flags(struct device_node *np, * The above example defines four GPIOs, two of which are not specified. * This function will return '4' */ -static inline int of_gpio_named_count(struct device_node *np, const char* propname) +static inline int of_gpio_named_count(const struct device_node *np, + const char *propname) { return of_count_phandle_with_args(np, propname, "#gpio-cells"); } @@ -109,12 +110,12 @@ static inline int of_gpio_named_count(struct device_node *np, const char* propna * * Same as of_gpio_named_count, but hard coded to use the 'gpios' property */ -static inline int of_gpio_count(struct device_node *np) +static inline int of_gpio_count(const struct device_node *np) { return of_gpio_named_count(np, "gpios"); } -static inline int of_get_gpio_flags(struct device_node *np, int index, +static inline int of_get_gpio_flags(const struct device_node *np, int index, enum of_gpio_flags *flags) { return of_get_named_gpio_flags(np, "gpios", index, flags); @@ -129,7 +130,7 @@ static inline int of_get_gpio_flags(struct device_node *np, int index, * Returns GPIO number to use with Linux generic GPIO API, or one of the errno * value on the error condition. */ -static inline int of_get_named_gpio(struct device_node *np, +static inline int of_get_named_gpio(const struct device_node *np, const char *propname, int index) { return of_get_named_gpio_flags(np, propname, index, NULL); @@ -143,7 +144,7 @@ static inline int of_get_named_gpio(struct device_node *np, * Returns GPIO number to use with Linux generic GPIO API, or one of the errno * value on the error condition. */ -static inline int of_get_gpio(struct device_node *np, int index) +static inline int of_get_gpio(const struct device_node *np, int index) { return of_get_gpio_flags(np, index, NULL); } -- cgit v1.2.3-70-g09d2 From 8990899d84d7f46c0c1cd3f41135707b26d0eeaa Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 28 Jul 2021 16:42:29 +0200 Subject: gpiolib: of: constify few local device_node variables gpiolib does not modify struct device_node, so few local pointers can point to a const data. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 1e5a6f63b2fe..0ad288ab6262 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -122,7 +122,7 @@ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip, bool of_gpio_need_valid_mask(const struct gpio_chip *gc) { int size; - struct device_node *np = gc->of_node; + const struct device_node *np = gc->of_node; size = of_property_count_u32_elems(np, "gpio-reserved-ranges"); if (size > 0 && size % 2 == 0) @@ -373,7 +373,7 @@ static struct gpio_desc *of_find_spi_gpio(struct device *dev, const char *con_id enum of_gpio_flags *of_flags) { char prop_name[32]; /* 32 is max size of property name */ - struct device_node *np = dev->of_node; + const struct device_node *np = dev->of_node; struct gpio_desc *desc; /* @@ -404,7 +404,7 @@ static struct gpio_desc *of_find_spi_cs_gpio(struct device *dev, unsigned int idx, unsigned long *flags) { - struct device_node *np = dev->of_node; + const struct device_node *np = dev->of_node; if (!IS_ENABLED(CONFIG_SPI_MASTER)) return ERR_PTR(-ENOENT); @@ -440,7 +440,7 @@ static struct gpio_desc *of_find_regulator_gpio(struct device *dev, const char * "wlf,ldo1ena", /* WM8994 */ "wlf,ldo2ena", /* WM8994 */ }; - struct device_node *np = dev->of_node; + const struct device_node *np = dev->of_node; struct gpio_desc *desc; int i; -- cgit v1.2.3-70-g09d2 From 2606e7c9f5fce1d6c8a75c20947049b63c1b8333 Mon Sep 17 00:00:00 2001 From: Akhil R Date: Mon, 19 Jul 2021 10:16:41 +0530 Subject: gpio: tegra186: Add ACPI support Add ACPI module ID to probe the driver from the ACPI based bootloader firmware. Signed-off-by: Akhil R Reviewed-by: Andy Shevchenko Reviewed-by: Jon Hunter Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-tegra186.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index d38980b9923a..046b7c8b15d1 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -610,15 +610,21 @@ static int tegra186_gpio_probe(struct platform_device *pdev) if (!gpio) return -ENOMEM; - gpio->soc = of_device_get_match_data(&pdev->dev); + gpio->soc = device_get_match_data(&pdev->dev); gpio->secure = devm_platform_ioremap_resource_byname(pdev, "security"); - if (IS_ERR(gpio->secure)) - return PTR_ERR(gpio->secure); + if (IS_ERR(gpio->secure)) { + gpio->secure = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(gpio->secure)) + return PTR_ERR(gpio->secure); + } gpio->base = devm_platform_ioremap_resource_byname(pdev, "gpio"); - if (IS_ERR(gpio->base)) - return PTR_ERR(gpio->base); + if (IS_ERR(gpio->base)) { + gpio->base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); + } err = platform_irq_count(pdev); if (err < 0) @@ -680,11 +686,13 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->gpio.names = (const char * const *)names; +#if defined(CONFIG_OF_GPIO) gpio->gpio.of_node = pdev->dev.of_node; gpio->gpio.of_gpio_n_cells = 2; gpio->gpio.of_xlate = tegra186_gpio_of_xlate; +#endif /* CONFIG_OF_GPIO */ - gpio->intc.name = pdev->dev.of_node->name; + gpio->intc.name = dev_name(&pdev->dev); gpio->intc.irq_ack = tegra186_irq_ack; gpio->intc.irq_mask = tegra186_irq_mask; gpio->intc.irq_unmask = tegra186_irq_unmask; @@ -896,10 +904,20 @@ static const struct of_device_id tegra186_gpio_of_match[] = { }; MODULE_DEVICE_TABLE(of, tegra186_gpio_of_match); +static const struct acpi_device_id tegra186_gpio_acpi_match[] = { + { .id = "NVDA0108", .driver_data = (kernel_ulong_t)&tegra186_main_soc }, + { .id = "NVDA0208", .driver_data = (kernel_ulong_t)&tegra186_aon_soc }, + { .id = "NVDA0308", .driver_data = (kernel_ulong_t)&tegra194_main_soc }, + { .id = "NVDA0408", .driver_data = (kernel_ulong_t)&tegra194_aon_soc }, + {} +}; +MODULE_DEVICE_TABLE(acpi, tegra186_gpio_acpi_match); + static struct platform_driver tegra186_gpio_driver = { .driver = { .name = "tegra186-gpio", .of_match_table = tegra186_gpio_of_match, + .acpi_match_table = tegra186_gpio_acpi_match, }, .probe = tegra186_gpio_probe, }; -- cgit v1.2.3-70-g09d2 From e9a13babd69f0ed2ac70b6fbee515afe88397b49 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Jul 2021 12:00:09 +0200 Subject: MAINTAINERS: update gpio-zynq.yaml reference Changeset 45ca16072b70 ("dt-bindings: gpio: zynq: convert bindings to YAML") renamed: Documentation/devicetree/bindings/gpio/gpio-zynq.txt to: Documentation/devicetree/bindings/gpio/gpio-zynq.yaml. Update its cross-reference accordingly. Fixes: 45ca16072b70 ("dt-bindings: gpio: zynq: convert bindings to YAML") Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Bartosz Golaszewski --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..6ffb5cbbeb93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20323,7 +20323,7 @@ R: Srinivas Neeli R: Michal Simek S: Maintained F: Documentation/devicetree/bindings/gpio/gpio-xilinx.txt -F: Documentation/devicetree/bindings/gpio/gpio-zynq.txt +F: Documentation/devicetree/bindings/gpio/gpio-zynq.yaml F: drivers/gpio/gpio-xilinx.c F: drivers/gpio/gpio-zynq.c -- cgit v1.2.3-70-g09d2 From 4b10651864429386ae931167d3518f37a8c762e0 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 6 Aug 2021 08:05:58 +0800 Subject: f2fs: avoid unneeded memory allocation in __add_ino_entry() __add_ino_entry() will allocate slab cache even if we have already cached ino entry in radix tree, e.g. for case of multiple devices. Let's check radix tree first under protection of rcu lock to see whether we need to do slab allocation, it will mitigate memory pressure from "f2fs_ino_entry" slab cache. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/checkpoint.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 7f6745f4630e..5b6ddeae1107 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -465,16 +465,28 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, unsigned int devidx, int type) { struct inode_management *im = &sbi->im[type]; - struct ino_entry *e, *tmp; + struct ino_entry *e = NULL, *new = NULL; + + if (type == FLUSH_INO) { + rcu_read_lock(); + e = radix_tree_lookup(&im->ino_root, ino); + rcu_read_unlock(); + } - tmp = f2fs_kmem_cache_alloc(ino_entry_slab, GFP_NOFS); +retry: + if (!e) + new = f2fs_kmem_cache_alloc(ino_entry_slab, GFP_NOFS); radix_tree_preload(GFP_NOFS | __GFP_NOFAIL); spin_lock(&im->ino_lock); e = radix_tree_lookup(&im->ino_root, ino); if (!e) { - e = tmp; + if (!new) { + spin_unlock(&im->ino_lock); + goto retry; + } + e = new; if (unlikely(radix_tree_insert(&im->ino_root, ino, e))) f2fs_bug_on(sbi, 1); @@ -492,8 +504,8 @@ static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, spin_unlock(&im->ino_lock); radix_tree_preload_end(); - if (e != tmp) - kmem_cache_free(ino_entry_slab, tmp); + if (new && e != new) + kmem_cache_free(ino_entry_slab, new); } static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) -- cgit v1.2.3-70-g09d2 From 65ddf6564843890a58ee3b18bb46ce67d96333fb Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Fri, 6 Aug 2021 08:04:37 +0800 Subject: f2fs: fix to do sanity check for sb/cp fields correctly This patch fixes below problems of sb/cp sanity check: - in sanity_check_raw_superi(), it missed to consider log header blocks while cp_payload check. - in f2fs_sanity_check_ckpt(), it missed to check nat_bits_blocks. Cc: Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- fs/f2fs/super.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 84cd085020cd..9e0e3c998142 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3264,11 +3264,13 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, return -EFSCORRUPTED; } - if (le32_to_cpu(raw_super->cp_payload) > - (blocks_per_seg - F2FS_CP_PACKS)) { - f2fs_info(sbi, "Insane cp_payload (%u > %u)", + if (le32_to_cpu(raw_super->cp_payload) >= + (blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_PERSIST_TYPE)) { + f2fs_info(sbi, "Insane cp_payload (%u >= %u)", le32_to_cpu(raw_super->cp_payload), - blocks_per_seg - F2FS_CP_PACKS); + blocks_per_seg - F2FS_CP_PACKS - + NR_CURSEG_PERSIST_TYPE); return -EFSCORRUPTED; } @@ -3304,6 +3306,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) unsigned int cp_pack_start_sum, cp_payload; block_t user_block_count, valid_user_blocks; block_t avail_node_count, valid_node_count; + unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks; int i, j; total = le32_to_cpu(raw_super->segment_count); @@ -3434,6 +3437,17 @@ skip_cross: return 1; } + nat_blocks = nat_segs << log_blocks_per_seg; + nat_bits_bytes = nat_blocks / BITS_PER_BYTE; + nat_bits_blocks = F2FS_BLK_ALIGN((nat_bits_bytes << 1) + 8); + if (__is_set_ckpt_flags(ckpt, CP_NAT_BITS_FLAG) && + (cp_payload + F2FS_CP_PACKS + + NR_CURSEG_PERSIST_TYPE + nat_bits_blocks >= blocks_per_seg)) { + f2fs_warn(sbi, "Insane cp_payload: %u, nat_bits_blocks: %u)", + cp_payload, nat_bits_blocks); + return -EFSCORRUPTED; + } + if (unlikely(f2fs_cp_error(sbi))) { f2fs_err(sbi, "A bug case: need to run fsck"); return 1; -- cgit v1.2.3-70-g09d2 From edfa378448b566f705f5e81fd1565dc39ef6b716 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 14 Jul 2021 12:17:36 +0200 Subject: clk: Align provider-specific CLK_* bit definitions The definition of CLK_MULTIPLIER_ROUND_CLOSEST is not aligned to the two bit definitions next to it. A deeper inspection reveals that the alignment of CLK_MULTIPLIER_ROUND_CLOSEST does match the most common alignment. Align the bit definitions for the various provider types throughout the file at 40 columns, to increase uniformity. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/5468cd9e50cda8fc59cb6baab9413c6c0de1a974.1626257689.git.geert+renesas@glider.be Signed-off-by: Stephen Boyd --- include/linux/clk-provider.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index d83b829305c0..7be81d5fcf8c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -342,7 +342,7 @@ struct clk_fixed_rate { unsigned long flags; }; -#define CLK_FIXED_RATE_PARENT_ACCURACY BIT(0) +#define CLK_FIXED_RATE_PARENT_ACCURACY BIT(0) extern const struct clk_ops clk_fixed_rate_ops; struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev, @@ -1020,8 +1020,8 @@ struct clk_fractional_divider { #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) -#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) -#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1) +#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) +#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1) extern const struct clk_ops clk_fractional_divider_ops; struct clk *clk_register_fractional_divider(struct device *dev, @@ -1069,9 +1069,9 @@ struct clk_multiplier { #define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) -#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) +#define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) #define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) -#define CLK_MULTIPLIER_BIG_ENDIAN BIT(2) +#define CLK_MULTIPLIER_BIG_ENDIAN BIT(2) extern const struct clk_ops clk_multiplier_ops; -- cgit v1.2.3-70-g09d2 From 28fc39f7abecaed2f4633cd5fd3775b8031dffde Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Sat, 31 Jul 2021 21:22:26 +0800 Subject: clk: palmas: Add a missing SPDX license header Add the missing SPDX license header to drivers/clk/clk-palmas.c. Signed-off-by: Jason Wang Link: https://lore.kernel.org/r/20210731132226.424853-1-wangborong@cdjrlc.com [sboyd@kernel.org: Also remove boilerplate from comment] Signed-off-by: Stephen Boyd --- drivers/clk/clk-palmas.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index e41a3a9f7528..b8c3d0da1918 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Clock driver for Palmas device. * @@ -6,15 +7,6 @@ * * Author: Laxman Dewangan * Peter Ujfalusi - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include -- cgit v1.2.3-70-g09d2 From 69a00fb3d6970681c15a23595ec54233ce10295c Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 3 Jul 2021 00:51:40 +0200 Subject: clk: divider: Implement and wire up .determine_rate by default .determine_rate is meant to replace .round_rate. The former comes with a benefit which is especially relevant on 32-bit systems: since .determine_rate uses an "unsigned long" (compared to a "signed long" which is used by .round_rate) the maximum value on 32-bit systems increases from 2^31 (or approx. 2.14GHz) to 2^32 (or approx. 4.29GHz). Implement .determine_rate in addition to .round_rate so drivers that are using clk_divider_{ro_,}ops can benefit from this by default. Keep the .round_rate callback for now since some drivers rely on clk_divider_ops.round_rate being implemented. Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20210702225145.2643303-2-martin.blumenstingl@googlemail.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-divider.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 87ba4966b0e8..f6b2bf558486 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -446,6 +446,27 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, divider->width, divider->flags); } +static int clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + val = clk_div_readl(divider) >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, + divider->flags, val); + } + + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); +} + int divider_get_val(unsigned long rate, unsigned long parent_rate, const struct clk_div_table *table, u8 width, unsigned long flags) @@ -501,6 +522,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, const struct clk_ops clk_divider_ops = { .recalc_rate = clk_divider_recalc_rate, .round_rate = clk_divider_round_rate, + .determine_rate = clk_divider_determine_rate, .set_rate = clk_divider_set_rate, }; EXPORT_SYMBOL_GPL(clk_divider_ops); @@ -508,6 +530,7 @@ EXPORT_SYMBOL_GPL(clk_divider_ops); const struct clk_ops clk_divider_ro_ops = { .recalc_rate = clk_divider_recalc_rate, .round_rate = clk_divider_round_rate, + .determine_rate = clk_divider_determine_rate, }; EXPORT_SYMBOL_GPL(clk_divider_ro_ops); -- cgit v1.2.3-70-g09d2 From 699470f372bbd9d087fd30444b126729a38217ac Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 3 Jul 2021 00:51:42 +0200 Subject: clk: bcm2835: Switch to clk_divider.determine_rate .determine_rate is meant to replace .round_rate in CCF in the future. Switch over to .determine_rate now that clk_divider_ops has gained support for that. Cc: Marek Szyprowski Cc: Nicolas Saenz Julienne Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-rpi-kernel@lists.infradead.org Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20210702225145.2643303-4-martin.blumenstingl@googlemail.com Tested-by: Marek Szyprowski Signed-off-by: Stephen Boyd --- drivers/clk/bcm/clk-bcm2835.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 1ac803e14fa3..a254512965eb 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -805,11 +805,10 @@ static int bcm2835_pll_divider_is_on(struct clk_hw *hw) return !(cprman_read(cprman, data->a2w_reg) & A2W_PLL_CHANNEL_DISABLE); } -static long bcm2835_pll_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +static int bcm2835_pll_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clk_divider_ops.round_rate(hw, rate, parent_rate); + return clk_divider_ops.determine_rate(hw, req); } static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw, @@ -901,7 +900,7 @@ static const struct clk_ops bcm2835_pll_divider_clk_ops = { .unprepare = bcm2835_pll_divider_off, .recalc_rate = bcm2835_pll_divider_get_rate, .set_rate = bcm2835_pll_divider_set_rate, - .round_rate = bcm2835_pll_divider_round_rate, + .determine_rate = bcm2835_pll_divider_determine_rate, .debug_init = bcm2835_pll_divider_debug_init, }; -- cgit v1.2.3-70-g09d2 From d1e40bc9ff0527bfceed1caa6c1a7a1e2013d7e5 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 3 Jul 2021 00:51:43 +0200 Subject: clk: stm32f4: Switch to clk_divider.determine_rate .determine_rate is meant to replace .round_rate in CCF in the future. Switch over to .determine_rate now that clk_divider_ops has gained support for that. Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20210702225145.2643303-5-martin.blumenstingl@googlemail.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-stm32f4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 18117ce5ff85..22267fb3e92e 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -709,10 +709,10 @@ static unsigned long stm32f4_pll_div_recalc_rate(struct clk_hw *hw, return clk_divider_ops.recalc_rate(hw, parent_rate); } -static long stm32f4_pll_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int stm32f4_pll_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clk_divider_ops.round_rate(hw, rate, prate); + return clk_divider_ops.determine_rate(hw, req); } static int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -738,7 +738,7 @@ static int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops stm32f4_pll_div_ops = { .recalc_rate = stm32f4_pll_div_recalc_rate, - .round_rate = stm32f4_pll_div_round_rate, + .determine_rate = stm32f4_pll_div_determine_rate, .set_rate = stm32f4_pll_div_set_rate, }; -- cgit v1.2.3-70-g09d2 From f9d6b4832ca8a7e00718ad6cabe7371649be4ae9 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 3 Jul 2021 00:51:44 +0200 Subject: clk: stm32h7: Switch to clk_divider.determine_rate .determine_rate is meant to replace .round_rate in CCF in the future. Switch over to .determine_rate now that clk_divider_ops has gained support for that. Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20210702225145.2643303-6-martin.blumenstingl@googlemail.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-stm32h7.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c index 0ea7261d15e0..1a701eada0c1 100644 --- a/drivers/clk/clk-stm32h7.c +++ b/drivers/clk/clk-stm32h7.c @@ -845,10 +845,10 @@ static unsigned long odf_divider_recalc_rate(struct clk_hw *hw, return clk_divider_ops.recalc_rate(hw, parent_rate); } -static long odf_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int odf_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clk_divider_ops.round_rate(hw, rate, prate); + return clk_divider_ops.determine_rate(hw, req); } static int odf_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -875,7 +875,7 @@ static int odf_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops odf_divider_ops = { .recalc_rate = odf_divider_recalc_rate, - .round_rate = odf_divider_round_rate, + .determine_rate = odf_divider_determine_rate, .set_rate = odf_divider_set_rate, }; -- cgit v1.2.3-70-g09d2 From 23a57ee7af01a51cf5e8568f3410dd493ecb8d3d Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 3 Jul 2021 00:51:45 +0200 Subject: clk: stm32mp1: Switch to clk_divider.determine_rate .determine_rate is meant to replace .round_rate in CCF in the future. Switch over to .determine_rate now that clk_divider_ops has gained support for that. Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Signed-off-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20210702225145.2643303-7-martin.blumenstingl@googlemail.com Signed-off-by: Stephen Boyd --- drivers/clk/clk-stm32mp1.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 256575bd29b9..4bd1fe7d8af4 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -1076,14 +1076,10 @@ static int clk_divider_rtc_set_rate(struct clk_hw *hw, unsigned long rate, static int clk_divider_rtc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - unsigned long best_parent_rate = req->best_parent_rate; + if (req->best_parent_hw == clk_hw_get_parent_by_index(hw, HSE_RTC)) + return clk_divider_ops.determine_rate(hw, req); - if (req->best_parent_hw == clk_hw_get_parent_by_index(hw, HSE_RTC)) { - req->rate = clk_divider_ops.round_rate(hw, req->rate, &best_parent_rate); - req->best_parent_rate = best_parent_rate; - } else { - req->rate = best_parent_rate; - } + req->rate = req->best_parent_rate; return 0; } -- cgit v1.2.3-70-g09d2 From edeb2ca74716056b2be62925f21494d7af65150f Mon Sep 17 00:00:00 2001 From: Martin Botka Date: Fri, 30 Jul 2021 23:59:24 +0200 Subject: clk: qcom: smd: Add support for SM6125 rpm clocks Add rpm smd clocks, PMIC and bus clocks which are required on SM6125 for clients to vote on. Signed-off-by: Martin Botka Link: https://lore.kernel.org/r/20210730215924.733350-2-martin.botka@somainline.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-smd-rpm.c | 56 ++++++++++++++++++++++++++++++++++++++++ include/linux/soc/qcom/smd-rpm.h | 1 + 2 files changed, 57 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 800b2fef1887..fa5215716465 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -913,6 +913,61 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = { .num_clks = ARRAY_SIZE(sdm660_clks), }; +/* SM6125 */ +DEFINE_CLK_SMD_RPM(sm6125, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); +DEFINE_CLK_SMD_RPM(sm6125, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); +DEFINE_CLK_SMD_RPM_BRANCH(sm6125, qdss_clk, qdss_a_clk, + QCOM_SMD_RPM_MISC_CLK, 1, 19200000); +DEFINE_CLK_SMD_RPM(sm6125, qup_clk, qup_a_clk, QCOM_SMD_RPM_QUP_CLK, 0); +DEFINE_CLK_SMD_RPM(sm6125, mmnrt_clk, mmnrt_a_clk, QCOM_SMD_RPM_MMAXI_CLK, 0); +DEFINE_CLK_SMD_RPM(sm6125, mmrt_clk, mmrt_a_clk, QCOM_SMD_RPM_MMAXI_CLK, 1); +DEFINE_CLK_SMD_RPM(sm6125, snoc_periph_clk, snoc_periph_a_clk, + QCOM_SMD_RPM_BUS_CLK, 0); +DEFINE_CLK_SMD_RPM(sm6125, snoc_lpass_clk, snoc_lpass_a_clk, + QCOM_SMD_RPM_BUS_CLK, 5); + +static struct clk_smd_rpm *sm6125_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, + [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_LN_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3, + [RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a, + [RPM_SMD_QUP_CLK] = &sm6125_qup_clk, + [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk, + [RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk, + [RPM_SMD_MMRT_A_CLK] = &sm6125_mmrt_a_clk, + [RPM_SMD_MMNRT_CLK] = &sm6125_mmnrt_clk, + [RPM_SMD_MMNRT_A_CLK] = &sm6125_mmnrt_a_clk, + [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk, + [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk, + [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk, + [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk, +}; + +static const struct rpm_smd_clk_desc rpm_clk_sm6125 = { + .clks = sm6125_clks, + .num_clks = ARRAY_SIZE(sm6125_clks), +}; + static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, @@ -925,6 +980,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 }, + { .compatible = "qcom,rpmcc-sm6125", .data = &rpm_clk_sm6125 }, { } }; MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table); diff --git a/include/linux/soc/qcom/smd-rpm.h b/include/linux/soc/qcom/smd-rpm.h index f2645ec52520..60e66fc9b6bf 100644 --- a/include/linux/soc/qcom/smd-rpm.h +++ b/include/linux/soc/qcom/smd-rpm.h @@ -29,6 +29,7 @@ struct qcom_smd_rpm; #define QCOM_SMD_RPM_NCPB 0x6270636E #define QCOM_SMD_RPM_OCMEM_PWR 0x706d636f #define QCOM_SMD_RPM_QPIC_CLK 0x63697071 +#define QCOM_SMD_RPM_QUP_CLK 0x707571 #define QCOM_SMD_RPM_SMPA 0x61706d73 #define QCOM_SMD_RPM_SMPB 0x62706d73 #define QCOM_SMD_RPM_SPDM 0x63707362 -- cgit v1.2.3-70-g09d2 From f55f32ee1070bc1d4e6f5d06a97794d3718381a3 Mon Sep 17 00:00:00 2001 From: Iskren Chernev Date: Sat, 31 Jul 2021 19:48:26 +0300 Subject: clk: qcom: smd: Add support for SM6115 rpm clocks Add rpm smd clocks, PMIC and bus clocks which are required on SM4250/6115 for clients to vote on. Signed-off-by: Iskren Chernev Link: https://lore.kernel.org/r/20210731164827.2756798-2-iskren.chernev@gmail.com [sboyd@kernel.org: Drop duplicate define, merge with sm6125 support] Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-smd-rpm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index fa5215716465..7390f5191c98 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -968,6 +968,47 @@ static const struct rpm_smd_clk_desc rpm_clk_sm6125 = { .num_clks = ARRAY_SIZE(sm6125_clks), }; +/* SM6115 */ +static struct clk_smd_rpm *sm6115_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, + [RPM_SMD_SNOC_CLK] = &sm6125_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &sm6125_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_QDSS_CLK] = &sm6125_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &sm6125_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_CNOC_CLK] = &sm6125_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &sm6125_cnoc_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_QUP_CLK] = &sm6125_qup_clk, + [RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk, + [RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk, + [RPM_SMD_MMRT_A_CLK] = &sm6125_mmrt_a_clk, + [RPM_SMD_MMNRT_CLK] = &sm6125_mmnrt_clk, + [RPM_SMD_MMNRT_A_CLK] = &sm6125_mmnrt_a_clk, + [RPM_SMD_SNOC_PERIPH_CLK] = &sm6125_snoc_periph_clk, + [RPM_SMD_SNOC_PERIPH_A_CLK] = &sm6125_snoc_periph_a_clk, + [RPM_SMD_SNOC_LPASS_CLK] = &sm6125_snoc_lpass_clk, + [RPM_SMD_SNOC_LPASS_A_CLK] = &sm6125_snoc_lpass_a_clk, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_sm6115 = { + .clks = sm6115_clks, + .num_clks = ARRAY_SIZE(sm6115_clks), +}; + static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, @@ -980,6 +1021,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 }, + { .compatible = "qcom,rpmcc-sm6115", .data = &rpm_clk_sm6115 }, { .compatible = "qcom,rpmcc-sm6125", .data = &rpm_clk_sm6125 }, { } }; -- cgit v1.2.3-70-g09d2 From 00555272dcdae71e96de08c924c4fef6b47d7e5b Mon Sep 17 00:00:00 2001 From: Vladimir Lypak Date: Thu, 5 Aug 2021 17:19:29 +0000 Subject: dt-bindings: clock: qcom-rpmcc: Add compatible for MSM8953 SoC Add compatible for MSM8953 SoC. Signed-off-by: Vladimir Lypak Signed-off-by: Sireesh Kodali Link: https://lore.kernel.org/r/c662hoLme5MIdelk5BVPsVgN77IqTLS0KwYwpauJiDs@cp3-web-047.plabs.ch Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt index 0e92747e53da..bffd2acdbb66 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt @@ -15,6 +15,7 @@ Required properties : "qcom,rpmcc-msm8226", "qcom,rpmcc" "qcom,rpmcc-msm8916", "qcom,rpmcc" "qcom,rpmcc-msm8936", "qcom,rpmcc" + "qcom,rpmcc-msm8953", "qcom,rpmcc" "qcom,rpmcc-msm8974", "qcom,rpmcc" "qcom,rpmcc-msm8976", "qcom,rpmcc" "qcom,rpmcc-apq8064", "qcom,rpmcc" -- cgit v1.2.3-70-g09d2 From 9c5376856693bf127b7d313e03ed030451064d05 Mon Sep 17 00:00:00 2001 From: Vladimir Lypak Date: Thu, 5 Aug 2021 17:19:44 +0000 Subject: clk: qcom: rpmcc: Add support for MSM8953 RPM clocks. Add definitions for RPM clocks used on MSM8953 platform. Signed-off-by: Vladimir Lypak Signed-off-by: Adam Skladowski Reviewed-by: Konrad Dybcio Signed-off-by: Sireesh Kodali Link: https://lore.kernel.org/r/QZ0fkozlubDdc7CvqjZPhAviFmjJ28ht7Y4PT3rYM@cp4-web-038.plabs.ch Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-smd-rpm.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 7390f5191c98..fbf4bc7de791 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -913,6 +913,42 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = { .num_clks = ARRAY_SIZE(sdm660_clks), }; +static struct clk_smd_rpm *msm8953_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_SYSMMNOC_CLK] = &msm8936_sysmmnoc_clk, + [RPM_SMD_SYSMMNOC_A_CLK] = &msm8936_sysmmnoc_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_RF_CLK3] = &msm8992_ln_bb_clk, + [RPM_SMD_RF_CLK3_A] = &msm8992_ln_bb_a_clk, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_msm8953 = { + .clks = msm8953_clks, + .num_clks = ARRAY_SIZE(msm8953_clks), +}; + /* SM6125 */ DEFINE_CLK_SMD_RPM(sm6125, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(sm6125, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); @@ -1013,6 +1049,7 @@ static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 }, + { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 }, { .compatible = "qcom,rpmcc-msm8992", .data = &rpm_clk_msm8992 }, -- cgit v1.2.3-70-g09d2 From c45e13fa3851e825c279c2cb0b7f6961f36f1095 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 6 Aug 2021 00:23:59 +0200 Subject: dt-bindings: clock: qcom: rpmcc: Document MDM9607 compatible Add the dt-binding for the RPM Clock Controller on the MDM9607 SoC. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210805222400.39027-1-konrad.dybcio@somainline.org Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,rpmcc.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt index bffd2acdbb66..a4877881f1d8 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt @@ -10,6 +10,7 @@ Required properties : - compatible : shall contain only one of the following. The generic compatible "qcom,rpmcc" should be also included. + "qcom,rpmcc-mdm9607", "qcom,rpmcc" "qcom,rpmcc-msm8660", "qcom,rpmcc" "qcom,rpmcc-apq8060", "qcom,rpmcc" "qcom,rpmcc-msm8226", "qcom,rpmcc" -- cgit v1.2.3-70-g09d2 From 48662d988d12fcaa6243e48f3407e8f7b2e5773d Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Fri, 6 Aug 2021 00:24:00 +0200 Subject: clk: qcom: smd-rpm: Add mdm9607 clocks Add support for RPM-managed clocks on the MDM9607 platform. Signed-off-by: Konrad Dybcio Link: https://lore.kernel.org/r/20210805222400.39027-2-konrad.dybcio@somainline.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-smd-rpm.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index fbf4bc7de791..bbc7fbcb6bc9 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -913,6 +913,28 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = { .num_clks = ARRAY_SIZE(sdm660_clks), }; +static struct clk_smd_rpm *mdm9607_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, + [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk, + [RPM_SMD_QPIC_CLK_A] = &qcs404_qpic_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, +}; + +static const struct rpm_smd_clk_desc rpm_clk_mdm9607 = { + .clks = mdm9607_clks, + .num_clks = ARRAY_SIZE(mdm9607_clks), +}; + static struct clk_smd_rpm *msm8953_clks[] = { [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, @@ -1046,6 +1068,7 @@ static const struct rpm_smd_clk_desc rpm_clk_sm6115 = { }; static const struct of_device_id rpm_smd_clk_match_table[] = { + { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 }, { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 }, -- cgit v1.2.3-70-g09d2 From 945cb3a105aef63af1354e0fbe10a0d1ca7a32c2 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 21 Jul 2021 15:53:29 -0700 Subject: clk: qcom: gpucc-sm8150: Add SC8180x support The GPU clock controller found in SC8180x is a variant of the same block found in SM8150, but with one additional clock frequency for the gmu_clk_src clock. Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20210721225329.3035779-1-bjorn.andersson@linaro.org Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,gpucc.yaml | 1 + drivers/clk/qcom/gpucc-sm8150.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml index ecfe21284073..46dff46d5760 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml @@ -26,6 +26,7 @@ properties: - qcom,sdm845-gpucc - qcom,sc7180-gpucc - qcom,sc7280-gpucc + - qcom,sc8180x-gpucc - qcom,sm8150-gpucc - qcom,sm8250-gpucc diff --git a/drivers/clk/qcom/gpucc-sm8150.c b/drivers/clk/qcom/gpucc-sm8150.c index 80fb6f73601d..8422fd047493 100644 --- a/drivers/clk/qcom/gpucc-sm8150.c +++ b/drivers/clk/qcom/gpucc-sm8150.c @@ -82,6 +82,14 @@ static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sc8180x[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + { } +}; + static struct clk_rcg2 gpu_cc_gmu_clk_src = { .cmd_rcgr = 0x1120, .mnd_width = 0, @@ -277,6 +285,7 @@ static const struct qcom_cc_desc gpu_cc_sm8150_desc = { }; static const struct of_device_id gpu_cc_sm8150_match_table[] = { + { .compatible = "qcom,sc8180x-gpucc" }, { .compatible = "qcom,sm8150-gpucc" }, { } }; @@ -290,6 +299,9 @@ static int gpu_cc_sm8150_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8180x-gpucc")) + gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sc8180x; + clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap); -- cgit v1.2.3-70-g09d2 From 0dfe9bf91f9f2993ae73c603571a85e3c6e6fc24 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 4 Jul 2021 10:40:29 +0800 Subject: clk: qcom: apcs-msm8916: Flag a53mux instead of a53pll as critical The clock source for MSM8916 cpu cores is like below. |\ a53pll --------| \ a53mux +------+ | |------------| cpus | gpll0_vote --------| / +------+ |/ So a53mux rather than a53pll is actually the parent clock of cpu cores. It makes more sense to flag a53mux as critical instead, so that when either a53pll or gpll0_vote is used by cpu cores, the clock will be kept enabled while the other can be disabled. Signed-off-by: Shawn Guo Link: https://lore.kernel.org/r/20210704024032.11559-2-shawn.guo@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/a53-pll.c | 1 - drivers/clk/qcom/apcs-msm8916.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c index af6ac17c7dae..d6756bd777ce 100644 --- a/drivers/clk/qcom/a53-pll.c +++ b/drivers/clk/qcom/a53-pll.c @@ -70,7 +70,6 @@ static int qcom_a53pll_probe(struct platform_device *pdev) init.parent_names = (const char *[]){ "xo" }; init.num_parents = 1; init.ops = &clk_pll_sr2_ops; - init.flags = CLK_IS_CRITICAL; pll->clkr.hw.init = &init; ret = devm_clk_register_regmap(dev, &pll->clkr); diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c index cf69a97d0439..d7ac6d6b15b6 100644 --- a/drivers/clk/qcom/apcs-msm8916.c +++ b/drivers/clk/qcom/apcs-msm8916.c @@ -65,7 +65,7 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) init.parent_data = pdata; init.num_parents = ARRAY_SIZE(pdata); init.ops = &clk_regmap_mux_div_ops; - init.flags = CLK_SET_RATE_PARENT; + init.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT; a53cc->clkr.hw.init = &init; a53cc->clkr.regmap = regmap; -- cgit v1.2.3-70-g09d2 From 05cc560c8cb4c2fe39022c1f397125470b28705c Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 4 Jul 2021 10:40:30 +0800 Subject: clk: qcom: a53pll/mux: Use unique clock name Different from MSM8916 which has only one a53pll/mux clock, MSM8939 gets three for Cluster0 (little cores), Cluster1 (big cores) and CCI (Cache Coherent Interconnect). That said, a53pll/mux clock needs to be named uniquely. Append @unit-address of device node to the clock name, so that a53pll/mux will be named like below on MSM8939. a53pll@b016000 a53pll@b116000 a53pll@b1d0000 a53mux@b1d1000 a53mux@b011000 a53mux@b111000 Signed-off-by: Shawn Guo Link: https://lore.kernel.org/r/20210704024032.11559-3-shawn.guo@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/a53-pll.c | 8 +++++++- drivers/clk/qcom/apcs-msm8916.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c index d6756bd777ce..96a118be912d 100644 --- a/drivers/clk/qcom/a53-pll.c +++ b/drivers/clk/qcom/a53-pll.c @@ -37,6 +37,7 @@ static const struct regmap_config a53pll_regmap_config = { static int qcom_a53pll_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct regmap *regmap; struct resource *res; struct clk_pll *pll; @@ -66,7 +67,12 @@ static int qcom_a53pll_probe(struct platform_device *pdev) pll->status_bit = 16; pll->freq_tbl = a53pll_freq; - init.name = "a53pll"; + /* Use an unique name by appending @unit-address */ + init.name = devm_kasprintf(dev, GFP_KERNEL, "a53pll%s", + strchrnul(np->full_name, '@')); + if (!init.name) + return -ENOMEM; + init.parent_names = (const char *[]){ "xo" }; init.num_parents = 1; init.ops = &clk_pll_sr2_ops; diff --git a/drivers/clk/qcom/apcs-msm8916.c b/drivers/clk/qcom/apcs-msm8916.c index d7ac6d6b15b6..89e0730810ac 100644 --- a/drivers/clk/qcom/apcs-msm8916.c +++ b/drivers/clk/qcom/apcs-msm8916.c @@ -46,6 +46,7 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device *parent = dev->parent; + struct device_node *np = parent->of_node; struct clk_regmap_mux_div *a53cc; struct regmap *regmap; struct clk_init_data init = { }; @@ -61,7 +62,12 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev) if (!a53cc) return -ENOMEM; - init.name = "a53mux"; + /* Use an unique name by appending parent's @unit-address */ + init.name = devm_kasprintf(dev, GFP_KERNEL, "a53mux%s", + strchrnul(np->full_name, '@')); + if (!init.name) + return -ENOMEM; + init.parent_data = pdata; init.num_parents = ARRAY_SIZE(pdata); init.ops = &clk_regmap_mux_div_ops; -- cgit v1.2.3-70-g09d2 From f9a6a326f66dfb7d62cef79c6755cc773e5fb8ad Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 4 Jul 2021 10:40:31 +0800 Subject: dt-bindings: clock: Update qcom,a53pll bindings for MSM8939 support Update qcom,a53pll bindings for MSM8939 support: - Add optional operating-points-v2 property - Add MSM8939 specific compatible Signed-off-by: Shawn Guo Link: https://lore.kernel.org/r/20210704024032.11559-4-shawn.guo@linaro.org Acked-by: Rob Herring Signed-off-by: Stephen Boyd --- Documentation/devicetree/bindings/clock/qcom,a53pll.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml index db3d0ea6bc7a..fbd758470b88 100644 --- a/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,a53pll.yaml @@ -18,6 +18,7 @@ properties: enum: - qcom,ipq6018-a53pll - qcom,msm8916-a53pll + - qcom,msm8939-a53pll reg: maxItems: 1 @@ -33,6 +34,8 @@ properties: items: - const: xo + operating-points-v2: true + required: - compatible - reg -- cgit v1.2.3-70-g09d2 From 5d9bc010db0a4f5b17b3f5f982a85c49bb911754 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 4 Jul 2021 10:40:32 +0800 Subject: clk: qcom: a53-pll: Add MSM8939 a53pll support MSM8939 has 3 a53pll clocks with different frequency table for Cluster0, Cluster1 and CCI. It adds function qcom_a53pll_get_freq_tbl() to create pll_freq_tbl from OPP, so that those a53pll frequencies can be defined in DT with operating-points-v2 bindings rather than being coded in the driver. In this case, one compatible rather than three would be needed for these 3 a53pll clocks. Signed-off-by: Shawn Guo Link: https://lore.kernel.org/r/20210704024032.11559-5-shawn.guo@linaro.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/a53-pll.c | 59 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/a53-pll.c b/drivers/clk/qcom/a53-pll.c index 96a118be912d..9e6decb9c26f 100644 --- a/drivers/clk/qcom/a53-pll.c +++ b/drivers/clk/qcom/a53-pll.c @@ -6,9 +6,11 @@ * Author: Georgi Djakov */ +#include #include #include #include +#include #include #include @@ -34,6 +36,55 @@ static const struct regmap_config a53pll_regmap_config = { .fast_io = true, }; +static struct pll_freq_tbl *qcom_a53pll_get_freq_tbl(struct device *dev) +{ + struct pll_freq_tbl *freq_tbl; + unsigned long xo_freq; + unsigned long freq; + struct clk *xo_clk; + int count; + int ret; + int i; + + xo_clk = devm_clk_get(dev, "xo"); + if (IS_ERR(xo_clk)) + return NULL; + + xo_freq = clk_get_rate(xo_clk); + + ret = devm_pm_opp_of_add_table(dev); + if (ret) + return NULL; + + count = dev_pm_opp_get_opp_count(dev); + if (count <= 0) + return NULL; + + freq_tbl = devm_kcalloc(dev, count + 1, sizeof(*freq_tbl), GFP_KERNEL); + if (!freq_tbl) + return NULL; + + for (i = 0, freq = 0; i < count; i++, freq++) { + struct dev_pm_opp *opp; + + opp = dev_pm_opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) + return NULL; + + /* Skip the freq that is not divisible */ + if (freq % xo_freq) + continue; + + freq_tbl[i].freq = freq; + freq_tbl[i].l = freq / xo_freq; + freq_tbl[i].n = 1; + + dev_pm_opp_put(opp); + } + + return freq_tbl; +} + static int qcom_a53pll_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -65,7 +116,12 @@ static int qcom_a53pll_probe(struct platform_device *pdev) pll->mode_reg = 0x00; pll->status_reg = 0x1c; pll->status_bit = 16; - pll->freq_tbl = a53pll_freq; + + pll->freq_tbl = qcom_a53pll_get_freq_tbl(dev); + if (!pll->freq_tbl) { + /* Fall on a53pll_freq if no freq_tbl is found from OPP */ + pll->freq_tbl = a53pll_freq; + } /* Use an unique name by appending @unit-address */ init.name = devm_kasprintf(dev, GFP_KERNEL, "a53pll%s", @@ -96,6 +152,7 @@ static int qcom_a53pll_probe(struct platform_device *pdev) static const struct of_device_id qcom_a53pll_match_table[] = { { .compatible = "qcom,msm8916-a53pll" }, + { .compatible = "qcom,msm8939-a53pll" }, { } }; MODULE_DEVICE_TABLE(of, qcom_a53pll_match_table); -- cgit v1.2.3-70-g09d2 From e3d2612f583ba6e234cb7fe4559132c8f28905f1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 3 Aug 2021 18:56:25 +0300 Subject: scsi: qla2xxx: Fix use after free in debug code The sp->free(sp); call frees "sp" and then the debug code dereferences it on the next line. Swap the order. Link: https://lore.kernel.org/r/20210803155625.GA22735@kili Fixes: 84318a9f01ce ("scsi: qla2xxx: edif: Add send, receive, and accept for auth_els") Reviewed-by: Ewan D. Milne Reviewed-by: Himanshu Madhani Signed-off-by: Dan Carpenter Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 0739f8ad525a..4b5d28d89d69 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -25,12 +25,12 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply; - sp->free(sp); - ql_dbg(ql_dbg_user, sp->vha, 0x7009, "%s: sp hdl %x, result=%x bsg ptr %p\n", __func__, sp->handle, res, bsg_job); + sp->free(sp); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); -- cgit v1.2.3-70-g09d2 From 77d0f07abada8c9aeb54caba879a298a0b94c02a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Aug 2021 14:13:44 +0100 Subject: scsi: qla2xxx: Remove redundant initialization of variable num_cnt The variable num_cnt is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210804131344.112635-1-colin.king@canonical.com Reviewed-by: Himanshu Madhani Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/qla2xxx/qla_edif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index fde410989c03..2db954a7aaf1 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -875,7 +875,7 @@ static int qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) { int32_t rval = 0; - int32_t num_cnt = 1; + int32_t num_cnt; struct fc_bsg_reply *bsg_reply = bsg_job->reply; struct app_pinfo_req app_req; struct app_pinfo_reply *app_reply; -- cgit v1.2.3-70-g09d2 From f0101af435c4640e78c0fa0dbacb443c0f31cfb7 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Mon, 2 Aug 2021 20:08:03 +0200 Subject: scsi: ufs: core: Remove redundant call in ufshcd_add_command_trace() ufshcd_add_cmd_upiu_trace() will be called later anyway. Simplify code by moving if-statement. Link: https://lore.kernel.org/r/20210802180803.100033-1-huobean@gmail.com Reviewed-by: Avri Altman Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 47a5085f16a9..d96409202819 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -369,14 +369,11 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, if (!cmd) return; - if (!trace_ufshcd_command_enabled()) { - /* trace UPIU W/O tracing command */ - ufshcd_add_cmd_upiu_trace(hba, tag, str_t); - return; - } - /* trace UPIU also */ ufshcd_add_cmd_upiu_trace(hba, tag, str_t); + if (!trace_ufshcd_command_enabled()) + return; + opcode = cmd->cmnd[0]; lba = scsi_get_lba(cmd); -- cgit v1.2.3-70-g09d2 From 63522bf3aced0a782b59f0314dbad5cdc8b14c59 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 4 Aug 2021 20:21:27 +0200 Subject: scsi: ufs: core: Add L2P entry swap quirk for Micron UFS For Micron UFS devices the L2P entry need to be byteswapped before sending an HPB READ command to the UFS device. Add the quirk UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ to address this. Link: https://lore.kernel.org/r/20210804182128.458356-2-huobean@gmail.com Reviewed-by: Avri Altman Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs_quirks.h | 6 ++++++ drivers/scsi/ufs/ufshcd.c | 3 ++- drivers/scsi/ufs/ufshpb.c | 15 ++++++++++----- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h index 07f559ac5883..35ec9ea79869 100644 --- a/drivers/scsi/ufs/ufs_quirks.h +++ b/drivers/scsi/ufs/ufs_quirks.h @@ -116,4 +116,10 @@ struct ufs_dev_fix { */ #define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) +/* + * Some UFS devices require L2P entry should be swapped before being sent to the + * UFS device for HPB READ command. + */ +#define UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ (1 << 12) + #endif /* UFS_QUIRKS_H_ */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d96409202819..6c263e94144b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -199,7 +199,8 @@ ufs_get_desired_pm_lvl_for_dev_link_state(enum ufs_dev_pwr_mode dev_state, static struct ufs_dev_fix ufs_fixups[] = { /* UFS cards deviations table */ UFS_FIX(UFS_VENDOR_MICRON, UFS_ANY_MODEL, - UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), + UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | + UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ), UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE | diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 54e8e019bdbe..d0eb14be47a3 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -323,15 +323,19 @@ ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx, } static void -ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, - u32 lpn, __be64 ppn, u8 transfer_len, int read_id) +ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshpb_lu *hpb, + struct ufshcd_lrb *lrbp, u32 lpn, __be64 ppn, + u8 transfer_len, int read_id) { unsigned char *cdb = lrbp->cmd->cmnd; - + __be64 ppn_tmp = ppn; cdb[0] = UFSHPB_READ; + if (hba->dev_quirks & UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ) + ppn_tmp = swab64(ppn); + /* ppn value is stored as big-endian in the host memory */ - memcpy(&cdb[6], &ppn, sizeof(__be64)); + memcpy(&cdb[6], &ppn_tmp, sizeof(__be64)); cdb[14] = transfer_len; cdb[15] = read_id; @@ -689,7 +693,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) } } - ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len, read_id); + ufshpb_set_hpb_read_to_upiu(hba, hpb, lrbp, lpn, ppn, transfer_len, + read_id); hpb->stats.hit_cnt++; return 0; -- cgit v1.2.3-70-g09d2 From f5efd4fe78de871515444b660029074be17ec11f Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 4 Aug 2021 20:21:28 +0200 Subject: scsi: ufs: core: Add lu_enable sysfs node We need to check whether HPB is enabled on a given LU from the userspace tool. Add lu_enable sysfs node. Link: https://lore.kernel.org/r/20210804182128.458356-3-huobean@gmail.com Tested-by: Avri Altman Reviewed-by: Avri Altman Signed-off-by: Bean Huo Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 08fe037069bc..5c405ff7b6ea 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -1163,6 +1163,7 @@ static DEVICE_ATTR_RO(_pname) #define UFS_UNIT_DESC_PARAM(_name, _uname, _size) \ UFS_LUN_DESC_PARAM(_name, _uname, UNIT, _size) +UFS_UNIT_DESC_PARAM(lu_enable, _LU_ENABLE, 1); UFS_UNIT_DESC_PARAM(boot_lun_id, _BOOT_LUN_ID, 1); UFS_UNIT_DESC_PARAM(lun_write_protect, _LU_WR_PROTECT, 1); UFS_UNIT_DESC_PARAM(lun_queue_depth, _LU_Q_DEPTH, 1); @@ -1181,8 +1182,8 @@ UFS_UNIT_DESC_PARAM(hpb_pinned_region_start_offset, _HPB_PIN_RGN_START_OFF, 2); UFS_UNIT_DESC_PARAM(hpb_number_pinned_regions, _HPB_NUM_PIN_RGNS, 2); UFS_UNIT_DESC_PARAM(wb_buf_alloc_units, _WB_BUF_ALLOC_UNITS, 4); - static struct attribute *ufs_sysfs_unit_descriptor[] = { + &dev_attr_lu_enable.attr, &dev_attr_boot_lun_id.attr, &dev_attr_lun_write_protect.attr, &dev_attr_lun_queue_depth.attr, -- cgit v1.2.3-70-g09d2 From dae68c6b9620ab694c8334de640c6d64daeb90e2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 4 Aug 2021 12:41:29 +0200 Subject: rtc: s5m: switch to devm_rtc_allocate_device Switch to devm_rtc_allocate_device/devm_rtc_register_device, this allows for further improvement of the driver. Signed-off-by: Alexandre Belloni Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20210804104133.5158-1-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-s5m.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 6b56f8eacba6..4c1596c55de8 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -788,12 +788,16 @@ static int s5m_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc", - &s5m_rtc_ops, THIS_MODULE); - + info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(info->rtc_dev)) return PTR_ERR(info->rtc_dev); + info->rtc_dev->ops = &s5m_rtc_ops; + + err = devm_rtc_register_device(info->rtc_dev); + if (err) + return err; + if (!info->irq) { dev_info(&pdev->dev, "Alarm IRQ not available\n"); return 0; -- cgit v1.2.3-70-g09d2 From 1ed4dba2bc166bae5af713a114ed91619ef70c43 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 4 Aug 2021 12:41:30 +0200 Subject: rtc: s5m: signal the core when alarm are not available Clear the RTC_FEATURE_ALARM bit to signal to the core when alarms are not available to ensure the alarm callbacks are never called and userspace is aware alarms are not supported. Signed-off-by: Alexandre Belloni Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20210804104133.5158-2-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-s5m.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 4c1596c55de8..ee195697e6c6 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -794,25 +794,20 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->rtc_dev->ops = &s5m_rtc_ops; - err = devm_rtc_register_device(info->rtc_dev); - if (err) - return err; - if (!info->irq) { - dev_info(&pdev->dev, "Alarm IRQ not available\n"); - return 0; - } - - ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, - s5m_rtc_alarm_irq, 0, "rtc-alarm0", - info); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", - info->irq, ret); - return ret; + clear_bit(RTC_FEATURE_ALARM, info->rtc_dev->features); + } else { + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, + s5m_rtc_alarm_irq, 0, "rtc-alarm0", + info); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + info->irq, ret); + return ret; + } } - return 0; + return devm_rtc_register_device(info->rtc_dev); } #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3-70-g09d2 From 308247d20464a684f335001f2f835240e67f9126 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 4 Aug 2021 12:41:31 +0200 Subject: rtc: s5m: enable wakeup only when available Call device_init_wakeup() only when alarms are available and the RTC is actually able to wake up the system. Signed-off-by: Alexandre Belloni Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20210804104133.5158-3-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-s5m.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index ee195697e6c6..87df797758fc 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -786,8 +786,6 @@ static int s5m_rtc_probe(struct platform_device *pdev) if (ret) return ret; - device_init_wakeup(&pdev->dev, 1); - info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(info->rtc_dev)) return PTR_ERR(info->rtc_dev); @@ -805,6 +803,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->irq, ret); return ret; } + device_init_wakeup(&pdev->dev, 1); } return devm_rtc_register_device(info->rtc_dev); -- cgit v1.2.3-70-g09d2 From fffd603ae9f6ee1da47fa4ae4c70c324323bc201 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 4 Aug 2021 12:41:32 +0200 Subject: rtc: s5m: set range The S5M8763X type seems to handles dates from year 0000 to 9999, there is no info on leap year handling after 2099. The other models handles dates from 2000 to 2099. Signed-off-by: Alexandre Belloni Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20210804104133.5158-4-alexandre.belloni@bootlin.com --- drivers/rtc/rtc-s5m.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 87df797758fc..fb9c6b709e13 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -204,15 +204,9 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_WEEKDAY] = 1 << tm->tm_wday; data[RTC_DATE] = tm->tm_mday; data[RTC_MONTH] = tm->tm_mon + 1; - data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; + data[RTC_YEAR1] = tm->tm_year - 100; - if (tm->tm_year < 100) { - pr_err("RTC cannot handle the year %d\n", - 1900 + tm->tm_year); - return -EINVAL; - } else { - return 0; - } + return 0; } /* @@ -792,6 +786,14 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->rtc_dev->ops = &s5m_rtc_ops; + if (info->device_type == S5M8763X) { + info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000; + info->rtc_dev->range_max = RTC_TIMESTAMP_END_9999; + } else { + info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; + info->rtc_dev->range_max = RTC_TIMESTAMP_END_2099; + } + if (!info->irq) { clear_bit(RTC_FEATURE_ALARM, info->rtc_dev->features); } else { -- cgit v1.2.3-70-g09d2 From 87689270b10fa9e6fac7242233b355cb6792b845 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:38 +0000 Subject: KVM: Rename lru_slot to last_used_slot lru_slot is used to keep track of the index of the most-recently used memslot. The correct acronym would be "mru" but that is not a common acronym. So call it last_used_slot which is a bit more obvious. Suggested-by: Paolo Bonzini Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-2-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/s390/kvm/kvm-s390.c | 4 ++-- include/linux/kvm_host.h | 6 +++--- virt/kvm/kvm_main.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 4527ac7b5961..02574d7b3612 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1953,7 +1953,7 @@ out: static int gfn_to_memslot_approx(struct kvm_memslots *slots, gfn_t gfn) { int start = 0, end = slots->used_slots; - int slot = atomic_read(&slots->lru_slot); + int slot = atomic_read(&slots->last_used_slot); struct kvm_memory_slot *memslots = slots->memslots; if (gfn >= memslots[slot].base_gfn && @@ -1974,7 +1974,7 @@ static int gfn_to_memslot_approx(struct kvm_memslots *slots, gfn_t gfn) if (gfn >= memslots[start].base_gfn && gfn < memslots[start].base_gfn + memslots[start].npages) { - atomic_set(&slots->lru_slot, start); + atomic_set(&slots->last_used_slot, start); } return start; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 5b6a69caccb5..bdfd5ed539c9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -522,7 +522,7 @@ struct kvm_memslots { u64 generation; /* The mapping table from slot id to the index in memslots[]. */ short id_to_index[KVM_MEM_SLOTS_NUM]; - atomic_t lru_slot; + atomic_t last_used_slot; int used_slots; struct kvm_memory_slot memslots[]; }; @@ -1200,7 +1200,7 @@ static inline struct kvm_memory_slot * search_memslots(struct kvm_memslots *slots, gfn_t gfn) { int start = 0, end = slots->used_slots; - int slot = atomic_read(&slots->lru_slot); + int slot = atomic_read(&slots->last_used_slot); struct kvm_memory_slot *memslots = slots->memslots; if (unlikely(!slots->used_slots)) @@ -1221,7 +1221,7 @@ search_memslots(struct kvm_memslots *slots, gfn_t gfn) if (start < slots->used_slots && gfn >= memslots[start].base_gfn && gfn < memslots[start].base_gfn + memslots[start].npages) { - atomic_set(&slots->lru_slot, start); + atomic_set(&slots->last_used_slot, start); return &memslots[start]; } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 930aeb8d3c3e..1984c7389787 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1224,8 +1224,8 @@ static inline void kvm_memslot_delete(struct kvm_memslots *slots, slots->used_slots--; - if (atomic_read(&slots->lru_slot) >= slots->used_slots) - atomic_set(&slots->lru_slot, 0); + if (atomic_read(&slots->last_used_slot) >= slots->used_slots) + atomic_set(&slots->last_used_slot, 0); for (i = slots->id_to_index[memslot->id]; i < slots->used_slots; i++) { mslots[i] = mslots[i + 1]; -- cgit v1.2.3-70-g09d2 From 0f22af940dc8ec4f437189096a5f8677995323b0 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:39 +0000 Subject: KVM: Move last_used_slot logic out of search_memslots Make search_memslots unconditionally search all memslots and move the last_used_slot logic up one level to __gfn_to_memslot. This is in preparation for introducing a per-vCPU last_used_slot. As part of this change convert existing callers of search_memslots to __gfn_to_memslot to avoid making any functional changes. Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-3-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/powerpc/kvm/book3s_64_vio.c | 2 +- arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +- include/linux/kvm_host.h | 64 +++++++++++++++++++++++++++---------- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 8da93fdfa59e..6365087f3160 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -346,7 +346,7 @@ static long kvmppc_tce_to_ua(struct kvm *kvm, unsigned long tce, unsigned long gfn = tce >> PAGE_SHIFT; struct kvm_memory_slot *memslot; - memslot = search_memslots(kvm_memslots(kvm), gfn); + memslot = __gfn_to_memslot(kvm_memslots(kvm), gfn); if (!memslot) return -EINVAL; diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index dc6591548f0c..f38dfe195ef2 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -80,7 +80,7 @@ static long kvmppc_rm_tce_to_ua(struct kvm *kvm, unsigned long gfn = tce >> PAGE_SHIFT; struct kvm_memory_slot *memslot; - memslot = search_memslots(kvm_memslots_raw(kvm), gfn); + memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn); if (!memslot) return -EINVAL; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index bdfd5ed539c9..f30b53a07917 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1189,29 +1189,43 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args); /* - * search_memslots() and __gfn_to_memslot() are here because they are - * used in non-modular code in arch/powerpc/kvm/book3s_hv_rm_mmu.c. - * gfn_to_memslot() itself isn't here as an inline because that would - * bloat other code too much. + * Returns a pointer to the memslot at slot_index if it contains gfn. + * Otherwise returns NULL. + */ +static inline struct kvm_memory_slot * +try_get_memslot(struct kvm_memslots *slots, int slot_index, gfn_t gfn) +{ + struct kvm_memory_slot *slot; + + if (slot_index < 0 || slot_index >= slots->used_slots) + return NULL; + + slot = &slots->memslots[slot_index]; + + if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) + return slot; + else + return NULL; +} + +/* + * Returns a pointer to the memslot that contains gfn and records the index of + * the slot in index. Otherwise returns NULL. * * IMPORTANT: Slots are sorted from highest GFN to lowest GFN! */ static inline struct kvm_memory_slot * -search_memslots(struct kvm_memslots *slots, gfn_t gfn) +search_memslots(struct kvm_memslots *slots, gfn_t gfn, int *index) { int start = 0, end = slots->used_slots; - int slot = atomic_read(&slots->last_used_slot); struct kvm_memory_slot *memslots = slots->memslots; + struct kvm_memory_slot *slot; if (unlikely(!slots->used_slots)) return NULL; - if (gfn >= memslots[slot].base_gfn && - gfn < memslots[slot].base_gfn + memslots[slot].npages) - return &memslots[slot]; - while (start < end) { - slot = start + (end - start) / 2; + int slot = start + (end - start) / 2; if (gfn >= memslots[slot].base_gfn) end = slot; @@ -1219,19 +1233,37 @@ search_memslots(struct kvm_memslots *slots, gfn_t gfn) start = slot + 1; } - if (start < slots->used_slots && gfn >= memslots[start].base_gfn && - gfn < memslots[start].base_gfn + memslots[start].npages) { - atomic_set(&slots->last_used_slot, start); - return &memslots[start]; + slot = try_get_memslot(slots, start, gfn); + if (slot) { + *index = start; + return slot; } return NULL; } +/* + * __gfn_to_memslot() and its descendants are here because it is called from + * non-modular code in arch/powerpc/kvm/book3s_64_vio{,_hv}.c. gfn_to_memslot() + * itself isn't here as an inline because that would bloat other code too much. + */ static inline struct kvm_memory_slot * __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn) { - return search_memslots(slots, gfn); + struct kvm_memory_slot *slot; + int slot_index = atomic_read(&slots->last_used_slot); + + slot = try_get_memslot(slots, slot_index, gfn); + if (slot) + return slot; + + slot = search_memslots(slots, gfn, &slot_index); + if (slot) { + atomic_set(&slots->last_used_slot, slot_index); + return slot; + } + + return NULL; } static inline unsigned long -- cgit v1.2.3-70-g09d2 From fe22ed827c5b60b895b15c5c3f04e04ac606be38 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:40 +0000 Subject: KVM: Cache the last used slot index per vCPU The memslot for a given gfn is looked up multiple times during page fault handling. Avoid binary searching for it multiple times by caching the most recently used slot. There is an existing VM-wide last_used_slot but that does not work well for cases where vCPUs are accessing memory in different slots (see performance data below). Another benefit of caching the most recently use slot (versus looking up the slot once and passing around a pointer) is speeding up memslot lookups *across* faults and during spte prefetching. To measure the performance of this change I ran dirty_log_perf_test with 64 vCPUs and 64 memslots and measured "Populate memory time" and "Iteration 2 dirty memory time". Tests were ran with eptad=N to force dirty logging to use fast_page_fault so its performance could be measured. Config | Metric | Before | After ---------- | ----------------------------- | ------ | ------ tdp_mmu=Y | Populate memory time | 6.76s | 5.47s tdp_mmu=Y | Iteration 2 dirty memory time | 2.83s | 0.31s tdp_mmu=N | Populate memory time | 20.4s | 18.7s tdp_mmu=N | Iteration 2 dirty memory time | 2.65s | 0.30s The "Iteration 2 dirty memory time" results are especially compelling because they are equivalent to running the same test with a single memslot. In other words, fast_page_fault performance no longer scales with the number of memslots. Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-4-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- include/linux/kvm_host.h | 13 +++++++++++++ virt/kvm/kvm_main.c | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f30b53a07917..492d183dd7d0 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -354,6 +354,13 @@ struct kvm_vcpu { struct kvm_vcpu_stat stat; char stats_id[KVM_STATS_NAME_SIZE]; struct kvm_dirty_ring dirty_ring; + + /* + * The index of the most recently used memslot by this vCPU. It's ok + * if this becomes stale due to memslot changes since we always check + * it is a valid slot. + */ + int last_used_slot; }; /* must be called with irqs disabled */ @@ -1200,6 +1207,12 @@ try_get_memslot(struct kvm_memslots *slots, int slot_index, gfn_t gfn) if (slot_index < 0 || slot_index >= slots->used_slots) return NULL; + /* + * slot_index can come from vcpu->last_used_slot which is not kept + * in sync with userspace-controllable memslot deletion. So use nospec + * to prevent the CPU from speculating past the end of memslots[]. + */ + slot_index = array_index_nospec(slot_index, slots->used_slots); slot = &slots->memslots[slot_index]; if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 1984c7389787..30d322519253 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -415,6 +415,7 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id) vcpu->preempted = false; vcpu->ready = false; preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops); + vcpu->last_used_slot = 0; } void kvm_vcpu_destroy(struct kvm_vcpu *vcpu) @@ -2025,7 +2026,26 @@ EXPORT_SYMBOL_GPL(gfn_to_memslot); struct kvm_memory_slot *kvm_vcpu_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn) { - return __gfn_to_memslot(kvm_vcpu_memslots(vcpu), gfn); + struct kvm_memslots *slots = kvm_vcpu_memslots(vcpu); + struct kvm_memory_slot *slot; + int slot_index; + + slot = try_get_memslot(slots, vcpu->last_used_slot, gfn); + if (slot) + return slot; + + /* + * Fall back to searching all memslots. We purposely use + * search_memslots() instead of __gfn_to_memslot() to avoid + * thrashing the VM-wide last_used_index in kvm_memslots. + */ + slot = search_memslots(slots, gfn, &slot_index); + if (slot) { + vcpu->last_used_slot = slot_index; + return slot; + } + + return NULL; } EXPORT_SYMBOL_GPL(kvm_vcpu_gfn_to_memslot); -- cgit v1.2.3-70-g09d2 From 081de470f1e6e83f9f460ba5ae8f57ff07f37692 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:41 +0000 Subject: KVM: x86/mmu: Leverage vcpu->last_used_slot in tdp_mmu_map_handle_target_level The existing TDP MMU methods to handle dirty logging are vcpu-agnostic since they can be driven by MMU notifiers and other non-vcpu-specific events in addition to page faults. However this means that the TDP MMU is not benefiting from the new vcpu->last_used_slot. Fix that by introducing a tdp_mmu_map_set_spte_atomic() which is only called during a TDP page fault and has access to the kvm_vcpu for fast slot lookups. This improves "Populate memory time" in dirty_log_perf_test by 5%: Command | Before | After ------------------------------- | ---------------- | ------------- ./dirty_log_perf_test -v64 -x64 | 5.472321072s | 5.169832886s Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-5-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/tdp_mmu.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 43f12f5d12c0..dab6cb46cdb2 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -542,15 +542,40 @@ static inline bool tdp_mmu_set_spte_atomic_no_dirty_log(struct kvm *kvm, return true; } -static inline bool tdp_mmu_set_spte_atomic(struct kvm *kvm, - struct tdp_iter *iter, - u64 new_spte) +/* + * tdp_mmu_map_set_spte_atomic - Set a leaf TDP MMU SPTE atomically to resolve a + * TDP page fault. + * + * @vcpu: The vcpu instance that took the TDP page fault. + * @iter: a tdp_iter instance currently on the SPTE that should be set + * @new_spte: The value the SPTE should be set to + * + * Returns: true if the SPTE was set, false if it was not. If false is returned, + * this function will have no side-effects. + */ +static inline bool tdp_mmu_map_set_spte_atomic(struct kvm_vcpu *vcpu, + struct tdp_iter *iter, + u64 new_spte) { + struct kvm *kvm = vcpu->kvm; + if (!tdp_mmu_set_spte_atomic_no_dirty_log(kvm, iter, new_spte)) return false; - handle_changed_spte_dirty_log(kvm, iter->as_id, iter->gfn, - iter->old_spte, new_spte, iter->level); + /* + * Use kvm_vcpu_gfn_to_memslot() instead of going through + * handle_changed_spte_dirty_log() to leverage vcpu->last_used_slot. + */ + if (is_writable_pte(new_spte)) { + struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, iter->gfn); + + if (slot && kvm_slot_dirty_track_enabled(slot)) { + /* Enforced by kvm_mmu_hugepage_adjust. */ + WARN_ON_ONCE(iter->level > PG_LEVEL_4K); + mark_page_dirty_in_slot(kvm, slot, iter->gfn); + } + } + return true; } @@ -563,7 +588,7 @@ static inline bool tdp_mmu_zap_spte_atomic(struct kvm *kvm, * immediately installing a present entry in its place * before the TLBs are flushed. */ - if (!tdp_mmu_set_spte_atomic(kvm, iter, REMOVED_SPTE)) + if (!tdp_mmu_set_spte_atomic_no_dirty_log(kvm, iter, REMOVED_SPTE)) return false; kvm_flush_remote_tlbs_with_address(kvm, iter->gfn, @@ -931,7 +956,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, if (new_spte == iter->old_spte) ret = RET_PF_SPURIOUS; - else if (!tdp_mmu_set_spte_atomic(vcpu->kvm, iter, new_spte)) + else if (!tdp_mmu_map_set_spte_atomic(vcpu, iter, new_spte)) return RET_PF_RETRY; /* @@ -1035,8 +1060,7 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, gpa_t gpa, u32 error_code, new_spte = make_nonleaf_spte(child_pt, !shadow_accessed_mask); - if (tdp_mmu_set_spte_atomic(vcpu->kvm, &iter, - new_spte)) { + if (tdp_mmu_set_spte_atomic_no_dirty_log(vcpu->kvm, &iter, new_spte)) { tdp_mmu_link_page(vcpu->kvm, sp, true, huge_page_disallowed && req_level >= iter.level); -- cgit v1.2.3-70-g09d2 From 601f8af01e5ae535b45cdb91234887c9fd861ad4 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:42 +0000 Subject: KVM: x86/mmu: Leverage vcpu->last_used_slot for rmap_add and rmap_recycle rmap_add() and rmap_recycle() both run in the context of the vCPU and thus we can use kvm_vcpu_gfn_to_memslot() to look up the memslot. This enables rmap_add() and rmap_recycle() to take advantage of vcpu->last_used_slot and avoid expensive memslot searching. This change improves the performance of "Populate memory time" in dirty_log_perf_test with tdp_mmu=N. In addition to improving the performance, "Populate memory time" no longer scales with the number of memslots in the VM. Command | Before | After ------------------------------- | ---------------- | ------------- ./dirty_log_perf_test -v64 -x1 | 15.18001570s | 14.99469366s ./dirty_log_perf_test -v64 -x64 | 18.71336392s | 14.98675076s Reviewed-by: Paolo Bonzini Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-6-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 232ced2e7bf8..3a0ae48a26e9 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1044,17 +1044,6 @@ static struct kvm_rmap_head *__gfn_to_rmap(gfn_t gfn, int level, return &slot->arch.rmap[level - PG_LEVEL_4K][idx]; } -static struct kvm_rmap_head *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, - struct kvm_mmu_page *sp) -{ - struct kvm_memslots *slots; - struct kvm_memory_slot *slot; - - slots = kvm_memslots_for_spte_role(kvm, sp->role); - slot = __gfn_to_memslot(slots, gfn); - return __gfn_to_rmap(gfn, sp->role.level, slot); -} - static bool rmap_can_add(struct kvm_vcpu *vcpu) { struct kvm_mmu_memory_cache *mc; @@ -1065,24 +1054,39 @@ static bool rmap_can_add(struct kvm_vcpu *vcpu) static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) { + struct kvm_memory_slot *slot; struct kvm_mmu_page *sp; struct kvm_rmap_head *rmap_head; sp = sptep_to_sp(spte); kvm_mmu_page_set_gfn(sp, spte - sp->spt, gfn); - rmap_head = gfn_to_rmap(vcpu->kvm, gfn, sp); + slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); + rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); return pte_list_add(vcpu, spte, rmap_head); } + static void rmap_remove(struct kvm *kvm, u64 *spte) { + struct kvm_memslots *slots; + struct kvm_memory_slot *slot; struct kvm_mmu_page *sp; gfn_t gfn; struct kvm_rmap_head *rmap_head; sp = sptep_to_sp(spte); gfn = kvm_mmu_page_get_gfn(sp, spte - sp->spt); - rmap_head = gfn_to_rmap(kvm, gfn, sp); + + /* + * Unlike rmap_add and rmap_recycle, rmap_remove does not run in the + * context of a vCPU so have to determine which memslots to use based + * on context information in sp->role. + */ + slots = kvm_memslots_for_spte_role(kvm, sp->role); + + slot = __gfn_to_memslot(slots, gfn); + rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); + __pte_list_remove(spte, rmap_head); } @@ -1620,12 +1624,13 @@ static bool kvm_test_age_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) { + struct kvm_memory_slot *slot; struct kvm_rmap_head *rmap_head; struct kvm_mmu_page *sp; sp = sptep_to_sp(spte); - - rmap_head = gfn_to_rmap(vcpu->kvm, gfn, sp); + slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); + rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); kvm_unmap_rmapp(vcpu->kvm, rmap_head, NULL, gfn, sp->role.level, __pte(0)); kvm_flush_remote_tlbs_with_address(vcpu->kvm, sp->gfn, -- cgit v1.2.3-70-g09d2 From 93e083d4f4bfe790eb1cdc87103bd6a84be9df75 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:43 +0000 Subject: KVM: x86/mmu: Rename __gfn_to_rmap to gfn_to_rmap gfn_to_rmap was removed in the previous patch so there is no need to retain the double underscore on __gfn_to_rmap. Reviewed-by: Paolo Bonzini Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-7-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- arch/x86/kvm/mmu/mmu.c | 25 ++++++++++++------------- arch/x86/kvm/mmu/mmu_audit.c | 4 ++-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 3a0ae48a26e9..964c797dcc46 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -1035,8 +1035,8 @@ out: return true; } -static struct kvm_rmap_head *__gfn_to_rmap(gfn_t gfn, int level, - const struct kvm_memory_slot *slot) +static struct kvm_rmap_head *gfn_to_rmap(gfn_t gfn, int level, + const struct kvm_memory_slot *slot) { unsigned long idx; @@ -1061,7 +1061,7 @@ static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) sp = sptep_to_sp(spte); kvm_mmu_page_set_gfn(sp, spte - sp->spt, gfn); slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); - rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); + rmap_head = gfn_to_rmap(gfn, sp->role.level, slot); return pte_list_add(vcpu, spte, rmap_head); } @@ -1085,7 +1085,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) slots = kvm_memslots_for_spte_role(kvm, sp->role); slot = __gfn_to_memslot(slots, gfn); - rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); + rmap_head = gfn_to_rmap(gfn, sp->role.level, slot); __pte_list_remove(spte, rmap_head); } @@ -1307,8 +1307,8 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm, return; while (mask) { - rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), - PG_LEVEL_4K, slot); + rmap_head = gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), + PG_LEVEL_4K, slot); __rmap_write_protect(kvm, rmap_head, false); /* clear the first set bit */ @@ -1340,8 +1340,8 @@ static void kvm_mmu_clear_dirty_pt_masked(struct kvm *kvm, return; while (mask) { - rmap_head = __gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), - PG_LEVEL_4K, slot); + rmap_head = gfn_to_rmap(slot->base_gfn + gfn_offset + __ffs(mask), + PG_LEVEL_4K, slot); __rmap_clear_dirty(kvm, rmap_head, slot); /* clear the first set bit */ @@ -1407,7 +1407,7 @@ bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm, if (kvm_memslots_have_rmaps(kvm)) { for (i = min_level; i <= KVM_MAX_HUGEPAGE_LEVEL; ++i) { - rmap_head = __gfn_to_rmap(gfn, i, slot); + rmap_head = gfn_to_rmap(gfn, i, slot); write_protected |= __rmap_write_protect(kvm, rmap_head, true); } } @@ -1502,9 +1502,8 @@ rmap_walk_init_level(struct slot_rmap_walk_iterator *iterator, int level) { iterator->level = level; iterator->gfn = iterator->start_gfn; - iterator->rmap = __gfn_to_rmap(iterator->gfn, level, iterator->slot); - iterator->end_rmap = __gfn_to_rmap(iterator->end_gfn, level, - iterator->slot); + iterator->rmap = gfn_to_rmap(iterator->gfn, level, iterator->slot); + iterator->end_rmap = gfn_to_rmap(iterator->end_gfn, level, iterator->slot); } static void @@ -1630,7 +1629,7 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) sp = sptep_to_sp(spte); slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); - rmap_head = __gfn_to_rmap(gfn, sp->role.level, slot); + rmap_head = gfn_to_rmap(gfn, sp->role.level, slot); kvm_unmap_rmapp(vcpu->kvm, rmap_head, NULL, gfn, sp->role.level, __pte(0)); kvm_flush_remote_tlbs_with_address(vcpu->kvm, sp->gfn, diff --git a/arch/x86/kvm/mmu/mmu_audit.c b/arch/x86/kvm/mmu/mmu_audit.c index cedc17b2f60e..9e7dcf999f08 100644 --- a/arch/x86/kvm/mmu/mmu_audit.c +++ b/arch/x86/kvm/mmu/mmu_audit.c @@ -147,7 +147,7 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) return; } - rmap_head = __gfn_to_rmap(gfn, rev_sp->role.level, slot); + rmap_head = gfn_to_rmap(gfn, rev_sp->role.level, slot); if (!rmap_head->val) { if (!__ratelimit(&ratelimit_state)) return; @@ -200,7 +200,7 @@ static void audit_write_protection(struct kvm *kvm, struct kvm_mmu_page *sp) slots = kvm_memslots_for_spte_role(kvm, sp->role); slot = __gfn_to_memslot(slots, sp->gfn); - rmap_head = __gfn_to_rmap(sp->gfn, PG_LEVEL_4K, slot); + rmap_head = gfn_to_rmap(sp->gfn, PG_LEVEL_4K, slot); for_each_rmap_spte(rmap_head, &iter, sptep) { if (is_writable_pte(*sptep)) -- cgit v1.2.3-70-g09d2 From 609e6202ea5f4ab5fa6f6bed9da5594e3e94c570 Mon Sep 17 00:00:00 2001 From: David Matlack Date: Wed, 4 Aug 2021 22:28:44 +0000 Subject: KVM: selftests: Support multiple slots in dirty_log_perf_test Introduce a new option to dirty_log_perf_test: -x number_of_slots. This causes the test to attempt to split the region of memory into the given number of slots. If the region cannot be evenly divided, the test will fail. This allows testing with more than one slot and therefore measure how performance scales with the number of memslots. Signed-off-by: David Matlack Message-Id: <20210804222844.1419481-8-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- .../selftests/kvm/access_tracking_perf_test.c | 2 +- tools/testing/selftests/kvm/demand_paging_test.c | 2 +- tools/testing/selftests/kvm/dirty_log_perf_test.c | 76 ++++++++++++++++++---- .../testing/selftests/kvm/include/perf_test_util.h | 2 +- tools/testing/selftests/kvm/lib/perf_test_util.c | 20 ++++-- .../kvm/memslot_modification_stress_test.c | 2 +- 6 files changed, 84 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tools/testing/selftests/kvm/access_tracking_perf_test.c index e2baa187a21e..3e23b2105f4b 100644 --- a/tools/testing/selftests/kvm/access_tracking_perf_test.c +++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c @@ -333,7 +333,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) pthread_t *vcpu_threads; int vcpus = params->vcpus; - vm = perf_test_create_vm(mode, vcpus, params->vcpu_memory_bytes, + vm = perf_test_create_vm(mode, vcpus, params->vcpu_memory_bytes, 1, params->backing_src); perf_test_setup_vcpus(vm, vcpus, params->vcpu_memory_bytes, diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index b74704305835..61266a729d88 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -293,7 +293,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) int vcpu_id; int r; - vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, + vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, 1, p->src_type); perf_test_args.wr_fract = 1; diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c index 80cbd3a748c0..034458dd89a2 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -94,8 +94,59 @@ struct test_params { int wr_fract; bool partition_vcpu_memory_access; enum vm_mem_backing_src_type backing_src; + int slots; }; +static void toggle_dirty_logging(struct kvm_vm *vm, int slots, bool enable) +{ + int i; + + for (i = 0; i < slots; i++) { + int slot = PERF_TEST_MEM_SLOT_INDEX + i; + int flags = enable ? KVM_MEM_LOG_DIRTY_PAGES : 0; + + vm_mem_region_set_flags(vm, slot, flags); + } +} + +static inline void enable_dirty_logging(struct kvm_vm *vm, int slots) +{ + toggle_dirty_logging(vm, slots, true); +} + +static inline void disable_dirty_logging(struct kvm_vm *vm, int slots) +{ + toggle_dirty_logging(vm, slots, false); +} + +static void get_dirty_log(struct kvm_vm *vm, int slots, unsigned long *bitmap, + uint64_t nr_pages) +{ + uint64_t slot_pages = nr_pages / slots; + int i; + + for (i = 0; i < slots; i++) { + int slot = PERF_TEST_MEM_SLOT_INDEX + i; + unsigned long *slot_bitmap = bitmap + i * slot_pages; + + kvm_vm_get_dirty_log(vm, slot, slot_bitmap); + } +} + +static void clear_dirty_log(struct kvm_vm *vm, int slots, unsigned long *bitmap, + uint64_t nr_pages) +{ + uint64_t slot_pages = nr_pages / slots; + int i; + + for (i = 0; i < slots; i++) { + int slot = PERF_TEST_MEM_SLOT_INDEX + i; + unsigned long *slot_bitmap = bitmap + i * slot_pages; + + kvm_vm_clear_dirty_log(vm, slot, slot_bitmap, 0, slot_pages); + } +} + static void run_test(enum vm_guest_mode mode, void *arg) { struct test_params *p = arg; @@ -114,7 +165,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) struct timespec clear_dirty_log_total = (struct timespec){0}; vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, - p->backing_src); + p->slots, p->backing_src); perf_test_args.wr_fract = p->wr_fract; @@ -163,8 +214,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) /* Enable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); - vm_mem_region_set_flags(vm, PERF_TEST_MEM_SLOT_INDEX, - KVM_MEM_LOG_DIRTY_PAGES); + enable_dirty_logging(vm, p->slots); ts_diff = timespec_elapsed(start); pr_info("Enabling dirty logging time: %ld.%.9lds\n\n", ts_diff.tv_sec, ts_diff.tv_nsec); @@ -190,8 +240,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) iteration, ts_diff.tv_sec, ts_diff.tv_nsec); clock_gettime(CLOCK_MONOTONIC, &start); - kvm_vm_get_dirty_log(vm, PERF_TEST_MEM_SLOT_INDEX, bmap); - + get_dirty_log(vm, p->slots, bmap, host_num_pages); ts_diff = timespec_elapsed(start); get_dirty_log_total = timespec_add(get_dirty_log_total, ts_diff); @@ -200,9 +249,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) if (dirty_log_manual_caps) { clock_gettime(CLOCK_MONOTONIC, &start); - kvm_vm_clear_dirty_log(vm, PERF_TEST_MEM_SLOT_INDEX, bmap, 0, - host_num_pages); - + clear_dirty_log(vm, p->slots, bmap, host_num_pages); ts_diff = timespec_elapsed(start); clear_dirty_log_total = timespec_add(clear_dirty_log_total, ts_diff); @@ -213,7 +260,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) /* Disable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); - vm_mem_region_set_flags(vm, PERF_TEST_MEM_SLOT_INDEX, 0); + disable_dirty_logging(vm, p->slots); ts_diff = timespec_elapsed(start); pr_info("Disabling dirty logging time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); @@ -244,7 +291,8 @@ static void help(char *name) { puts(""); printf("usage: %s [-h] [-i iterations] [-p offset] " - "[-m mode] [-b vcpu bytes] [-v vcpus] [-o] [-s mem type]\n", name); + "[-m mode] [-b vcpu bytes] [-v vcpus] [-o] [-s mem type]" + "[-x memslots]\n", name); puts(""); printf(" -i: specify iteration counts (default: %"PRIu64")\n", TEST_HOST_LOOP_N); @@ -263,6 +311,8 @@ static void help(char *name) " them into a separate region of memory for each vCPU.\n"); printf(" -s: specify the type of memory that should be used to\n" " back the guest data region.\n\n"); + printf(" -x: Split the memory region into this number of memslots.\n" + " (default: 1)"); backing_src_help(); puts(""); exit(0); @@ -276,6 +326,7 @@ int main(int argc, char *argv[]) .wr_fract = 1, .partition_vcpu_memory_access = true, .backing_src = VM_MEM_SRC_ANONYMOUS, + .slots = 1, }; int opt; @@ -286,7 +337,7 @@ int main(int argc, char *argv[]) guest_modes_append_default(); - while ((opt = getopt(argc, argv, "hi:p:m:b:f:v:os:")) != -1) { + while ((opt = getopt(argc, argv, "hi:p:m:b:f:v:os:x:")) != -1) { switch (opt) { case 'i': p.iterations = atoi(optarg); @@ -316,6 +367,9 @@ int main(int argc, char *argv[]) case 's': p.backing_src = parse_backing_src_type(optarg); break; + case 'x': + p.slots = atoi(optarg); + break; case 'h': default: help(argv[0]); diff --git a/tools/testing/selftests/kvm/include/perf_test_util.h b/tools/testing/selftests/kvm/include/perf_test_util.h index 005f2143adeb..df9f1a3a3ffb 100644 --- a/tools/testing/selftests/kvm/include/perf_test_util.h +++ b/tools/testing/selftests/kvm/include/perf_test_util.h @@ -44,7 +44,7 @@ extern struct perf_test_args perf_test_args; extern uint64_t guest_test_phys_mem; struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus, - uint64_t vcpu_memory_bytes, + uint64_t vcpu_memory_bytes, int slots, enum vm_mem_backing_src_type backing_src); void perf_test_destroy_vm(struct kvm_vm *vm); void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus, diff --git a/tools/testing/selftests/kvm/lib/perf_test_util.c b/tools/testing/selftests/kvm/lib/perf_test_util.c index b488f4aefea8..aebb223d34a7 100644 --- a/tools/testing/selftests/kvm/lib/perf_test_util.c +++ b/tools/testing/selftests/kvm/lib/perf_test_util.c @@ -50,11 +50,12 @@ static void guest_code(uint32_t vcpu_id) } struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus, - uint64_t vcpu_memory_bytes, + uint64_t vcpu_memory_bytes, int slots, enum vm_mem_backing_src_type backing_src) { struct kvm_vm *vm; uint64_t guest_num_pages; + int i; pr_info("Testing guest mode: %s\n", vm_guest_mode_string(mode)); @@ -68,6 +69,9 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus, "Guest memory size is not host page size aligned."); TEST_ASSERT(vcpu_memory_bytes % perf_test_args.guest_page_size == 0, "Guest memory size is not guest page size aligned."); + TEST_ASSERT(guest_num_pages % slots == 0, + "Guest memory cannot be evenly divided into %d slots.", + slots); vm = vm_create_with_vcpus(mode, vcpus, DEFAULT_GUEST_PHY_PAGES, (vcpus * vcpu_memory_bytes) / perf_test_args.guest_page_size, @@ -95,10 +99,16 @@ struct kvm_vm *perf_test_create_vm(enum vm_guest_mode mode, int vcpus, #endif pr_info("guest physical test memory offset: 0x%lx\n", guest_test_phys_mem); - /* Add an extra memory slot for testing */ - vm_userspace_mem_region_add(vm, backing_src, guest_test_phys_mem, - PERF_TEST_MEM_SLOT_INDEX, - guest_num_pages, 0); + /* Add extra memory slots for testing */ + for (i = 0; i < slots; i++) { + uint64_t region_pages = guest_num_pages / slots; + vm_paddr_t region_start = guest_test_phys_mem + + region_pages * perf_test_args.guest_page_size * i; + + vm_userspace_mem_region_add(vm, backing_src, region_start, + PERF_TEST_MEM_SLOT_INDEX + i, + region_pages, 0); + } /* Do mapping for the demand paging memory slot */ virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, guest_num_pages); diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c b/tools/testing/selftests/kvm/memslot_modification_stress_test.c index 98351ba0933c..8a9c6ccce3ca 100644 --- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c +++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c @@ -105,7 +105,7 @@ static void run_test(enum vm_guest_mode mode, void *arg) struct kvm_vm *vm; int vcpu_id; - vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, + vm = perf_test_create_vm(mode, nr_vcpus, guest_percpu_mem_size, 1, VM_MEM_SRC_ANONYMOUS); perf_test_args.wr_fract = 1; -- cgit v1.2.3-70-g09d2 From e184b1e589a7fbb80bfdd0364c11422999a17a26 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 27 Jul 2021 09:49:28 -0700 Subject: platform/x86/intel: Move Intel PMT drivers to new subfolder Move all Intel Platform Monitoring Technology drivers to drivers/platform/x86/intel/pmt. Signed-off-by: David E. Box Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210727164928.3171521-1-david.e.box@linux.intel.com Signed-off-by: Hans de Goede --- MAINTAINERS | 2 +- drivers/platform/x86/Kconfig | 36 --- drivers/platform/x86/Makefile | 3 - drivers/platform/x86/intel/Kconfig | 1 + drivers/platform/x86/intel/Makefile | 1 + drivers/platform/x86/intel/pmt/Kconfig | 40 ++++ drivers/platform/x86/intel/pmt/Makefile | 12 + drivers/platform/x86/intel/pmt/class.c | 344 +++++++++++++++++++++++++++++ drivers/platform/x86/intel/pmt/class.h | 53 +++++ drivers/platform/x86/intel/pmt/crashlog.c | 327 +++++++++++++++++++++++++++ drivers/platform/x86/intel/pmt/telemetry.c | 140 ++++++++++++ drivers/platform/x86/intel_pmt_class.c | 344 ----------------------------- drivers/platform/x86/intel_pmt_class.h | 53 ----- drivers/platform/x86/intel_pmt_crashlog.c | 327 --------------------------- drivers/platform/x86/intel_pmt_telemetry.c | 140 ------------ 15 files changed, 919 insertions(+), 904 deletions(-) create mode 100644 drivers/platform/x86/intel/pmt/Kconfig create mode 100644 drivers/platform/x86/intel/pmt/Makefile create mode 100644 drivers/platform/x86/intel/pmt/class.c create mode 100644 drivers/platform/x86/intel/pmt/class.h create mode 100644 drivers/platform/x86/intel/pmt/crashlog.c create mode 100644 drivers/platform/x86/intel/pmt/telemetry.c delete mode 100644 drivers/platform/x86/intel_pmt_class.c delete mode 100644 drivers/platform/x86/intel_pmt_class.h delete mode 100644 drivers/platform/x86/intel_pmt_crashlog.c delete mode 100644 drivers/platform/x86/intel_pmt_telemetry.c diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..14dd0045bc78 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9494,7 +9494,7 @@ INTEL PMT DRIVER M: "David E. Box" S: Maintained F: drivers/mfd/intel_pmt.c -F: drivers/platform/x86/intel_pmt_* +F: drivers/platform/x86/intel/pmt/ INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT M: Stanislav Yakovlev diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index d12db6c316ea..6ad35158ae4e 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1208,42 +1208,6 @@ config INTEL_PMC_CORE - Low Power Mode registers (Tigerlake and beyond) - PMC quirks as needed to enable SLPS0/S0ix -config INTEL_PMT_CLASS - tristate - help - The Intel Platform Monitoring Technology (PMT) class driver provides - the basic sysfs interface and file hierarchy used by PMT devices. - - For more information, see: - - - To compile this driver as a module, choose M here: the module - will be called intel_pmt_class. - -config INTEL_PMT_TELEMETRY - tristate "Intel Platform Monitoring Technology (PMT) Telemetry driver" - depends on MFD_INTEL_PMT - select INTEL_PMT_CLASS - help - The Intel Platform Monitory Technology (PMT) Telemetry driver provides - access to hardware telemetry metrics on devices that support the - feature. - - To compile this driver as a module, choose M here: the module - will be called intel_pmt_telemetry. - -config INTEL_PMT_CRASHLOG - tristate "Intel Platform Monitoring Technology (PMT) Crashlog driver" - depends on MFD_INTEL_PMT - select INTEL_PMT_CLASS - help - The Intel Platform Monitoring Technology (PMT) crashlog driver provides - access to hardware crashlog capabilities on devices that support the - feature. - - To compile this driver as a module, choose M here: the module - will be called intel_pmt_crashlog. - config INTEL_PUNIT_IPC tristate "Intel P-Unit IPC Driver" help diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 7ee369aab10d..5edfdc2ea7f2 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -129,9 +129,6 @@ obj-$(CONFIG_INTEL_BXTWC_PMIC_TMU) += intel_bxtwc_tmu.o obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o -obj-$(CONFIG_INTEL_PMT_CLASS) += intel_pmt_class.o -obj-$(CONFIG_INTEL_PMT_TELEMETRY) += intel_pmt_telemetry.o -obj-$(CONFIG_INTEL_PMT_CRASHLOG) += intel_pmt_crashlog.o obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o obj-$(CONFIG_INTEL_SCU_PCI) += intel_scu_pcidrv.o diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig index f2eef337eb98..6eec084d9bf9 100644 --- a/drivers/platform/x86/intel/Kconfig +++ b/drivers/platform/x86/intel/Kconfig @@ -18,5 +18,6 @@ if X86_PLATFORM_DRIVERS_INTEL source "drivers/platform/x86/intel/int33fe/Kconfig" source "drivers/platform/x86/intel/int3472/Kconfig" +source "drivers/platform/x86/intel/pmt/Kconfig" endif # X86_PLATFORM_DRIVERS_INTEL diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile index 0653055942d5..ca0ec2c85b05 100644 --- a/drivers/platform/x86/intel/Makefile +++ b/drivers/platform/x86/intel/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_INTEL_CHT_INT33FE) += int33fe/ obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/ +obj-$(CONFIG_INTEL_PMT_CLASS) += pmt/ diff --git a/drivers/platform/x86/intel/pmt/Kconfig b/drivers/platform/x86/intel/pmt/Kconfig new file mode 100644 index 000000000000..d630f883a717 --- /dev/null +++ b/drivers/platform/x86/intel/pmt/Kconfig @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Intel Platform Monitoring Technology drivers +# + +config INTEL_PMT_CLASS + tristate + help + The Intel Platform Monitoring Technology (PMT) class driver provides + the basic sysfs interface and file hierarchy used by PMT devices. + + For more information, see: + + + To compile this driver as a module, choose M here: the module + will be called intel_pmt_class. + +config INTEL_PMT_TELEMETRY + tristate "Intel Platform Monitoring Technology (PMT) Telemetry driver" + depends on MFD_INTEL_PMT + select INTEL_PMT_CLASS + help + The Intel Platform Monitory Technology (PMT) Telemetry driver provides + access to hardware telemetry metrics on devices that support the + feature. + + To compile this driver as a module, choose M here: the module + will be called intel_pmt_telemetry. + +config INTEL_PMT_CRASHLOG + tristate "Intel Platform Monitoring Technology (PMT) Crashlog driver" + depends on MFD_INTEL_PMT + select INTEL_PMT_CLASS + help + The Intel Platform Monitoring Technology (PMT) crashlog driver provides + access to hardware crashlog capabilities on devices that support the + feature. + + To compile this driver as a module, choose M here: the module + will be called intel_pmt_crashlog. diff --git a/drivers/platform/x86/intel/pmt/Makefile b/drivers/platform/x86/intel/pmt/Makefile new file mode 100644 index 000000000000..019103ee6522 --- /dev/null +++ b/drivers/platform/x86/intel/pmt/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for linux/drivers/platform/x86/intel/pmt +# Intel Platform Monitoring Technology Drivers +# + +pmt_class-objs += class.o +obj-$(CONFIG_INTEL_PMT_CLASS) += pmt_class.o +pmt_telemetry-objs += telemetry.o +obj-$(CONFIG_INTEL_PMT_TELEMETRY) += pmt_telemetry.o +pmt_crashlog-objs += crashlog.o +obj-$(CONFIG_INTEL_PMT_CRASHLOG) += pmt_crashlog.o diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c new file mode 100644 index 000000000000..659b1073033c --- /dev/null +++ b/drivers/platform/x86/intel/pmt/class.c @@ -0,0 +1,344 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Platform Monitory Technology Telemetry driver + * + * Copyright (c) 2020, Intel Corporation. + * All Rights Reserved. + * + * Author: "Alexander Duyck" + */ + +#include +#include +#include +#include + +#include "class.h" + +#define PMT_XA_START 0 +#define PMT_XA_MAX INT_MAX +#define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) + +/* + * Early implementations of PMT on client platforms have some + * differences from the server platforms (which use the Out Of Band + * Management Services Module OOBMSM). This list tracks those + * platforms as needed to handle those differences. Newer client + * platforms are expected to be fully compatible with server. + */ +static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ + { PCI_VDEVICE(INTEL, 0x490e) }, /* DG1 */ + { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ + { } +}; + +bool intel_pmt_is_early_client_hw(struct device *dev) +{ + struct pci_dev *parent = to_pci_dev(dev->parent); + + return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); +} +EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); + +/* + * sysfs + */ +static ssize_t +intel_pmt_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, + size_t count) +{ + struct intel_pmt_entry *entry = container_of(attr, + struct intel_pmt_entry, + pmt_bin_attr); + + if (off < 0) + return -EINVAL; + + if (off >= entry->size) + return 0; + + if (count > entry->size - off) + count = entry->size - off; + + memcpy_fromio(buf, entry->base + off, count); + + return count; +} + +static int +intel_pmt_mmap(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, struct vm_area_struct *vma) +{ + struct intel_pmt_entry *entry = container_of(attr, + struct intel_pmt_entry, + pmt_bin_attr); + unsigned long vsize = vma->vm_end - vma->vm_start; + struct device *dev = kobj_to_dev(kobj); + unsigned long phys = entry->base_addr; + unsigned long pfn = PFN_DOWN(phys); + unsigned long psize; + + if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) + return -EROFS; + + psize = (PFN_UP(entry->base_addr + entry->size) - pfn) * PAGE_SIZE; + if (vsize > psize) { + dev_err(dev, "Requested mmap size is too large\n"); + return -EINVAL; + } + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (io_remap_pfn_range(vma, vma->vm_start, pfn, + vsize, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +static ssize_t +guid_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct intel_pmt_entry *entry = dev_get_drvdata(dev); + + return sprintf(buf, "0x%x\n", entry->guid); +} +static DEVICE_ATTR_RO(guid); + +static ssize_t size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct intel_pmt_entry *entry = dev_get_drvdata(dev); + + return sprintf(buf, "%zu\n", entry->size); +} +static DEVICE_ATTR_RO(size); + +static ssize_t +offset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct intel_pmt_entry *entry = dev_get_drvdata(dev); + + return sprintf(buf, "%lu\n", offset_in_page(entry->base_addr)); +} +static DEVICE_ATTR_RO(offset); + +static struct attribute *intel_pmt_attrs[] = { + &dev_attr_guid.attr, + &dev_attr_size.attr, + &dev_attr_offset.attr, + NULL +}; +ATTRIBUTE_GROUPS(intel_pmt); + +static struct class intel_pmt_class = { + .name = "intel_pmt", + .owner = THIS_MODULE, + .dev_groups = intel_pmt_groups, +}; + +static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, + struct intel_pmt_header *header, + struct device *dev, + struct resource *disc_res) +{ + struct pci_dev *pci_dev = to_pci_dev(dev->parent); + u8 bir; + + /* + * The base offset should always be 8 byte aligned. + * + * For non-local access types the lower 3 bits of base offset + * contains the index of the base address register where the + * telemetry can be found. + */ + bir = GET_BIR(header->base_offset); + + /* Local access and BARID only for now */ + switch (header->access_type) { + case ACCESS_LOCAL: + if (bir) { + dev_err(dev, + "Unsupported BAR index %d for access type %d\n", + bir, header->access_type); + return -EINVAL; + } + /* + * For access_type LOCAL, the base address is as follows: + * base address = end of discovery region + base offset + */ + entry->base_addr = disc_res->end + 1 + header->base_offset; + + /* + * Some hardware use a different calculation for the base address + * when access_type == ACCESS_LOCAL. On the these systems + * ACCCESS_LOCAL refers to an address in the same BAR as the + * header but at a fixed offset. But as the header address was + * supplied to the driver, we don't know which BAR it was in. + * So search for the bar whose range includes the header address. + */ + if (intel_pmt_is_early_client_hw(dev)) { + int i; + + entry->base_addr = 0; + for (i = 0; i < 6; i++) + if (disc_res->start >= pci_resource_start(pci_dev, i) && + (disc_res->start <= pci_resource_end(pci_dev, i))) { + entry->base_addr = pci_resource_start(pci_dev, i) + + header->base_offset; + break; + } + if (!entry->base_addr) + return -EINVAL; + } + + break; + case ACCESS_BARID: + /* + * If another BAR was specified then the base offset + * represents the offset within that BAR. SO retrieve the + * address from the parent PCI device and add offset. + */ + entry->base_addr = pci_resource_start(pci_dev, bir) + + GET_ADDRESS(header->base_offset); + break; + default: + dev_err(dev, "Unsupported access type %d\n", + header->access_type); + return -EINVAL; + } + + entry->guid = header->guid; + entry->size = header->size; + + return 0; +} + +static int intel_pmt_dev_register(struct intel_pmt_entry *entry, + struct intel_pmt_namespace *ns, + struct device *parent) +{ + struct resource res = {0}; + struct device *dev; + int ret; + + ret = xa_alloc(ns->xa, &entry->devid, entry, PMT_XA_LIMIT, GFP_KERNEL); + if (ret) + return ret; + + dev = device_create(&intel_pmt_class, parent, MKDEV(0, 0), entry, + "%s%d", ns->name, entry->devid); + + if (IS_ERR(dev)) { + dev_err(parent, "Could not create %s%d device node\n", + ns->name, entry->devid); + ret = PTR_ERR(dev); + goto fail_dev_create; + } + + entry->kobj = &dev->kobj; + + if (ns->attr_grp) { + ret = sysfs_create_group(entry->kobj, ns->attr_grp); + if (ret) + goto fail_sysfs; + } + + /* if size is 0 assume no data buffer, so no file needed */ + if (!entry->size) + return 0; + + res.start = entry->base_addr; + res.end = res.start + entry->size - 1; + res.flags = IORESOURCE_MEM; + + entry->base = devm_ioremap_resource(dev, &res); + if (IS_ERR(entry->base)) { + ret = PTR_ERR(entry->base); + goto fail_ioremap; + } + + sysfs_bin_attr_init(&entry->pmt_bin_attr); + entry->pmt_bin_attr.attr.name = ns->name; + entry->pmt_bin_attr.attr.mode = 0440; + entry->pmt_bin_attr.mmap = intel_pmt_mmap; + entry->pmt_bin_attr.read = intel_pmt_read; + entry->pmt_bin_attr.size = entry->size; + + ret = sysfs_create_bin_file(&dev->kobj, &entry->pmt_bin_attr); + if (!ret) + return 0; + +fail_ioremap: + if (ns->attr_grp) + sysfs_remove_group(entry->kobj, ns->attr_grp); +fail_sysfs: + device_unregister(dev); +fail_dev_create: + xa_erase(ns->xa, entry->devid); + + return ret; +} + +int intel_pmt_dev_create(struct intel_pmt_entry *entry, + struct intel_pmt_namespace *ns, + struct platform_device *pdev, int idx) +{ + struct intel_pmt_header header; + struct resource *disc_res; + int ret = -ENODEV; + + disc_res = platform_get_resource(pdev, IORESOURCE_MEM, idx); + if (!disc_res) + return ret; + + entry->disc_table = devm_platform_ioremap_resource(pdev, idx); + if (IS_ERR(entry->disc_table)) + return PTR_ERR(entry->disc_table); + + ret = ns->pmt_header_decode(entry, &header, &pdev->dev); + if (ret) + return ret; + + ret = intel_pmt_populate_entry(entry, &header, &pdev->dev, disc_res); + if (ret) + return ret; + + return intel_pmt_dev_register(entry, ns, &pdev->dev); + +} +EXPORT_SYMBOL_GPL(intel_pmt_dev_create); + +void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, + struct intel_pmt_namespace *ns) +{ + struct device *dev = kobj_to_dev(entry->kobj); + + if (entry->size) + sysfs_remove_bin_file(entry->kobj, &entry->pmt_bin_attr); + + if (ns->attr_grp) + sysfs_remove_group(entry->kobj, ns->attr_grp); + + device_unregister(dev); + xa_erase(ns->xa, entry->devid); +} +EXPORT_SYMBOL_GPL(intel_pmt_dev_destroy); + +static int __init pmt_class_init(void) +{ + return class_register(&intel_pmt_class); +} + +static void __exit pmt_class_exit(void) +{ + class_unregister(&intel_pmt_class); +} + +module_init(pmt_class_init); +module_exit(pmt_class_exit); + +MODULE_AUTHOR("Alexander Duyck "); +MODULE_DESCRIPTION("Intel PMT Class driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h new file mode 100644 index 000000000000..1337019c2873 --- /dev/null +++ b/drivers/platform/x86/intel/pmt/class.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _INTEL_PMT_CLASS_H +#define _INTEL_PMT_CLASS_H + +#include +#include +#include +#include +#include +#include + +/* PMT access types */ +#define ACCESS_BARID 2 +#define ACCESS_LOCAL 3 + +/* PMT discovery base address/offset register layout */ +#define GET_BIR(v) ((v) & GENMASK(2, 0)) +#define GET_ADDRESS(v) ((v) & GENMASK(31, 3)) + +struct intel_pmt_entry { + struct bin_attribute pmt_bin_attr; + struct kobject *kobj; + void __iomem *disc_table; + void __iomem *base; + unsigned long base_addr; + size_t size; + u32 guid; + int devid; +}; + +struct intel_pmt_header { + u32 base_offset; + u32 size; + u32 guid; + u8 access_type; +}; + +struct intel_pmt_namespace { + const char *name; + struct xarray *xa; + const struct attribute_group *attr_grp; + int (*pmt_header_decode)(struct intel_pmt_entry *entry, + struct intel_pmt_header *header, + struct device *dev); +}; + +bool intel_pmt_is_early_client_hw(struct device *dev); +int intel_pmt_dev_create(struct intel_pmt_entry *entry, + struct intel_pmt_namespace *ns, + struct platform_device *pdev, int idx); +void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, + struct intel_pmt_namespace *ns); +#endif diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c new file mode 100644 index 000000000000..1c1021f04d3c --- /dev/null +++ b/drivers/platform/x86/intel/pmt/crashlog.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Platform Monitoring Technology Crashlog driver + * + * Copyright (c) 2020, Intel Corporation. + * All Rights Reserved. + * + * Author: "Alexander Duyck" + */ + +#include +#include +#include +#include +#include +#include + +#include "class.h" + +#define DRV_NAME "pmt_crashlog" + +/* Crashlog discovery header types */ +#define CRASH_TYPE_OOBMSM 1 + +/* Control Flags */ +#define CRASHLOG_FLAG_DISABLE BIT(28) + +/* + * Bits 29 and 30 control the state of bit 31. + * + * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured. + * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31. + * Bit 31 is the read-only status with a 1 indicating log is complete. + */ +#define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(29) +#define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(30) +#define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) +#define CRASHLOG_FLAG_TRIGGER_MASK GENMASK(31, 28) + +/* Crashlog Discovery Header */ +#define CONTROL_OFFSET 0x0 +#define GUID_OFFSET 0x4 +#define BASE_OFFSET 0x8 +#define SIZE_OFFSET 0xC +#define GET_ACCESS(v) ((v) & GENMASK(3, 0)) +#define GET_TYPE(v) (((v) & GENMASK(7, 4)) >> 4) +#define GET_VERSION(v) (((v) & GENMASK(19, 16)) >> 16) +/* size is in bytes */ +#define GET_SIZE(v) ((v) * sizeof(u32)) + +struct crashlog_entry { + /* entry must be first member of struct */ + struct intel_pmt_entry entry; + struct mutex control_mutex; +}; + +struct pmt_crashlog_priv { + int num_entries; + struct crashlog_entry entry[]; +}; + +/* + * I/O + */ +static bool pmt_crashlog_complete(struct intel_pmt_entry *entry) +{ + u32 control = readl(entry->disc_table + CONTROL_OFFSET); + + /* return current value of the crashlog complete flag */ + return !!(control & CRASHLOG_FLAG_TRIGGER_COMPLETE); +} + +static bool pmt_crashlog_disabled(struct intel_pmt_entry *entry) +{ + u32 control = readl(entry->disc_table + CONTROL_OFFSET); + + /* return current value of the crashlog disabled flag */ + return !!(control & CRASHLOG_FLAG_DISABLE); +} + +static bool pmt_crashlog_supported(struct intel_pmt_entry *entry) +{ + u32 discovery_header = readl(entry->disc_table + CONTROL_OFFSET); + u32 crash_type, version; + + crash_type = GET_TYPE(discovery_header); + version = GET_VERSION(discovery_header); + + /* + * Currently we only recognize OOBMSM version 0 devices. + * We can ignore all other crashlog devices in the system. + */ + return crash_type == CRASH_TYPE_OOBMSM && version == 0; +} + +static void pmt_crashlog_set_disable(struct intel_pmt_entry *entry, + bool disable) +{ + u32 control = readl(entry->disc_table + CONTROL_OFFSET); + + /* clear trigger bits so we are only modifying disable flag */ + control &= ~CRASHLOG_FLAG_TRIGGER_MASK; + + if (disable) + control |= CRASHLOG_FLAG_DISABLE; + else + control &= ~CRASHLOG_FLAG_DISABLE; + + writel(control, entry->disc_table + CONTROL_OFFSET); +} + +static void pmt_crashlog_set_clear(struct intel_pmt_entry *entry) +{ + u32 control = readl(entry->disc_table + CONTROL_OFFSET); + + control &= ~CRASHLOG_FLAG_TRIGGER_MASK; + control |= CRASHLOG_FLAG_TRIGGER_CLEAR; + + writel(control, entry->disc_table + CONTROL_OFFSET); +} + +static void pmt_crashlog_set_execute(struct intel_pmt_entry *entry) +{ + u32 control = readl(entry->disc_table + CONTROL_OFFSET); + + control &= ~CRASHLOG_FLAG_TRIGGER_MASK; + control |= CRASHLOG_FLAG_TRIGGER_EXECUTE; + + writel(control, entry->disc_table + CONTROL_OFFSET); +} + +/* + * sysfs + */ +static ssize_t +enable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct intel_pmt_entry *entry = dev_get_drvdata(dev); + int enabled = !pmt_crashlog_disabled(entry); + + return sprintf(buf, "%d\n", enabled); +} + +static ssize_t +enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct crashlog_entry *entry; + bool enabled; + int result; + + entry = dev_get_drvdata(dev); + + result = kstrtobool(buf, &enabled); + if (result) + return result; + + mutex_lock(&entry->control_mutex); + pmt_crashlog_set_disable(&entry->entry, !enabled); + mutex_unlock(&entry->control_mutex); + + return count; +} +static DEVICE_ATTR_RW(enable); + +static ssize_t +trigger_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct intel_pmt_entry *entry; + int trigger; + + entry = dev_get_drvdata(dev); + trigger = pmt_crashlog_complete(entry); + + return sprintf(buf, "%d\n", trigger); +} + +static ssize_t +trigger_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct crashlog_entry *entry; + bool trigger; + int result; + + entry = dev_get_drvdata(dev); + + result = kstrtobool(buf, &trigger); + if (result) + return result; + + mutex_lock(&entry->control_mutex); + + if (!trigger) { + pmt_crashlog_set_clear(&entry->entry); + } else if (pmt_crashlog_complete(&entry->entry)) { + /* we cannot trigger a new crash if one is still pending */ + result = -EEXIST; + goto err; + } else if (pmt_crashlog_disabled(&entry->entry)) { + /* if device is currently disabled, return busy */ + result = -EBUSY; + goto err; + } else { + pmt_crashlog_set_execute(&entry->entry); + } + + result = count; +err: + mutex_unlock(&entry->control_mutex); + return result; +} +static DEVICE_ATTR_RW(trigger); + +static struct attribute *pmt_crashlog_attrs[] = { + &dev_attr_enable.attr, + &dev_attr_trigger.attr, + NULL +}; + +static const struct attribute_group pmt_crashlog_group = { + .attrs = pmt_crashlog_attrs, +}; + +static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry, + struct intel_pmt_header *header, + struct device *dev) +{ + void __iomem *disc_table = entry->disc_table; + struct crashlog_entry *crashlog; + + if (!pmt_crashlog_supported(entry)) + return 1; + + /* initialize control mutex */ + crashlog = container_of(entry, struct crashlog_entry, entry); + mutex_init(&crashlog->control_mutex); + + header->access_type = GET_ACCESS(readl(disc_table)); + header->guid = readl(disc_table + GUID_OFFSET); + header->base_offset = readl(disc_table + BASE_OFFSET); + + /* Size is measured in DWORDS, but accessor returns bytes */ + header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET)); + + return 0; +} + +static DEFINE_XARRAY_ALLOC(crashlog_array); +static struct intel_pmt_namespace pmt_crashlog_ns = { + .name = "crashlog", + .xa = &crashlog_array, + .attr_grp = &pmt_crashlog_group, + .pmt_header_decode = pmt_crashlog_header_decode, +}; + +/* + * initialization + */ +static int pmt_crashlog_remove(struct platform_device *pdev) +{ + struct pmt_crashlog_priv *priv = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < priv->num_entries; i++) + intel_pmt_dev_destroy(&priv->entry[i].entry, &pmt_crashlog_ns); + + return 0; +} + +static int pmt_crashlog_probe(struct platform_device *pdev) +{ + struct pmt_crashlog_priv *priv; + size_t size; + int i, ret; + + size = struct_size(priv, entry, pdev->num_resources); + priv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + for (i = 0; i < pdev->num_resources; i++) { + struct intel_pmt_entry *entry = &priv->entry[i].entry; + + ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, pdev, i); + if (ret < 0) + goto abort_probe; + if (ret) + continue; + + priv->num_entries++; + } + + return 0; +abort_probe: + pmt_crashlog_remove(pdev); + return ret; +} + +static struct platform_driver pmt_crashlog_driver = { + .driver = { + .name = DRV_NAME, + }, + .remove = pmt_crashlog_remove, + .probe = pmt_crashlog_probe, +}; + +static int __init pmt_crashlog_init(void) +{ + return platform_driver_register(&pmt_crashlog_driver); +} + +static void __exit pmt_crashlog_exit(void) +{ + platform_driver_unregister(&pmt_crashlog_driver); + xa_destroy(&crashlog_array); +} + +module_init(pmt_crashlog_init); +module_exit(pmt_crashlog_exit); + +MODULE_AUTHOR("Alexander Duyck "); +MODULE_DESCRIPTION("Intel PMT Crashlog driver"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c new file mode 100644 index 000000000000..a58843360fbf --- /dev/null +++ b/drivers/platform/x86/intel/pmt/telemetry.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Platform Monitory Technology Telemetry driver + * + * Copyright (c) 2020, Intel Corporation. + * All Rights Reserved. + * + * Author: "David E. Box" + */ + +#include +#include +#include +#include +#include +#include + +#include "class.h" + +#define TELEM_DEV_NAME "pmt_telemetry" + +#define TELEM_SIZE_OFFSET 0x0 +#define TELEM_GUID_OFFSET 0x4 +#define TELEM_BASE_OFFSET 0x8 +#define TELEM_ACCESS(v) ((v) & GENMASK(3, 0)) +/* size is in bytes */ +#define TELEM_SIZE(v) (((v) & GENMASK(27, 12)) >> 10) + +/* Used by client hardware to identify a fixed telemetry entry*/ +#define TELEM_CLIENT_FIXED_BLOCK_GUID 0x10000000 + +struct pmt_telem_priv { + int num_entries; + struct intel_pmt_entry entry[]; +}; + +static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry, + struct device *dev) +{ + u32 guid = readl(entry->disc_table + TELEM_GUID_OFFSET); + + if (guid != TELEM_CLIENT_FIXED_BLOCK_GUID) + return false; + + return intel_pmt_is_early_client_hw(dev); +} + +static int pmt_telem_header_decode(struct intel_pmt_entry *entry, + struct intel_pmt_header *header, + struct device *dev) +{ + void __iomem *disc_table = entry->disc_table; + + if (pmt_telem_region_overlaps(entry, dev)) + return 1; + + header->access_type = TELEM_ACCESS(readl(disc_table)); + header->guid = readl(disc_table + TELEM_GUID_OFFSET); + header->base_offset = readl(disc_table + TELEM_BASE_OFFSET); + + /* Size is measured in DWORDS, but accessor returns bytes */ + header->size = TELEM_SIZE(readl(disc_table)); + + return 0; +} + +static DEFINE_XARRAY_ALLOC(telem_array); +static struct intel_pmt_namespace pmt_telem_ns = { + .name = "telem", + .xa = &telem_array, + .pmt_header_decode = pmt_telem_header_decode, +}; + +static int pmt_telem_remove(struct platform_device *pdev) +{ + struct pmt_telem_priv *priv = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < priv->num_entries; i++) + intel_pmt_dev_destroy(&priv->entry[i], &pmt_telem_ns); + + return 0; +} + +static int pmt_telem_probe(struct platform_device *pdev) +{ + struct pmt_telem_priv *priv; + size_t size; + int i, ret; + + size = struct_size(priv, entry, pdev->num_resources); + priv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + for (i = 0; i < pdev->num_resources; i++) { + struct intel_pmt_entry *entry = &priv->entry[i]; + + ret = intel_pmt_dev_create(entry, &pmt_telem_ns, pdev, i); + if (ret < 0) + goto abort_probe; + if (ret) + continue; + + priv->num_entries++; + } + + return 0; +abort_probe: + pmt_telem_remove(pdev); + return ret; +} + +static struct platform_driver pmt_telem_driver = { + .driver = { + .name = TELEM_DEV_NAME, + }, + .remove = pmt_telem_remove, + .probe = pmt_telem_probe, +}; + +static int __init pmt_telem_init(void) +{ + return platform_driver_register(&pmt_telem_driver); +} +module_init(pmt_telem_init); + +static void __exit pmt_telem_exit(void) +{ + platform_driver_unregister(&pmt_telem_driver); + xa_destroy(&telem_array); +} +module_exit(pmt_telem_exit); + +MODULE_AUTHOR("David E. Box "); +MODULE_DESCRIPTION("Intel PMT Telemetry driver"); +MODULE_ALIAS("platform:" TELEM_DEV_NAME); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel_pmt_class.c b/drivers/platform/x86/intel_pmt_class.c deleted file mode 100644 index c86ff15b1ed5..000000000000 --- a/drivers/platform/x86/intel_pmt_class.c +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel Platform Monitory Technology Telemetry driver - * - * Copyright (c) 2020, Intel Corporation. - * All Rights Reserved. - * - * Author: "Alexander Duyck" - */ - -#include -#include -#include -#include - -#include "intel_pmt_class.h" - -#define PMT_XA_START 0 -#define PMT_XA_MAX INT_MAX -#define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) - -/* - * Early implementations of PMT on client platforms have some - * differences from the server platforms (which use the Out Of Band - * Management Services Module OOBMSM). This list tracks those - * platforms as needed to handle those differences. Newer client - * platforms are expected to be fully compatible with server. - */ -static const struct pci_device_id pmt_telem_early_client_pci_ids[] = { - { PCI_VDEVICE(INTEL, 0x467d) }, /* ADL */ - { PCI_VDEVICE(INTEL, 0x490e) }, /* DG1 */ - { PCI_VDEVICE(INTEL, 0x9a0d) }, /* TGL */ - { } -}; - -bool intel_pmt_is_early_client_hw(struct device *dev) -{ - struct pci_dev *parent = to_pci_dev(dev->parent); - - return !!pci_match_id(pmt_telem_early_client_pci_ids, parent); -} -EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); - -/* - * sysfs - */ -static ssize_t -intel_pmt_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, loff_t off, - size_t count) -{ - struct intel_pmt_entry *entry = container_of(attr, - struct intel_pmt_entry, - pmt_bin_attr); - - if (off < 0) - return -EINVAL; - - if (off >= entry->size) - return 0; - - if (count > entry->size - off) - count = entry->size - off; - - memcpy_fromio(buf, entry->base + off, count); - - return count; -} - -static int -intel_pmt_mmap(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, struct vm_area_struct *vma) -{ - struct intel_pmt_entry *entry = container_of(attr, - struct intel_pmt_entry, - pmt_bin_attr); - unsigned long vsize = vma->vm_end - vma->vm_start; - struct device *dev = kobj_to_dev(kobj); - unsigned long phys = entry->base_addr; - unsigned long pfn = PFN_DOWN(phys); - unsigned long psize; - - if (vma->vm_flags & (VM_WRITE | VM_MAYWRITE)) - return -EROFS; - - psize = (PFN_UP(entry->base_addr + entry->size) - pfn) * PAGE_SIZE; - if (vsize > psize) { - dev_err(dev, "Requested mmap size is too large\n"); - return -EINVAL; - } - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - if (io_remap_pfn_range(vma, vma->vm_start, pfn, - vsize, vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - -static ssize_t -guid_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct intel_pmt_entry *entry = dev_get_drvdata(dev); - - return sprintf(buf, "0x%x\n", entry->guid); -} -static DEVICE_ATTR_RO(guid); - -static ssize_t size_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct intel_pmt_entry *entry = dev_get_drvdata(dev); - - return sprintf(buf, "%zu\n", entry->size); -} -static DEVICE_ATTR_RO(size); - -static ssize_t -offset_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct intel_pmt_entry *entry = dev_get_drvdata(dev); - - return sprintf(buf, "%lu\n", offset_in_page(entry->base_addr)); -} -static DEVICE_ATTR_RO(offset); - -static struct attribute *intel_pmt_attrs[] = { - &dev_attr_guid.attr, - &dev_attr_size.attr, - &dev_attr_offset.attr, - NULL -}; -ATTRIBUTE_GROUPS(intel_pmt); - -static struct class intel_pmt_class = { - .name = "intel_pmt", - .owner = THIS_MODULE, - .dev_groups = intel_pmt_groups, -}; - -static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, - struct device *dev, - struct resource *disc_res) -{ - struct pci_dev *pci_dev = to_pci_dev(dev->parent); - u8 bir; - - /* - * The base offset should always be 8 byte aligned. - * - * For non-local access types the lower 3 bits of base offset - * contains the index of the base address register where the - * telemetry can be found. - */ - bir = GET_BIR(header->base_offset); - - /* Local access and BARID only for now */ - switch (header->access_type) { - case ACCESS_LOCAL: - if (bir) { - dev_err(dev, - "Unsupported BAR index %d for access type %d\n", - bir, header->access_type); - return -EINVAL; - } - /* - * For access_type LOCAL, the base address is as follows: - * base address = end of discovery region + base offset - */ - entry->base_addr = disc_res->end + 1 + header->base_offset; - - /* - * Some hardware use a different calculation for the base address - * when access_type == ACCESS_LOCAL. On the these systems - * ACCCESS_LOCAL refers to an address in the same BAR as the - * header but at a fixed offset. But as the header address was - * supplied to the driver, we don't know which BAR it was in. - * So search for the bar whose range includes the header address. - */ - if (intel_pmt_is_early_client_hw(dev)) { - int i; - - entry->base_addr = 0; - for (i = 0; i < 6; i++) - if (disc_res->start >= pci_resource_start(pci_dev, i) && - (disc_res->start <= pci_resource_end(pci_dev, i))) { - entry->base_addr = pci_resource_start(pci_dev, i) + - header->base_offset; - break; - } - if (!entry->base_addr) - return -EINVAL; - } - - break; - case ACCESS_BARID: - /* - * If another BAR was specified then the base offset - * represents the offset within that BAR. SO retrieve the - * address from the parent PCI device and add offset. - */ - entry->base_addr = pci_resource_start(pci_dev, bir) + - GET_ADDRESS(header->base_offset); - break; - default: - dev_err(dev, "Unsupported access type %d\n", - header->access_type); - return -EINVAL; - } - - entry->guid = header->guid; - entry->size = header->size; - - return 0; -} - -static int intel_pmt_dev_register(struct intel_pmt_entry *entry, - struct intel_pmt_namespace *ns, - struct device *parent) -{ - struct resource res = {0}; - struct device *dev; - int ret; - - ret = xa_alloc(ns->xa, &entry->devid, entry, PMT_XA_LIMIT, GFP_KERNEL); - if (ret) - return ret; - - dev = device_create(&intel_pmt_class, parent, MKDEV(0, 0), entry, - "%s%d", ns->name, entry->devid); - - if (IS_ERR(dev)) { - dev_err(parent, "Could not create %s%d device node\n", - ns->name, entry->devid); - ret = PTR_ERR(dev); - goto fail_dev_create; - } - - entry->kobj = &dev->kobj; - - if (ns->attr_grp) { - ret = sysfs_create_group(entry->kobj, ns->attr_grp); - if (ret) - goto fail_sysfs; - } - - /* if size is 0 assume no data buffer, so no file needed */ - if (!entry->size) - return 0; - - res.start = entry->base_addr; - res.end = res.start + entry->size - 1; - res.flags = IORESOURCE_MEM; - - entry->base = devm_ioremap_resource(dev, &res); - if (IS_ERR(entry->base)) { - ret = PTR_ERR(entry->base); - goto fail_ioremap; - } - - sysfs_bin_attr_init(&entry->pmt_bin_attr); - entry->pmt_bin_attr.attr.name = ns->name; - entry->pmt_bin_attr.attr.mode = 0440; - entry->pmt_bin_attr.mmap = intel_pmt_mmap; - entry->pmt_bin_attr.read = intel_pmt_read; - entry->pmt_bin_attr.size = entry->size; - - ret = sysfs_create_bin_file(&dev->kobj, &entry->pmt_bin_attr); - if (!ret) - return 0; - -fail_ioremap: - if (ns->attr_grp) - sysfs_remove_group(entry->kobj, ns->attr_grp); -fail_sysfs: - device_unregister(dev); -fail_dev_create: - xa_erase(ns->xa, entry->devid); - - return ret; -} - -int intel_pmt_dev_create(struct intel_pmt_entry *entry, - struct intel_pmt_namespace *ns, - struct platform_device *pdev, int idx) -{ - struct intel_pmt_header header; - struct resource *disc_res; - int ret = -ENODEV; - - disc_res = platform_get_resource(pdev, IORESOURCE_MEM, idx); - if (!disc_res) - return ret; - - entry->disc_table = devm_platform_ioremap_resource(pdev, idx); - if (IS_ERR(entry->disc_table)) - return PTR_ERR(entry->disc_table); - - ret = ns->pmt_header_decode(entry, &header, &pdev->dev); - if (ret) - return ret; - - ret = intel_pmt_populate_entry(entry, &header, &pdev->dev, disc_res); - if (ret) - return ret; - - return intel_pmt_dev_register(entry, ns, &pdev->dev); - -} -EXPORT_SYMBOL_GPL(intel_pmt_dev_create); - -void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, - struct intel_pmt_namespace *ns) -{ - struct device *dev = kobj_to_dev(entry->kobj); - - if (entry->size) - sysfs_remove_bin_file(entry->kobj, &entry->pmt_bin_attr); - - if (ns->attr_grp) - sysfs_remove_group(entry->kobj, ns->attr_grp); - - device_unregister(dev); - xa_erase(ns->xa, entry->devid); -} -EXPORT_SYMBOL_GPL(intel_pmt_dev_destroy); - -static int __init pmt_class_init(void) -{ - return class_register(&intel_pmt_class); -} - -static void __exit pmt_class_exit(void) -{ - class_unregister(&intel_pmt_class); -} - -module_init(pmt_class_init); -module_exit(pmt_class_exit); - -MODULE_AUTHOR("Alexander Duyck "); -MODULE_DESCRIPTION("Intel PMT Class driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel_pmt_class.h b/drivers/platform/x86/intel_pmt_class.h deleted file mode 100644 index 1337019c2873..000000000000 --- a/drivers/platform/x86/intel_pmt_class.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _INTEL_PMT_CLASS_H -#define _INTEL_PMT_CLASS_H - -#include -#include -#include -#include -#include -#include - -/* PMT access types */ -#define ACCESS_BARID 2 -#define ACCESS_LOCAL 3 - -/* PMT discovery base address/offset register layout */ -#define GET_BIR(v) ((v) & GENMASK(2, 0)) -#define GET_ADDRESS(v) ((v) & GENMASK(31, 3)) - -struct intel_pmt_entry { - struct bin_attribute pmt_bin_attr; - struct kobject *kobj; - void __iomem *disc_table; - void __iomem *base; - unsigned long base_addr; - size_t size; - u32 guid; - int devid; -}; - -struct intel_pmt_header { - u32 base_offset; - u32 size; - u32 guid; - u8 access_type; -}; - -struct intel_pmt_namespace { - const char *name; - struct xarray *xa; - const struct attribute_group *attr_grp; - int (*pmt_header_decode)(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, - struct device *dev); -}; - -bool intel_pmt_is_early_client_hw(struct device *dev); -int intel_pmt_dev_create(struct intel_pmt_entry *entry, - struct intel_pmt_namespace *ns, - struct platform_device *pdev, int idx); -void intel_pmt_dev_destroy(struct intel_pmt_entry *entry, - struct intel_pmt_namespace *ns); -#endif diff --git a/drivers/platform/x86/intel_pmt_crashlog.c b/drivers/platform/x86/intel_pmt_crashlog.c deleted file mode 100644 index 56963ceb6345..000000000000 --- a/drivers/platform/x86/intel_pmt_crashlog.c +++ /dev/null @@ -1,327 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel Platform Monitoring Technology Crashlog driver - * - * Copyright (c) 2020, Intel Corporation. - * All Rights Reserved. - * - * Author: "Alexander Duyck" - */ - -#include -#include -#include -#include -#include -#include - -#include "intel_pmt_class.h" - -#define DRV_NAME "pmt_crashlog" - -/* Crashlog discovery header types */ -#define CRASH_TYPE_OOBMSM 1 - -/* Control Flags */ -#define CRASHLOG_FLAG_DISABLE BIT(28) - -/* - * Bits 29 and 30 control the state of bit 31. - * - * Bit 29 will clear bit 31, if set, allowing a new crashlog to be captured. - * Bit 30 will immediately trigger a crashlog to be generated, setting bit 31. - * Bit 31 is the read-only status with a 1 indicating log is complete. - */ -#define CRASHLOG_FLAG_TRIGGER_CLEAR BIT(29) -#define CRASHLOG_FLAG_TRIGGER_EXECUTE BIT(30) -#define CRASHLOG_FLAG_TRIGGER_COMPLETE BIT(31) -#define CRASHLOG_FLAG_TRIGGER_MASK GENMASK(31, 28) - -/* Crashlog Discovery Header */ -#define CONTROL_OFFSET 0x0 -#define GUID_OFFSET 0x4 -#define BASE_OFFSET 0x8 -#define SIZE_OFFSET 0xC -#define GET_ACCESS(v) ((v) & GENMASK(3, 0)) -#define GET_TYPE(v) (((v) & GENMASK(7, 4)) >> 4) -#define GET_VERSION(v) (((v) & GENMASK(19, 16)) >> 16) -/* size is in bytes */ -#define GET_SIZE(v) ((v) * sizeof(u32)) - -struct crashlog_entry { - /* entry must be first member of struct */ - struct intel_pmt_entry entry; - struct mutex control_mutex; -}; - -struct pmt_crashlog_priv { - int num_entries; - struct crashlog_entry entry[]; -}; - -/* - * I/O - */ -static bool pmt_crashlog_complete(struct intel_pmt_entry *entry) -{ - u32 control = readl(entry->disc_table + CONTROL_OFFSET); - - /* return current value of the crashlog complete flag */ - return !!(control & CRASHLOG_FLAG_TRIGGER_COMPLETE); -} - -static bool pmt_crashlog_disabled(struct intel_pmt_entry *entry) -{ - u32 control = readl(entry->disc_table + CONTROL_OFFSET); - - /* return current value of the crashlog disabled flag */ - return !!(control & CRASHLOG_FLAG_DISABLE); -} - -static bool pmt_crashlog_supported(struct intel_pmt_entry *entry) -{ - u32 discovery_header = readl(entry->disc_table + CONTROL_OFFSET); - u32 crash_type, version; - - crash_type = GET_TYPE(discovery_header); - version = GET_VERSION(discovery_header); - - /* - * Currently we only recognize OOBMSM version 0 devices. - * We can ignore all other crashlog devices in the system. - */ - return crash_type == CRASH_TYPE_OOBMSM && version == 0; -} - -static void pmt_crashlog_set_disable(struct intel_pmt_entry *entry, - bool disable) -{ - u32 control = readl(entry->disc_table + CONTROL_OFFSET); - - /* clear trigger bits so we are only modifying disable flag */ - control &= ~CRASHLOG_FLAG_TRIGGER_MASK; - - if (disable) - control |= CRASHLOG_FLAG_DISABLE; - else - control &= ~CRASHLOG_FLAG_DISABLE; - - writel(control, entry->disc_table + CONTROL_OFFSET); -} - -static void pmt_crashlog_set_clear(struct intel_pmt_entry *entry) -{ - u32 control = readl(entry->disc_table + CONTROL_OFFSET); - - control &= ~CRASHLOG_FLAG_TRIGGER_MASK; - control |= CRASHLOG_FLAG_TRIGGER_CLEAR; - - writel(control, entry->disc_table + CONTROL_OFFSET); -} - -static void pmt_crashlog_set_execute(struct intel_pmt_entry *entry) -{ - u32 control = readl(entry->disc_table + CONTROL_OFFSET); - - control &= ~CRASHLOG_FLAG_TRIGGER_MASK; - control |= CRASHLOG_FLAG_TRIGGER_EXECUTE; - - writel(control, entry->disc_table + CONTROL_OFFSET); -} - -/* - * sysfs - */ -static ssize_t -enable_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct intel_pmt_entry *entry = dev_get_drvdata(dev); - int enabled = !pmt_crashlog_disabled(entry); - - return sprintf(buf, "%d\n", enabled); -} - -static ssize_t -enable_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct crashlog_entry *entry; - bool enabled; - int result; - - entry = dev_get_drvdata(dev); - - result = kstrtobool(buf, &enabled); - if (result) - return result; - - mutex_lock(&entry->control_mutex); - pmt_crashlog_set_disable(&entry->entry, !enabled); - mutex_unlock(&entry->control_mutex); - - return count; -} -static DEVICE_ATTR_RW(enable); - -static ssize_t -trigger_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct intel_pmt_entry *entry; - int trigger; - - entry = dev_get_drvdata(dev); - trigger = pmt_crashlog_complete(entry); - - return sprintf(buf, "%d\n", trigger); -} - -static ssize_t -trigger_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct crashlog_entry *entry; - bool trigger; - int result; - - entry = dev_get_drvdata(dev); - - result = kstrtobool(buf, &trigger); - if (result) - return result; - - mutex_lock(&entry->control_mutex); - - if (!trigger) { - pmt_crashlog_set_clear(&entry->entry); - } else if (pmt_crashlog_complete(&entry->entry)) { - /* we cannot trigger a new crash if one is still pending */ - result = -EEXIST; - goto err; - } else if (pmt_crashlog_disabled(&entry->entry)) { - /* if device is currently disabled, return busy */ - result = -EBUSY; - goto err; - } else { - pmt_crashlog_set_execute(&entry->entry); - } - - result = count; -err: - mutex_unlock(&entry->control_mutex); - return result; -} -static DEVICE_ATTR_RW(trigger); - -static struct attribute *pmt_crashlog_attrs[] = { - &dev_attr_enable.attr, - &dev_attr_trigger.attr, - NULL -}; - -static const struct attribute_group pmt_crashlog_group = { - .attrs = pmt_crashlog_attrs, -}; - -static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, - struct device *dev) -{ - void __iomem *disc_table = entry->disc_table; - struct crashlog_entry *crashlog; - - if (!pmt_crashlog_supported(entry)) - return 1; - - /* initialize control mutex */ - crashlog = container_of(entry, struct crashlog_entry, entry); - mutex_init(&crashlog->control_mutex); - - header->access_type = GET_ACCESS(readl(disc_table)); - header->guid = readl(disc_table + GUID_OFFSET); - header->base_offset = readl(disc_table + BASE_OFFSET); - - /* Size is measured in DWORDS, but accessor returns bytes */ - header->size = GET_SIZE(readl(disc_table + SIZE_OFFSET)); - - return 0; -} - -static DEFINE_XARRAY_ALLOC(crashlog_array); -static struct intel_pmt_namespace pmt_crashlog_ns = { - .name = "crashlog", - .xa = &crashlog_array, - .attr_grp = &pmt_crashlog_group, - .pmt_header_decode = pmt_crashlog_header_decode, -}; - -/* - * initialization - */ -static int pmt_crashlog_remove(struct platform_device *pdev) -{ - struct pmt_crashlog_priv *priv = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < priv->num_entries; i++) - intel_pmt_dev_destroy(&priv->entry[i].entry, &pmt_crashlog_ns); - - return 0; -} - -static int pmt_crashlog_probe(struct platform_device *pdev) -{ - struct pmt_crashlog_priv *priv; - size_t size; - int i, ret; - - size = struct_size(priv, entry, pdev->num_resources); - priv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!priv) - return -ENOMEM; - - platform_set_drvdata(pdev, priv); - - for (i = 0; i < pdev->num_resources; i++) { - struct intel_pmt_entry *entry = &priv->entry[i].entry; - - ret = intel_pmt_dev_create(entry, &pmt_crashlog_ns, pdev, i); - if (ret < 0) - goto abort_probe; - if (ret) - continue; - - priv->num_entries++; - } - - return 0; -abort_probe: - pmt_crashlog_remove(pdev); - return ret; -} - -static struct platform_driver pmt_crashlog_driver = { - .driver = { - .name = DRV_NAME, - }, - .remove = pmt_crashlog_remove, - .probe = pmt_crashlog_probe, -}; - -static int __init pmt_crashlog_init(void) -{ - return platform_driver_register(&pmt_crashlog_driver); -} - -static void __exit pmt_crashlog_exit(void) -{ - platform_driver_unregister(&pmt_crashlog_driver); - xa_destroy(&crashlog_array); -} - -module_init(pmt_crashlog_init); -module_exit(pmt_crashlog_exit); - -MODULE_AUTHOR("Alexander Duyck "); -MODULE_DESCRIPTION("Intel PMT Crashlog driver"); -MODULE_ALIAS("platform:" DRV_NAME); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel_pmt_telemetry.c b/drivers/platform/x86/intel_pmt_telemetry.c deleted file mode 100644 index 9b95ef050457..000000000000 --- a/drivers/platform/x86/intel_pmt_telemetry.c +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel Platform Monitory Technology Telemetry driver - * - * Copyright (c) 2020, Intel Corporation. - * All Rights Reserved. - * - * Author: "David E. Box" - */ - -#include -#include -#include -#include -#include -#include - -#include "intel_pmt_class.h" - -#define TELEM_DEV_NAME "pmt_telemetry" - -#define TELEM_SIZE_OFFSET 0x0 -#define TELEM_GUID_OFFSET 0x4 -#define TELEM_BASE_OFFSET 0x8 -#define TELEM_ACCESS(v) ((v) & GENMASK(3, 0)) -/* size is in bytes */ -#define TELEM_SIZE(v) (((v) & GENMASK(27, 12)) >> 10) - -/* Used by client hardware to identify a fixed telemetry entry*/ -#define TELEM_CLIENT_FIXED_BLOCK_GUID 0x10000000 - -struct pmt_telem_priv { - int num_entries; - struct intel_pmt_entry entry[]; -}; - -static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry, - struct device *dev) -{ - u32 guid = readl(entry->disc_table + TELEM_GUID_OFFSET); - - if (guid != TELEM_CLIENT_FIXED_BLOCK_GUID) - return false; - - return intel_pmt_is_early_client_hw(dev); -} - -static int pmt_telem_header_decode(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, - struct device *dev) -{ - void __iomem *disc_table = entry->disc_table; - - if (pmt_telem_region_overlaps(entry, dev)) - return 1; - - header->access_type = TELEM_ACCESS(readl(disc_table)); - header->guid = readl(disc_table + TELEM_GUID_OFFSET); - header->base_offset = readl(disc_table + TELEM_BASE_OFFSET); - - /* Size is measured in DWORDS, but accessor returns bytes */ - header->size = TELEM_SIZE(readl(disc_table)); - - return 0; -} - -static DEFINE_XARRAY_ALLOC(telem_array); -static struct intel_pmt_namespace pmt_telem_ns = { - .name = "telem", - .xa = &telem_array, - .pmt_header_decode = pmt_telem_header_decode, -}; - -static int pmt_telem_remove(struct platform_device *pdev) -{ - struct pmt_telem_priv *priv = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < priv->num_entries; i++) - intel_pmt_dev_destroy(&priv->entry[i], &pmt_telem_ns); - - return 0; -} - -static int pmt_telem_probe(struct platform_device *pdev) -{ - struct pmt_telem_priv *priv; - size_t size; - int i, ret; - - size = struct_size(priv, entry, pdev->num_resources); - priv = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); - if (!priv) - return -ENOMEM; - - platform_set_drvdata(pdev, priv); - - for (i = 0; i < pdev->num_resources; i++) { - struct intel_pmt_entry *entry = &priv->entry[i]; - - ret = intel_pmt_dev_create(entry, &pmt_telem_ns, pdev, i); - if (ret < 0) - goto abort_probe; - if (ret) - continue; - - priv->num_entries++; - } - - return 0; -abort_probe: - pmt_telem_remove(pdev); - return ret; -} - -static struct platform_driver pmt_telem_driver = { - .driver = { - .name = TELEM_DEV_NAME, - }, - .remove = pmt_telem_remove, - .probe = pmt_telem_probe, -}; - -static int __init pmt_telem_init(void) -{ - return platform_driver_register(&pmt_telem_driver); -} -module_init(pmt_telem_init); - -static void __exit pmt_telem_exit(void) -{ - platform_driver_unregister(&pmt_telem_driver); - xa_destroy(&telem_array); -} -module_exit(pmt_telem_exit); - -MODULE_AUTHOR("David E. Box "); -MODULE_DESCRIPTION("Intel PMT Telemetry driver"); -MODULE_ALIAS("platform:" TELEM_DEV_NAME); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 53cbf462f6b5c9de364efdf443ffb74ed082463a Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 2 Aug 2021 10:58:20 -0700 Subject: dmaengine: idxd: Remove unused status variable in irq_process_work_list() status is no longer used within this block: drivers/dma/idxd/irq.c:255:6: warning: unused variable 'status' [-Wunused-variable] u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; ^ 1 warning generated. Fixes: b60bb6e2bfc1 ("dmaengine: idxd: fix abort status check") Signed-off-by: Nathan Chancellor Acked-by: Dave Jiang Link: https://lore.kernel.org/r/20210802175820.3153920-1-nathan@kernel.org Signed-off-by: Vinod Koul --- drivers/dma/idxd/irq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 65dc7bbb0a13..91e46ca3a0ad 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -252,8 +252,6 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, spin_unlock_irqrestore(&irq_entry->list_lock, flags); list_for_each_entry(desc, &flist, list) { - u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; - /* * Check against the original status as ABORT is software defined * and 0xff, which DSA_COMP_STATUS_MASK can mask out. -- cgit v1.2.3-70-g09d2 From dfa6a2f4c2eab087959faff5a87119c8ff766c74 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Aug 2021 21:43:53 +0300 Subject: dmaengine: dw: Remove error message from DT parsing code Users are a bit frightened of the harmless message that tells that DT is missed on ACPI-based platforms. Remove it for good, it will simplify the future conversion to fwnode and device property APIs. Fixes: a9ddb575d6d6 ("dmaengine: dw_dmac: Enhance device tree support") Depends-on: f5e84eae7956 ("dmaengine: dw: platform: Split OF helpers to separate module") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199379 Signed-off-by: Andy Shevchenko Reviewed-by: Serge Semin Tested-by: Serge Semin Link: https://lore.kernel.org/r/20210802184355.49879-1-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw/of.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/dma/dw/of.c b/drivers/dma/dw/of.c index c1cf7675b9d1..4d2b89142721 100644 --- a/drivers/dma/dw/of.c +++ b/drivers/dma/dw/of.c @@ -54,11 +54,6 @@ struct dw_dma_platform_data *dw_dma_parse_dt(struct platform_device *pdev) u32 nr_masters; u32 nr_channels; - if (!np) { - dev_err(&pdev->dev, "Missing DT data\n"); - return NULL; - } - if (of_property_read_u32(np, "dma-masters", &nr_masters)) return NULL; if (nr_masters < 1 || nr_masters > DW_DMA_MAX_NR_MASTERS) -- cgit v1.2.3-70-g09d2 From 08bf54fcf5ca87328541e035090c6a85c8e064f4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Aug 2021 21:43:54 +0300 Subject: dmaengine: dw: Convert members to u32 in platform data u32 is a type that is used for properties retrieval from DT. With the type change it allows to clean up properties reading routine. While at it, order the fields in way how they are parsed. Signed-off-by: Andy Shevchenko Reviewed-by: Serge Semin Tested-by: Serge Semin Link: https://lore.kernel.org/r/20210802184355.49879-2-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- include/linux/platform_data/dma-dw.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/linux/platform_data/dma-dw.h b/include/linux/platform_data/dma-dw.h index b11b0c8bc5da..860ba4bc5ead 100644 --- a/include/linux/platform_data/dma-dw.h +++ b/include/linux/platform_data/dma-dw.h @@ -41,11 +41,11 @@ struct dw_dma_slave { /** * struct dw_dma_platform_data - Controller configuration parameters + * @nr_masters: Number of AHB masters supported by the controller * @nr_channels: Number of channels supported by hardware (max 8) * @chan_allocation_order: Allocate channels starting from 0 or 7 * @chan_priority: Set channel priority increasing from 0 to 7 or 7 to 0. * @block_size: Maximum block size supported by the controller - * @nr_masters: Number of AHB masters supported by the controller * @data_width: Maximum data width supported by hardware per AHB master * (in bytes, power of 2) * @multi_block: Multi block transfers supported by hardware per channel. @@ -55,25 +55,25 @@ struct dw_dma_slave { * @quirks: Optional platform quirks. */ struct dw_dma_platform_data { - unsigned int nr_channels; + u32 nr_masters; + u32 nr_channels; #define CHAN_ALLOCATION_ASCENDING 0 /* zero to seven */ #define CHAN_ALLOCATION_DESCENDING 1 /* seven to zero */ - unsigned char chan_allocation_order; + u32 chan_allocation_order; #define CHAN_PRIORITY_ASCENDING 0 /* chan0 highest */ #define CHAN_PRIORITY_DESCENDING 1 /* chan7 highest */ - unsigned char chan_priority; - unsigned int block_size; - unsigned char nr_masters; - unsigned char data_width[DW_DMA_MAX_NR_MASTERS]; - unsigned char multi_block[DW_DMA_MAX_NR_CHANNELS]; + u32 chan_priority; + u32 block_size; + u32 data_width[DW_DMA_MAX_NR_MASTERS]; + u32 multi_block[DW_DMA_MAX_NR_CHANNELS]; u32 max_burst[DW_DMA_MAX_NR_CHANNELS]; #define CHAN_PROTCTL_PRIVILEGED BIT(0) #define CHAN_PROTCTL_BUFFERABLE BIT(1) #define CHAN_PROTCTL_CACHEABLE BIT(2) #define CHAN_PROTCTL_MASK GENMASK(2, 0) - unsigned char protctl; + u32 protctl; #define DW_DMA_QUIRK_XBAR_PRESENT BIT(0) - unsigned int quirks; + u32 quirks; }; #endif /* _PLATFORM_DATA_DMA_DW_H */ -- cgit v1.2.3-70-g09d2 From d6ff82cc1bff97923dfa0640d27271bc220a5004 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Aug 2021 21:43:55 +0300 Subject: dmaengine: dw: Simplify DT property parser Since we converted internal data types to match DT, there is no need to have an intermediate conversion layer, hence drop a few conditionals and for loops for good. Signed-off-by: Andy Shevchenko Reviewed-by: Serge Semin Tested-by: Serge Semin Link: https://lore.kernel.org/r/20210802184355.49879-3-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- drivers/dma/dw/of.c | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/dma/dw/of.c b/drivers/dma/dw/of.c index 4d2b89142721..523ca806837c 100644 --- a/drivers/dma/dw/of.c +++ b/drivers/dma/dw/of.c @@ -50,7 +50,7 @@ struct dw_dma_platform_data *dw_dma_parse_dt(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct dw_dma_platform_data *pdata; - u32 tmp, arr[DW_DMA_MAX_NR_MASTERS], mb[DW_DMA_MAX_NR_CHANNELS]; + u32 tmp, arr[DW_DMA_MAX_NR_MASTERS]; u32 nr_masters; u32 nr_channels; @@ -71,41 +71,29 @@ struct dw_dma_platform_data *dw_dma_parse_dt(struct platform_device *pdev) pdata->nr_masters = nr_masters; pdata->nr_channels = nr_channels; - if (!of_property_read_u32(np, "chan_allocation_order", &tmp)) - pdata->chan_allocation_order = (unsigned char)tmp; + of_property_read_u32(np, "chan_allocation_order", &pdata->chan_allocation_order); + of_property_read_u32(np, "chan_priority", &pdata->chan_priority); - if (!of_property_read_u32(np, "chan_priority", &tmp)) - pdata->chan_priority = tmp; + of_property_read_u32(np, "block_size", &pdata->block_size); - if (!of_property_read_u32(np, "block_size", &tmp)) - pdata->block_size = tmp; - - if (!of_property_read_u32_array(np, "data-width", arr, nr_masters)) { - for (tmp = 0; tmp < nr_masters; tmp++) - pdata->data_width[tmp] = arr[tmp]; - } else if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) { + /* Try deprecated property first */ + if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) { for (tmp = 0; tmp < nr_masters; tmp++) pdata->data_width[tmp] = BIT(arr[tmp] & 0x07); } - if (!of_property_read_u32_array(np, "multi-block", mb, nr_channels)) { - for (tmp = 0; tmp < nr_channels; tmp++) - pdata->multi_block[tmp] = mb[tmp]; - } else { - for (tmp = 0; tmp < nr_channels; tmp++) - pdata->multi_block[tmp] = 1; - } + /* If "data_width" and "data-width" both provided use the latter one */ + of_property_read_u32_array(np, "data-width", pdata->data_width, nr_masters); - if (of_property_read_u32_array(np, "snps,max-burst-len", pdata->max_burst, - nr_channels)) { - memset32(pdata->max_burst, DW_DMA_MAX_BURST, nr_channels); - } + memset32(pdata->multi_block, 1, nr_channels); + of_property_read_u32_array(np, "multi-block", pdata->multi_block, nr_channels); - if (!of_property_read_u32(np, "snps,dma-protection-control", &tmp)) { - if (tmp > CHAN_PROTCTL_MASK) - return NULL; - pdata->protctl = tmp; - } + memset32(pdata->max_burst, DW_DMA_MAX_BURST, nr_channels); + of_property_read_u32_array(np, "snps,max-burst-len", pdata->max_burst, nr_channels); + + of_property_read_u32(np, "snps,dma-protection-control", &pdata->protctl); + if (pdata->protctl > CHAN_PROTCTL_MASK) + return NULL; return pdata; } -- cgit v1.2.3-70-g09d2 From 4153a7f6440f46261a3004009eaa914914f08055 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 4 Aug 2021 21:51:40 +0200 Subject: dmaengine: xilinx: Add empty device_config function Various DMA users call the dmaengine_slave_config() and expect it to succeed, but that can only succeed if .device_config is implemented. Add empty device_config function rather than patching all the places which use dmaengine_slave_config(). Signed-off-by: Marek Vasut Cc: Akinobu Mita Cc: Kedareswara rao Appana Cc: Michal Simek Cc: Vinod Koul Link: https://lore.kernel.org/r/20210804195140.61396-1-marex@denx.de Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_dma.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 213e1a7314b7..97cbde4e0a29 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -1657,6 +1657,17 @@ static void xilinx_dma_issue_pending(struct dma_chan *dchan) spin_unlock_irqrestore(&chan->lock, flags); } +/** + * xilinx_dma_device_config - Configure the DMA channel + * @dchan: DMA channel + * @config: channel configuration + */ +static int xilinx_dma_device_config(struct dma_chan *dchan, + struct dma_slave_config *config) +{ + return 0; +} + /** * xilinx_dma_complete_descriptor - Mark the active descriptor as complete * @chan : xilinx DMA channel @@ -3095,6 +3106,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) xdev->common.device_synchronize = xilinx_dma_synchronize; xdev->common.device_tx_status = xilinx_dma_tx_status; xdev->common.device_issue_pending = xilinx_dma_issue_pending; + xdev->common.device_config = xilinx_dma_device_config; if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; -- cgit v1.2.3-70-g09d2 From 81c2f79c2104c5b48f01da674bc2f7d4bc600db4 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 3 Aug 2021 15:32:06 -0700 Subject: dmaengine: idxd: add capability check for 'block on fault' attribute The device general capability has a bit that indicate whether 'block on fault' is supported. Add check to wq sysfs knob to check if cap exists before allowing user to toggle. Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162802992615.3084999.12539468940404102898.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/sysfs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 4c01587c9d4a..a88886d0f27b 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -642,6 +642,9 @@ static ssize_t wq_block_on_fault_store(struct device *dev, bool bof; int rc; + if (!idxd->hw.gen_cap.block_on_fault) + return -EOPNOTSUPP; + if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) return -EPERM; -- cgit v1.2.3-70-g09d2 From bd2f4ae5e019efcfadd6b491204fd60adf14f4a3 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 3 Aug 2021 15:37:15 -0700 Subject: dmaengine: idxd: clear block on fault flag when clear wq The block on fault flag is not cleared when we disable or reset wq. This causes it to remain set if the user does not clear it on the next configuration load. Add clear of flag in dxd_wq_disable_cleanup() routine. Fixes: da32b28c95a7 ("dmaengine: idxd: cleanup workqueue config after disabling") Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162803023553.3086015.8158952172068868803.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 86fa4b4590f9..21f0d732b76e 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -402,6 +402,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) wq->priority = 0; wq->ats_dis = 0; clear_bit(WQ_FLAG_DEDICATED, &wq->flags); + clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags); memset(wq->name, 0, WQ_NAME_SIZE); } -- cgit v1.2.3-70-g09d2 From d803c8b9f3f2b8e5c047f2d0a27a9ea3ef91510f Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Tue, 3 Aug 2021 15:29:30 -0700 Subject: dmaengine: idxd: make I/O interrupt handler one shot The interrupt thread handler currently loops forever to process outstanding completions. This causes either an "irq X: nobody cared" kernel splat or the NMI watchdog kicks in due to running too long in the function. The irq thread handler is expected to run again after exiting if there are interrupts fired while the thread handler is running. So the handler code can process all the completed I/O in a single pass and exit without losing the follow on completed I/O. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162802977005.3084234.11836261157026497585.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/irq.c | 59 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 51 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 91e46ca3a0ad..11addb394793 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -22,11 +22,6 @@ struct idxd_fault { struct idxd_device *idxd; }; -static int irq_process_work_list(struct idxd_irq_entry *irq_entry, - int *processed, u64 data); -static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, - int *processed, u64 data); - static void idxd_device_reinit(struct work_struct *work) { struct idxd_device *idxd = container_of(work, struct idxd_device, work); @@ -177,18 +172,15 @@ irqreturn_t idxd_misc_thread(int vec, void *data) return IRQ_HANDLED; } -static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, - int *processed, u64 data) +static void irq_process_pending_llist(struct idxd_irq_entry *irq_entry) { struct idxd_desc *desc, *t; struct llist_node *head; - int queued = 0; unsigned long flags; - *processed = 0; head = llist_del_all(&irq_entry->pending_llist); if (!head) - goto out; + return; llist_for_each_entry_safe(desc, t, head, llnode) { u8 status = desc->completion->status & DSA_COMP_STATUS_MASK; @@ -200,35 +192,25 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry, */ if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) { complete_desc(desc, IDXD_COMPLETE_ABORT); - (*processed)++; continue; } complete_desc(desc, IDXD_COMPLETE_NORMAL); - (*processed)++; } else { spin_lock_irqsave(&irq_entry->list_lock, flags); list_add_tail(&desc->list, &irq_entry->work_list); spin_unlock_irqrestore(&irq_entry->list_lock, flags); - queued++; } } - - out: - return queued; } -static int irq_process_work_list(struct idxd_irq_entry *irq_entry, - int *processed, u64 data) +static void irq_process_work_list(struct idxd_irq_entry *irq_entry) { - int queued = 0; unsigned long flags; LIST_HEAD(flist); struct idxd_desc *desc, *n; - *processed = 0; - /* * This lock protects list corruption from access of list outside of the irq handler * thread. @@ -236,16 +218,13 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, spin_lock_irqsave(&irq_entry->list_lock, flags); if (list_empty(&irq_entry->work_list)) { spin_unlock_irqrestore(&irq_entry->list_lock, flags); - return 0; + return; } list_for_each_entry_safe(desc, n, &irq_entry->work_list, list) { if (desc->completion->status) { list_del(&desc->list); - (*processed)++; list_add_tail(&desc->list, &flist); - } else { - queued++; } } @@ -263,13 +242,11 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry, complete_desc(desc, IDXD_COMPLETE_NORMAL); } - - return queued; } -static int idxd_desc_process(struct idxd_irq_entry *irq_entry) +irqreturn_t idxd_wq_thread(int irq, void *data) { - int rc, processed, total = 0; + struct idxd_irq_entry *irq_entry = data; /* * There are two lists we are processing. The pending_llist is where @@ -288,29 +265,9 @@ static int idxd_desc_process(struct idxd_irq_entry *irq_entry) * and process the completed entries. * 4. If the entry is still waiting on hardware, list_add_tail() to * the work_list. - * 5. Repeat until no more descriptors. */ - do { - rc = irq_process_work_list(irq_entry, &processed, 0); - total += processed; - if (rc != 0) - continue; - - rc = irq_process_pending_llist(irq_entry, &processed, 0); - total += processed; - } while (rc != 0); - - return total; -} - -irqreturn_t idxd_wq_thread(int irq, void *data) -{ - struct idxd_irq_entry *irq_entry = data; - int processed; - - processed = idxd_desc_process(irq_entry); - if (processed == 0) - return IRQ_NONE; + irq_process_work_list(irq_entry); + irq_process_pending_llist(irq_entry); return IRQ_HANDLED; } -- cgit v1.2.3-70-g09d2 From 32bdc01988413031c6e743714c2b40bdd773e5db Mon Sep 17 00:00:00 2001 From: David Matlack Date: Thu, 5 Aug 2021 17:28:21 +0000 Subject: KVM: selftests: Move vcpu_args_set into perf_test_util perf_test_util is used to set up KVM selftests where vCPUs touch a region of memory. The guest code is implemented in perf_test_util.c (not the calling selftests). The guest code requires a 1 parameter, the vcpuid, which has to be set by calling vcpu_args_set(vm, vcpu_id, 1, vcpu_id). Today all of the selftests that use perf_test_util are making this call. Instead, perf_test_util should just do it. This will save some code but more importantly prevents mistakes since totally non-obvious that this needs to be called and failing to do so results in vCPUs not accessing the right regions of memory. Signed-off-by: David Matlack Message-Id: <20210805172821.2622793-1-dmatlack@google.com> Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/access_tracking_perf_test.c | 2 -- tools/testing/selftests/kvm/demand_paging_test.c | 1 - tools/testing/selftests/kvm/dirty_log_perf_test.c | 1 - tools/testing/selftests/kvm/lib/perf_test_util.c | 2 ++ tools/testing/selftests/kvm/memslot_modification_stress_test.c | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/kvm/access_tracking_perf_test.c b/tools/testing/selftests/kvm/access_tracking_perf_test.c index 3e23b2105f4b..71e277c7c3f3 100644 --- a/tools/testing/selftests/kvm/access_tracking_perf_test.c +++ b/tools/testing/selftests/kvm/access_tracking_perf_test.c @@ -222,8 +222,6 @@ static void *vcpu_thread_main(void *arg) int vcpu_id = vcpu_args->vcpu_id; int current_iteration = -1; - vcpu_args_set(vm, vcpu_id, 1, vcpu_id); - while (spin_wait_for_next_iteration(¤t_iteration)) { switch (READ_ONCE(iteration_work)) { case ITERATION_ACCESS_MEMORY: diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 61266a729d88..e79c1b64977f 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -52,7 +52,6 @@ static void *vcpu_worker(void *data) struct timespec start; struct timespec ts_diff; - vcpu_args_set(vm, vcpu_id, 1, vcpu_id); run = vcpu_state(vm, vcpu_id); clock_gettime(CLOCK_MONOTONIC, &start); diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c index 034458dd89a2..3c30d0045d8d 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -44,7 +44,6 @@ static void *vcpu_worker(void *data) struct perf_test_vcpu_args *vcpu_args = (struct perf_test_vcpu_args *)data; int vcpu_id = vcpu_args->vcpu_id; - vcpu_args_set(vm, vcpu_id, 1, vcpu_id); run = vcpu_state(vm, vcpu_id); while (!READ_ONCE(host_quit)) { diff --git a/tools/testing/selftests/kvm/lib/perf_test_util.c b/tools/testing/selftests/kvm/lib/perf_test_util.c index aebb223d34a7..0ef80dbdc116 100644 --- a/tools/testing/selftests/kvm/lib/perf_test_util.c +++ b/tools/testing/selftests/kvm/lib/perf_test_util.c @@ -150,6 +150,8 @@ void perf_test_setup_vcpus(struct kvm_vm *vm, int vcpus, vcpu_gpa = guest_test_phys_mem; } + vcpu_args_set(vm, vcpu_id, 1, vcpu_id); + pr_debug("Added VCPU %d with test mem gpa [%lx, %lx)\n", vcpu_id, vcpu_gpa, vcpu_gpa + (vcpu_args->pages * perf_test_args.guest_page_size)); diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c b/tools/testing/selftests/kvm/memslot_modification_stress_test.c index 8a9c6ccce3ca..4cfcafea9f5a 100644 --- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c +++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c @@ -45,7 +45,6 @@ static void *vcpu_worker(void *data) struct kvm_vm *vm = perf_test_args.vm; struct kvm_run *run; - vcpu_args_set(vm, vcpu_id, 1, vcpu_id); run = vcpu_state(vm, vcpu_id); /* Let the guest access its memory until a stop signal is received */ -- cgit v1.2.3-70-g09d2 From 5161a55c069f53d88da49274cbef6e3c74eadea9 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 2 Aug 2021 10:29:38 -0700 Subject: cxl: Move cxl_core to new directory CXL core is growing, and it's already arguably unmanageable. To support future growth, move core functionality to a new directory and rename the file to represent just bus support. Future work will remove non-bus functionality. Note that mem.h is renamed to cxlmem.h to avoid a namespace collision with the global ARCH=um mem.h header. Reported-by: kernel test robot Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792537866.368511.8915631504621088321.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- Documentation/driver-api/cxl/memory-devices.rst | 2 +- drivers/cxl/Makefile | 4 +- drivers/cxl/core.c | 1067 ----------------------- drivers/cxl/core/Makefile | 5 + drivers/cxl/core/bus.c | 1067 +++++++++++++++++++++++ drivers/cxl/cxlmem.h | 81 ++ drivers/cxl/mem.h | 81 -- drivers/cxl/pci.c | 2 +- drivers/cxl/pmem.c | 2 +- 9 files changed, 1157 insertions(+), 1154 deletions(-) delete mode 100644 drivers/cxl/core.c create mode 100644 drivers/cxl/core/Makefile create mode 100644 drivers/cxl/core/bus.c create mode 100644 drivers/cxl/cxlmem.h delete mode 100644 drivers/cxl/mem.h diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst index 487ce4f41d77..a86e2c7c551a 100644 --- a/Documentation/driver-api/cxl/memory-devices.rst +++ b/Documentation/driver-api/cxl/memory-devices.rst @@ -36,7 +36,7 @@ CXL Core .. kernel-doc:: drivers/cxl/cxl.h :internal: -.. kernel-doc:: drivers/cxl/core.c +.. kernel-doc:: drivers/cxl/core/bus.c :doc: cxl core External Interfaces diff --git a/drivers/cxl/Makefile b/drivers/cxl/Makefile index 32954059b37b..d1aaabc940f3 100644 --- a/drivers/cxl/Makefile +++ b/drivers/cxl/Makefile @@ -1,11 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CXL_BUS) += cxl_core.o +obj-$(CONFIG_CXL_BUS) += core/ obj-$(CONFIG_CXL_MEM) += cxl_pci.o obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o -ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -cxl_core-y := core.o cxl_pci-y := pci.o cxl_acpi-y := acpi.o cxl_pmem-y := pmem.o diff --git a/drivers/cxl/core.c b/drivers/cxl/core.c deleted file mode 100644 index a2e4d54fc7bc..000000000000 --- a/drivers/cxl/core.c +++ /dev/null @@ -1,1067 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright(c) 2020 Intel Corporation. All rights reserved. */ -#include -#include -#include -#include -#include -#include -#include "cxl.h" -#include "mem.h" - -/** - * DOC: cxl core - * - * The CXL core provides a sysfs hierarchy for control devices and a rendezvous - * point for cross-device interleave coordination through cxl ports. - */ - -static DEFINE_IDA(cxl_port_ida); - -static ssize_t devtype_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%s\n", dev->type->name); -} -static DEVICE_ATTR_RO(devtype); - -static struct attribute *cxl_base_attributes[] = { - &dev_attr_devtype.attr, - NULL, -}; - -static struct attribute_group cxl_base_attribute_group = { - .attrs = cxl_base_attributes, -}; - -static ssize_t start_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cxl_decoder *cxld = to_cxl_decoder(dev); - - return sysfs_emit(buf, "%#llx\n", cxld->range.start); -} -static DEVICE_ATTR_RO(start); - -static ssize_t size_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cxl_decoder *cxld = to_cxl_decoder(dev); - - return sysfs_emit(buf, "%#llx\n", range_len(&cxld->range)); -} -static DEVICE_ATTR_RO(size); - -#define CXL_DECODER_FLAG_ATTR(name, flag) \ -static ssize_t name##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct cxl_decoder *cxld = to_cxl_decoder(dev); \ - \ - return sysfs_emit(buf, "%s\n", \ - (cxld->flags & (flag)) ? "1" : "0"); \ -} \ -static DEVICE_ATTR_RO(name) - -CXL_DECODER_FLAG_ATTR(cap_pmem, CXL_DECODER_F_PMEM); -CXL_DECODER_FLAG_ATTR(cap_ram, CXL_DECODER_F_RAM); -CXL_DECODER_FLAG_ATTR(cap_type2, CXL_DECODER_F_TYPE2); -CXL_DECODER_FLAG_ATTR(cap_type3, CXL_DECODER_F_TYPE3); -CXL_DECODER_FLAG_ATTR(locked, CXL_DECODER_F_LOCK); - -static ssize_t target_type_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cxl_decoder *cxld = to_cxl_decoder(dev); - - switch (cxld->target_type) { - case CXL_DECODER_ACCELERATOR: - return sysfs_emit(buf, "accelerator\n"); - case CXL_DECODER_EXPANDER: - return sysfs_emit(buf, "expander\n"); - } - return -ENXIO; -} -static DEVICE_ATTR_RO(target_type); - -static ssize_t target_list_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cxl_decoder *cxld = to_cxl_decoder(dev); - ssize_t offset = 0; - int i, rc = 0; - - device_lock(dev); - for (i = 0; i < cxld->interleave_ways; i++) { - struct cxl_dport *dport = cxld->target[i]; - struct cxl_dport *next = NULL; - - if (!dport) - break; - - if (i + 1 < cxld->interleave_ways) - next = cxld->target[i + 1]; - rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id, - next ? "," : ""); - if (rc < 0) - break; - offset += rc; - } - device_unlock(dev); - - if (rc < 0) - return rc; - - rc = sysfs_emit_at(buf, offset, "\n"); - if (rc < 0) - return rc; - - return offset + rc; -} -static DEVICE_ATTR_RO(target_list); - -static struct attribute *cxl_decoder_base_attrs[] = { - &dev_attr_start.attr, - &dev_attr_size.attr, - &dev_attr_locked.attr, - &dev_attr_target_list.attr, - NULL, -}; - -static struct attribute_group cxl_decoder_base_attribute_group = { - .attrs = cxl_decoder_base_attrs, -}; - -static struct attribute *cxl_decoder_root_attrs[] = { - &dev_attr_cap_pmem.attr, - &dev_attr_cap_ram.attr, - &dev_attr_cap_type2.attr, - &dev_attr_cap_type3.attr, - NULL, -}; - -static struct attribute_group cxl_decoder_root_attribute_group = { - .attrs = cxl_decoder_root_attrs, -}; - -static const struct attribute_group *cxl_decoder_root_attribute_groups[] = { - &cxl_decoder_root_attribute_group, - &cxl_decoder_base_attribute_group, - &cxl_base_attribute_group, - NULL, -}; - -static struct attribute *cxl_decoder_switch_attrs[] = { - &dev_attr_target_type.attr, - NULL, -}; - -static struct attribute_group cxl_decoder_switch_attribute_group = { - .attrs = cxl_decoder_switch_attrs, -}; - -static const struct attribute_group *cxl_decoder_switch_attribute_groups[] = { - &cxl_decoder_switch_attribute_group, - &cxl_decoder_base_attribute_group, - &cxl_base_attribute_group, - NULL, -}; - -static void cxl_decoder_release(struct device *dev) -{ - struct cxl_decoder *cxld = to_cxl_decoder(dev); - struct cxl_port *port = to_cxl_port(dev->parent); - - ida_free(&port->decoder_ida, cxld->id); - kfree(cxld); -} - -static const struct device_type cxl_decoder_switch_type = { - .name = "cxl_decoder_switch", - .release = cxl_decoder_release, - .groups = cxl_decoder_switch_attribute_groups, -}; - -static const struct device_type cxl_decoder_root_type = { - .name = "cxl_decoder_root", - .release = cxl_decoder_release, - .groups = cxl_decoder_root_attribute_groups, -}; - -bool is_root_decoder(struct device *dev) -{ - return dev->type == &cxl_decoder_root_type; -} -EXPORT_SYMBOL_GPL(is_root_decoder); - -struct cxl_decoder *to_cxl_decoder(struct device *dev) -{ - if (dev_WARN_ONCE(dev, dev->type->release != cxl_decoder_release, - "not a cxl_decoder device\n")) - return NULL; - return container_of(dev, struct cxl_decoder, dev); -} -EXPORT_SYMBOL_GPL(to_cxl_decoder); - -static void cxl_dport_release(struct cxl_dport *dport) -{ - list_del(&dport->list); - put_device(dport->dport); - kfree(dport); -} - -static void cxl_port_release(struct device *dev) -{ - struct cxl_port *port = to_cxl_port(dev); - struct cxl_dport *dport, *_d; - - device_lock(dev); - list_for_each_entry_safe(dport, _d, &port->dports, list) - cxl_dport_release(dport); - device_unlock(dev); - ida_free(&cxl_port_ida, port->id); - kfree(port); -} - -static const struct attribute_group *cxl_port_attribute_groups[] = { - &cxl_base_attribute_group, - NULL, -}; - -static const struct device_type cxl_port_type = { - .name = "cxl_port", - .release = cxl_port_release, - .groups = cxl_port_attribute_groups, -}; - -struct cxl_port *to_cxl_port(struct device *dev) -{ - if (dev_WARN_ONCE(dev, dev->type != &cxl_port_type, - "not a cxl_port device\n")) - return NULL; - return container_of(dev, struct cxl_port, dev); -} - -static void unregister_port(void *_port) -{ - struct cxl_port *port = _port; - struct cxl_dport *dport; - - device_lock(&port->dev); - list_for_each_entry(dport, &port->dports, list) { - char link_name[CXL_TARGET_STRLEN]; - - if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", - dport->port_id) >= CXL_TARGET_STRLEN) - continue; - sysfs_remove_link(&port->dev.kobj, link_name); - } - device_unlock(&port->dev); - device_unregister(&port->dev); -} - -static void cxl_unlink_uport(void *_port) -{ - struct cxl_port *port = _port; - - sysfs_remove_link(&port->dev.kobj, "uport"); -} - -static int devm_cxl_link_uport(struct device *host, struct cxl_port *port) -{ - int rc; - - rc = sysfs_create_link(&port->dev.kobj, &port->uport->kobj, "uport"); - if (rc) - return rc; - return devm_add_action_or_reset(host, cxl_unlink_uport, port); -} - -static struct cxl_port *cxl_port_alloc(struct device *uport, - resource_size_t component_reg_phys, - struct cxl_port *parent_port) -{ - struct cxl_port *port; - struct device *dev; - int rc; - - port = kzalloc(sizeof(*port), GFP_KERNEL); - if (!port) - return ERR_PTR(-ENOMEM); - - rc = ida_alloc(&cxl_port_ida, GFP_KERNEL); - if (rc < 0) - goto err; - port->id = rc; - - /* - * The top-level cxl_port "cxl_root" does not have a cxl_port as - * its parent and it does not have any corresponding component - * registers as its decode is described by a fixed platform - * description. - */ - dev = &port->dev; - if (parent_port) - dev->parent = &parent_port->dev; - else - dev->parent = uport; - - port->uport = uport; - port->component_reg_phys = component_reg_phys; - ida_init(&port->decoder_ida); - INIT_LIST_HEAD(&port->dports); - - device_initialize(dev); - device_set_pm_not_required(dev); - dev->bus = &cxl_bus_type; - dev->type = &cxl_port_type; - - return port; - -err: - kfree(port); - return ERR_PTR(rc); -} - -/** - * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy - * @host: host device for devm operations - * @uport: "physical" device implementing this upstream port - * @component_reg_phys: (optional) for configurable cxl_port instances - * @parent_port: next hop up in the CXL memory decode hierarchy - */ -struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, - resource_size_t component_reg_phys, - struct cxl_port *parent_port) -{ - struct cxl_port *port; - struct device *dev; - int rc; - - port = cxl_port_alloc(uport, component_reg_phys, parent_port); - if (IS_ERR(port)) - return port; - - dev = &port->dev; - if (parent_port) - rc = dev_set_name(dev, "port%d", port->id); - else - rc = dev_set_name(dev, "root%d", port->id); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - rc = devm_add_action_or_reset(host, unregister_port, port); - if (rc) - return ERR_PTR(rc); - - rc = devm_cxl_link_uport(host, port); - if (rc) - return ERR_PTR(rc); - - return port; - -err: - put_device(dev); - return ERR_PTR(rc); -} -EXPORT_SYMBOL_GPL(devm_cxl_add_port); - -static struct cxl_dport *find_dport(struct cxl_port *port, int id) -{ - struct cxl_dport *dport; - - device_lock_assert(&port->dev); - list_for_each_entry (dport, &port->dports, list) - if (dport->port_id == id) - return dport; - return NULL; -} - -static int add_dport(struct cxl_port *port, struct cxl_dport *new) -{ - struct cxl_dport *dup; - - device_lock(&port->dev); - dup = find_dport(port, new->port_id); - if (dup) - dev_err(&port->dev, - "unable to add dport%d-%s non-unique port id (%s)\n", - new->port_id, dev_name(new->dport), - dev_name(dup->dport)); - else - list_add_tail(&new->list, &port->dports); - device_unlock(&port->dev); - - return dup ? -EEXIST : 0; -} - -/** - * cxl_add_dport - append downstream port data to a cxl_port - * @port: the cxl_port that references this dport - * @dport_dev: firmware or PCI device representing the dport - * @port_id: identifier for this dport in a decoder's target list - * @component_reg_phys: optional location of CXL component registers - * - * Note that all allocations and links are undone by cxl_port deletion - * and release. - */ -int cxl_add_dport(struct cxl_port *port, struct device *dport_dev, int port_id, - resource_size_t component_reg_phys) -{ - char link_name[CXL_TARGET_STRLEN]; - struct cxl_dport *dport; - int rc; - - if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", port_id) >= - CXL_TARGET_STRLEN) - return -EINVAL; - - dport = kzalloc(sizeof(*dport), GFP_KERNEL); - if (!dport) - return -ENOMEM; - - INIT_LIST_HEAD(&dport->list); - dport->dport = get_device(dport_dev); - dport->port_id = port_id; - dport->component_reg_phys = component_reg_phys; - dport->port = port; - - rc = add_dport(port, dport); - if (rc) - goto err; - - rc = sysfs_create_link(&port->dev.kobj, &dport_dev->kobj, link_name); - if (rc) - goto err; - - return 0; -err: - cxl_dport_release(dport); - return rc; -} -EXPORT_SYMBOL_GPL(cxl_add_dport); - -static struct cxl_decoder * -cxl_decoder_alloc(struct cxl_port *port, int nr_targets, resource_size_t base, - resource_size_t len, int interleave_ways, - int interleave_granularity, enum cxl_decoder_type type, - unsigned long flags) -{ - struct cxl_decoder *cxld; - struct device *dev; - int rc = 0; - - if (interleave_ways < 1) - return ERR_PTR(-EINVAL); - - device_lock(&port->dev); - if (list_empty(&port->dports)) - rc = -EINVAL; - device_unlock(&port->dev); - if (rc) - return ERR_PTR(rc); - - cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL); - if (!cxld) - return ERR_PTR(-ENOMEM); - - rc = ida_alloc(&port->decoder_ida, GFP_KERNEL); - if (rc < 0) - goto err; - - *cxld = (struct cxl_decoder) { - .id = rc, - .range = { - .start = base, - .end = base + len - 1, - }, - .flags = flags, - .interleave_ways = interleave_ways, - .interleave_granularity = interleave_granularity, - .target_type = type, - }; - - /* handle implied target_list */ - if (interleave_ways == 1) - cxld->target[0] = - list_first_entry(&port->dports, struct cxl_dport, list); - dev = &cxld->dev; - device_initialize(dev); - device_set_pm_not_required(dev); - dev->parent = &port->dev; - dev->bus = &cxl_bus_type; - - /* root ports do not have a cxl_port_type parent */ - if (port->dev.parent->type == &cxl_port_type) - dev->type = &cxl_decoder_switch_type; - else - dev->type = &cxl_decoder_root_type; - - return cxld; -err: - kfree(cxld); - return ERR_PTR(rc); -} - -static void unregister_dev(void *dev) -{ - device_unregister(dev); -} - -struct cxl_decoder * -devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, - resource_size_t base, resource_size_t len, - int interleave_ways, int interleave_granularity, - enum cxl_decoder_type type, unsigned long flags) -{ - struct cxl_decoder *cxld; - struct device *dev; - int rc; - - cxld = cxl_decoder_alloc(port, nr_targets, base, len, interleave_ways, - interleave_granularity, type, flags); - if (IS_ERR(cxld)) - return cxld; - - dev = &cxld->dev; - rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - rc = devm_add_action_or_reset(host, unregister_dev, dev); - if (rc) - return ERR_PTR(rc); - return cxld; - -err: - put_device(dev); - return ERR_PTR(rc); -} -EXPORT_SYMBOL_GPL(devm_cxl_add_decoder); - -/** - * cxl_probe_component_regs() - Detect CXL Component register blocks - * @dev: Host device of the @base mapping - * @base: Mapping containing the HDM Decoder Capability Header - * @map: Map object describing the register block information found - * - * See CXL 2.0 8.2.4 Component Register Layout and Definition - * See CXL 2.0 8.2.5.5 CXL Device Register Interface - * - * Probe for component register information and return it in map object. - */ -void cxl_probe_component_regs(struct device *dev, void __iomem *base, - struct cxl_component_reg_map *map) -{ - int cap, cap_count; - u64 cap_array; - - *map = (struct cxl_component_reg_map) { 0 }; - - /* - * CXL.cache and CXL.mem registers are at offset 0x1000 as defined in - * CXL 2.0 8.2.4 Table 141. - */ - base += CXL_CM_OFFSET; - - cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET); - - if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) { - dev_err(dev, - "Couldn't locate the CXL.cache and CXL.mem capability array header./n"); - return; - } - - /* It's assumed that future versions will be backward compatible */ - cap_count = FIELD_GET(CXL_CM_CAP_HDR_ARRAY_SIZE_MASK, cap_array); - - for (cap = 1; cap <= cap_count; cap++) { - void __iomem *register_block; - u32 hdr; - int decoder_cnt; - u16 cap_id, offset; - u32 length; - - hdr = readl(base + cap * 0x4); - - cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr); - offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr); - register_block = base + offset; - - switch (cap_id) { - case CXL_CM_CAP_CAP_ID_HDM: - dev_dbg(dev, "found HDM decoder capability (0x%x)\n", - offset); - - hdr = readl(register_block); - - decoder_cnt = cxl_hdm_decoder_count(hdr); - length = 0x20 * decoder_cnt + 0x10; - - map->hdm_decoder.valid = true; - map->hdm_decoder.offset = CXL_CM_OFFSET + offset; - map->hdm_decoder.size = length; - break; - default: - dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, - offset); - break; - } - } -} -EXPORT_SYMBOL_GPL(cxl_probe_component_regs); - -static void cxl_nvdimm_bridge_release(struct device *dev) -{ - struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); - - kfree(cxl_nvb); -} - -static const struct attribute_group *cxl_nvdimm_bridge_attribute_groups[] = { - &cxl_base_attribute_group, - NULL, -}; - -static const struct device_type cxl_nvdimm_bridge_type = { - .name = "cxl_nvdimm_bridge", - .release = cxl_nvdimm_bridge_release, - .groups = cxl_nvdimm_bridge_attribute_groups, -}; - -struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) -{ - if (dev_WARN_ONCE(dev, dev->type != &cxl_nvdimm_bridge_type, - "not a cxl_nvdimm_bridge device\n")) - return NULL; - return container_of(dev, struct cxl_nvdimm_bridge, dev); -} -EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); - -static struct cxl_nvdimm_bridge * -cxl_nvdimm_bridge_alloc(struct cxl_port *port) -{ - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - - cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); - if (!cxl_nvb) - return ERR_PTR(-ENOMEM); - - dev = &cxl_nvb->dev; - cxl_nvb->port = port; - cxl_nvb->state = CXL_NVB_NEW; - device_initialize(dev); - device_set_pm_not_required(dev); - dev->parent = &port->dev; - dev->bus = &cxl_bus_type; - dev->type = &cxl_nvdimm_bridge_type; - - return cxl_nvb; -} - -static void unregister_nvb(void *_cxl_nvb) -{ - struct cxl_nvdimm_bridge *cxl_nvb = _cxl_nvb; - bool flush; - - /* - * If the bridge was ever activated then there might be in-flight state - * work to flush. Once the state has been changed to 'dead' then no new - * work can be queued by user-triggered bind. - */ - device_lock(&cxl_nvb->dev); - flush = cxl_nvb->state != CXL_NVB_NEW; - cxl_nvb->state = CXL_NVB_DEAD; - device_unlock(&cxl_nvb->dev); - - /* - * Even though the device core will trigger device_release_driver() - * before the unregister, it does not know about the fact that - * cxl_nvdimm_bridge_driver defers ->remove() work. So, do the driver - * release not and flush it before tearing down the nvdimm device - * hierarchy. - */ - device_release_driver(&cxl_nvb->dev); - if (flush) - flush_work(&cxl_nvb->state_work); - device_unregister(&cxl_nvb->dev); -} - -struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, - struct cxl_port *port) -{ - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - int rc; - - if (!IS_ENABLED(CONFIG_CXL_PMEM)) - return ERR_PTR(-ENXIO); - - cxl_nvb = cxl_nvdimm_bridge_alloc(port); - if (IS_ERR(cxl_nvb)) - return cxl_nvb; - - dev = &cxl_nvb->dev; - rc = dev_set_name(dev, "nvdimm-bridge"); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb); - if (rc) - return ERR_PTR(rc); - - return cxl_nvb; - -err: - put_device(dev); - return ERR_PTR(rc); -} -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); - -static void cxl_nvdimm_release(struct device *dev) -{ - struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); - - kfree(cxl_nvd); -} - -static const struct attribute_group *cxl_nvdimm_attribute_groups[] = { - &cxl_base_attribute_group, - NULL, -}; - -static const struct device_type cxl_nvdimm_type = { - .name = "cxl_nvdimm", - .release = cxl_nvdimm_release, - .groups = cxl_nvdimm_attribute_groups, -}; - -bool is_cxl_nvdimm(struct device *dev) -{ - return dev->type == &cxl_nvdimm_type; -} -EXPORT_SYMBOL_GPL(is_cxl_nvdimm); - -struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) -{ - if (dev_WARN_ONCE(dev, !is_cxl_nvdimm(dev), - "not a cxl_nvdimm device\n")) - return NULL; - return container_of(dev, struct cxl_nvdimm, dev); -} -EXPORT_SYMBOL_GPL(to_cxl_nvdimm); - -static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) -{ - struct cxl_nvdimm *cxl_nvd; - struct device *dev; - - cxl_nvd = kzalloc(sizeof(*cxl_nvd), GFP_KERNEL); - if (!cxl_nvd) - return ERR_PTR(-ENOMEM); - - dev = &cxl_nvd->dev; - cxl_nvd->cxlmd = cxlmd; - device_initialize(dev); - device_set_pm_not_required(dev); - dev->parent = &cxlmd->dev; - dev->bus = &cxl_bus_type; - dev->type = &cxl_nvdimm_type; - - return cxl_nvd; -} - -int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd) -{ - struct cxl_nvdimm *cxl_nvd; - struct device *dev; - int rc; - - cxl_nvd = cxl_nvdimm_alloc(cxlmd); - if (IS_ERR(cxl_nvd)) - return PTR_ERR(cxl_nvd); - - dev = &cxl_nvd->dev; - rc = dev_set_name(dev, "pmem%d", cxlmd->id); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - dev_dbg(host, "%s: register %s\n", dev_name(dev->parent), - dev_name(dev)); - - return devm_add_action_or_reset(host, unregister_dev, dev); - -err: - put_device(dev); - return rc; -} -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); - -/** - * cxl_probe_device_regs() - Detect CXL Device register blocks - * @dev: Host device of the @base mapping - * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface - * @map: Map object describing the register block information found - * - * Probe for device register information and return it in map object. - */ -void cxl_probe_device_regs(struct device *dev, void __iomem *base, - struct cxl_device_reg_map *map) -{ - int cap, cap_count; - u64 cap_array; - - *map = (struct cxl_device_reg_map){ 0 }; - - cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET); - if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) != - CXLDEV_CAP_ARRAY_CAP_ID) - return; - - cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array); - - for (cap = 1; cap <= cap_count; cap++) { - u32 offset, length; - u16 cap_id; - - cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK, - readl(base + cap * 0x10)); - offset = readl(base + cap * 0x10 + 0x4); - length = readl(base + cap * 0x10 + 0x8); - - switch (cap_id) { - case CXLDEV_CAP_CAP_ID_DEVICE_STATUS: - dev_dbg(dev, "found Status capability (0x%x)\n", offset); - - map->status.valid = true; - map->status.offset = offset; - map->status.size = length; - break; - case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX: - dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset); - map->mbox.valid = true; - map->mbox.offset = offset; - map->mbox.size = length; - break; - case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX: - dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset); - break; - case CXLDEV_CAP_CAP_ID_MEMDEV: - dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); - map->memdev.valid = true; - map->memdev.offset = offset; - map->memdev.size = length; - break; - default: - if (cap_id >= 0x8000) - dev_dbg(dev, "Vendor cap ID: %#x offset: %#x\n", cap_id, offset); - else - dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset); - break; - } - } -} -EXPORT_SYMBOL_GPL(cxl_probe_device_regs); - -static void __iomem *devm_cxl_iomap_block(struct device *dev, - resource_size_t addr, - resource_size_t length) -{ - void __iomem *ret_val; - struct resource *res; - - res = devm_request_mem_region(dev, addr, length, dev_name(dev)); - if (!res) { - resource_size_t end = addr + length - 1; - - dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end); - return NULL; - } - - ret_val = devm_ioremap(dev, addr, length); - if (!ret_val) - dev_err(dev, "Failed to map region %pr\n", res); - - return ret_val; -} - -int cxl_map_component_regs(struct pci_dev *pdev, - struct cxl_component_regs *regs, - struct cxl_register_map *map) -{ - struct device *dev = &pdev->dev; - resource_size_t phys_addr; - resource_size_t length; - - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - - phys_addr += map->component_map.hdm_decoder.offset; - length = map->component_map.hdm_decoder.size; - regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); - if (!regs->hdm_decoder) - return -ENOMEM; - - return 0; -} -EXPORT_SYMBOL_GPL(cxl_map_component_regs); - -int cxl_map_device_regs(struct pci_dev *pdev, - struct cxl_device_regs *regs, - struct cxl_register_map *map) -{ - struct device *dev = &pdev->dev; - resource_size_t phys_addr; - - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - - if (map->device_map.status.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.status.offset; - length = map->device_map.status.size; - regs->status = devm_cxl_iomap_block(dev, addr, length); - if (!regs->status) - return -ENOMEM; - } - - if (map->device_map.mbox.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.mbox.offset; - length = map->device_map.mbox.size; - regs->mbox = devm_cxl_iomap_block(dev, addr, length); - if (!regs->mbox) - return -ENOMEM; - } - - if (map->device_map.memdev.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.memdev.offset; - length = map->device_map.memdev.size; - regs->memdev = devm_cxl_iomap_block(dev, addr, length); - if (!regs->memdev) - return -ENOMEM; - } - - return 0; -} -EXPORT_SYMBOL_GPL(cxl_map_device_regs); - -/** - * __cxl_driver_register - register a driver for the cxl bus - * @cxl_drv: cxl driver structure to attach - * @owner: owning module/driver - * @modname: KBUILD_MODNAME for parent driver - */ -int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, - const char *modname) -{ - if (!cxl_drv->probe) { - pr_debug("%s ->probe() must be specified\n", modname); - return -EINVAL; - } - - if (!cxl_drv->name) { - pr_debug("%s ->name must be specified\n", modname); - return -EINVAL; - } - - if (!cxl_drv->id) { - pr_debug("%s ->id must be specified\n", modname); - return -EINVAL; - } - - cxl_drv->drv.bus = &cxl_bus_type; - cxl_drv->drv.owner = owner; - cxl_drv->drv.mod_name = modname; - cxl_drv->drv.name = cxl_drv->name; - - return driver_register(&cxl_drv->drv); -} -EXPORT_SYMBOL_GPL(__cxl_driver_register); - -void cxl_driver_unregister(struct cxl_driver *cxl_drv) -{ - driver_unregister(&cxl_drv->drv); -} -EXPORT_SYMBOL_GPL(cxl_driver_unregister); - -static int cxl_device_id(struct device *dev) -{ - if (dev->type == &cxl_nvdimm_bridge_type) - return CXL_DEVICE_NVDIMM_BRIDGE; - if (dev->type == &cxl_nvdimm_type) - return CXL_DEVICE_NVDIMM; - return 0; -} - -static int cxl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return add_uevent_var(env, "MODALIAS=" CXL_MODALIAS_FMT, - cxl_device_id(dev)); -} - -static int cxl_bus_match(struct device *dev, struct device_driver *drv) -{ - return cxl_device_id(dev) == to_cxl_drv(drv)->id; -} - -static int cxl_bus_probe(struct device *dev) -{ - return to_cxl_drv(dev->driver)->probe(dev); -} - -static int cxl_bus_remove(struct device *dev) -{ - struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver); - - if (cxl_drv->remove) - cxl_drv->remove(dev); - return 0; -} - -struct bus_type cxl_bus_type = { - .name = "cxl", - .uevent = cxl_bus_uevent, - .match = cxl_bus_match, - .probe = cxl_bus_probe, - .remove = cxl_bus_remove, -}; -EXPORT_SYMBOL_GPL(cxl_bus_type); - -static __init int cxl_core_init(void) -{ - return bus_register(&cxl_bus_type); -} - -static void cxl_core_exit(void) -{ - bus_unregister(&cxl_bus_type); -} - -module_init(cxl_core_init); -module_exit(cxl_core_exit); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile new file mode 100644 index 000000000000..ad137f96e5c8 --- /dev/null +++ b/drivers/cxl/core/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_CXL_BUS) += cxl_core.o + +ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl +cxl_core-y := bus.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c new file mode 100644 index 000000000000..0815eec23944 --- /dev/null +++ b/drivers/cxl/core/bus.c @@ -0,0 +1,1067 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2020 Intel Corporation. All rights reserved. */ +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: cxl core + * + * The CXL core provides a sysfs hierarchy for control devices and a rendezvous + * point for cross-device interleave coordination through cxl ports. + */ + +static DEFINE_IDA(cxl_port_ida); + +static ssize_t devtype_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%s\n", dev->type->name); +} +static DEVICE_ATTR_RO(devtype); + +static struct attribute *cxl_base_attributes[] = { + &dev_attr_devtype.attr, + NULL, +}; + +static struct attribute_group cxl_base_attribute_group = { + .attrs = cxl_base_attributes, +}; + +static ssize_t start_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cxl_decoder *cxld = to_cxl_decoder(dev); + + return sysfs_emit(buf, "%#llx\n", cxld->range.start); +} +static DEVICE_ATTR_RO(start); + +static ssize_t size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cxl_decoder *cxld = to_cxl_decoder(dev); + + return sysfs_emit(buf, "%#llx\n", range_len(&cxld->range)); +} +static DEVICE_ATTR_RO(size); + +#define CXL_DECODER_FLAG_ATTR(name, flag) \ +static ssize_t name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct cxl_decoder *cxld = to_cxl_decoder(dev); \ + \ + return sysfs_emit(buf, "%s\n", \ + (cxld->flags & (flag)) ? "1" : "0"); \ +} \ +static DEVICE_ATTR_RO(name) + +CXL_DECODER_FLAG_ATTR(cap_pmem, CXL_DECODER_F_PMEM); +CXL_DECODER_FLAG_ATTR(cap_ram, CXL_DECODER_F_RAM); +CXL_DECODER_FLAG_ATTR(cap_type2, CXL_DECODER_F_TYPE2); +CXL_DECODER_FLAG_ATTR(cap_type3, CXL_DECODER_F_TYPE3); +CXL_DECODER_FLAG_ATTR(locked, CXL_DECODER_F_LOCK); + +static ssize_t target_type_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_decoder *cxld = to_cxl_decoder(dev); + + switch (cxld->target_type) { + case CXL_DECODER_ACCELERATOR: + return sysfs_emit(buf, "accelerator\n"); + case CXL_DECODER_EXPANDER: + return sysfs_emit(buf, "expander\n"); + } + return -ENXIO; +} +static DEVICE_ATTR_RO(target_type); + +static ssize_t target_list_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_decoder *cxld = to_cxl_decoder(dev); + ssize_t offset = 0; + int i, rc = 0; + + device_lock(dev); + for (i = 0; i < cxld->interleave_ways; i++) { + struct cxl_dport *dport = cxld->target[i]; + struct cxl_dport *next = NULL; + + if (!dport) + break; + + if (i + 1 < cxld->interleave_ways) + next = cxld->target[i + 1]; + rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id, + next ? "," : ""); + if (rc < 0) + break; + offset += rc; + } + device_unlock(dev); + + if (rc < 0) + return rc; + + rc = sysfs_emit_at(buf, offset, "\n"); + if (rc < 0) + return rc; + + return offset + rc; +} +static DEVICE_ATTR_RO(target_list); + +static struct attribute *cxl_decoder_base_attrs[] = { + &dev_attr_start.attr, + &dev_attr_size.attr, + &dev_attr_locked.attr, + &dev_attr_target_list.attr, + NULL, +}; + +static struct attribute_group cxl_decoder_base_attribute_group = { + .attrs = cxl_decoder_base_attrs, +}; + +static struct attribute *cxl_decoder_root_attrs[] = { + &dev_attr_cap_pmem.attr, + &dev_attr_cap_ram.attr, + &dev_attr_cap_type2.attr, + &dev_attr_cap_type3.attr, + NULL, +}; + +static struct attribute_group cxl_decoder_root_attribute_group = { + .attrs = cxl_decoder_root_attrs, +}; + +static const struct attribute_group *cxl_decoder_root_attribute_groups[] = { + &cxl_decoder_root_attribute_group, + &cxl_decoder_base_attribute_group, + &cxl_base_attribute_group, + NULL, +}; + +static struct attribute *cxl_decoder_switch_attrs[] = { + &dev_attr_target_type.attr, + NULL, +}; + +static struct attribute_group cxl_decoder_switch_attribute_group = { + .attrs = cxl_decoder_switch_attrs, +}; + +static const struct attribute_group *cxl_decoder_switch_attribute_groups[] = { + &cxl_decoder_switch_attribute_group, + &cxl_decoder_base_attribute_group, + &cxl_base_attribute_group, + NULL, +}; + +static void cxl_decoder_release(struct device *dev) +{ + struct cxl_decoder *cxld = to_cxl_decoder(dev); + struct cxl_port *port = to_cxl_port(dev->parent); + + ida_free(&port->decoder_ida, cxld->id); + kfree(cxld); +} + +static const struct device_type cxl_decoder_switch_type = { + .name = "cxl_decoder_switch", + .release = cxl_decoder_release, + .groups = cxl_decoder_switch_attribute_groups, +}; + +static const struct device_type cxl_decoder_root_type = { + .name = "cxl_decoder_root", + .release = cxl_decoder_release, + .groups = cxl_decoder_root_attribute_groups, +}; + +bool is_root_decoder(struct device *dev) +{ + return dev->type == &cxl_decoder_root_type; +} +EXPORT_SYMBOL_GPL(is_root_decoder); + +struct cxl_decoder *to_cxl_decoder(struct device *dev) +{ + if (dev_WARN_ONCE(dev, dev->type->release != cxl_decoder_release, + "not a cxl_decoder device\n")) + return NULL; + return container_of(dev, struct cxl_decoder, dev); +} +EXPORT_SYMBOL_GPL(to_cxl_decoder); + +static void cxl_dport_release(struct cxl_dport *dport) +{ + list_del(&dport->list); + put_device(dport->dport); + kfree(dport); +} + +static void cxl_port_release(struct device *dev) +{ + struct cxl_port *port = to_cxl_port(dev); + struct cxl_dport *dport, *_d; + + device_lock(dev); + list_for_each_entry_safe(dport, _d, &port->dports, list) + cxl_dport_release(dport); + device_unlock(dev); + ida_free(&cxl_port_ida, port->id); + kfree(port); +} + +static const struct attribute_group *cxl_port_attribute_groups[] = { + &cxl_base_attribute_group, + NULL, +}; + +static const struct device_type cxl_port_type = { + .name = "cxl_port", + .release = cxl_port_release, + .groups = cxl_port_attribute_groups, +}; + +struct cxl_port *to_cxl_port(struct device *dev) +{ + if (dev_WARN_ONCE(dev, dev->type != &cxl_port_type, + "not a cxl_port device\n")) + return NULL; + return container_of(dev, struct cxl_port, dev); +} + +static void unregister_port(void *_port) +{ + struct cxl_port *port = _port; + struct cxl_dport *dport; + + device_lock(&port->dev); + list_for_each_entry(dport, &port->dports, list) { + char link_name[CXL_TARGET_STRLEN]; + + if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", + dport->port_id) >= CXL_TARGET_STRLEN) + continue; + sysfs_remove_link(&port->dev.kobj, link_name); + } + device_unlock(&port->dev); + device_unregister(&port->dev); +} + +static void cxl_unlink_uport(void *_port) +{ + struct cxl_port *port = _port; + + sysfs_remove_link(&port->dev.kobj, "uport"); +} + +static int devm_cxl_link_uport(struct device *host, struct cxl_port *port) +{ + int rc; + + rc = sysfs_create_link(&port->dev.kobj, &port->uport->kobj, "uport"); + if (rc) + return rc; + return devm_add_action_or_reset(host, cxl_unlink_uport, port); +} + +static struct cxl_port *cxl_port_alloc(struct device *uport, + resource_size_t component_reg_phys, + struct cxl_port *parent_port) +{ + struct cxl_port *port; + struct device *dev; + int rc; + + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) + return ERR_PTR(-ENOMEM); + + rc = ida_alloc(&cxl_port_ida, GFP_KERNEL); + if (rc < 0) + goto err; + port->id = rc; + + /* + * The top-level cxl_port "cxl_root" does not have a cxl_port as + * its parent and it does not have any corresponding component + * registers as its decode is described by a fixed platform + * description. + */ + dev = &port->dev; + if (parent_port) + dev->parent = &parent_port->dev; + else + dev->parent = uport; + + port->uport = uport; + port->component_reg_phys = component_reg_phys; + ida_init(&port->decoder_ida); + INIT_LIST_HEAD(&port->dports); + + device_initialize(dev); + device_set_pm_not_required(dev); + dev->bus = &cxl_bus_type; + dev->type = &cxl_port_type; + + return port; + +err: + kfree(port); + return ERR_PTR(rc); +} + +/** + * devm_cxl_add_port - register a cxl_port in CXL memory decode hierarchy + * @host: host device for devm operations + * @uport: "physical" device implementing this upstream port + * @component_reg_phys: (optional) for configurable cxl_port instances + * @parent_port: next hop up in the CXL memory decode hierarchy + */ +struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport, + resource_size_t component_reg_phys, + struct cxl_port *parent_port) +{ + struct cxl_port *port; + struct device *dev; + int rc; + + port = cxl_port_alloc(uport, component_reg_phys, parent_port); + if (IS_ERR(port)) + return port; + + dev = &port->dev; + if (parent_port) + rc = dev_set_name(dev, "port%d", port->id); + else + rc = dev_set_name(dev, "root%d", port->id); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + rc = devm_add_action_or_reset(host, unregister_port, port); + if (rc) + return ERR_PTR(rc); + + rc = devm_cxl_link_uport(host, port); + if (rc) + return ERR_PTR(rc); + + return port; + +err: + put_device(dev); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(devm_cxl_add_port); + +static struct cxl_dport *find_dport(struct cxl_port *port, int id) +{ + struct cxl_dport *dport; + + device_lock_assert(&port->dev); + list_for_each_entry (dport, &port->dports, list) + if (dport->port_id == id) + return dport; + return NULL; +} + +static int add_dport(struct cxl_port *port, struct cxl_dport *new) +{ + struct cxl_dport *dup; + + device_lock(&port->dev); + dup = find_dport(port, new->port_id); + if (dup) + dev_err(&port->dev, + "unable to add dport%d-%s non-unique port id (%s)\n", + new->port_id, dev_name(new->dport), + dev_name(dup->dport)); + else + list_add_tail(&new->list, &port->dports); + device_unlock(&port->dev); + + return dup ? -EEXIST : 0; +} + +/** + * cxl_add_dport - append downstream port data to a cxl_port + * @port: the cxl_port that references this dport + * @dport_dev: firmware or PCI device representing the dport + * @port_id: identifier for this dport in a decoder's target list + * @component_reg_phys: optional location of CXL component registers + * + * Note that all allocations and links are undone by cxl_port deletion + * and release. + */ +int cxl_add_dport(struct cxl_port *port, struct device *dport_dev, int port_id, + resource_size_t component_reg_phys) +{ + char link_name[CXL_TARGET_STRLEN]; + struct cxl_dport *dport; + int rc; + + if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", port_id) >= + CXL_TARGET_STRLEN) + return -EINVAL; + + dport = kzalloc(sizeof(*dport), GFP_KERNEL); + if (!dport) + return -ENOMEM; + + INIT_LIST_HEAD(&dport->list); + dport->dport = get_device(dport_dev); + dport->port_id = port_id; + dport->component_reg_phys = component_reg_phys; + dport->port = port; + + rc = add_dport(port, dport); + if (rc) + goto err; + + rc = sysfs_create_link(&port->dev.kobj, &dport_dev->kobj, link_name); + if (rc) + goto err; + + return 0; +err: + cxl_dport_release(dport); + return rc; +} +EXPORT_SYMBOL_GPL(cxl_add_dport); + +static struct cxl_decoder * +cxl_decoder_alloc(struct cxl_port *port, int nr_targets, resource_size_t base, + resource_size_t len, int interleave_ways, + int interleave_granularity, enum cxl_decoder_type type, + unsigned long flags) +{ + struct cxl_decoder *cxld; + struct device *dev; + int rc = 0; + + if (interleave_ways < 1) + return ERR_PTR(-EINVAL); + + device_lock(&port->dev); + if (list_empty(&port->dports)) + rc = -EINVAL; + device_unlock(&port->dev); + if (rc) + return ERR_PTR(rc); + + cxld = kzalloc(struct_size(cxld, target, nr_targets), GFP_KERNEL); + if (!cxld) + return ERR_PTR(-ENOMEM); + + rc = ida_alloc(&port->decoder_ida, GFP_KERNEL); + if (rc < 0) + goto err; + + *cxld = (struct cxl_decoder) { + .id = rc, + .range = { + .start = base, + .end = base + len - 1, + }, + .flags = flags, + .interleave_ways = interleave_ways, + .interleave_granularity = interleave_granularity, + .target_type = type, + }; + + /* handle implied target_list */ + if (interleave_ways == 1) + cxld->target[0] = + list_first_entry(&port->dports, struct cxl_dport, list); + dev = &cxld->dev; + device_initialize(dev); + device_set_pm_not_required(dev); + dev->parent = &port->dev; + dev->bus = &cxl_bus_type; + + /* root ports do not have a cxl_port_type parent */ + if (port->dev.parent->type == &cxl_port_type) + dev->type = &cxl_decoder_switch_type; + else + dev->type = &cxl_decoder_root_type; + + return cxld; +err: + kfree(cxld); + return ERR_PTR(rc); +} + +static void unregister_dev(void *dev) +{ + device_unregister(dev); +} + +struct cxl_decoder * +devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, + resource_size_t base, resource_size_t len, + int interleave_ways, int interleave_granularity, + enum cxl_decoder_type type, unsigned long flags) +{ + struct cxl_decoder *cxld; + struct device *dev; + int rc; + + cxld = cxl_decoder_alloc(port, nr_targets, base, len, interleave_ways, + interleave_granularity, type, flags); + if (IS_ERR(cxld)) + return cxld; + + dev = &cxld->dev; + rc = dev_set_name(dev, "decoder%d.%d", port->id, cxld->id); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + rc = devm_add_action_or_reset(host, unregister_dev, dev); + if (rc) + return ERR_PTR(rc); + return cxld; + +err: + put_device(dev); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(devm_cxl_add_decoder); + +/** + * cxl_probe_component_regs() - Detect CXL Component register blocks + * @dev: Host device of the @base mapping + * @base: Mapping containing the HDM Decoder Capability Header + * @map: Map object describing the register block information found + * + * See CXL 2.0 8.2.4 Component Register Layout and Definition + * See CXL 2.0 8.2.5.5 CXL Device Register Interface + * + * Probe for component register information and return it in map object. + */ +void cxl_probe_component_regs(struct device *dev, void __iomem *base, + struct cxl_component_reg_map *map) +{ + int cap, cap_count; + u64 cap_array; + + *map = (struct cxl_component_reg_map) { 0 }; + + /* + * CXL.cache and CXL.mem registers are at offset 0x1000 as defined in + * CXL 2.0 8.2.4 Table 141. + */ + base += CXL_CM_OFFSET; + + cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET); + + if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) { + dev_err(dev, + "Couldn't locate the CXL.cache and CXL.mem capability array header./n"); + return; + } + + /* It's assumed that future versions will be backward compatible */ + cap_count = FIELD_GET(CXL_CM_CAP_HDR_ARRAY_SIZE_MASK, cap_array); + + for (cap = 1; cap <= cap_count; cap++) { + void __iomem *register_block; + u32 hdr; + int decoder_cnt; + u16 cap_id, offset; + u32 length; + + hdr = readl(base + cap * 0x4); + + cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr); + offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr); + register_block = base + offset; + + switch (cap_id) { + case CXL_CM_CAP_CAP_ID_HDM: + dev_dbg(dev, "found HDM decoder capability (0x%x)\n", + offset); + + hdr = readl(register_block); + + decoder_cnt = cxl_hdm_decoder_count(hdr); + length = 0x20 * decoder_cnt + 0x10; + + map->hdm_decoder.valid = true; + map->hdm_decoder.offset = CXL_CM_OFFSET + offset; + map->hdm_decoder.size = length; + break; + default: + dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, + offset); + break; + } + } +} +EXPORT_SYMBOL_GPL(cxl_probe_component_regs); + +static void cxl_nvdimm_bridge_release(struct device *dev) +{ + struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); + + kfree(cxl_nvb); +} + +static const struct attribute_group *cxl_nvdimm_bridge_attribute_groups[] = { + &cxl_base_attribute_group, + NULL, +}; + +static const struct device_type cxl_nvdimm_bridge_type = { + .name = "cxl_nvdimm_bridge", + .release = cxl_nvdimm_bridge_release, + .groups = cxl_nvdimm_bridge_attribute_groups, +}; + +struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) +{ + if (dev_WARN_ONCE(dev, dev->type != &cxl_nvdimm_bridge_type, + "not a cxl_nvdimm_bridge device\n")) + return NULL; + return container_of(dev, struct cxl_nvdimm_bridge, dev); +} +EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); + +static struct cxl_nvdimm_bridge * +cxl_nvdimm_bridge_alloc(struct cxl_port *port) +{ + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + + cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); + if (!cxl_nvb) + return ERR_PTR(-ENOMEM); + + dev = &cxl_nvb->dev; + cxl_nvb->port = port; + cxl_nvb->state = CXL_NVB_NEW; + device_initialize(dev); + device_set_pm_not_required(dev); + dev->parent = &port->dev; + dev->bus = &cxl_bus_type; + dev->type = &cxl_nvdimm_bridge_type; + + return cxl_nvb; +} + +static void unregister_nvb(void *_cxl_nvb) +{ + struct cxl_nvdimm_bridge *cxl_nvb = _cxl_nvb; + bool flush; + + /* + * If the bridge was ever activated then there might be in-flight state + * work to flush. Once the state has been changed to 'dead' then no new + * work can be queued by user-triggered bind. + */ + device_lock(&cxl_nvb->dev); + flush = cxl_nvb->state != CXL_NVB_NEW; + cxl_nvb->state = CXL_NVB_DEAD; + device_unlock(&cxl_nvb->dev); + + /* + * Even though the device core will trigger device_release_driver() + * before the unregister, it does not know about the fact that + * cxl_nvdimm_bridge_driver defers ->remove() work. So, do the driver + * release not and flush it before tearing down the nvdimm device + * hierarchy. + */ + device_release_driver(&cxl_nvb->dev); + if (flush) + flush_work(&cxl_nvb->state_work); + device_unregister(&cxl_nvb->dev); +} + +struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, + struct cxl_port *port) +{ + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + int rc; + + if (!IS_ENABLED(CONFIG_CXL_PMEM)) + return ERR_PTR(-ENXIO); + + cxl_nvb = cxl_nvdimm_bridge_alloc(port); + if (IS_ERR(cxl_nvb)) + return cxl_nvb; + + dev = &cxl_nvb->dev; + rc = dev_set_name(dev, "nvdimm-bridge"); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb); + if (rc) + return ERR_PTR(rc); + + return cxl_nvb; + +err: + put_device(dev); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); + +static void cxl_nvdimm_release(struct device *dev) +{ + struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); + + kfree(cxl_nvd); +} + +static const struct attribute_group *cxl_nvdimm_attribute_groups[] = { + &cxl_base_attribute_group, + NULL, +}; + +static const struct device_type cxl_nvdimm_type = { + .name = "cxl_nvdimm", + .release = cxl_nvdimm_release, + .groups = cxl_nvdimm_attribute_groups, +}; + +bool is_cxl_nvdimm(struct device *dev) +{ + return dev->type == &cxl_nvdimm_type; +} +EXPORT_SYMBOL_GPL(is_cxl_nvdimm); + +struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) +{ + if (dev_WARN_ONCE(dev, !is_cxl_nvdimm(dev), + "not a cxl_nvdimm device\n")) + return NULL; + return container_of(dev, struct cxl_nvdimm, dev); +} +EXPORT_SYMBOL_GPL(to_cxl_nvdimm); + +static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) +{ + struct cxl_nvdimm *cxl_nvd; + struct device *dev; + + cxl_nvd = kzalloc(sizeof(*cxl_nvd), GFP_KERNEL); + if (!cxl_nvd) + return ERR_PTR(-ENOMEM); + + dev = &cxl_nvd->dev; + cxl_nvd->cxlmd = cxlmd; + device_initialize(dev); + device_set_pm_not_required(dev); + dev->parent = &cxlmd->dev; + dev->bus = &cxl_bus_type; + dev->type = &cxl_nvdimm_type; + + return cxl_nvd; +} + +int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd) +{ + struct cxl_nvdimm *cxl_nvd; + struct device *dev; + int rc; + + cxl_nvd = cxl_nvdimm_alloc(cxlmd); + if (IS_ERR(cxl_nvd)) + return PTR_ERR(cxl_nvd); + + dev = &cxl_nvd->dev; + rc = dev_set_name(dev, "pmem%d", cxlmd->id); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + dev_dbg(host, "%s: register %s\n", dev_name(dev->parent), + dev_name(dev)); + + return devm_add_action_or_reset(host, unregister_dev, dev); + +err: + put_device(dev); + return rc; +} +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); + +/** + * cxl_probe_device_regs() - Detect CXL Device register blocks + * @dev: Host device of the @base mapping + * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface + * @map: Map object describing the register block information found + * + * Probe for device register information and return it in map object. + */ +void cxl_probe_device_regs(struct device *dev, void __iomem *base, + struct cxl_device_reg_map *map) +{ + int cap, cap_count; + u64 cap_array; + + *map = (struct cxl_device_reg_map){ 0 }; + + cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET); + if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) != + CXLDEV_CAP_ARRAY_CAP_ID) + return; + + cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array); + + for (cap = 1; cap <= cap_count; cap++) { + u32 offset, length; + u16 cap_id; + + cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK, + readl(base + cap * 0x10)); + offset = readl(base + cap * 0x10 + 0x4); + length = readl(base + cap * 0x10 + 0x8); + + switch (cap_id) { + case CXLDEV_CAP_CAP_ID_DEVICE_STATUS: + dev_dbg(dev, "found Status capability (0x%x)\n", offset); + + map->status.valid = true; + map->status.offset = offset; + map->status.size = length; + break; + case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX: + dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset); + map->mbox.valid = true; + map->mbox.offset = offset; + map->mbox.size = length; + break; + case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX: + dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset); + break; + case CXLDEV_CAP_CAP_ID_MEMDEV: + dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); + map->memdev.valid = true; + map->memdev.offset = offset; + map->memdev.size = length; + break; + default: + if (cap_id >= 0x8000) + dev_dbg(dev, "Vendor cap ID: %#x offset: %#x\n", cap_id, offset); + else + dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset); + break; + } + } +} +EXPORT_SYMBOL_GPL(cxl_probe_device_regs); + +static void __iomem *devm_cxl_iomap_block(struct device *dev, + resource_size_t addr, + resource_size_t length) +{ + void __iomem *ret_val; + struct resource *res; + + res = devm_request_mem_region(dev, addr, length, dev_name(dev)); + if (!res) { + resource_size_t end = addr + length - 1; + + dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end); + return NULL; + } + + ret_val = devm_ioremap(dev, addr, length); + if (!ret_val) + dev_err(dev, "Failed to map region %pr\n", res); + + return ret_val; +} + +int cxl_map_component_regs(struct pci_dev *pdev, + struct cxl_component_regs *regs, + struct cxl_register_map *map) +{ + struct device *dev = &pdev->dev; + resource_size_t phys_addr; + resource_size_t length; + + phys_addr = pci_resource_start(pdev, map->barno); + phys_addr += map->block_offset; + + phys_addr += map->component_map.hdm_decoder.offset; + length = map->component_map.hdm_decoder.size; + regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); + if (!regs->hdm_decoder) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(cxl_map_component_regs); + +int cxl_map_device_regs(struct pci_dev *pdev, + struct cxl_device_regs *regs, + struct cxl_register_map *map) +{ + struct device *dev = &pdev->dev; + resource_size_t phys_addr; + + phys_addr = pci_resource_start(pdev, map->barno); + phys_addr += map->block_offset; + + if (map->device_map.status.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.status.offset; + length = map->device_map.status.size; + regs->status = devm_cxl_iomap_block(dev, addr, length); + if (!regs->status) + return -ENOMEM; + } + + if (map->device_map.mbox.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.mbox.offset; + length = map->device_map.mbox.size; + regs->mbox = devm_cxl_iomap_block(dev, addr, length); + if (!regs->mbox) + return -ENOMEM; + } + + if (map->device_map.memdev.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.memdev.offset; + length = map->device_map.memdev.size; + regs->memdev = devm_cxl_iomap_block(dev, addr, length); + if (!regs->memdev) + return -ENOMEM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(cxl_map_device_regs); + +/** + * __cxl_driver_register - register a driver for the cxl bus + * @cxl_drv: cxl driver structure to attach + * @owner: owning module/driver + * @modname: KBUILD_MODNAME for parent driver + */ +int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, + const char *modname) +{ + if (!cxl_drv->probe) { + pr_debug("%s ->probe() must be specified\n", modname); + return -EINVAL; + } + + if (!cxl_drv->name) { + pr_debug("%s ->name must be specified\n", modname); + return -EINVAL; + } + + if (!cxl_drv->id) { + pr_debug("%s ->id must be specified\n", modname); + return -EINVAL; + } + + cxl_drv->drv.bus = &cxl_bus_type; + cxl_drv->drv.owner = owner; + cxl_drv->drv.mod_name = modname; + cxl_drv->drv.name = cxl_drv->name; + + return driver_register(&cxl_drv->drv); +} +EXPORT_SYMBOL_GPL(__cxl_driver_register); + +void cxl_driver_unregister(struct cxl_driver *cxl_drv) +{ + driver_unregister(&cxl_drv->drv); +} +EXPORT_SYMBOL_GPL(cxl_driver_unregister); + +static int cxl_device_id(struct device *dev) +{ + if (dev->type == &cxl_nvdimm_bridge_type) + return CXL_DEVICE_NVDIMM_BRIDGE; + if (dev->type == &cxl_nvdimm_type) + return CXL_DEVICE_NVDIMM; + return 0; +} + +static int cxl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + return add_uevent_var(env, "MODALIAS=" CXL_MODALIAS_FMT, + cxl_device_id(dev)); +} + +static int cxl_bus_match(struct device *dev, struct device_driver *drv) +{ + return cxl_device_id(dev) == to_cxl_drv(drv)->id; +} + +static int cxl_bus_probe(struct device *dev) +{ + return to_cxl_drv(dev->driver)->probe(dev); +} + +static int cxl_bus_remove(struct device *dev) +{ + struct cxl_driver *cxl_drv = to_cxl_drv(dev->driver); + + if (cxl_drv->remove) + cxl_drv->remove(dev); + return 0; +} + +struct bus_type cxl_bus_type = { + .name = "cxl", + .uevent = cxl_bus_uevent, + .match = cxl_bus_match, + .probe = cxl_bus_probe, + .remove = cxl_bus_remove, +}; +EXPORT_SYMBOL_GPL(cxl_bus_type); + +static __init int cxl_core_init(void) +{ + return bus_register(&cxl_bus_type); +} + +static void cxl_core_exit(void) +{ + bus_unregister(&cxl_bus_type); +} + +module_init(cxl_core_init); +module_exit(cxl_core_exit); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h new file mode 100644 index 000000000000..8f02d02b26b4 --- /dev/null +++ b/drivers/cxl/cxlmem.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2020-2021 Intel Corporation. */ +#ifndef __CXL_MEM_H__ +#define __CXL_MEM_H__ +#include +#include "cxl.h" + +/* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */ +#define CXLMDEV_STATUS_OFFSET 0x0 +#define CXLMDEV_DEV_FATAL BIT(0) +#define CXLMDEV_FW_HALT BIT(1) +#define CXLMDEV_STATUS_MEDIA_STATUS_MASK GENMASK(3, 2) +#define CXLMDEV_MS_NOT_READY 0 +#define CXLMDEV_MS_READY 1 +#define CXLMDEV_MS_ERROR 2 +#define CXLMDEV_MS_DISABLED 3 +#define CXLMDEV_READY(status) \ + (FIELD_GET(CXLMDEV_STATUS_MEDIA_STATUS_MASK, status) == \ + CXLMDEV_MS_READY) +#define CXLMDEV_MBOX_IF_READY BIT(4) +#define CXLMDEV_RESET_NEEDED_MASK GENMASK(7, 5) +#define CXLMDEV_RESET_NEEDED_NOT 0 +#define CXLMDEV_RESET_NEEDED_COLD 1 +#define CXLMDEV_RESET_NEEDED_WARM 2 +#define CXLMDEV_RESET_NEEDED_HOT 3 +#define CXLMDEV_RESET_NEEDED_CXL 4 +#define CXLMDEV_RESET_NEEDED(status) \ + (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \ + CXLMDEV_RESET_NEEDED_NOT) + +/* + * An entire PCI topology full of devices should be enough for any + * config + */ +#define CXL_MEM_MAX_DEVS 65536 + +/** + * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device + * @dev: driver core device object + * @cdev: char dev core object for ioctl operations + * @cxlm: pointer to the parent device driver data + * @id: id number of this memdev instance. + */ +struct cxl_memdev { + struct device dev; + struct cdev cdev; + struct cxl_mem *cxlm; + int id; +}; + +/** + * struct cxl_mem - A CXL memory device + * @pdev: The PCI device associated with this CXL device. + * @cxlmd: Logical memory device chardev / interface + * @regs: Parsed register blocks + * @payload_size: Size of space for payload + * (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register) + * @lsa_size: Size of Label Storage Area + * (CXL 2.0 8.2.9.5.1.1 Identify Memory Device) + * @mbox_mutex: Mutex to synchronize mailbox access. + * @firmware_version: Firmware version for the memory device. + * @enabled_cmds: Hardware commands found enabled in CEL. + * @pmem_range: Persistent memory capacity information. + * @ram_range: Volatile memory capacity information. + */ +struct cxl_mem { + struct pci_dev *pdev; + struct cxl_memdev *cxlmd; + + struct cxl_regs regs; + + size_t payload_size; + size_t lsa_size; + struct mutex mbox_mutex; /* Protects device mailbox and firmware */ + char firmware_version[0x10]; + unsigned long *enabled_cmds; + + struct range pmem_range; + struct range ram_range; +}; +#endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/mem.h b/drivers/cxl/mem.h deleted file mode 100644 index 8f02d02b26b4..000000000000 --- a/drivers/cxl/mem.h +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright(c) 2020-2021 Intel Corporation. */ -#ifndef __CXL_MEM_H__ -#define __CXL_MEM_H__ -#include -#include "cxl.h" - -/* CXL 2.0 8.2.8.5.1.1 Memory Device Status Register */ -#define CXLMDEV_STATUS_OFFSET 0x0 -#define CXLMDEV_DEV_FATAL BIT(0) -#define CXLMDEV_FW_HALT BIT(1) -#define CXLMDEV_STATUS_MEDIA_STATUS_MASK GENMASK(3, 2) -#define CXLMDEV_MS_NOT_READY 0 -#define CXLMDEV_MS_READY 1 -#define CXLMDEV_MS_ERROR 2 -#define CXLMDEV_MS_DISABLED 3 -#define CXLMDEV_READY(status) \ - (FIELD_GET(CXLMDEV_STATUS_MEDIA_STATUS_MASK, status) == \ - CXLMDEV_MS_READY) -#define CXLMDEV_MBOX_IF_READY BIT(4) -#define CXLMDEV_RESET_NEEDED_MASK GENMASK(7, 5) -#define CXLMDEV_RESET_NEEDED_NOT 0 -#define CXLMDEV_RESET_NEEDED_COLD 1 -#define CXLMDEV_RESET_NEEDED_WARM 2 -#define CXLMDEV_RESET_NEEDED_HOT 3 -#define CXLMDEV_RESET_NEEDED_CXL 4 -#define CXLMDEV_RESET_NEEDED(status) \ - (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \ - CXLMDEV_RESET_NEEDED_NOT) - -/* - * An entire PCI topology full of devices should be enough for any - * config - */ -#define CXL_MEM_MAX_DEVS 65536 - -/** - * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device - * @dev: driver core device object - * @cdev: char dev core object for ioctl operations - * @cxlm: pointer to the parent device driver data - * @id: id number of this memdev instance. - */ -struct cxl_memdev { - struct device dev; - struct cdev cdev; - struct cxl_mem *cxlm; - int id; -}; - -/** - * struct cxl_mem - A CXL memory device - * @pdev: The PCI device associated with this CXL device. - * @cxlmd: Logical memory device chardev / interface - * @regs: Parsed register blocks - * @payload_size: Size of space for payload - * (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register) - * @lsa_size: Size of Label Storage Area - * (CXL 2.0 8.2.9.5.1.1 Identify Memory Device) - * @mbox_mutex: Mutex to synchronize mailbox access. - * @firmware_version: Firmware version for the memory device. - * @enabled_cmds: Hardware commands found enabled in CEL. - * @pmem_range: Persistent memory capacity information. - * @ram_range: Volatile memory capacity information. - */ -struct cxl_mem { - struct pci_dev *pdev; - struct cxl_memdev *cxlmd; - - struct cxl_regs regs; - - size_t payload_size; - size_t lsa_size; - struct mutex mbox_mutex; /* Protects device mailbox and firmware */ - char firmware_version[0x10]; - unsigned long *enabled_cmds; - - struct range pmem_range; - struct range ram_range; -}; -#endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 4cf351a3cf99..a945c5fda292 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -12,9 +12,9 @@ #include #include #include +#include "cxlmem.h" #include "pci.h" #include "cxl.h" -#include "mem.h" /** * DOC: cxl pci diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index 0088e41dd2f3..9652c3ee41e7 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -6,7 +6,7 @@ #include #include #include -#include "mem.h" +#include "cxlmem.h" #include "cxl.h" /* -- cgit v1.2.3-70-g09d2 From 95aaed266801a801add6d17cd3a4f7deb610af2e Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 2 Aug 2021 10:29:43 -0700 Subject: cxl/core: Improve CXL core kernel docs Now that CXL core's role is well understood, the documentation should reflect that information. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792538379.368511.9055351193841619781.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/cxl/core/bus.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index 0815eec23944..6ea69d70086b 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -12,8 +12,15 @@ /** * DOC: cxl core * - * The CXL core provides a sysfs hierarchy for control devices and a rendezvous - * point for cross-device interleave coordination through cxl ports. + * The CXL core provides a set of interfaces that can be consumed by CXL aware + * drivers. The interfaces allow for creation, modification, and destruction of + * regions, memory devices, ports, and decoders. CXL aware drivers must register + * with the CXL core via these interfaces in order to be able to participate in + * cross-device interleave coordination. The CXL core also establishes and + * maintains the bridge to the nvdimm subsystem. + * + * CXL core introduces sysfs hierarchy to control the devices that are + * instantiated by the core. */ static DEFINE_IDA(cxl_port_ida); -- cgit v1.2.3-70-g09d2 From 06737cd0d216be1cf6e8052e4fca0d391298f184 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 Aug 2021 10:29:49 -0700 Subject: cxl/core: Move pmem functionality Refactor the pmem / nvdimm-bridge functionality from core/bus.c to core/pmem.c. Introduce drivers/core/core.h to communicate data structures and helpers between the core bus and other functionality that registers devices on the bus. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792538899.368511.3881663908293411300.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- Documentation/driver-api/cxl/memory-devices.rst | 3 + drivers/cxl/core/Makefile | 1 + drivers/cxl/core/bus.c | 205 +----------------------- drivers/cxl/core/core.h | 17 ++ drivers/cxl/core/pmem.c | 204 +++++++++++++++++++++++ 5 files changed, 228 insertions(+), 202 deletions(-) create mode 100644 drivers/cxl/core/core.h create mode 100644 drivers/cxl/core/pmem.c diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst index a86e2c7c551a..e65c0ba82229 100644 --- a/Documentation/driver-api/cxl/memory-devices.rst +++ b/Documentation/driver-api/cxl/memory-devices.rst @@ -39,6 +39,9 @@ CXL Core .. kernel-doc:: drivers/cxl/core/bus.c :doc: cxl core +.. kernel-doc:: drivers/cxl/core/pmem.c + :internal: + External Interfaces =================== diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index ad137f96e5c8..e037521fe02b 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_CXL_BUS) += cxl_core.o ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl cxl_core-y := bus.o +cxl_core-y += pmem.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index 6ea69d70086b..408654ad70db 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -8,6 +8,7 @@ #include #include #include +#include "core.h" /** * DOC: cxl core @@ -37,7 +38,7 @@ static struct attribute *cxl_base_attributes[] = { NULL, }; -static struct attribute_group cxl_base_attribute_group = { +struct attribute_group cxl_base_attribute_group = { .attrs = cxl_base_attributes, }; @@ -514,11 +515,6 @@ err: return ERR_PTR(rc); } -static void unregister_dev(void *dev) -{ - device_unregister(dev); -} - struct cxl_decoder * devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, resource_size_t base, resource_size_t len, @@ -543,7 +539,7 @@ devm_cxl_add_decoder(struct device *host, struct cxl_port *port, int nr_targets, if (rc) goto err; - rc = devm_add_action_or_reset(host, unregister_dev, dev); + rc = devm_add_action_or_reset(host, unregister_cxl_dev, dev); if (rc) return ERR_PTR(rc); return cxld; @@ -626,201 +622,6 @@ void cxl_probe_component_regs(struct device *dev, void __iomem *base, } EXPORT_SYMBOL_GPL(cxl_probe_component_regs); -static void cxl_nvdimm_bridge_release(struct device *dev) -{ - struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); - - kfree(cxl_nvb); -} - -static const struct attribute_group *cxl_nvdimm_bridge_attribute_groups[] = { - &cxl_base_attribute_group, - NULL, -}; - -static const struct device_type cxl_nvdimm_bridge_type = { - .name = "cxl_nvdimm_bridge", - .release = cxl_nvdimm_bridge_release, - .groups = cxl_nvdimm_bridge_attribute_groups, -}; - -struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) -{ - if (dev_WARN_ONCE(dev, dev->type != &cxl_nvdimm_bridge_type, - "not a cxl_nvdimm_bridge device\n")) - return NULL; - return container_of(dev, struct cxl_nvdimm_bridge, dev); -} -EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); - -static struct cxl_nvdimm_bridge * -cxl_nvdimm_bridge_alloc(struct cxl_port *port) -{ - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - - cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); - if (!cxl_nvb) - return ERR_PTR(-ENOMEM); - - dev = &cxl_nvb->dev; - cxl_nvb->port = port; - cxl_nvb->state = CXL_NVB_NEW; - device_initialize(dev); - device_set_pm_not_required(dev); - dev->parent = &port->dev; - dev->bus = &cxl_bus_type; - dev->type = &cxl_nvdimm_bridge_type; - - return cxl_nvb; -} - -static void unregister_nvb(void *_cxl_nvb) -{ - struct cxl_nvdimm_bridge *cxl_nvb = _cxl_nvb; - bool flush; - - /* - * If the bridge was ever activated then there might be in-flight state - * work to flush. Once the state has been changed to 'dead' then no new - * work can be queued by user-triggered bind. - */ - device_lock(&cxl_nvb->dev); - flush = cxl_nvb->state != CXL_NVB_NEW; - cxl_nvb->state = CXL_NVB_DEAD; - device_unlock(&cxl_nvb->dev); - - /* - * Even though the device core will trigger device_release_driver() - * before the unregister, it does not know about the fact that - * cxl_nvdimm_bridge_driver defers ->remove() work. So, do the driver - * release not and flush it before tearing down the nvdimm device - * hierarchy. - */ - device_release_driver(&cxl_nvb->dev); - if (flush) - flush_work(&cxl_nvb->state_work); - device_unregister(&cxl_nvb->dev); -} - -struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, - struct cxl_port *port) -{ - struct cxl_nvdimm_bridge *cxl_nvb; - struct device *dev; - int rc; - - if (!IS_ENABLED(CONFIG_CXL_PMEM)) - return ERR_PTR(-ENXIO); - - cxl_nvb = cxl_nvdimm_bridge_alloc(port); - if (IS_ERR(cxl_nvb)) - return cxl_nvb; - - dev = &cxl_nvb->dev; - rc = dev_set_name(dev, "nvdimm-bridge"); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb); - if (rc) - return ERR_PTR(rc); - - return cxl_nvb; - -err: - put_device(dev); - return ERR_PTR(rc); -} -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); - -static void cxl_nvdimm_release(struct device *dev) -{ - struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); - - kfree(cxl_nvd); -} - -static const struct attribute_group *cxl_nvdimm_attribute_groups[] = { - &cxl_base_attribute_group, - NULL, -}; - -static const struct device_type cxl_nvdimm_type = { - .name = "cxl_nvdimm", - .release = cxl_nvdimm_release, - .groups = cxl_nvdimm_attribute_groups, -}; - -bool is_cxl_nvdimm(struct device *dev) -{ - return dev->type == &cxl_nvdimm_type; -} -EXPORT_SYMBOL_GPL(is_cxl_nvdimm); - -struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) -{ - if (dev_WARN_ONCE(dev, !is_cxl_nvdimm(dev), - "not a cxl_nvdimm device\n")) - return NULL; - return container_of(dev, struct cxl_nvdimm, dev); -} -EXPORT_SYMBOL_GPL(to_cxl_nvdimm); - -static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) -{ - struct cxl_nvdimm *cxl_nvd; - struct device *dev; - - cxl_nvd = kzalloc(sizeof(*cxl_nvd), GFP_KERNEL); - if (!cxl_nvd) - return ERR_PTR(-ENOMEM); - - dev = &cxl_nvd->dev; - cxl_nvd->cxlmd = cxlmd; - device_initialize(dev); - device_set_pm_not_required(dev); - dev->parent = &cxlmd->dev; - dev->bus = &cxl_bus_type; - dev->type = &cxl_nvdimm_type; - - return cxl_nvd; -} - -int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd) -{ - struct cxl_nvdimm *cxl_nvd; - struct device *dev; - int rc; - - cxl_nvd = cxl_nvdimm_alloc(cxlmd); - if (IS_ERR(cxl_nvd)) - return PTR_ERR(cxl_nvd); - - dev = &cxl_nvd->dev; - rc = dev_set_name(dev, "pmem%d", cxlmd->id); - if (rc) - goto err; - - rc = device_add(dev); - if (rc) - goto err; - - dev_dbg(host, "%s: register %s\n", dev_name(dev->parent), - dev_name(dev)); - - return devm_add_action_or_reset(host, unregister_dev, dev); - -err: - put_device(dev); - return rc; -} -EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); - /** * cxl_probe_device_regs() - Detect CXL Device register blocks * @dev: Host device of the @base mapping diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h new file mode 100644 index 000000000000..49045daf8bd7 --- /dev/null +++ b/drivers/cxl/core/core.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright(c) 2020 Intel Corporation. */ + +#ifndef __CXL_CORE_H__ +#define __CXL_CORE_H__ + +extern const struct device_type cxl_nvdimm_bridge_type; +extern const struct device_type cxl_nvdimm_type; + +extern struct attribute_group cxl_base_attribute_group; + +static inline void unregister_cxl_dev(void *dev) +{ + device_unregister(dev); +} + +#endif /* __CXL_CORE_H__ */ diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c new file mode 100644 index 000000000000..69c97cc0d945 --- /dev/null +++ b/drivers/cxl/core/pmem.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2020 Intel Corporation. */ + +#include +#include +#include +#include + +#include "core.h" + +static void cxl_nvdimm_bridge_release(struct device *dev) +{ + struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); + + kfree(cxl_nvb); +} + +static const struct attribute_group *cxl_nvdimm_bridge_attribute_groups[] = { + &cxl_base_attribute_group, + NULL, +}; + +const struct device_type cxl_nvdimm_bridge_type = { + .name = "cxl_nvdimm_bridge", + .release = cxl_nvdimm_bridge_release, + .groups = cxl_nvdimm_bridge_attribute_groups, +}; + +struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev) +{ + if (dev_WARN_ONCE(dev, dev->type != &cxl_nvdimm_bridge_type, + "not a cxl_nvdimm_bridge device\n")) + return NULL; + return container_of(dev, struct cxl_nvdimm_bridge, dev); +} +EXPORT_SYMBOL_GPL(to_cxl_nvdimm_bridge); + +static struct cxl_nvdimm_bridge * +cxl_nvdimm_bridge_alloc(struct cxl_port *port) +{ + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + + cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); + if (!cxl_nvb) + return ERR_PTR(-ENOMEM); + + dev = &cxl_nvb->dev; + cxl_nvb->port = port; + cxl_nvb->state = CXL_NVB_NEW; + device_initialize(dev); + device_set_pm_not_required(dev); + dev->parent = &port->dev; + dev->bus = &cxl_bus_type; + dev->type = &cxl_nvdimm_bridge_type; + + return cxl_nvb; +} + +static void unregister_nvb(void *_cxl_nvb) +{ + struct cxl_nvdimm_bridge *cxl_nvb = _cxl_nvb; + bool flush; + + /* + * If the bridge was ever activated then there might be in-flight state + * work to flush. Once the state has been changed to 'dead' then no new + * work can be queued by user-triggered bind. + */ + device_lock(&cxl_nvb->dev); + flush = cxl_nvb->state != CXL_NVB_NEW; + cxl_nvb->state = CXL_NVB_DEAD; + device_unlock(&cxl_nvb->dev); + + /* + * Even though the device core will trigger device_release_driver() + * before the unregister, it does not know about the fact that + * cxl_nvdimm_bridge_driver defers ->remove() work. So, do the driver + * release not and flush it before tearing down the nvdimm device + * hierarchy. + */ + device_release_driver(&cxl_nvb->dev); + if (flush) + flush_work(&cxl_nvb->state_work); + device_unregister(&cxl_nvb->dev); +} + +struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, + struct cxl_port *port) +{ + struct cxl_nvdimm_bridge *cxl_nvb; + struct device *dev; + int rc; + + if (!IS_ENABLED(CONFIG_CXL_PMEM)) + return ERR_PTR(-ENXIO); + + cxl_nvb = cxl_nvdimm_bridge_alloc(port); + if (IS_ERR(cxl_nvb)) + return cxl_nvb; + + dev = &cxl_nvb->dev; + rc = dev_set_name(dev, "nvdimm-bridge"); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb); + if (rc) + return ERR_PTR(rc); + + return cxl_nvb; + +err: + put_device(dev); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm_bridge); + +static void cxl_nvdimm_release(struct device *dev) +{ + struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); + + kfree(cxl_nvd); +} + +static const struct attribute_group *cxl_nvdimm_attribute_groups[] = { + &cxl_base_attribute_group, + NULL, +}; + +const struct device_type cxl_nvdimm_type = { + .name = "cxl_nvdimm", + .release = cxl_nvdimm_release, + .groups = cxl_nvdimm_attribute_groups, +}; + +bool is_cxl_nvdimm(struct device *dev) +{ + return dev->type == &cxl_nvdimm_type; +} +EXPORT_SYMBOL_GPL(is_cxl_nvdimm); + +struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev) +{ + if (dev_WARN_ONCE(dev, !is_cxl_nvdimm(dev), + "not a cxl_nvdimm device\n")) + return NULL; + return container_of(dev, struct cxl_nvdimm, dev); +} +EXPORT_SYMBOL_GPL(to_cxl_nvdimm); + +static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) +{ + struct cxl_nvdimm *cxl_nvd; + struct device *dev; + + cxl_nvd = kzalloc(sizeof(*cxl_nvd), GFP_KERNEL); + if (!cxl_nvd) + return ERR_PTR(-ENOMEM); + + dev = &cxl_nvd->dev; + cxl_nvd->cxlmd = cxlmd; + device_initialize(dev); + device_set_pm_not_required(dev); + dev->parent = &cxlmd->dev; + dev->bus = &cxl_bus_type; + dev->type = &cxl_nvdimm_type; + + return cxl_nvd; +} + +int devm_cxl_add_nvdimm(struct device *host, struct cxl_memdev *cxlmd) +{ + struct cxl_nvdimm *cxl_nvd; + struct device *dev; + int rc; + + cxl_nvd = cxl_nvdimm_alloc(cxlmd); + if (IS_ERR(cxl_nvd)) + return PTR_ERR(cxl_nvd); + + dev = &cxl_nvd->dev; + rc = dev_set_name(dev, "pmem%d", cxlmd->id); + if (rc) + goto err; + + rc = device_add(dev); + if (rc) + goto err; + + dev_dbg(host, "%s: register %s\n", dev_name(dev->parent), + dev_name(dev)); + + return devm_add_action_or_reset(host, unregister_cxl_dev, dev); + +err: + put_device(dev); + return rc; +} +EXPORT_SYMBOL_GPL(devm_cxl_add_nvdimm); -- cgit v1.2.3-70-g09d2 From 0f06157e0135f5563efbc9aadbd93ba3d9322cab Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 3 Aug 2021 07:25:38 -0700 Subject: cxl/core: Move register mapping infrastructure The register mapping infrastructure is large enough to move to its own compilation unit. This also cleans up an unnecessary include of core/bus.c. Reported-by: kernel test robot Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162800068975.665205.12895551621746585289.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- Documentation/driver-api/cxl/memory-devices.rst | 3 + drivers/cxl/core/Makefile | 1 + drivers/cxl/core/bus.c | 228 ----------------------- drivers/cxl/core/regs.c | 236 ++++++++++++++++++++++++ 4 files changed, 240 insertions(+), 228 deletions(-) create mode 100644 drivers/cxl/core/regs.c diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst index e65c0ba82229..46847d8c70a0 100644 --- a/Documentation/driver-api/cxl/memory-devices.rst +++ b/Documentation/driver-api/cxl/memory-devices.rst @@ -42,6 +42,9 @@ CXL Core .. kernel-doc:: drivers/cxl/core/pmem.c :internal: +.. kernel-doc:: drivers/cxl/core/regs.c + :internal: + External Interfaces =================== diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index e037521fe02b..a3522d2fbf5b 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_CXL_BUS) += cxl_core.o ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl cxl_core-y := bus.o cxl_core-y += pmem.o +cxl_core-y += regs.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index 408654ad70db..c938d8590c9f 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -550,234 +550,6 @@ err: } EXPORT_SYMBOL_GPL(devm_cxl_add_decoder); -/** - * cxl_probe_component_regs() - Detect CXL Component register blocks - * @dev: Host device of the @base mapping - * @base: Mapping containing the HDM Decoder Capability Header - * @map: Map object describing the register block information found - * - * See CXL 2.0 8.2.4 Component Register Layout and Definition - * See CXL 2.0 8.2.5.5 CXL Device Register Interface - * - * Probe for component register information and return it in map object. - */ -void cxl_probe_component_regs(struct device *dev, void __iomem *base, - struct cxl_component_reg_map *map) -{ - int cap, cap_count; - u64 cap_array; - - *map = (struct cxl_component_reg_map) { 0 }; - - /* - * CXL.cache and CXL.mem registers are at offset 0x1000 as defined in - * CXL 2.0 8.2.4 Table 141. - */ - base += CXL_CM_OFFSET; - - cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET); - - if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) { - dev_err(dev, - "Couldn't locate the CXL.cache and CXL.mem capability array header./n"); - return; - } - - /* It's assumed that future versions will be backward compatible */ - cap_count = FIELD_GET(CXL_CM_CAP_HDR_ARRAY_SIZE_MASK, cap_array); - - for (cap = 1; cap <= cap_count; cap++) { - void __iomem *register_block; - u32 hdr; - int decoder_cnt; - u16 cap_id, offset; - u32 length; - - hdr = readl(base + cap * 0x4); - - cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr); - offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr); - register_block = base + offset; - - switch (cap_id) { - case CXL_CM_CAP_CAP_ID_HDM: - dev_dbg(dev, "found HDM decoder capability (0x%x)\n", - offset); - - hdr = readl(register_block); - - decoder_cnt = cxl_hdm_decoder_count(hdr); - length = 0x20 * decoder_cnt + 0x10; - - map->hdm_decoder.valid = true; - map->hdm_decoder.offset = CXL_CM_OFFSET + offset; - map->hdm_decoder.size = length; - break; - default: - dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, - offset); - break; - } - } -} -EXPORT_SYMBOL_GPL(cxl_probe_component_regs); - -/** - * cxl_probe_device_regs() - Detect CXL Device register blocks - * @dev: Host device of the @base mapping - * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface - * @map: Map object describing the register block information found - * - * Probe for device register information and return it in map object. - */ -void cxl_probe_device_regs(struct device *dev, void __iomem *base, - struct cxl_device_reg_map *map) -{ - int cap, cap_count; - u64 cap_array; - - *map = (struct cxl_device_reg_map){ 0 }; - - cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET); - if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) != - CXLDEV_CAP_ARRAY_CAP_ID) - return; - - cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array); - - for (cap = 1; cap <= cap_count; cap++) { - u32 offset, length; - u16 cap_id; - - cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK, - readl(base + cap * 0x10)); - offset = readl(base + cap * 0x10 + 0x4); - length = readl(base + cap * 0x10 + 0x8); - - switch (cap_id) { - case CXLDEV_CAP_CAP_ID_DEVICE_STATUS: - dev_dbg(dev, "found Status capability (0x%x)\n", offset); - - map->status.valid = true; - map->status.offset = offset; - map->status.size = length; - break; - case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX: - dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset); - map->mbox.valid = true; - map->mbox.offset = offset; - map->mbox.size = length; - break; - case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX: - dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset); - break; - case CXLDEV_CAP_CAP_ID_MEMDEV: - dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); - map->memdev.valid = true; - map->memdev.offset = offset; - map->memdev.size = length; - break; - default: - if (cap_id >= 0x8000) - dev_dbg(dev, "Vendor cap ID: %#x offset: %#x\n", cap_id, offset); - else - dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset); - break; - } - } -} -EXPORT_SYMBOL_GPL(cxl_probe_device_regs); - -static void __iomem *devm_cxl_iomap_block(struct device *dev, - resource_size_t addr, - resource_size_t length) -{ - void __iomem *ret_val; - struct resource *res; - - res = devm_request_mem_region(dev, addr, length, dev_name(dev)); - if (!res) { - resource_size_t end = addr + length - 1; - - dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end); - return NULL; - } - - ret_val = devm_ioremap(dev, addr, length); - if (!ret_val) - dev_err(dev, "Failed to map region %pr\n", res); - - return ret_val; -} - -int cxl_map_component_regs(struct pci_dev *pdev, - struct cxl_component_regs *regs, - struct cxl_register_map *map) -{ - struct device *dev = &pdev->dev; - resource_size_t phys_addr; - resource_size_t length; - - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - - phys_addr += map->component_map.hdm_decoder.offset; - length = map->component_map.hdm_decoder.size; - regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); - if (!regs->hdm_decoder) - return -ENOMEM; - - return 0; -} -EXPORT_SYMBOL_GPL(cxl_map_component_regs); - -int cxl_map_device_regs(struct pci_dev *pdev, - struct cxl_device_regs *regs, - struct cxl_register_map *map) -{ - struct device *dev = &pdev->dev; - resource_size_t phys_addr; - - phys_addr = pci_resource_start(pdev, map->barno); - phys_addr += map->block_offset; - - if (map->device_map.status.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.status.offset; - length = map->device_map.status.size; - regs->status = devm_cxl_iomap_block(dev, addr, length); - if (!regs->status) - return -ENOMEM; - } - - if (map->device_map.mbox.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.mbox.offset; - length = map->device_map.mbox.size; - regs->mbox = devm_cxl_iomap_block(dev, addr, length); - if (!regs->mbox) - return -ENOMEM; - } - - if (map->device_map.memdev.valid) { - resource_size_t addr; - resource_size_t length; - - addr = phys_addr + map->device_map.memdev.offset; - length = map->device_map.memdev.size; - regs->memdev = devm_cxl_iomap_block(dev, addr, length); - if (!regs->memdev) - return -ENOMEM; - } - - return 0; -} -EXPORT_SYMBOL_GPL(cxl_map_device_regs); - /** * __cxl_driver_register - register a driver for the cxl bus * @cxl_drv: cxl driver structure to attach diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c new file mode 100644 index 000000000000..8535a7b94f28 --- /dev/null +++ b/drivers/cxl/core/regs.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2020 Intel Corporation. */ + +#include +#include +#include +#include +#include + +/** + * cxl_probe_component_regs() - Detect CXL Component register blocks + * @dev: Host device of the @base mapping + * @base: Mapping containing the HDM Decoder Capability Header + * @map: Map object describing the register block information found + * + * See CXL 2.0 8.2.4 Component Register Layout and Definition + * See CXL 2.0 8.2.5.5 CXL Device Register Interface + * + * Probe for component register information and return it in map object. + */ +void cxl_probe_component_regs(struct device *dev, void __iomem *base, + struct cxl_component_reg_map *map) +{ + int cap, cap_count; + u64 cap_array; + + *map = (struct cxl_component_reg_map) { 0 }; + + /* + * CXL.cache and CXL.mem registers are at offset 0x1000 as defined in + * CXL 2.0 8.2.4 Table 141. + */ + base += CXL_CM_OFFSET; + + cap_array = readq(base + CXL_CM_CAP_HDR_OFFSET); + + if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) { + dev_err(dev, + "Couldn't locate the CXL.cache and CXL.mem capability array header./n"); + return; + } + + /* It's assumed that future versions will be backward compatible */ + cap_count = FIELD_GET(CXL_CM_CAP_HDR_ARRAY_SIZE_MASK, cap_array); + + for (cap = 1; cap <= cap_count; cap++) { + void __iomem *register_block; + u32 hdr; + int decoder_cnt; + u16 cap_id, offset; + u32 length; + + hdr = readl(base + cap * 0x4); + + cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr); + offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr); + register_block = base + offset; + + switch (cap_id) { + case CXL_CM_CAP_CAP_ID_HDM: + dev_dbg(dev, "found HDM decoder capability (0x%x)\n", + offset); + + hdr = readl(register_block); + + decoder_cnt = cxl_hdm_decoder_count(hdr); + length = 0x20 * decoder_cnt + 0x10; + + map->hdm_decoder.valid = true; + map->hdm_decoder.offset = CXL_CM_OFFSET + offset; + map->hdm_decoder.size = length; + break; + default: + dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id, + offset); + break; + } + } +} +EXPORT_SYMBOL_GPL(cxl_probe_component_regs); + +/** + * cxl_probe_device_regs() - Detect CXL Device register blocks + * @dev: Host device of the @base mapping + * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface + * @map: Map object describing the register block information found + * + * Probe for device register information and return it in map object. + */ +void cxl_probe_device_regs(struct device *dev, void __iomem *base, + struct cxl_device_reg_map *map) +{ + int cap, cap_count; + u64 cap_array; + + *map = (struct cxl_device_reg_map){ 0 }; + + cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET); + if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) != + CXLDEV_CAP_ARRAY_CAP_ID) + return; + + cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array); + + for (cap = 1; cap <= cap_count; cap++) { + u32 offset, length; + u16 cap_id; + + cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK, + readl(base + cap * 0x10)); + offset = readl(base + cap * 0x10 + 0x4); + length = readl(base + cap * 0x10 + 0x8); + + switch (cap_id) { + case CXLDEV_CAP_CAP_ID_DEVICE_STATUS: + dev_dbg(dev, "found Status capability (0x%x)\n", offset); + + map->status.valid = true; + map->status.offset = offset; + map->status.size = length; + break; + case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX: + dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset); + map->mbox.valid = true; + map->mbox.offset = offset; + map->mbox.size = length; + break; + case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX: + dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset); + break; + case CXLDEV_CAP_CAP_ID_MEMDEV: + dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset); + map->memdev.valid = true; + map->memdev.offset = offset; + map->memdev.size = length; + break; + default: + if (cap_id >= 0x8000) + dev_dbg(dev, "Vendor cap ID: %#x offset: %#x\n", cap_id, offset); + else + dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset); + break; + } + } +} +EXPORT_SYMBOL_GPL(cxl_probe_device_regs); + +static void __iomem *devm_cxl_iomap_block(struct device *dev, + resource_size_t addr, + resource_size_t length) +{ + void __iomem *ret_val; + struct resource *res; + + res = devm_request_mem_region(dev, addr, length, dev_name(dev)); + if (!res) { + resource_size_t end = addr + length - 1; + + dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end); + return NULL; + } + + ret_val = devm_ioremap(dev, addr, length); + if (!ret_val) + dev_err(dev, "Failed to map region %pr\n", res); + + return ret_val; +} + +int cxl_map_component_regs(struct pci_dev *pdev, + struct cxl_component_regs *regs, + struct cxl_register_map *map) +{ + struct device *dev = &pdev->dev; + resource_size_t phys_addr; + resource_size_t length; + + phys_addr = pci_resource_start(pdev, map->barno); + phys_addr += map->block_offset; + + phys_addr += map->component_map.hdm_decoder.offset; + length = map->component_map.hdm_decoder.size; + regs->hdm_decoder = devm_cxl_iomap_block(dev, phys_addr, length); + if (!regs->hdm_decoder) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(cxl_map_component_regs); + +int cxl_map_device_regs(struct pci_dev *pdev, + struct cxl_device_regs *regs, + struct cxl_register_map *map) +{ + struct device *dev = &pdev->dev; + resource_size_t phys_addr; + + phys_addr = pci_resource_start(pdev, map->barno); + phys_addr += map->block_offset; + + if (map->device_map.status.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.status.offset; + length = map->device_map.status.size; + regs->status = devm_cxl_iomap_block(dev, addr, length); + if (!regs->status) + return -ENOMEM; + } + + if (map->device_map.mbox.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.mbox.offset; + length = map->device_map.mbox.size; + regs->mbox = devm_cxl_iomap_block(dev, addr, length); + if (!regs->mbox) + return -ENOMEM; + } + + if (map->device_map.memdev.valid) { + resource_size_t addr; + resource_size_t length; + + addr = phys_addr + map->device_map.memdev.offset; + length = map->device_map.memdev.size; + regs->memdev = devm_cxl_iomap_block(dev, addr, length); + if (!regs->memdev) + return -ENOMEM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(cxl_map_device_regs); -- cgit v1.2.3-70-g09d2 From 9cc238c7a526dba9ee8c210fa2828886fc65db66 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 2 Aug 2021 10:29:59 -0700 Subject: cxl/pci: Introduce cdevm_file_operations In preparation for moving cxl_memdev allocation to the core, introduce cdevm_file_operations to coordinate file operations shutdown relative to driver data release. The motivation for moving cxl_memdev allocation to the core (beyond better file organization of sysfs attributes in core/ and drivers in cxl/), is that device lifetime is longer than module lifetime. The cxl_pci module should be free to come and go without needing to coordinate with devices that need the text associated with cxl_memdev_release() to stay resident. The move will fix a use after free bug when looping driver load / unload with CONFIG_DEBUG_KOBJECT_RELEASE=y. Another motivation for passing in file_operations to the core cxl_memdev creation flow is to allow for alternate drivers, like unit test code, to define their own ioctl backends. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792539962.368511.2962268954245340288.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/cxl/cxlmem.h | 15 ++++++++++++ drivers/cxl/pci.c | 65 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 8f02d02b26b4..0cd463de1342 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -34,6 +34,21 @@ */ #define CXL_MEM_MAX_DEVS 65536 +/** + * struct cdevm_file_operations - devm coordinated cdev file operations + * @fops: file operations that are synchronized against @shutdown + * @shutdown: disconnect driver data + * + * @shutdown is invoked in the devres release path to disconnect any + * driver instance data from @dev. It assumes synchronization with any + * fops operation that requires driver data. After @shutdown an + * operation may only reference @device data. + */ +struct cdevm_file_operations { + struct file_operations fops; + void (*shutdown)(struct device *dev); +}; + /** * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device * @dev: driver core device object diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index a945c5fda292..f7a5ad5e1f4a 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -806,13 +806,30 @@ static int cxl_memdev_release_file(struct inode *inode, struct file *file) return 0; } -static const struct file_operations cxl_memdev_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cxl_memdev_ioctl, - .open = cxl_memdev_open, - .release = cxl_memdev_release_file, - .compat_ioctl = compat_ptr_ioctl, - .llseek = noop_llseek, +static struct cxl_memdev *to_cxl_memdev(struct device *dev) +{ + return container_of(dev, struct cxl_memdev, dev); +} + +static void cxl_memdev_shutdown(struct device *dev) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + + down_write(&cxl_memdev_rwsem); + cxlmd->cxlm = NULL; + up_write(&cxl_memdev_rwsem); +} + +static const struct cdevm_file_operations cxl_memdev_fops = { + .fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = cxl_memdev_ioctl, + .open = cxl_memdev_open, + .release = cxl_memdev_release_file, + .compat_ioctl = compat_ptr_ioctl, + .llseek = noop_llseek, + }, + .shutdown = cxl_memdev_shutdown, }; static inline struct cxl_mem_command *cxl_mem_find_command(u16 opcode) @@ -1161,11 +1178,6 @@ free_maps: return ret; } -static struct cxl_memdev *to_cxl_memdev(struct device *dev) -{ - return container_of(dev, struct cxl_memdev, dev); -} - static void cxl_memdev_release(struct device *dev) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); @@ -1281,24 +1293,22 @@ static const struct device_type cxl_memdev_type = { .groups = cxl_memdev_attribute_groups, }; -static void cxl_memdev_shutdown(struct cxl_memdev *cxlmd) -{ - down_write(&cxl_memdev_rwsem); - cxlmd->cxlm = NULL; - up_write(&cxl_memdev_rwsem); -} - static void cxl_memdev_unregister(void *_cxlmd) { struct cxl_memdev *cxlmd = _cxlmd; struct device *dev = &cxlmd->dev; + struct cdev *cdev = &cxlmd->cdev; + const struct cdevm_file_operations *cdevm_fops; + + cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops); + cdevm_fops->shutdown(dev); cdev_device_del(&cxlmd->cdev, dev); - cxl_memdev_shutdown(cxlmd); put_device(dev); } -static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm) +static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm, + const struct file_operations *fops) { struct pci_dev *pdev = cxlm->pdev; struct cxl_memdev *cxlmd; @@ -1324,7 +1334,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm) device_set_pm_not_required(dev); cdev = &cxlmd->cdev; - cdev_init(cdev, &cxl_memdev_fops); + cdev_init(cdev, fops); return cxlmd; err: @@ -1332,15 +1342,16 @@ err: return ERR_PTR(rc); } -static struct cxl_memdev *devm_cxl_add_memdev(struct device *host, - struct cxl_mem *cxlm) +static struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops) { struct cxl_memdev *cxlmd; struct device *dev; struct cdev *cdev; int rc; - cxlmd = cxl_memdev_alloc(cxlm); + cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops); if (IS_ERR(cxlmd)) return cxlmd; @@ -1370,7 +1381,7 @@ err: * The cdev was briefly live, shutdown any ioctl operations that * saw that state. */ - cxl_memdev_shutdown(cxlmd); + cdevm_fops->shutdown(dev); put_device(dev); return ERR_PTR(rc); } @@ -1611,7 +1622,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; - cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm); + cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); -- cgit v1.2.3-70-g09d2 From 3d135db510240fefd79da46181493d3e3b415f6b Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 2 Aug 2021 10:30:05 -0700 Subject: cxl/core: Move memdev management to core The motivation for moving cxl_memdev allocation to the core (beyond better file organization of sysfs attributes in core/ and drivers in cxl/), is that device lifetime is longer than module lifetime. The cxl_pci module should be free to come and go without needing to coordinate with devices that need the text associated with cxl_memdev_release() to stay resident. The move fixes a use after free bug when looping driver load / unload with CONFIG_DEBUG_KOBJECT_RELEASE=y. Another motivation for disconnecting cxl_memdev creation from cxl_pci is to enable other drivers, like a unit test driver, to registers memdevs. Fixes: b39cb1052a5c ("cxl/mem: Register CXL memX devices") Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792540495.368511.9748638751088219595.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- drivers/cxl/core/Makefile | 1 + drivers/cxl/core/bus.c | 16 ++- drivers/cxl/core/core.h | 3 + drivers/cxl/core/memdev.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/cxl/cxlmem.h | 15 +-- drivers/cxl/pci.c | 228 +----------------------------------------- 6 files changed, 275 insertions(+), 234 deletions(-) create mode 100644 drivers/cxl/core/memdev.c diff --git a/drivers/cxl/core/Makefile b/drivers/cxl/core/Makefile index a3522d2fbf5b..0fdbf3c6ac1a 100644 --- a/drivers/cxl/core/Makefile +++ b/drivers/cxl/core/Makefile @@ -5,3 +5,4 @@ ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=CXL -I$(srctree)/drivers/cxl cxl_core-y := bus.o cxl_core-y += pmem.o cxl_core-y += regs.o +cxl_core-y += memdev.o diff --git a/drivers/cxl/core/bus.c b/drivers/cxl/core/bus.c index c938d8590c9f..37b87adaa33f 100644 --- a/drivers/cxl/core/bus.c +++ b/drivers/cxl/core/bus.c @@ -634,12 +634,26 @@ EXPORT_SYMBOL_GPL(cxl_bus_type); static __init int cxl_core_init(void) { - return bus_register(&cxl_bus_type); + int rc; + + rc = cxl_memdev_init(); + if (rc) + return rc; + + rc = bus_register(&cxl_bus_type); + if (rc) + goto err; + return 0; + +err: + cxl_memdev_exit(); + return rc; } static void cxl_core_exit(void) { bus_unregister(&cxl_bus_type); + cxl_memdev_exit(); } module_init(cxl_core_init); diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 49045daf8bd7..036a3c8106b4 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -14,4 +14,7 @@ static inline void unregister_cxl_dev(void *dev) device_unregister(dev); } +int cxl_memdev_init(void); +void cxl_memdev_exit(void); + #endif /* __CXL_CORE_H__ */ diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c new file mode 100644 index 000000000000..a9c317e32010 --- /dev/null +++ b/drivers/cxl/core/memdev.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2020 Intel Corporation. */ + +#include +#include +#include +#include +#include +#include "core.h" + +/* + * An entire PCI topology full of devices should be enough for any + * config + */ +#define CXL_MEM_MAX_DEVS 65536 + +static int cxl_mem_major; +static DEFINE_IDA(cxl_memdev_ida); + +static void cxl_memdev_release(struct device *dev) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + + ida_free(&cxl_memdev_ida, cxlmd->id); + kfree(cxlmd); +} + +static char *cxl_memdev_devnode(struct device *dev, umode_t *mode, kuid_t *uid, + kgid_t *gid) +{ + return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev)); +} + +static ssize_t firmware_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mem *cxlm = cxlmd->cxlm; + + return sysfs_emit(buf, "%.16s\n", cxlm->firmware_version); +} +static DEVICE_ATTR_RO(firmware_version); + +static ssize_t payload_max_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mem *cxlm = cxlmd->cxlm; + + return sysfs_emit(buf, "%zu\n", cxlm->payload_size); +} +static DEVICE_ATTR_RO(payload_max); + +static ssize_t label_storage_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mem *cxlm = cxlmd->cxlm; + + return sysfs_emit(buf, "%zu\n", cxlm->lsa_size); +} +static DEVICE_ATTR_RO(label_storage_size); + +static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mem *cxlm = cxlmd->cxlm; + unsigned long long len = range_len(&cxlm->ram_range); + + return sysfs_emit(buf, "%#llx\n", len); +} + +static struct device_attribute dev_attr_ram_size = + __ATTR(size, 0444, ram_size_show, NULL); + +static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + struct cxl_mem *cxlm = cxlmd->cxlm; + unsigned long long len = range_len(&cxlm->pmem_range); + + return sysfs_emit(buf, "%#llx\n", len); +} + +static struct device_attribute dev_attr_pmem_size = + __ATTR(size, 0444, pmem_size_show, NULL); + +static struct attribute *cxl_memdev_attributes[] = { + &dev_attr_firmware_version.attr, + &dev_attr_payload_max.attr, + &dev_attr_label_storage_size.attr, + NULL, +}; + +static struct attribute *cxl_memdev_pmem_attributes[] = { + &dev_attr_pmem_size.attr, + NULL, +}; + +static struct attribute *cxl_memdev_ram_attributes[] = { + &dev_attr_ram_size.attr, + NULL, +}; + +static struct attribute_group cxl_memdev_attribute_group = { + .attrs = cxl_memdev_attributes, +}; + +static struct attribute_group cxl_memdev_ram_attribute_group = { + .name = "ram", + .attrs = cxl_memdev_ram_attributes, +}; + +static struct attribute_group cxl_memdev_pmem_attribute_group = { + .name = "pmem", + .attrs = cxl_memdev_pmem_attributes, +}; + +static const struct attribute_group *cxl_memdev_attribute_groups[] = { + &cxl_memdev_attribute_group, + &cxl_memdev_ram_attribute_group, + &cxl_memdev_pmem_attribute_group, + NULL, +}; + +static const struct device_type cxl_memdev_type = { + .name = "cxl_memdev", + .release = cxl_memdev_release, + .devnode = cxl_memdev_devnode, + .groups = cxl_memdev_attribute_groups, +}; + +static void cxl_memdev_unregister(void *_cxlmd) +{ + struct cxl_memdev *cxlmd = _cxlmd; + struct device *dev = &cxlmd->dev; + struct cdev *cdev = &cxlmd->cdev; + const struct cdevm_file_operations *cdevm_fops; + + cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops); + cdevm_fops->shutdown(dev); + + cdev_device_del(&cxlmd->cdev, dev); + put_device(dev); +} + +static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm, + const struct file_operations *fops) +{ + struct pci_dev *pdev = cxlm->pdev; + struct cxl_memdev *cxlmd; + struct device *dev; + struct cdev *cdev; + int rc; + + cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL); + if (!cxlmd) + return ERR_PTR(-ENOMEM); + + rc = ida_alloc_range(&cxl_memdev_ida, 0, CXL_MEM_MAX_DEVS, GFP_KERNEL); + if (rc < 0) + goto err; + cxlmd->id = rc; + + dev = &cxlmd->dev; + device_initialize(dev); + dev->parent = &pdev->dev; + dev->bus = &cxl_bus_type; + dev->devt = MKDEV(cxl_mem_major, cxlmd->id); + dev->type = &cxl_memdev_type; + device_set_pm_not_required(dev); + + cdev = &cxlmd->cdev; + cdev_init(cdev, fops); + return cxlmd; + +err: + kfree(cxlmd); + return ERR_PTR(rc); +} + +struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops) +{ + struct cxl_memdev *cxlmd; + struct device *dev; + struct cdev *cdev; + int rc; + + cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops); + if (IS_ERR(cxlmd)) + return cxlmd; + + dev = &cxlmd->dev; + rc = dev_set_name(dev, "mem%d", cxlmd->id); + if (rc) + goto err; + + /* + * Activate ioctl operations, no cxl_memdev_rwsem manipulation + * needed as this is ordered with cdev_add() publishing the device. + */ + cxlmd->cxlm = cxlm; + + cdev = &cxlmd->cdev; + rc = cdev_device_add(cdev, dev); + if (rc) + goto err; + + rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd); + if (rc) + return ERR_PTR(rc); + return cxlmd; + +err: + /* + * The cdev was briefly live, shutdown any ioctl operations that + * saw that state. + */ + cdevm_fops->shutdown(dev); + put_device(dev); + return ERR_PTR(rc); +} +EXPORT_SYMBOL_GPL(devm_cxl_add_memdev); + +__init int cxl_memdev_init(void) +{ + dev_t devt; + int rc; + + rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl"); + if (rc) + return rc; + + cxl_mem_major = MAJOR(devt); + + return 0; +} + +void cxl_memdev_exit(void) +{ + unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS); +} diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 0cd463de1342..25345ece25f8 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -28,12 +28,6 @@ (FIELD_GET(CXLMDEV_RESET_NEEDED_MASK, status) != \ CXLMDEV_RESET_NEEDED_NOT) -/* - * An entire PCI topology full of devices should be enough for any - * config - */ -#define CXL_MEM_MAX_DEVS 65536 - /** * struct cdevm_file_operations - devm coordinated cdev file operations * @fops: file operations that are synchronized against @shutdown @@ -63,6 +57,15 @@ struct cxl_memdev { int id; }; +static inline struct cxl_memdev *to_cxl_memdev(struct device *dev) +{ + return container_of(dev, struct cxl_memdev, dev); +} + +struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops); + /** * struct cxl_mem - A CXL memory device * @pdev: The PCI device associated with this CXL device. diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index f7a5ad5e1f4a..193983e6edce 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -94,8 +94,6 @@ struct mbox_cmd { #define CXL_MBOX_SUCCESS 0 }; -static int cxl_mem_major; -static DEFINE_IDA(cxl_memdev_ida); static DECLARE_RWSEM(cxl_memdev_rwsem); static struct dentry *cxl_debugfs; static bool cxl_raw_allow_all; @@ -806,11 +804,6 @@ static int cxl_memdev_release_file(struct inode *inode, struct file *file) return 0; } -static struct cxl_memdev *to_cxl_memdev(struct device *dev) -{ - return container_of(dev, struct cxl_memdev, dev); -} - static void cxl_memdev_shutdown(struct device *dev) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); @@ -1178,214 +1171,6 @@ free_maps: return ret; } -static void cxl_memdev_release(struct device *dev) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - - ida_free(&cxl_memdev_ida, cxlmd->id); - kfree(cxlmd); -} - -static char *cxl_memdev_devnode(struct device *dev, umode_t *mode, kuid_t *uid, - kgid_t *gid) -{ - return kasprintf(GFP_KERNEL, "cxl/%s", dev_name(dev)); -} - -static ssize_t firmware_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_mem *cxlm = cxlmd->cxlm; - - return sysfs_emit(buf, "%.16s\n", cxlm->firmware_version); -} -static DEVICE_ATTR_RO(firmware_version); - -static ssize_t payload_max_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_mem *cxlm = cxlmd->cxlm; - - return sysfs_emit(buf, "%zu\n", cxlm->payload_size); -} -static DEVICE_ATTR_RO(payload_max); - -static ssize_t label_storage_size_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_mem *cxlm = cxlmd->cxlm; - - return sysfs_emit(buf, "%zu\n", cxlm->lsa_size); -} -static DEVICE_ATTR_RO(label_storage_size); - -static ssize_t ram_size_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_mem *cxlm = cxlmd->cxlm; - unsigned long long len = range_len(&cxlm->ram_range); - - return sysfs_emit(buf, "%#llx\n", len); -} - -static struct device_attribute dev_attr_ram_size = - __ATTR(size, 0444, ram_size_show, NULL); - -static ssize_t pmem_size_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cxl_memdev *cxlmd = to_cxl_memdev(dev); - struct cxl_mem *cxlm = cxlmd->cxlm; - unsigned long long len = range_len(&cxlm->pmem_range); - - return sysfs_emit(buf, "%#llx\n", len); -} - -static struct device_attribute dev_attr_pmem_size = - __ATTR(size, 0444, pmem_size_show, NULL); - -static struct attribute *cxl_memdev_attributes[] = { - &dev_attr_firmware_version.attr, - &dev_attr_payload_max.attr, - &dev_attr_label_storage_size.attr, - NULL, -}; - -static struct attribute *cxl_memdev_pmem_attributes[] = { - &dev_attr_pmem_size.attr, - NULL, -}; - -static struct attribute *cxl_memdev_ram_attributes[] = { - &dev_attr_ram_size.attr, - NULL, -}; - -static struct attribute_group cxl_memdev_attribute_group = { - .attrs = cxl_memdev_attributes, -}; - -static struct attribute_group cxl_memdev_ram_attribute_group = { - .name = "ram", - .attrs = cxl_memdev_ram_attributes, -}; - -static struct attribute_group cxl_memdev_pmem_attribute_group = { - .name = "pmem", - .attrs = cxl_memdev_pmem_attributes, -}; - -static const struct attribute_group *cxl_memdev_attribute_groups[] = { - &cxl_memdev_attribute_group, - &cxl_memdev_ram_attribute_group, - &cxl_memdev_pmem_attribute_group, - NULL, -}; - -static const struct device_type cxl_memdev_type = { - .name = "cxl_memdev", - .release = cxl_memdev_release, - .devnode = cxl_memdev_devnode, - .groups = cxl_memdev_attribute_groups, -}; - -static void cxl_memdev_unregister(void *_cxlmd) -{ - struct cxl_memdev *cxlmd = _cxlmd; - struct device *dev = &cxlmd->dev; - struct cdev *cdev = &cxlmd->cdev; - const struct cdevm_file_operations *cdevm_fops; - - cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops); - cdevm_fops->shutdown(dev); - - cdev_device_del(&cxlmd->cdev, dev); - put_device(dev); -} - -static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm, - const struct file_operations *fops) -{ - struct pci_dev *pdev = cxlm->pdev; - struct cxl_memdev *cxlmd; - struct device *dev; - struct cdev *cdev; - int rc; - - cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL); - if (!cxlmd) - return ERR_PTR(-ENOMEM); - - rc = ida_alloc_range(&cxl_memdev_ida, 0, CXL_MEM_MAX_DEVS, GFP_KERNEL); - if (rc < 0) - goto err; - cxlmd->id = rc; - - dev = &cxlmd->dev; - device_initialize(dev); - dev->parent = &pdev->dev; - dev->bus = &cxl_bus_type; - dev->devt = MKDEV(cxl_mem_major, cxlmd->id); - dev->type = &cxl_memdev_type; - device_set_pm_not_required(dev); - - cdev = &cxlmd->cdev; - cdev_init(cdev, fops); - return cxlmd; - -err: - kfree(cxlmd); - return ERR_PTR(rc); -} - -static struct cxl_memdev * -devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, - const struct cdevm_file_operations *cdevm_fops) -{ - struct cxl_memdev *cxlmd; - struct device *dev; - struct cdev *cdev; - int rc; - - cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops); - if (IS_ERR(cxlmd)) - return cxlmd; - - dev = &cxlmd->dev; - rc = dev_set_name(dev, "mem%d", cxlmd->id); - if (rc) - goto err; - - /* - * Activate ioctl operations, no cxl_memdev_rwsem manipulation - * needed as this is ordered with cdev_add() publishing the device. - */ - cxlmd->cxlm = cxlm; - - cdev = &cxlmd->cdev; - rc = cdev_device_add(cdev, dev); - if (rc) - goto err; - - rc = devm_add_action_or_reset(host, cxl_memdev_unregister, cxlmd); - if (rc) - return ERR_PTR(rc); - return cxlmd; - -err: - /* - * The cdev was briefly live, shutdown any ioctl operations that - * saw that state. - */ - cdevm_fops->shutdown(dev); - put_device(dev); - return ERR_PTR(rc); -} - static int cxl_xfer_log(struct cxl_mem *cxlm, uuid_t *uuid, u32 size, u8 *out) { u32 remaining = size; @@ -1651,25 +1436,15 @@ static struct pci_driver cxl_mem_driver = { static __init int cxl_mem_init(void) { struct dentry *mbox_debugfs; - dev_t devt; int rc; /* Double check the anonymous union trickery in struct cxl_regs */ BUILD_BUG_ON(offsetof(struct cxl_regs, memdev) != offsetof(struct cxl_regs, device_regs.memdev)); - rc = alloc_chrdev_region(&devt, 0, CXL_MEM_MAX_DEVS, "cxl"); - if (rc) - return rc; - - cxl_mem_major = MAJOR(devt); - rc = pci_register_driver(&cxl_mem_driver); - if (rc) { - unregister_chrdev_region(MKDEV(cxl_mem_major, 0), - CXL_MEM_MAX_DEVS); + if (rc) return rc; - } cxl_debugfs = debugfs_create_dir("cxl", NULL); mbox_debugfs = debugfs_create_dir("mbox", cxl_debugfs); @@ -1683,7 +1458,6 @@ static __exit void cxl_mem_exit(void) { debugfs_remove_recursive(cxl_debugfs); pci_unregister_driver(&cxl_mem_driver); - unregister_chrdev_region(MKDEV(cxl_mem_major, 0), CXL_MEM_MAX_DEVS); } MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 1e39db573e4cdf798b899de2b1e72ac9bea08013 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 16 Jul 2021 16:15:46 -0700 Subject: cxl/pci: Ignore unknown register block types In an effort to explicit avoid supporting vendor specific register blocks (which can happily be mapped from userspace), entirely skip probing unknown types. The secondary benefit of this will be revealed in the future with code simplification. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/20210716231548.174778-2-ben.widawsky@intel.com Signed-off-by: Dan Williams --- drivers/cxl/pci.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 193983e6edce..90a1c895e442 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1118,14 +1118,6 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) u64 offset; u8 bar; - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) { - ret = -ENOMEM; - goto free_maps; - } - - list_add(&map->list, ®ister_maps); - pci_read_config_dword(pdev, regloc, ®_lo); pci_read_config_dword(pdev, regloc + 4, ®_hi); @@ -1135,6 +1127,18 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) dev_dbg(dev, "Found register block in bar %u @ 0x%llx of type %u\n", bar, offset, reg_type); + /* Ignore unknown register block types */ + if (reg_type > CXL_REGLOC_RBI_MEMDEV) + continue; + + map = kzalloc(sizeof(*map), GFP_KERNEL); + if (!map) { + ret = -ENOMEM; + goto free_maps; + } + + list_add(&map->list, ®ister_maps); + base = cxl_mem_map_regblock(cxlm, bar, offset); if (!base) { ret = -ENOMEM; -- cgit v1.2.3-70-g09d2 From 5b68705d1e6340127464ef0ac0e1de94f823f14e Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 16 Jul 2021 16:15:47 -0700 Subject: cxl/pci: Simplify register setup It is desirable to retain the mappings from the calling function. By simplifying this code, it will be much more straightforward to do that. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/20210716231548.174778-3-ben.widawsky@intel.com Signed-off-by: Dan Williams --- drivers/cxl/cxl.h | 1 - drivers/cxl/pci.c | 38 ++++++++++++-------------------------- drivers/cxl/pci.h | 1 + 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index b6bda39a59e3..53927f9fa77e 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -140,7 +140,6 @@ struct cxl_device_reg_map { }; struct cxl_register_map { - struct list_head list; u64 block_offset; u8 reg_type; u8 barno; diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 90a1c895e442..47315bb2db10 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1091,9 +1091,8 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) struct device *dev = &pdev->dev; u32 regloc_size, regblocks; void __iomem *base; - int regloc, i; - struct cxl_register_map *map, *n; - LIST_HEAD(register_maps); + int regloc, i, n_maps; + struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES]; int ret = 0; regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID); @@ -1112,7 +1111,7 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET; regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8; - for (i = 0; i < regblocks; i++, regloc += 8) { + for (i = 0, n_maps = 0; i < regblocks; i++, regloc += 8) { u32 reg_lo, reg_hi; u8 reg_type; u64 offset; @@ -1131,20 +1130,11 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) if (reg_type > CXL_REGLOC_RBI_MEMDEV) continue; - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) { - ret = -ENOMEM; - goto free_maps; - } - - list_add(&map->list, ®ister_maps); - base = cxl_mem_map_regblock(cxlm, bar, offset); - if (!base) { - ret = -ENOMEM; - goto free_maps; - } + if (!base) + return -ENOMEM; + map = &maps[n_maps]; map->barno = bar; map->block_offset = offset; map->reg_type = reg_type; @@ -1155,21 +1145,17 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) cxl_mem_unmap_regblock(cxlm, base); if (ret) - goto free_maps; + return ret; + + n_maps++; } pci_release_mem_regions(pdev); - list_for_each_entry(map, ®ister_maps, list) { - ret = cxl_map_regs(cxlm, map); + for (i = 0; i < n_maps; i++) { + ret = cxl_map_regs(cxlm, &maps[i]); if (ret) - goto free_maps; - } - -free_maps: - list_for_each_entry_safe(map, n, ®ister_maps, list) { - list_del(&map->list); - kfree(map); + break; } return ret; diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h index dad7a831f65f..8c1a58813816 100644 --- a/drivers/cxl/pci.h +++ b/drivers/cxl/pci.h @@ -25,6 +25,7 @@ #define CXL_REGLOC_RBI_COMPONENT 1 #define CXL_REGLOC_RBI_VIRT 2 #define CXL_REGLOC_RBI_MEMDEV 3 +#define CXL_REGLOC_RBI_TYPES CXL_REGLOC_RBI_MEMDEV + 1 #define CXL_REGLOC_ADDR_MASK GENMASK(31, 16) -- cgit v1.2.3-70-g09d2 From 67db87dc8284070adb15b3c02c1c31d5cf51c5d6 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 30 Jul 2021 23:27:15 +0300 Subject: dmaengine: acpi: Avoid comparison GSI with Linux vIRQ Currently the CRST parsing relies on the fact that on most of x86 devices the IRQ mapping is 1:1 with Linux vIRQ. However, it may be not true for some. Fix this by converting GSI to Linux vIRQ before checking it. Fixes: ee8209fd026b ("dma: acpi-dma: parse CSRT to extract additional resources") Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210730202715.24375-1-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- drivers/dma/acpi-dma.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index 235f1396f968..52768dc8ce12 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -70,10 +70,14 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, si = (const struct acpi_csrt_shared_info *)&grp[1]; - /* Match device by MMIO and IRQ */ + /* Match device by MMIO */ if (si->mmio_base_low != lower_32_bits(mem) || - si->mmio_base_high != upper_32_bits(mem) || - si->gsi_interrupt != irq) + si->mmio_base_high != upper_32_bits(mem)) + return 0; + + /* Match device by Linux vIRQ */ + ret = acpi_register_gsi(NULL, si->gsi_interrupt, si->interrupt_mode, si->interrupt_polarity); + if (ret != irq) return 0; dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", -- cgit v1.2.3-70-g09d2 From 15cb0321a55e12af6b8456e9ec66a11cb367a673 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 2 Aug 2021 20:55:32 +0300 Subject: dmaengine: acpi: Check for errors from acpi_register_gsi() separately While IRQ test agaist the returned variable in practice is a good enough there is still a room for theoretical mistake in case the vIRQ of the device contains the same error code that acpi_register_gsi() may return. Due to this, check for error code separately from matching the vIRQs. Besides that, append documentation to tell why acpi_gsi_to_irq() can't be used and we call acpi_register_gsi() instead. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210802175532.54311-1-andriy.shevchenko@linux.intel.com Signed-off-by: Vinod Koul --- drivers/dma/acpi-dma.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index 52768dc8ce12..5906eae26e2a 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -75,8 +75,16 @@ static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp, si->mmio_base_high != upper_32_bits(mem)) return 0; - /* Match device by Linux vIRQ */ + /* + * acpi_gsi_to_irq() can't be used because some platforms do not save + * registered IRQs in the MP table. Instead we just try to register + * the GSI, which is the core part of the above mentioned function. + */ ret = acpi_register_gsi(NULL, si->gsi_interrupt, si->interrupt_mode, si->interrupt_polarity); + if (ret < 0) + return 0; + + /* Match device by Linux vIRQ */ if (ret != irq) return 0; -- cgit v1.2.3-70-g09d2 From 9fce3b3a0ab4cad407a27b5e36603c23f1b5b278 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 6 Aug 2021 08:36:43 -0700 Subject: dmaengine: idxd: remove interrupt flag for completion list spinlock The list lock is never acquired in interrupt context. Therefore there is no need to disable interrupts. Remove interrupt flags for lock operations. Reviewed-by: Dan Williams Signed-off-by: Dave Jiang Link: https://lore.kernel.org/r/162826417450.3454650.3733188117742416238.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/irq.c | 12 +++++------- drivers/dma/idxd/submit.c | 5 ++--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 11addb394793..d221c2e37460 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -176,7 +176,6 @@ static void irq_process_pending_llist(struct idxd_irq_entry *irq_entry) { struct idxd_desc *desc, *t; struct llist_node *head; - unsigned long flags; head = llist_del_all(&irq_entry->pending_llist); if (!head) @@ -197,17 +196,16 @@ static void irq_process_pending_llist(struct idxd_irq_entry *irq_entry) complete_desc(desc, IDXD_COMPLETE_NORMAL); } else { - spin_lock_irqsave(&irq_entry->list_lock, flags); + spin_lock(&irq_entry->list_lock); list_add_tail(&desc->list, &irq_entry->work_list); - spin_unlock_irqrestore(&irq_entry->list_lock, flags); + spin_unlock(&irq_entry->list_lock); } } } static void irq_process_work_list(struct idxd_irq_entry *irq_entry) { - unsigned long flags; LIST_HEAD(flist); struct idxd_desc *desc, *n; @@ -215,9 +213,9 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry) * This lock protects list corruption from access of list outside of the irq handler * thread. */ - spin_lock_irqsave(&irq_entry->list_lock, flags); + spin_lock(&irq_entry->list_lock); if (list_empty(&irq_entry->work_list)) { - spin_unlock_irqrestore(&irq_entry->list_lock, flags); + spin_unlock(&irq_entry->list_lock); return; } @@ -228,7 +226,7 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry) } } - spin_unlock_irqrestore(&irq_entry->list_lock, flags); + spin_unlock(&irq_entry->list_lock); list_for_each_entry(desc, &flist, list) { /* diff --git a/drivers/dma/idxd/submit.c b/drivers/dma/idxd/submit.c index 92ae9a157cc9..4b514c63af15 100644 --- a/drivers/dma/idxd/submit.c +++ b/drivers/dma/idxd/submit.c @@ -106,14 +106,13 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, { struct idxd_desc *d, *t, *found = NULL; struct llist_node *head; - unsigned long flags; desc->completion->status = IDXD_COMP_DESC_ABORT; /* * Grab the list lock so it will block the irq thread handler. This allows the * abort code to locate the descriptor need to be aborted. */ - spin_lock_irqsave(&ie->list_lock, flags); + spin_lock(&ie->list_lock); head = llist_del_all(&ie->pending_llist); if (head) { llist_for_each_entry_safe(d, t, head, llnode) { @@ -127,7 +126,7 @@ static void llist_abort_desc(struct idxd_wq *wq, struct idxd_irq_entry *ie, if (!found) found = list_abort_desc(wq, ie, desc); - spin_unlock_irqrestore(&ie->list_lock, flags); + spin_unlock(&ie->list_lock); if (found) complete_desc(found, IDXD_COMPLETE_ABORT); -- cgit v1.2.3-70-g09d2 From 40b52225e58cd3adf9358146b4b39dccfbfe5892 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 6 Aug 2021 11:05:36 -0700 Subject: xfs: remove support for disabling quota accounting on a mounted file system Disabling quota accounting is hairy, racy code with all kinds of pitfalls. And it has a very strange mind set, as quota accounting (unlike enforcement) really is a propery of the on-disk format. There is no good use case for supporting this. Signed-off-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_trans_resv.c | 30 ----- fs/xfs/libxfs/xfs_trans_resv.h | 2 - fs/xfs/xfs_dquot_item.c | 134 ----------------------- fs/xfs/xfs_dquot_item.h | 17 --- fs/xfs/xfs_qm.c | 2 +- fs/xfs/xfs_qm.h | 3 - fs/xfs/xfs_qm_syscalls.c | 241 ++--------------------------------------- fs/xfs/xfs_trans_dquot.c | 38 ------- 8 files changed, 13 insertions(+), 454 deletions(-) diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index d1a0848cb52e..ce12c8142bd1 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -798,29 +798,6 @@ xfs_calc_qm_dqalloc_reservation( XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); } -/* - * Turning off quotas. - * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 - * the superblock for the quota flags: sector size - */ -STATIC uint -xfs_calc_qm_quotaoff_reservation( - struct xfs_mount *mp) -{ - return sizeof(struct xfs_qoff_logitem) * 2 + - xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); -} - -/* - * End of turning off quotas. - * the quota off logitems: sizeof(struct xfs_qoff_logitem) * 2 - */ -STATIC uint -xfs_calc_qm_quotaoff_end_reservation(void) -{ - return sizeof(struct xfs_qoff_logitem) * 2; -} - /* * Syncing the incore super block changes to disk. * the super block to reflect the changes: sector size @@ -923,13 +900,6 @@ xfs_trans_resv_calc( resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(); resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; - resp->tr_qm_quotaoff.tr_logres = xfs_calc_qm_quotaoff_reservation(mp); - resp->tr_qm_quotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; - - resp->tr_qm_equotaoff.tr_logres = - xfs_calc_qm_quotaoff_end_reservation(); - resp->tr_qm_equotaoff.tr_logcount = XFS_DEFAULT_LOG_COUNT; - resp->tr_sb.tr_logres = xfs_calc_sb_reservation(mp); resp->tr_sb.tr_logcount = XFS_DEFAULT_LOG_COUNT; diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h index 7241ab28cf84..fc4e9b369a3a 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.h +++ b/fs/xfs/libxfs/xfs_trans_resv.h @@ -46,8 +46,6 @@ struct xfs_trans_resv { struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ - struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ - struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */ struct xfs_trans_res tr_sb; /* modify superblock */ struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */ }; diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 8ed47b739b6c..6a1aae799cf1 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -218,137 +218,3 @@ xfs_qm_dquot_logitem_init( &xfs_dquot_item_ops); lp->qli_dquot = dqp; } - -/*------------------ QUOTAOFF LOG ITEMS -------------------*/ - -static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip) -{ - return container_of(lip, struct xfs_qoff_logitem, qql_item); -} - - -/* - * This returns the number of iovecs needed to log the given quotaoff item. - * We only need 1 iovec for an quotaoff item. It just logs the - * quotaoff_log_format structure. - */ -STATIC void -xfs_qm_qoff_logitem_size( - struct xfs_log_item *lip, - int *nvecs, - int *nbytes) -{ - *nvecs += 1; - *nbytes += sizeof(struct xfs_qoff_logitem); -} - -STATIC void -xfs_qm_qoff_logitem_format( - struct xfs_log_item *lip, - struct xfs_log_vec *lv) -{ - struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); - struct xfs_log_iovec *vecp = NULL; - struct xfs_qoff_logformat *qlf; - - qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QUOTAOFF); - qlf->qf_type = XFS_LI_QUOTAOFF; - qlf->qf_size = 1; - qlf->qf_flags = qflip->qql_flags; - xlog_finish_iovec(lv, vecp, sizeof(struct xfs_qoff_logitem)); -} - -/* - * There isn't much you can do to push a quotaoff item. It is simply - * stuck waiting for the log to be flushed to disk. - */ -STATIC uint -xfs_qm_qoff_logitem_push( - struct xfs_log_item *lip, - struct list_head *buffer_list) -{ - return XFS_ITEM_LOCKED; -} - -STATIC xfs_lsn_t -xfs_qm_qoffend_logitem_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip); - struct xfs_qoff_logitem *qfs = qfe->qql_start_lip; - - xfs_qm_qoff_logitem_relse(qfs); - - kmem_free(lip->li_lv_shadow); - kmem_free(qfe); - return (xfs_lsn_t)-1; -} - -STATIC void -xfs_qm_qoff_logitem_release( - struct xfs_log_item *lip) -{ - struct xfs_qoff_logitem *qoff = QOFF_ITEM(lip); - - if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) { - if (qoff->qql_start_lip) - xfs_qm_qoff_logitem_relse(qoff->qql_start_lip); - xfs_qm_qoff_logitem_relse(qoff); - } -} - -static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { - .iop_size = xfs_qm_qoff_logitem_size, - .iop_format = xfs_qm_qoff_logitem_format, - .iop_committed = xfs_qm_qoffend_logitem_committed, - .iop_push = xfs_qm_qoff_logitem_push, - .iop_release = xfs_qm_qoff_logitem_release, -}; - -static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { - .iop_size = xfs_qm_qoff_logitem_size, - .iop_format = xfs_qm_qoff_logitem_format, - .iop_push = xfs_qm_qoff_logitem_push, - .iop_release = xfs_qm_qoff_logitem_release, -}; - -/* - * Delete the quotaoff intent from the AIL and free it. On success, - * this should only be called for the start item. It can be used for - * either on shutdown or abort. - */ -void -xfs_qm_qoff_logitem_relse( - struct xfs_qoff_logitem *qoff) -{ - struct xfs_log_item *lip = &qoff->qql_item; - - ASSERT(test_bit(XFS_LI_IN_AIL, &lip->li_flags) || - test_bit(XFS_LI_ABORTED, &lip->li_flags) || - XFS_FORCED_SHUTDOWN(lip->li_mountp)); - xfs_trans_ail_delete(lip, 0); - kmem_free(lip->li_lv_shadow); - kmem_free(qoff); -} - -/* - * Allocate and initialize an quotaoff item of the correct quota type(s). - */ -struct xfs_qoff_logitem * -xfs_qm_qoff_logitem_init( - struct xfs_mount *mp, - struct xfs_qoff_logitem *start, - uint flags) -{ - struct xfs_qoff_logitem *qf; - - qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), 0); - - xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ? - &xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops); - qf->qql_item.li_mountp = mp; - qf->qql_start_lip = start; - qf->qql_flags = flags; - return qf; -} diff --git a/fs/xfs/xfs_dquot_item.h b/fs/xfs/xfs_dquot_item.h index 2b86a43d7ce2..794710c24474 100644 --- a/fs/xfs/xfs_dquot_item.h +++ b/fs/xfs/xfs_dquot_item.h @@ -9,7 +9,6 @@ struct xfs_dquot; struct xfs_trans; struct xfs_mount; -struct xfs_qoff_logitem; struct xfs_dq_logitem { struct xfs_log_item qli_item; /* common portion */ @@ -17,22 +16,6 @@ struct xfs_dq_logitem { xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ }; -struct xfs_qoff_logitem { - struct xfs_log_item qql_item; /* common portion */ - struct xfs_qoff_logitem *qql_start_lip; /* qoff-start logitem, if any */ - unsigned int qql_flags; -}; - - void xfs_qm_dquot_logitem_init(struct xfs_dquot *dqp); -struct xfs_qoff_logitem *xfs_qm_qoff_logitem_init(struct xfs_mount *mp, - struct xfs_qoff_logitem *start, - uint flags); -void xfs_qm_qoff_logitem_relse(struct xfs_qoff_logitem *); -struct xfs_qoff_logitem *xfs_trans_get_qoff_item(struct xfs_trans *tp, - struct xfs_qoff_logitem *startqoff, - uint flags); -void xfs_trans_log_quotaoff_item(struct xfs_trans *tp, - struct xfs_qoff_logitem *qlp); #endif /* __XFS_DQUOT_ITEM_H__ */ diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index fe341f3fd419..580b9dba2112 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -185,7 +185,7 @@ out_unlock: /* * Purge the dquot cache. */ -void +static void xfs_qm_dqpurge_all( struct xfs_mount *mp, uint flags) diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index ebbb484c49dc..442a0f97a9d4 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -140,9 +140,6 @@ struct xfs_dquot_acct { extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); -/* dquot stuff */ -extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); - /* quota ops */ extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); extern int xfs_qm_scall_getquota(struct xfs_mount *mp, diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 13a56e1ea15c..d16deb75dc83 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -19,91 +19,11 @@ #include "xfs_qm.h" #include "xfs_icache.h" -STATIC int -xfs_qm_log_quotaoff( - struct xfs_mount *mp, - struct xfs_qoff_logitem **qoffstartp, - uint flags) -{ - struct xfs_trans *tp; - int error; - struct xfs_qoff_logitem *qoffi; - - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp); - if (error) - goto out; - - qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); - xfs_trans_log_quotaoff_item(tp, qoffi); - - spin_lock(&mp->m_sb_lock); - mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; - spin_unlock(&mp->m_sb_lock); - - xfs_log_sb(tp); - - /* - * We have to make sure that the transaction is secure on disk before we - * return and actually stop quota accounting. So, make it synchronous. - * We don't care about quotoff's performance. - */ - xfs_trans_set_sync(tp); - error = xfs_trans_commit(tp); - if (error) - goto out; - - *qoffstartp = qoffi; -out: - return error; -} - -STATIC int -xfs_qm_log_quotaoff_end( - struct xfs_mount *mp, - struct xfs_qoff_logitem **startqoff, - uint flags) -{ - struct xfs_trans *tp; - int error; - struct xfs_qoff_logitem *qoffi; - - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp); - if (error) - return error; - - qoffi = xfs_trans_get_qoff_item(tp, *startqoff, - flags & XFS_ALL_QUOTA_ACCT); - xfs_trans_log_quotaoff_item(tp, qoffi); - *startqoff = NULL; - - /* - * We have to make sure that the transaction is secure on disk before we - * return and actually stop quota accounting. So, make it synchronous. - * We don't care about quotoff's performance. - */ - xfs_trans_set_sync(tp); - return xfs_trans_commit(tp); -} - -/* - * Turn off quota accounting and/or enforcement for all udquots and/or - * gdquots. Called only at unmount time. - * - * This assumes that there are no dquots of this file system cached - * incore, and modifies the ondisk dquot directly. Therefore, for example, - * it is an error to call this twice, without purging the cache. - */ int xfs_qm_scall_quotaoff( xfs_mount_t *mp, uint flags) { - struct xfs_quotainfo *q = mp->m_quotainfo; - uint dqtype; - int error; - uint inactivate_flags; - struct xfs_qoff_logitem *qoffstart = NULL; - /* * No file system can have quotas enabled on disk but not in core. * Note that quota utilities (like quotaoff) _expect_ @@ -111,160 +31,23 @@ xfs_qm_scall_quotaoff( */ if ((mp->m_qflags & flags) == 0) return -EEXIST; - error = 0; - - flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); /* - * We don't want to deal with two quotaoffs messing up each other, - * so we're going to serialize it. quotaoff isn't exactly a performance - * critical thing. - * If quotaoff, then we must be dealing with the root filesystem. + * We do not support actually turning off quota accounting any more. + * Just log a warning and ignore the accounting related flags. */ - ASSERT(q); - mutex_lock(&q->qi_quotaofflock); + if (flags & XFS_ALL_QUOTA_ACCT) + xfs_info(mp, "disabling of quota accounting not supported."); - /* - * If we're just turning off quota enforcement, change mp and go. - */ - if ((flags & XFS_ALL_QUOTA_ACCT) == 0) { - mp->m_qflags &= ~(flags); - - spin_lock(&mp->m_sb_lock); - mp->m_sb.sb_qflags = mp->m_qflags; - spin_unlock(&mp->m_sb_lock); - mutex_unlock(&q->qi_quotaofflock); - - /* XXX what to do if error ? Revert back to old vals incore ? */ - return xfs_sync_sb(mp, false); - } - - dqtype = 0; - inactivate_flags = 0; - /* - * If accounting is off, we must turn enforcement off, clear the - * quota 'CHKD' certificate to make it known that we have to - * do a quotacheck the next time this quota is turned on. - */ - if (flags & XFS_UQUOTA_ACCT) { - dqtype |= XFS_QMOPT_UQUOTA; - flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD); - inactivate_flags |= XFS_UQUOTA_ACTIVE; - } - if (flags & XFS_GQUOTA_ACCT) { - dqtype |= XFS_QMOPT_GQUOTA; - flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); - inactivate_flags |= XFS_GQUOTA_ACTIVE; - } - if (flags & XFS_PQUOTA_ACCT) { - dqtype |= XFS_QMOPT_PQUOTA; - flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD); - inactivate_flags |= XFS_PQUOTA_ACTIVE; - } - - /* - * Nothing to do? Don't complain. This happens when we're just - * turning off quota enforcement. - */ - if ((mp->m_qflags & flags) == 0) - goto out_unlock; - - /* - * Write the LI_QUOTAOFF log record, and do SB changes atomically, - * and synchronously. If we fail to write, we should abort the - * operation as it cannot be recovered safely if we crash. - */ - error = xfs_qm_log_quotaoff(mp, &qoffstart, flags); - if (error) - goto out_unlock; - - /* - * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct - * to take care of the race between dqget and quotaoff. We don't take - * any special locks to reset these bits. All processes need to check - * these bits *after* taking inode lock(s) to see if the particular - * quota type is in the process of being turned off. If *ACTIVE, it is - * guaranteed that all dquot structures and all quotainode ptrs will all - * stay valid as long as that inode is kept locked. - * - * There is no turning back after this. - */ - mp->m_qflags &= ~inactivate_flags; - - /* - * Give back all the dquot reference(s) held by inodes. - * Here we go thru every single incore inode in this file system, and - * do a dqrele on the i_udquot/i_gdquot that it may have. - * Essentially, as long as somebody has an inode locked, this guarantees - * that quotas will not be turned off. This is handy because in a - * transaction once we lock the inode(s) and check for quotaon, we can - * depend on the quota inodes (and other things) being valid as long as - * we keep the lock(s). - */ - error = xfs_dqrele_all_inodes(mp, flags); - ASSERT(!error); - - /* - * Next we make the changes in the quota flag in the mount struct. - * This isn't protected by a particular lock directly, because we - * don't want to take a mrlock every time we depend on quotas being on. - */ - mp->m_qflags &= ~flags; - - /* - * Go through all the dquots of this file system and purge them, - * according to what was turned off. - */ - xfs_qm_dqpurge_all(mp, dqtype); - - /* - * Transactions that had started before ACTIVE state bit was cleared - * could have logged many dquots, so they'd have higher LSNs than - * the first QUOTAOFF log record does. If we happen to crash when - * the tail of the log has gone past the QUOTAOFF record, but - * before the last dquot modification, those dquots __will__ - * recover, and that's not good. - * - * So, we have QUOTAOFF start and end logitems; the start - * logitem won't get overwritten until the end logitem appears... - */ - error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags); - if (error) { - /* We're screwed now. Shutdown is the only option. */ - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); - goto out_unlock; - } - - /* - * If all quotas are completely turned off, close shop. - */ - if (mp->m_qflags == 0) { - mutex_unlock(&q->qi_quotaofflock); - xfs_qm_destroy_quotainfo(mp); - return 0; - } - - /* - * Release our quotainode references if we don't need them anymore. - */ - if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) { - xfs_irele(q->qi_uquotaip); - q->qi_uquotaip = NULL; - } - if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) { - xfs_irele(q->qi_gquotaip); - q->qi_gquotaip = NULL; - } - if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) { - xfs_irele(q->qi_pquotaip); - q->qi_pquotaip = NULL; - } + mutex_lock(&mp->m_quotainfo->qi_quotaofflock); + mp->m_qflags &= ~(flags & XFS_ALL_QUOTA_ENFD); + spin_lock(&mp->m_sb_lock); + mp->m_sb.sb_qflags = mp->m_qflags; + spin_unlock(&mp->m_sb_lock); + mutex_unlock(&mp->m_quotainfo->qi_quotaofflock); -out_unlock: - if (error && qoffstart) - xfs_qm_qoff_logitem_relse(qoffstart); - mutex_unlock(&q->qi_quotaofflock); - return error; + /* XXX what to do if error ? Revert back to old vals incore ? */ + return xfs_sync_sb(mp, false); } STATIC int diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index 48e09ea30ee5..b7e4b05a559b 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -843,44 +843,6 @@ xfs_trans_reserve_quota_icreate( dblocks, 1, XFS_QMOPT_RES_REGBLKS); } -/* - * This routine is called to allocate a quotaoff log item. - */ -struct xfs_qoff_logitem * -xfs_trans_get_qoff_item( - struct xfs_trans *tp, - struct xfs_qoff_logitem *startqoff, - uint flags) -{ - struct xfs_qoff_logitem *q; - - ASSERT(tp != NULL); - - q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags); - ASSERT(q != NULL); - - /* - * Get a log_item_desc to point at the new item. - */ - xfs_trans_add_item(tp, &q->qql_item); - return q; -} - - -/* - * This is called to mark the quotaoff logitem as needing - * to be logged when the transaction is committed. The logitem must - * already be associated with the given transaction. - */ -void -xfs_trans_log_quotaoff_item( - struct xfs_trans *tp, - struct xfs_qoff_logitem *qlp) -{ - tp->t_flags |= XFS_TRANS_DIRTY; - set_bit(XFS_LI_DIRTY, &qlp->qql_item.li_flags); -} - STATIC void xfs_trans_alloc_dqinfo( xfs_trans_t *tp) -- cgit v1.2.3-70-g09d2 From 777eb1fa857ec38afd518b3adc25cfac0f4af13b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 6 Aug 2021 11:05:36 -0700 Subject: xfs: remove xfs_dqrele_all_inodes xfs_dqrele_all_inodes is unused now, remove it and all supporting code. Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 107 +--------------------------------------------------- fs/xfs/xfs_icache.h | 6 --- 2 files changed, 1 insertion(+), 112 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 6007683482c6..086a88b8dfdb 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -38,9 +38,6 @@ * radix tree tags when convenient. Avoid existing XFS_IWALK namespace. */ enum xfs_icwalk_goal { - /* Goals that are not related to tags; these must be < 0. */ - XFS_ICWALK_DQRELE = -1, - /* Goals directly associated with tagged inodes. */ XFS_ICWALK_BLOCKGC = XFS_ICI_BLOCKGC_TAG, XFS_ICWALK_RECLAIM = XFS_ICI_RECLAIM_TAG, @@ -64,9 +61,6 @@ static int xfs_icwalk_ag(struct xfs_perag *pag, * Private inode cache walk flags for struct xfs_icwalk. Must not * coincide with XFS_ICWALK_FLAGS_VALID. */ -#define XFS_ICWALK_FLAG_DROP_UDQUOT (1U << 31) -#define XFS_ICWALK_FLAG_DROP_GDQUOT (1U << 30) -#define XFS_ICWALK_FLAG_DROP_PDQUOT (1U << 29) /* Stop scanning after icw_scan_limit inodes. */ #define XFS_ICWALK_FLAG_SCAN_LIMIT (1U << 28) @@ -74,10 +68,7 @@ static int xfs_icwalk_ag(struct xfs_perag *pag, #define XFS_ICWALK_FLAG_RECLAIM_SICK (1U << 27) #define XFS_ICWALK_FLAG_UNION (1U << 26) /* union filter algorithm */ -#define XFS_ICWALK_PRIVATE_FLAGS (XFS_ICWALK_FLAG_DROP_UDQUOT | \ - XFS_ICWALK_FLAG_DROP_GDQUOT | \ - XFS_ICWALK_FLAG_DROP_PDQUOT | \ - XFS_ICWALK_FLAG_SCAN_LIMIT | \ +#define XFS_ICWALK_PRIVATE_FLAGS (XFS_ICWALK_FLAG_SCAN_LIMIT | \ XFS_ICWALK_FLAG_RECLAIM_SICK | \ XFS_ICWALK_FLAG_UNION) @@ -817,97 +808,6 @@ xfs_icache_inode_is_allocated( return 0; } -#ifdef CONFIG_XFS_QUOTA -/* Decide if we want to grab this inode to drop its dquots. */ -static bool -xfs_dqrele_igrab( - struct xfs_inode *ip) -{ - bool ret = false; - - ASSERT(rcu_read_lock_held()); - - /* Check for stale RCU freed inode */ - spin_lock(&ip->i_flags_lock); - if (!ip->i_ino) - goto out_unlock; - - /* - * Skip inodes that are anywhere in the reclaim machinery because we - * drop dquots before tagging an inode for reclamation. - */ - if (ip->i_flags & (XFS_IRECLAIM | XFS_IRECLAIMABLE)) - goto out_unlock; - - /* - * The inode looks alive; try to grab a VFS reference so that it won't - * get destroyed. If we got the reference, return true to say that - * we grabbed the inode. - * - * If we can't get the reference, then we know the inode had its VFS - * state torn down and hasn't yet entered the reclaim machinery. Since - * we also know that dquots are detached from an inode before it enters - * reclaim, we can skip the inode. - */ - ret = igrab(VFS_I(ip)) != NULL; - -out_unlock: - spin_unlock(&ip->i_flags_lock); - return ret; -} - -/* Drop this inode's dquots. */ -static void -xfs_dqrele_inode( - struct xfs_inode *ip, - struct xfs_icwalk *icw) -{ - if (xfs_iflags_test(ip, XFS_INEW)) - xfs_inew_wait(ip); - - xfs_ilock(ip, XFS_ILOCK_EXCL); - if (icw->icw_flags & XFS_ICWALK_FLAG_DROP_UDQUOT) { - xfs_qm_dqrele(ip->i_udquot); - ip->i_udquot = NULL; - } - if (icw->icw_flags & XFS_ICWALK_FLAG_DROP_GDQUOT) { - xfs_qm_dqrele(ip->i_gdquot); - ip->i_gdquot = NULL; - } - if (icw->icw_flags & XFS_ICWALK_FLAG_DROP_PDQUOT) { - xfs_qm_dqrele(ip->i_pdquot); - ip->i_pdquot = NULL; - } - xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_irele(ip); -} - -/* - * Detach all dquots from incore inodes if we can. The caller must already - * have dropped the relevant XFS_[UGP]QUOTA_ACTIVE flags so that dquots will - * not get reattached. - */ -int -xfs_dqrele_all_inodes( - struct xfs_mount *mp, - unsigned int qflags) -{ - struct xfs_icwalk icw = { .icw_flags = 0 }; - - if (qflags & XFS_UQUOTA_ACCT) - icw.icw_flags |= XFS_ICWALK_FLAG_DROP_UDQUOT; - if (qflags & XFS_GQUOTA_ACCT) - icw.icw_flags |= XFS_ICWALK_FLAG_DROP_GDQUOT; - if (qflags & XFS_PQUOTA_ACCT) - icw.icw_flags |= XFS_ICWALK_FLAG_DROP_PDQUOT; - - return xfs_icwalk(mp, XFS_ICWALK_DQRELE, &icw); -} -#else -# define xfs_dqrele_igrab(ip) (false) -# define xfs_dqrele_inode(ip, priv) ((void)0) -#endif /* CONFIG_XFS_QUOTA */ - /* * Grab the inode for reclaim exclusively. * @@ -1647,8 +1547,6 @@ xfs_icwalk_igrab( struct xfs_icwalk *icw) { switch (goal) { - case XFS_ICWALK_DQRELE: - return xfs_dqrele_igrab(ip); case XFS_ICWALK_BLOCKGC: return xfs_blockgc_igrab(ip); case XFS_ICWALK_RECLAIM: @@ -1672,9 +1570,6 @@ xfs_icwalk_process_inode( int error = 0; switch (goal) { - case XFS_ICWALK_DQRELE: - xfs_dqrele_inode(ip, icw); - break; case XFS_ICWALK_BLOCKGC: error = xfs_blockgc_scan_inode(ip, icw); break; diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index c751cc32dc46..d0062ebb3f7a 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -68,12 +68,6 @@ void xfs_inode_clear_cowblocks_tag(struct xfs_inode *ip); void xfs_blockgc_worker(struct work_struct *work); -#ifdef CONFIG_XFS_QUOTA -int xfs_dqrele_all_inodes(struct xfs_mount *mp, unsigned int qflags); -#else -# define xfs_dqrele_all_inodes(mp, qflags) (0) -#endif - int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino, bool *inuse); -- cgit v1.2.3-70-g09d2 From e497dfba6bd7b11856fef4e9e8050de895b7faea Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 6 Aug 2021 11:05:36 -0700 Subject: xfs: remove the flags argument to xfs_qm_dquot_walk We always purge all dquots now, so drop the argument. Signed-off-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_qm.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 580b9dba2112..2b34273d0405 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -187,15 +187,11 @@ out_unlock: */ static void xfs_qm_dqpurge_all( - struct xfs_mount *mp, - uint flags) + struct xfs_mount *mp) { - if (flags & XFS_QMOPT_UQUOTA) - xfs_qm_dquot_walk(mp, XFS_DQTYPE_USER, xfs_qm_dqpurge, NULL); - if (flags & XFS_QMOPT_GQUOTA) - xfs_qm_dquot_walk(mp, XFS_DQTYPE_GROUP, xfs_qm_dqpurge, NULL); - if (flags & XFS_QMOPT_PQUOTA) - xfs_qm_dquot_walk(mp, XFS_DQTYPE_PROJ, xfs_qm_dqpurge, NULL); + xfs_qm_dquot_walk(mp, XFS_DQTYPE_USER, xfs_qm_dqpurge, NULL); + xfs_qm_dquot_walk(mp, XFS_DQTYPE_GROUP, xfs_qm_dqpurge, NULL); + xfs_qm_dquot_walk(mp, XFS_DQTYPE_PROJ, xfs_qm_dqpurge, NULL); } /* @@ -206,7 +202,7 @@ xfs_qm_unmount( struct xfs_mount *mp) { if (mp->m_quotainfo) { - xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL); + xfs_qm_dqpurge_all(mp); xfs_qm_destroy_quotainfo(mp); } } @@ -1359,7 +1355,7 @@ xfs_qm_quotacheck( * at this point (because we intentionally didn't in dqget_noattach). */ if (error) { - xfs_qm_dqpurge_all(mp, XFS_QMOPT_QUOTALL); + xfs_qm_dqpurge_all(mp); goto error_return; } -- cgit v1.2.3-70-g09d2 From 149e53afc851713a70b6a06ebfaf2ebf25975454 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 6 Aug 2021 11:05:37 -0700 Subject: xfs: remove the active vs running quota differentiation These only made a difference when quotaoff supported disabling quota accounting on a mounted file system, so we can switch everyone to use a single set of flags and helpers now. Note that the *QUOTA_ON naming for the helpers is kept as it was the much more commonly used one. Signed-off-by: Christoph Hellwig Reviewed-by: Carlos Maiolino Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_quota_defs.h | 30 ++++--------------------- fs/xfs/scrub/quota.c | 2 +- fs/xfs/xfs_dquot.c | 3 --- fs/xfs/xfs_ioctl.c | 2 +- fs/xfs/xfs_iops.c | 4 ++-- fs/xfs/xfs_mount.c | 4 +--- fs/xfs/xfs_qm.c | 26 ++++++++++----------- fs/xfs/xfs_qm_syscalls.c | 2 +- fs/xfs/xfs_quotaops.c | 30 +++++++++---------------- fs/xfs/xfs_super.c | 51 +++++++++++++++++------------------------- fs/xfs/xfs_trans_dquot.c | 11 +++++---- 11 files changed, 58 insertions(+), 107 deletions(-) diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index 0f0af4e35032..a02c5062f9b2 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -60,36 +60,14 @@ typedef uint8_t xfs_dqtype_t; #define XFS_DQUOT_LOGRES(mp) \ ((sizeof(struct xfs_dq_logformat) + sizeof(struct xfs_disk_dquot)) * 6) -#define XFS_IS_QUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) -#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) -#define XFS_IS_PQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) -#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) +#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT) +#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT) +#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACCT) +#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT) #define XFS_IS_UQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_UQUOTA_ENFD) #define XFS_IS_GQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_GQUOTA_ENFD) #define XFS_IS_PQUOTA_ENFORCED(mp) ((mp)->m_qflags & XFS_PQUOTA_ENFD) -/* - * Incore only flags for quotaoff - these bits get cleared when quota(s) - * are in the process of getting turned off. These flags are in m_qflags but - * never in sb_qflags. - */ -#define XFS_UQUOTA_ACTIVE 0x1000 /* uquotas are being turned off */ -#define XFS_GQUOTA_ACTIVE 0x2000 /* gquotas are being turned off */ -#define XFS_PQUOTA_ACTIVE 0x4000 /* pquotas are being turned off */ -#define XFS_ALL_QUOTA_ACTIVE \ - (XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) - -/* - * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees - * quota will be not be switched off as long as that inode lock is held. - */ -#define XFS_IS_QUOTA_ON(mp) ((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE | \ - XFS_PQUOTA_ACTIVE)) -#define XFS_IS_UQUOTA_ON(mp) ((mp)->m_qflags & XFS_UQUOTA_ACTIVE) -#define XFS_IS_GQUOTA_ON(mp) ((mp)->m_qflags & XFS_GQUOTA_ACTIVE) -#define XFS_IS_PQUOTA_ON(mp) ((mp)->m_qflags & XFS_PQUOTA_ACTIVE) - /* * Flags to tell various functions what to do. Not all of these are meaningful * to a single function. None of these XFS_QMOPT_* flags are meant to have diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c index acbb9839d42f..3cccd6d5b577 100644 --- a/fs/xfs/scrub/quota.c +++ b/fs/xfs/scrub/quota.c @@ -42,7 +42,7 @@ xchk_setup_quota( xfs_dqtype_t dqtype; int error; - if (!XFS_IS_QUOTA_RUNNING(sc->mp) || !XFS_IS_QUOTA_ON(sc->mp)) + if (!XFS_IS_QUOTA_ON(sc->mp)) return -ENOENT; dqtype = xchk_quota_to_dqtype(sc); diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index ecd5059d6928..c301b18b7685 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -847,9 +847,6 @@ xfs_qm_dqget_checks( struct xfs_mount *mp, xfs_dqtype_t type) { - if (WARN_ON_ONCE(!XFS_IS_QUOTA_RUNNING(mp))) - return -ESRCH; - switch (type) { case XFS_DQTYPE_USER: if (!XFS_IS_UQUOTA_ON(mp)) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 16039ea10ac9..e2d995502cd8 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1450,7 +1450,7 @@ xfs_fileattr_set( /* Change the ownerships and register project quota modifications */ if (ip->i_projid != fa->fsx_projid) { - if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) { + if (XFS_IS_PQUOTA_ON(mp)) { olddquot = xfs_qm_vop_chown(tp, ip, &ip->i_pdquot, pdqp); } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 93c082db04b7..327d65ef1e26 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -778,7 +778,7 @@ xfs_setattr_nonsize( * in the transaction. */ if (!uid_eq(iuid, uid)) { - if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) { + if (XFS_IS_UQUOTA_ON(mp)) { ASSERT(mask & ATTR_UID); ASSERT(udqp); olddquot1 = xfs_qm_vop_chown(tp, ip, @@ -787,7 +787,7 @@ xfs_setattr_nonsize( inode->i_uid = uid; } if (!gid_eq(igid, gid)) { - if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { + if (XFS_IS_GQUOTA_ON(mp)) { ASSERT(xfs_sb_version_has_pquotino(&mp->m_sb) || !XFS_IS_PQUOTA_ON(mp)); ASSERT(mask & ATTR_GID); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d0755494597f..baf7b323cb15 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -836,13 +836,11 @@ xfs_mountfs( /* * Initialise the XFS quota management subsystem for this mount */ - if (XFS_IS_QUOTA_RUNNING(mp)) { + if (XFS_IS_QUOTA_ON(mp)) { error = xfs_qm_newmount(mp, "amount, "aflags); if (error) goto out_rtunmount; } else { - ASSERT(!XFS_IS_QUOTA_ON(mp)); - /* * If a file system had quotas running earlier, but decided to * mount without -o uquota/pquota/gquota options, revoke the diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 2b34273d0405..351d99bc52e5 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -295,8 +295,6 @@ xfs_qm_need_dqattach( { struct xfs_mount *mp = ip->i_mount; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return false; if (!XFS_IS_QUOTA_ON(mp)) return false; if (!XFS_NOT_DQATTACHED(mp, ip)) @@ -631,7 +629,7 @@ xfs_qm_init_quotainfo( struct xfs_quotainfo *qinf; int error; - ASSERT(XFS_IS_QUOTA_RUNNING(mp)); + ASSERT(XFS_IS_QUOTA_ON(mp)); qinf = mp->m_quotainfo = kmem_zalloc(sizeof(struct xfs_quotainfo), 0); @@ -676,11 +674,11 @@ xfs_qm_init_quotainfo( xfs_qm_init_timelimits(mp, XFS_DQTYPE_GROUP); xfs_qm_init_timelimits(mp, XFS_DQTYPE_PROJ); - if (XFS_IS_UQUOTA_RUNNING(mp)) + if (XFS_IS_UQUOTA_ON(mp)) xfs_qm_set_defquota(mp, XFS_DQTYPE_USER, qinf); - if (XFS_IS_GQUOTA_RUNNING(mp)) + if (XFS_IS_GQUOTA_ON(mp)) xfs_qm_set_defquota(mp, XFS_DQTYPE_GROUP, qinf); - if (XFS_IS_PQUOTA_RUNNING(mp)) + if (XFS_IS_PQUOTA_ON(mp)) xfs_qm_set_defquota(mp, XFS_DQTYPE_PROJ, qinf); qinf->qi_shrinker.count_objects = xfs_qm_shrink_count; @@ -1143,7 +1141,7 @@ xfs_qm_dqusage_adjust( xfs_filblks_t rtblks = 0; /* total rt blks */ int error; - ASSERT(XFS_IS_QUOTA_RUNNING(mp)); + ASSERT(XFS_IS_QUOTA_ON(mp)); /* * rootino must have its resources accounted for, not so with the quota @@ -1284,7 +1282,7 @@ xfs_qm_quotacheck( flags = 0; ASSERT(uip || gip || pip); - ASSERT(XFS_IS_QUOTA_RUNNING(mp)); + ASSERT(XFS_IS_QUOTA_ON(mp)); xfs_notice(mp, "Quotacheck needed: Please wait."); @@ -1414,7 +1412,7 @@ xfs_qm_mount_quotas( goto write_changes; } - ASSERT(XFS_IS_QUOTA_RUNNING(mp)); + ASSERT(XFS_IS_QUOTA_ON(mp)); /* * Allocate the quotainfo structure inside the mount struct, and @@ -1469,7 +1467,7 @@ xfs_qm_mount_quotas( * the incore structures are convinced that quotas are * off, but the on disk superblock doesn't know that ! */ - ASSERT(!(XFS_IS_QUOTA_RUNNING(mp))); + ASSERT(!(XFS_IS_QUOTA_ON(mp))); xfs_alert(mp, "%s: Superblock update failed!", __func__); } @@ -1641,7 +1639,7 @@ xfs_qm_vop_dqalloc( int error; uint lockflags; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; lockflags = XFS_ILOCK_EXCL; @@ -1772,7 +1770,7 @@ xfs_qm_vop_chown( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); + ASSERT(XFS_IS_QUOTA_ON(ip->i_mount)); /* old dquot */ prevdq = *IO_olddq; @@ -1825,7 +1823,7 @@ xfs_qm_vop_rename_dqattach( struct xfs_mount *mp = i_tab[0]->i_mount; int i; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; for (i = 0; (i < 4 && i_tab[i]); i++) { @@ -1856,7 +1854,7 @@ xfs_qm_vop_create_dqattach( { struct xfs_mount *mp = tp->t_mountp; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return; ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index d16deb75dc83..982cd6613a4c 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -204,7 +204,7 @@ xfs_qm_scall_quotaon( (mp->m_qflags & XFS_GQUOTA_ACCT))) return 0; - if (! XFS_IS_QUOTA_RUNNING(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return -ESRCH; /* diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 88d70c236a54..07989bd67728 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c @@ -60,18 +60,18 @@ xfs_fs_get_quota_state( struct xfs_quotainfo *q = mp->m_quotainfo; memset(state, 0, sizeof(*state)); - if (!XFS_IS_QUOTA_RUNNING(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; state->s_incoredqs = q->qi_dquots; - if (XFS_IS_UQUOTA_RUNNING(mp)) + if (XFS_IS_UQUOTA_ON(mp)) state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED; if (XFS_IS_UQUOTA_ENFORCED(mp)) state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; - if (XFS_IS_GQUOTA_RUNNING(mp)) + if (XFS_IS_GQUOTA_ON(mp)) state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED; if (XFS_IS_GQUOTA_ENFORCED(mp)) state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; - if (XFS_IS_PQUOTA_RUNNING(mp)) + if (XFS_IS_PQUOTA_ON(mp)) state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED; if (XFS_IS_PQUOTA_ENFORCED(mp)) state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED; @@ -114,10 +114,8 @@ xfs_fs_set_info( if (sb_rdonly(sb)) return -EROFS; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) - return -ESRCH; + return -ENOSYS; if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK) return -EINVAL; if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0) @@ -164,7 +162,7 @@ xfs_quota_enable( if (sb_rdonly(sb)) return -EROFS; - if (!XFS_IS_QUOTA_RUNNING(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return -ENOSYS; return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags)); @@ -179,10 +177,8 @@ xfs_quota_disable( if (sb_rdonly(sb)) return -EROFS; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) - return -EINVAL; + return -ENOSYS; return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags)); } @@ -223,10 +219,8 @@ xfs_fs_get_dqblk( struct xfs_mount *mp = XFS_M(sb); xfs_dqid_t id; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) - return -ESRCH; + return -ENOSYS; id = from_kqid(&init_user_ns, qid); return xfs_qm_scall_getquota(mp, id, xfs_quota_type(qid.type), qdq); @@ -243,10 +237,8 @@ xfs_fs_get_nextdqblk( struct xfs_mount *mp = XFS_M(sb); xfs_dqid_t id; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) - return -ESRCH; + return -ENOSYS; id = from_kqid(&init_user_ns, *qid); ret = xfs_qm_scall_getquota_next(mp, &id, xfs_quota_type(qid->type), @@ -269,10 +261,8 @@ xfs_fs_set_dqblk( if (sb_rdonly(sb)) return -EROFS; - if (!XFS_IS_QUOTA_RUNNING(mp)) - return -ENOSYS; if (!XFS_IS_QUOTA_ON(mp)) - return -ESRCH; + return -ENOSYS; return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), xfs_quota_type(qid.type), qdq); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 2c9e26a44546..36fc81e52dc2 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -201,25 +201,20 @@ xfs_fs_show_options( seq_printf(m, ",swidth=%d", (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); - if (mp->m_qflags & XFS_UQUOTA_ACCT) { - if (mp->m_qflags & XFS_UQUOTA_ENFD) - seq_puts(m, ",usrquota"); - else - seq_puts(m, ",uqnoenforce"); - } + if (mp->m_qflags & XFS_UQUOTA_ENFD) + seq_puts(m, ",usrquota"); + else if (mp->m_qflags & XFS_UQUOTA_ACCT) + seq_puts(m, ",uqnoenforce"); - if (mp->m_qflags & XFS_PQUOTA_ACCT) { - if (mp->m_qflags & XFS_PQUOTA_ENFD) - seq_puts(m, ",prjquota"); - else - seq_puts(m, ",pqnoenforce"); - } - if (mp->m_qflags & XFS_GQUOTA_ACCT) { - if (mp->m_qflags & XFS_GQUOTA_ENFD) - seq_puts(m, ",grpquota"); - else - seq_puts(m, ",gqnoenforce"); - } + if (mp->m_qflags & XFS_PQUOTA_ENFD) + seq_puts(m, ",prjquota"); + else if (mp->m_qflags & XFS_PQUOTA_ACCT) + seq_puts(m, ",pqnoenforce"); + + if (mp->m_qflags & XFS_GQUOTA_ENFD) + seq_puts(m, ",grpquota"); + else if (mp->m_qflags & XFS_GQUOTA_ACCT) + seq_puts(m, ",gqnoenforce"); if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) seq_puts(m, ",noquota"); @@ -962,8 +957,8 @@ xfs_finish_flags( return -EROFS; } - if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) && - (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE)) && + if ((mp->m_qflags & XFS_GQUOTA_ACCT) && + (mp->m_qflags & XFS_PQUOTA_ACCT) && !xfs_sb_version_has_pquotino(&mp->m_sb)) { xfs_warn(mp, "Super block does not support project and group quota together"); @@ -1228,35 +1223,31 @@ xfs_fs_parse_param( case Opt_noquota: parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; - parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE; return 0; case Opt_quota: case Opt_uquota: case Opt_usrquota: - parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | - XFS_UQUOTA_ENFD); + parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ENFD); return 0; case Opt_qnoenforce: case Opt_uqnoenforce: - parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); + parsing_mp->m_qflags |= XFS_UQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_UQUOTA_ENFD; return 0; case Opt_pquota: case Opt_prjquota: - parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | - XFS_PQUOTA_ENFD); + parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ENFD); return 0; case Opt_pqnoenforce: - parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); + parsing_mp->m_qflags |= XFS_PQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_PQUOTA_ENFD; return 0; case Opt_gquota: case Opt_grpquota: - parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | - XFS_GQUOTA_ENFD); + parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ENFD); return 0; case Opt_gqnoenforce: - parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); + parsing_mp->m_qflags |= XFS_GQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_GQUOTA_ENFD; return 0; case Opt_discard: diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index b7e4b05a559b..eb76bc5bed9d 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -132,8 +132,7 @@ xfs_trans_mod_dquot_byino( { xfs_mount_t *mp = tp->t_mountp; - if (!XFS_IS_QUOTA_RUNNING(mp) || - !XFS_IS_QUOTA_ON(mp) || + if (!XFS_IS_QUOTA_ON(mp) || xfs_is_quota_inode(&mp->m_sb, ip->i_ino)) return; @@ -192,7 +191,7 @@ xfs_trans_mod_dquot( struct xfs_dqtrx *qtrx; ASSERT(tp); - ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp)); + ASSERT(XFS_IS_QUOTA_ON(tp->t_mountp)); qtrx = NULL; if (!delta) @@ -738,7 +737,7 @@ xfs_trans_reserve_quota_bydquots( { int error; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; ASSERT(flags & XFS_QMOPT_RESBLK_MASK); @@ -795,7 +794,7 @@ xfs_trans_reserve_quota_nblks( unsigned int qflags = 0; int error; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino)); @@ -836,7 +835,7 @@ xfs_trans_reserve_quota_icreate( { struct xfs_mount *mp = tp->t_mountp; - if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) + if (!XFS_IS_QUOTA_ON(mp)) return 0; return xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp, pdqp, -- cgit v1.2.3-70-g09d2 From f1653c2e2831e9db6cd68473bbec581782df03a5 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 6 Aug 2021 11:05:37 -0700 Subject: xfs: introduce CPU hotplug infrastructure We need to move to per-cpu state for both deferred inode inactivation and CIL tracking, but to do that we need to handle CPUs being removed from the system by the hot-plug code. Introduce generic XFS infrastructure to handle CPU hotplug events that is set up at module init time and torn down at module exit time. Initially, we only need CPU dead notifications, so we only set up a callback for these notifications. The infrastructure can be updated in future for other CPU hotplug state machine notifications easily if ever needed. Signed-off-by: Dave Chinner [djwong: rearrange some macros, fix function prototypes] Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_super.c | 42 +++++++++++++++++++++++++++++++++++++++++- include/linux/cpuhotplug.h | 1 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 36fc81e52dc2..d47fac7c8afd 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -2111,6 +2111,39 @@ xfs_destroy_workqueues(void) destroy_workqueue(xfs_alloc_wq); } +#ifdef CONFIG_HOTPLUG_CPU +static int +xfs_cpu_dead( + unsigned int cpu) +{ + return 0; +} + +static int __init +xfs_cpu_hotplug_init(void) +{ + int error; + + error = cpuhp_setup_state_nocalls(CPUHP_XFS_DEAD, "xfs:dead", NULL, + xfs_cpu_dead); + if (error < 0) + xfs_alert(NULL, +"Failed to initialise CPU hotplug, error %d. XFS is non-functional.", + error); + return error; +} + +static void +xfs_cpu_hotplug_destroy(void) +{ + cpuhp_remove_state_nocalls(CPUHP_XFS_DEAD); +} + +#else /* !CONFIG_HOTPLUG_CPU */ +static inline int xfs_cpu_hotplug_init(void) { return 0; } +static inline void xfs_cpu_hotplug_destroy(void) {} +#endif + STATIC int __init init_xfs_fs(void) { @@ -2123,10 +2156,14 @@ init_xfs_fs(void) xfs_dir_startup(); - error = xfs_init_zones(); + error = xfs_cpu_hotplug_init(); if (error) goto out; + error = xfs_init_zones(); + if (error) + goto out_destroy_hp; + error = xfs_init_workqueues(); if (error) goto out_destroy_zones; @@ -2206,6 +2243,8 @@ init_xfs_fs(void) xfs_destroy_workqueues(); out_destroy_zones: xfs_destroy_zones(); + out_destroy_hp: + xfs_cpu_hotplug_destroy(); out: return error; } @@ -2228,6 +2267,7 @@ exit_xfs_fs(void) xfs_destroy_workqueues(); xfs_destroy_zones(); xfs_uuid_table_free(); + xfs_cpu_hotplug_destroy(); } module_init(init_xfs_fs); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index f39b34b13871..439adc05be4e 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -52,6 +52,7 @@ enum cpuhp_state { CPUHP_FS_BUFF_DEAD, CPUHP_PRINTK_DEAD, CPUHP_MM_MEMCQ_DEAD, + CPUHP_XFS_DEAD, CPUHP_PERCPU_CNT_DEAD, CPUHP_RADIX_DEAD, CPUHP_PAGE_ALLOC, -- cgit v1.2.3-70-g09d2 From 0ed17f01c85401abf1706d9825796fc6661c0889 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 6 Aug 2021 11:05:38 -0700 Subject: xfs: introduce all-mounts list for cpu hotplug notifications The inode inactivation and CIL tracking percpu structures are per-xfs_mount structures. That means when we get a CPU dead notification, we need to then iterate all the per-cpu structure instances to process them. Rather than keeping linked lists of per-cpu structures in each subsystem, add a list of all xfs_mounts that the generic xfs_cpu_dead() function will iterate and call into each subsystem appropriately. This allows us to handle both per-mount and global XFS percpu state from xfs_cpu_dead(), and avoids the need to link subsystem structures that can be easily found from the xfs_mount into their own global lists. Signed-off-by: Dave Chinner [djwong: expand some comments about mount list setup ordering rules] Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_super.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index c78b63fe779a..ed7064596f94 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -82,6 +82,7 @@ typedef struct xfs_mount { xfs_buftarg_t *m_ddev_targp; /* saves taking the address */ xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ + struct list_head m_mount_list; /* global mount list */ /* * Optional cache of rt summary level per bitmap block with the * invariant that m_rsum_cache[bbno] <= the minimum i for which diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d47fac7c8afd..c2c9c02b9d62 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -49,6 +49,28 @@ static struct kset *xfs_kset; /* top-level xfs sysfs dir */ static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ #endif +#ifdef CONFIG_HOTPLUG_CPU +static LIST_HEAD(xfs_mount_list); +static DEFINE_SPINLOCK(xfs_mount_list_lock); + +static inline void xfs_mount_list_add(struct xfs_mount *mp) +{ + spin_lock(&xfs_mount_list_lock); + list_add(&mp->m_mount_list, &xfs_mount_list); + spin_unlock(&xfs_mount_list_lock); +} + +static inline void xfs_mount_list_del(struct xfs_mount *mp) +{ + spin_lock(&xfs_mount_list_lock); + list_del(&mp->m_mount_list); + spin_unlock(&xfs_mount_list_lock); +} +#else /* !CONFIG_HOTPLUG_CPU */ +static inline void xfs_mount_list_add(struct xfs_mount *mp) {} +static inline void xfs_mount_list_del(struct xfs_mount *mp) {} +#endif + enum xfs_dax_mode { XFS_DAX_INODE = 0, XFS_DAX_ALWAYS = 1, @@ -1038,6 +1060,7 @@ xfs_fs_put_super( xfs_freesb(mp); free_percpu(mp->m_stats.xs_stats); + xfs_mount_list_del(mp); xfs_destroy_percpu_counters(mp); xfs_destroy_mount_workqueues(mp); xfs_close_devices(mp); @@ -1409,6 +1432,13 @@ xfs_fs_fill_super( if (error) goto out_destroy_workqueues; + /* + * All percpu data structures requiring cleanup when a cpu goes offline + * must be allocated before adding this @mp to the cpu-dead handler's + * mount list. + */ + xfs_mount_list_add(mp); + /* Allocate stats memory before we do operations that might use it */ mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); if (!mp->m_stats.xs_stats) { @@ -1617,6 +1647,7 @@ xfs_fs_fill_super( out_free_stats: free_percpu(mp->m_stats.xs_stats); out_destroy_counters: + xfs_mount_list_del(mp); xfs_destroy_percpu_counters(mp); out_destroy_workqueues: xfs_destroy_mount_workqueues(mp); @@ -2116,6 +2147,15 @@ static int xfs_cpu_dead( unsigned int cpu) { + struct xfs_mount *mp, *n; + + spin_lock(&xfs_mount_list_lock); + list_for_each_entry_safe(mp, n, &xfs_mount_list, m_mount_list) { + spin_unlock(&xfs_mount_list_lock); + /* xfs_subsys_dead(mp, cpu); */ + spin_lock(&xfs_mount_list_lock); + } + spin_unlock(&xfs_mount_list_lock); return 0; } -- cgit v1.2.3-70-g09d2 From c6c2066db3963e519a7ff8f432fcec956f4d23b4 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:38 -0700 Subject: xfs: move xfs_inactive call to xfs_inode_mark_reclaimable Move the xfs_inactive call and all the other debugging checks and stats updates into xfs_inode_mark_reclaimable because most of that are implementation details about the inode cache. This is preparation for deferred inactivation that is coming up. We also move it around xfs_icache.c in preparation for deferred inactivation. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 99 +++++++++++++++++++++++++++++++++++++++-------------- fs/xfs/xfs_super.c | 50 --------------------------- 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 086a88b8dfdb..f0e77ed0b8bb 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -292,31 +292,6 @@ xfs_perag_clear_inode_tag( trace_xfs_perag_clear_inode_tag(mp, pag->pag_agno, tag, _RET_IP_); } -/* - * We set the inode flag atomically with the radix tree tag. - * Once we get tag lookups on the radix tree, this inode flag - * can go away. - */ -void -xfs_inode_mark_reclaimable( - struct xfs_inode *ip) -{ - struct xfs_mount *mp = ip->i_mount; - struct xfs_perag *pag; - - pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); - spin_lock(&pag->pag_ici_lock); - spin_lock(&ip->i_flags_lock); - - xfs_perag_set_inode_tag(pag, XFS_INO_TO_AGINO(mp, ip->i_ino), - XFS_ICI_RECLAIM_TAG); - __xfs_iflags_set(ip, XFS_IRECLAIMABLE); - - spin_unlock(&ip->i_flags_lock); - spin_unlock(&pag->pag_ici_lock); - xfs_perag_put(pag); -} - static inline void xfs_inew_wait( struct xfs_inode *ip) @@ -1739,3 +1714,77 @@ xfs_icwalk( return last_error; BUILD_BUG_ON(XFS_ICWALK_PRIVATE_FLAGS & XFS_ICWALK_FLAGS_VALID); } + +#ifdef DEBUG +static void +xfs_check_delalloc( + struct xfs_inode *ip, + int whichfork) +{ + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); + struct xfs_bmbt_irec got; + struct xfs_iext_cursor icur; + + if (!ifp || !xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got)) + return; + do { + if (isnullstartblock(got.br_startblock)) { + xfs_warn(ip->i_mount, + "ino %llx %s fork has delalloc extent at [0x%llx:0x%llx]", + ip->i_ino, + whichfork == XFS_DATA_FORK ? "data" : "cow", + got.br_startoff, got.br_blockcount); + } + } while (xfs_iext_next_extent(ifp, &icur, &got)); +} +#else +#define xfs_check_delalloc(ip, whichfork) do { } while (0) +#endif + +/* + * We set the inode flag atomically with the radix tree tag. + * Once we get tag lookups on the radix tree, this inode flag + * can go away. + */ +void +xfs_inode_mark_reclaimable( + struct xfs_inode *ip) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_perag *pag; + + xfs_inactive(ip); + + if (!XFS_FORCED_SHUTDOWN(mp) && ip->i_delayed_blks) { + xfs_check_delalloc(ip, XFS_DATA_FORK); + xfs_check_delalloc(ip, XFS_COW_FORK); + ASSERT(0); + } + + XFS_STATS_INC(mp, vn_reclaim); + + /* + * We should never get here with one of the reclaim flags already set. + */ + ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); + ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); + + /* + * We always use background reclaim here because even if the inode is + * clean, it still may be under IO and hence we have wait for IO + * completion to occur before we can reclaim the inode. The background + * reclaim path handles this more efficiently than we can here, so + * simply let background reclaim tear down all inodes. + */ + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); + spin_lock(&pag->pag_ici_lock); + spin_lock(&ip->i_flags_lock); + + xfs_perag_set_inode_tag(pag, XFS_INO_TO_AGINO(mp, ip->i_ino), + XFS_ICI_RECLAIM_TAG); + __xfs_iflags_set(ip, XFS_IRECLAIMABLE); + + spin_unlock(&ip->i_flags_lock); + spin_unlock(&pag->pag_ici_lock); + xfs_perag_put(pag); +} diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index c2c9c02b9d62..e0b97e4c8e16 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -613,32 +613,6 @@ xfs_fs_alloc_inode( return NULL; } -#ifdef DEBUG -static void -xfs_check_delalloc( - struct xfs_inode *ip, - int whichfork) -{ - struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); - struct xfs_bmbt_irec got; - struct xfs_iext_cursor icur; - - if (!ifp || !xfs_iext_lookup_extent(ip, ifp, 0, &icur, &got)) - return; - do { - if (isnullstartblock(got.br_startblock)) { - xfs_warn(ip->i_mount, - "ino %llx %s fork has delalloc extent at [0x%llx:0x%llx]", - ip->i_ino, - whichfork == XFS_DATA_FORK ? "data" : "cow", - got.br_startoff, got.br_blockcount); - } - } while (xfs_iext_next_extent(ifp, &icur, &got)); -} -#else -#define xfs_check_delalloc(ip, whichfork) do { } while (0) -#endif - /* * Now that the generic code is guaranteed not to be accessing * the linux inode, we can inactivate and reclaim the inode. @@ -654,30 +628,6 @@ xfs_fs_destroy_inode( ASSERT(!rwsem_is_locked(&inode->i_rwsem)); XFS_STATS_INC(ip->i_mount, vn_rele); XFS_STATS_INC(ip->i_mount, vn_remove); - - xfs_inactive(ip); - - if (!XFS_FORCED_SHUTDOWN(ip->i_mount) && ip->i_delayed_blks) { - xfs_check_delalloc(ip, XFS_DATA_FORK); - xfs_check_delalloc(ip, XFS_COW_FORK); - ASSERT(0); - } - - XFS_STATS_INC(ip->i_mount, vn_reclaim); - - /* - * We should never get here with one of the reclaim flags already set. - */ - ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); - ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); - - /* - * We always use background reclaim here because even if the inode is - * clean, it still may be under IO and hence we have wait for IO - * completion to occur before we can reclaim the inode. The background - * reclaim path handles this more efficiently than we can here, so - * simply let background reclaim tear down all inodes. - */ xfs_inode_mark_reclaimable(ip); } -- cgit v1.2.3-70-g09d2 From 62af7d54a0ec0b6f99d7d55ebeb9ecbb3371bc67 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:39 -0700 Subject: xfs: detach dquots from inode if we don't need to inactivate it If we don't need to inactivate an inode, we can detach the dquots and move on to reclamation. This isn't strictly required here; it's a preparation patch for deferred inactivation per reviewer request[1] to move the creation of xfs_inode_needs_inactivation into a separate change. Eventually this !need_inactive chunk will turn into the code path for inodes that skip xfs_inactive and go straight to memory reclaim. [1] https://lore.kernel.org/linux-xfs/20210609012838.GW2945738@locust/T/#mca6d958521cb88bbc1bfe1a30767203328d410b5 Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 8 +++++++- fs/xfs/xfs_inode.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index f0e77ed0b8bb..b9214733d0c3 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1752,8 +1752,14 @@ xfs_inode_mark_reclaimable( { struct xfs_mount *mp = ip->i_mount; struct xfs_perag *pag; + bool need_inactive = xfs_inode_needs_inactive(ip); - xfs_inactive(ip); + if (!need_inactive) { + /* Going straight to reclaim, so drop the dquots. */ + xfs_qm_dqdetach(ip); + } else { + xfs_inactive(ip); + } if (!XFS_FORCED_SHUTDOWN(mp) && ip->i_delayed_blks) { xfs_check_delalloc(ip, XFS_DATA_FORK); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 990b72ae3635..3c6ce1f6f643 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1654,6 +1654,59 @@ xfs_inactive_ifree( return 0; } +/* + * Returns true if we need to update the on-disk metadata before we can free + * the memory used by this inode. Updates include freeing post-eof + * preallocations; freeing COW staging extents; and marking the inode free in + * the inobt if it is on the unlinked list. + */ +bool +xfs_inode_needs_inactive( + struct xfs_inode *ip) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_ifork *cow_ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK); + + /* + * If the inode is already free, then there can be nothing + * to clean up here. + */ + if (VFS_I(ip)->i_mode == 0) + return false; + + /* If this is a read-only mount, don't do this (would generate I/O) */ + if (mp->m_flags & XFS_MOUNT_RDONLY) + return false; + + /* If the log isn't running, push inodes straight to reclaim. */ + if (XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_NORECOVERY)) + return false; + + /* Metadata inodes require explicit resource cleanup. */ + if (xfs_is_metadata_inode(ip)) + return false; + + /* Want to clean out the cow blocks if there are any. */ + if (cow_ifp && cow_ifp->if_bytes > 0) + return true; + + /* Unlinked files must be freed. */ + if (VFS_I(ip)->i_nlink == 0) + return true; + + /* + * This file isn't being freed, so check if there are post-eof blocks + * to free. @force is true because we are evicting an inode from the + * cache. Post-eof blocks must be freed, lest we end up with broken + * free space accounting. + * + * Note: don't bother with iolock here since lockdep complains about + * acquiring it in reclaim context. We have the only reference to the + * inode at this point anyways. + */ + return xfs_can_free_eofblocks(ip, true); +} + /* * xfs_inactive * diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 4b6703dbffb8..e3137bbc7b14 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -493,6 +493,8 @@ extern struct kmem_zone *xfs_inode_zone; /* The default CoW extent size hint. */ #define XFS_DEFAULT_COWEXTSZ_HINT 32 +bool xfs_inode_needs_inactive(struct xfs_inode *ip); + int xfs_iunlink_init(struct xfs_perag *pag); void xfs_iunlink_destroy(struct xfs_perag *pag); -- cgit v1.2.3-70-g09d2 From ab23a7768739a23d21d8a16ca37dff96b1ca957a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 6 Aug 2021 11:05:39 -0700 Subject: xfs: per-cpu deferred inode inactivation queues Move inode inactivation to background work contexts so that it no longer runs in the context that releases the final reference to an inode. This will allow process work that ends up blocking on inactivation to continue doing work while the filesytem processes the inactivation in the background. A typical demonstration of this is unlinking an inode with lots of extents. The extents are removed during inactivation, so this blocks the process that unlinked the inode from the directory structure. By moving the inactivation to the background process, the userspace applicaiton can keep working (e.g. unlinking the next inode in the directory) while the inactivation work on the previous inode is done by a different CPU. The implementation of the queue is relatively simple. We use a per-cpu lockless linked list (llist) to queue inodes for inactivation without requiring serialisation mechanisms, and a work item to allow the queue to be processed by a CPU bound worker thread. We also keep a count of the queue depth so that we can trigger work after a number of deferred inactivations have been queued. The use of a bound workqueue with a single work depth allows the workqueue to run one work item per CPU. We queue the work item on the CPU we are currently running on, and so this essentially gives us affine per-cpu worker threads for the per-cpu queues. THis maintains the effective CPU affinity that occurs within XFS at the AG level due to all objects in a directory being local to an AG. Hence inactivation work tends to run on the same CPU that last accessed all the objects that inactivation accesses and this maintains hot CPU caches for unlink workloads. A depth of 32 inodes was chosen to match the number of inodes in an inode cluster buffer. This hopefully allows sequential allocation/unlink behaviours to defering inactivation of all the inodes in a single cluster buffer at a time, further helping maintain hot CPU and buffer cache accesses while running inactivations. A hard per-cpu queue throttle of 256 inode has been set to avoid runaway queuing when inodes that take a long to time inactivate are being processed. For example, when unlinking inodes with large numbers of extents that can take a lot of processing to free. Signed-off-by: Dave Chinner [djwong: tweak comments and tracepoints, convert opflags to state bits] Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/scrub/common.c | 7 + fs/xfs/xfs_icache.c | 346 ++++++++++++++++++++++++++++++++++++++++++----- fs/xfs/xfs_icache.h | 6 + fs/xfs/xfs_inode.h | 20 ++- fs/xfs/xfs_log_recover.c | 7 + fs/xfs/xfs_mount.c | 26 +++- fs/xfs/xfs_mount.h | 43 +++++- fs/xfs/xfs_super.c | 114 ++++++++++++++-- fs/xfs/xfs_trace.h | 50 ++++++- 9 files changed, 571 insertions(+), 48 deletions(-) diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 8558ca05e11d..06b697f72f23 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -884,6 +884,7 @@ xchk_stop_reaping( { sc->flags |= XCHK_REAPING_DISABLED; xfs_blockgc_stop(sc->mp); + xfs_inodegc_stop(sc->mp); } /* Restart background reaping of resources. */ @@ -891,6 +892,12 @@ void xchk_start_reaping( struct xfs_scrub *sc) { + /* + * Readonly filesystems do not perform inactivation, so there's no + * need to restart the worker. + */ + if (!(sc->mp->m_flags & XFS_MOUNT_RDONLY)) + xfs_inodegc_start(sc->mp); xfs_blockgc_start(sc->mp); sc->flags &= ~XCHK_REAPING_DISABLED; } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index b9214733d0c3..7d93edb331fb 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -213,7 +213,7 @@ xfs_blockgc_queue( { rcu_read_lock(); if (radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_BLOCKGC_TAG)) - queue_delayed_work(pag->pag_mount->m_gc_workqueue, + queue_delayed_work(pag->pag_mount->m_blockgc_wq, &pag->pag_blockgc_work, msecs_to_jiffies(xfs_blockgc_secs * 1000)); rcu_read_unlock(); @@ -450,6 +450,21 @@ xfs_iget_check_free_state( return 0; } +/* Make all pending inactivation work start immediately. */ +static void +xfs_inodegc_queue_all( + struct xfs_mount *mp) +{ + struct xfs_inodegc *gc; + int cpu; + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + if (!llist_empty(&gc->list)) + queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); + } +} + /* * Check the validity of the inode we just found it the cache */ @@ -482,13 +497,30 @@ xfs_iget_cache_hit( * reclaimable state, wait for the initialisation to complete * before continuing. * + * If we're racing with the inactivation worker we also want to wait. + * If we're creating a new file, it's possible that the worker + * previously marked the inode as free on disk but hasn't finished + * updating the incore state yet. The AGI buffer will be dirty and + * locked to the icreate transaction, so a synchronous push of the + * inodegc workers would result in deadlock. For a regular iget, the + * worker is running already, so we might as well wait. + * * XXX(hch): eventually we should do something equivalent to * wait_on_inode to wait for these flags to be cleared * instead of polling for it. */ - if (ip->i_flags & (XFS_INEW | XFS_IRECLAIM)) + if (ip->i_flags & (XFS_INEW | XFS_IRECLAIM | XFS_INACTIVATING)) goto out_skip; + if (ip->i_flags & XFS_NEED_INACTIVE) { + /* Unlinked inodes cannot be re-grabbed. */ + if (VFS_I(ip)->i_nlink == 0) { + error = -ENOENT; + goto out_error; + } + goto out_inodegc_flush; + } + /* * Check the inode free state is valid. This also detects lookup * racing with unlinks. @@ -536,6 +568,17 @@ out_error: spin_unlock(&ip->i_flags_lock); rcu_read_unlock(); return error; + +out_inodegc_flush: + spin_unlock(&ip->i_flags_lock); + rcu_read_unlock(); + /* + * Do not wait for the workers, because the caller could hold an AGI + * buffer lock. We're just going to sleep in a loop anyway. + */ + if (xfs_is_inodegc_enabled(mp)) + xfs_inodegc_queue_all(mp); + return -EAGAIN; } static int @@ -863,6 +906,7 @@ xfs_reclaim_inode( xfs_iflags_clear(ip, XFS_IFLUSHING); reclaim: + trace_xfs_inode_reclaiming(ip); /* * Because we use RCU freeing we need to ensure the inode always appears @@ -1340,6 +1384,8 @@ xfs_blockgc_start( /* Don't try to run block gc on an inode that's in any of these states. */ #define XFS_BLOCKGC_NOGRAB_IFLAGS (XFS_INEW | \ + XFS_NEED_INACTIVE | \ + XFS_INACTIVATING | \ XFS_IRECLAIMABLE | \ XFS_IRECLAIM) /* @@ -1741,25 +1787,13 @@ xfs_check_delalloc( #define xfs_check_delalloc(ip, whichfork) do { } while (0) #endif -/* - * We set the inode flag atomically with the radix tree tag. - * Once we get tag lookups on the radix tree, this inode flag - * can go away. - */ -void -xfs_inode_mark_reclaimable( +/* Schedule the inode for reclaim. */ +static void +xfs_inodegc_set_reclaimable( struct xfs_inode *ip) { struct xfs_mount *mp = ip->i_mount; struct xfs_perag *pag; - bool need_inactive = xfs_inode_needs_inactive(ip); - - if (!need_inactive) { - /* Going straight to reclaim, so drop the dquots. */ - xfs_qm_dqdetach(ip); - } else { - xfs_inactive(ip); - } if (!XFS_FORCED_SHUTDOWN(mp) && ip->i_delayed_blks) { xfs_check_delalloc(ip, XFS_DATA_FORK); @@ -1767,30 +1801,276 @@ xfs_inode_mark_reclaimable( ASSERT(0); } - XFS_STATS_INC(mp, vn_reclaim); - - /* - * We should never get here with one of the reclaim flags already set. - */ - ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); - ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_IRECLAIM)); - - /* - * We always use background reclaim here because even if the inode is - * clean, it still may be under IO and hence we have wait for IO - * completion to occur before we can reclaim the inode. The background - * reclaim path handles this more efficiently than we can here, so - * simply let background reclaim tear down all inodes. - */ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); spin_lock(&pag->pag_ici_lock); spin_lock(&ip->i_flags_lock); + trace_xfs_inode_set_reclaimable(ip); + ip->i_flags &= ~(XFS_NEED_INACTIVE | XFS_INACTIVATING); + ip->i_flags |= XFS_IRECLAIMABLE; xfs_perag_set_inode_tag(pag, XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG); - __xfs_iflags_set(ip, XFS_IRECLAIMABLE); spin_unlock(&ip->i_flags_lock); spin_unlock(&pag->pag_ici_lock); xfs_perag_put(pag); } + +/* + * Free all speculative preallocations and possibly even the inode itself. + * This is the last chance to make changes to an otherwise unreferenced file + * before incore reclamation happens. + */ +static void +xfs_inodegc_inactivate( + struct xfs_inode *ip) +{ + trace_xfs_inode_inactivating(ip); + xfs_inactive(ip); + xfs_inodegc_set_reclaimable(ip); +} + +void +xfs_inodegc_worker( + struct work_struct *work) +{ + struct xfs_inodegc *gc = container_of(work, struct xfs_inodegc, + work); + struct llist_node *node = llist_del_all(&gc->list); + struct xfs_inode *ip, *n; + + WRITE_ONCE(gc->items, 0); + + if (!node) + return; + + ip = llist_entry(node, struct xfs_inode, i_gclist); + trace_xfs_inodegc_worker(ip->i_mount, __return_address); + + llist_for_each_entry_safe(ip, n, node, i_gclist) { + xfs_iflags_set(ip, XFS_INACTIVATING); + xfs_inodegc_inactivate(ip); + } +} + +/* + * Force all currently queued inode inactivation work to run immediately, and + * wait for the work to finish. Two pass - queue all the work first pass, wait + * for it in a second pass. + */ +void +xfs_inodegc_flush( + struct xfs_mount *mp) +{ + struct xfs_inodegc *gc; + int cpu; + + if (!xfs_is_inodegc_enabled(mp)) + return; + + trace_xfs_inodegc_flush(mp, __return_address); + + xfs_inodegc_queue_all(mp); + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + flush_work(&gc->work); + } +} + +/* + * Flush all the pending work and then disable the inode inactivation background + * workers and wait for them to stop. + */ +void +xfs_inodegc_stop( + struct xfs_mount *mp) +{ + struct xfs_inodegc *gc; + int cpu; + + if (!xfs_clear_inodegc_enabled(mp)) + return; + + xfs_inodegc_queue_all(mp); + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + cancel_work_sync(&gc->work); + } + trace_xfs_inodegc_stop(mp, __return_address); +} + +/* + * Enable the inode inactivation background workers and schedule deferred inode + * inactivation work if there is any. + */ +void +xfs_inodegc_start( + struct xfs_mount *mp) +{ + if (xfs_set_inodegc_enabled(mp)) + return; + + trace_xfs_inodegc_start(mp, __return_address); + xfs_inodegc_queue_all(mp); +} + +/* + * Schedule the inactivation worker when: + * + * - We've accumulated more than one inode cluster buffer's worth of inodes. + */ +static inline bool +xfs_inodegc_want_queue_work( + struct xfs_inode *ip, + unsigned int items) +{ + struct xfs_mount *mp = ip->i_mount; + + if (items > mp->m_ino_geo.inodes_per_cluster) + return true; + + return false; +} + +/* + * Upper bound on the number of inodes in each AG that can be queued for + * inactivation at any given time, to avoid monopolizing the workqueue. + */ +#define XFS_INODEGC_MAX_BACKLOG (4 * XFS_INODES_PER_CHUNK) + +/* + * Make the frontend wait for inactivations when: + * + * - The queue depth exceeds the maximum allowable percpu backlog. + * + * Note: If the current thread is running a transaction, we don't ever want to + * wait for other transactions because that could introduce a deadlock. + */ +static inline bool +xfs_inodegc_want_flush_work( + struct xfs_inode *ip, + unsigned int items) +{ + if (current->journal_info) + return false; + + if (items > XFS_INODEGC_MAX_BACKLOG) + return true; + + return false; +} + +/* + * Queue a background inactivation worker if there are inodes that need to be + * inactivated and higher level xfs code hasn't disabled the background + * workers. + */ +static void +xfs_inodegc_queue( + struct xfs_inode *ip) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_inodegc *gc; + int items; + + trace_xfs_inode_set_need_inactive(ip); + spin_lock(&ip->i_flags_lock); + ip->i_flags |= XFS_NEED_INACTIVE; + spin_unlock(&ip->i_flags_lock); + + gc = get_cpu_ptr(mp->m_inodegc); + llist_add(&ip->i_gclist, &gc->list); + items = READ_ONCE(gc->items); + WRITE_ONCE(gc->items, items + 1); + put_cpu_ptr(gc); + + if (!xfs_is_inodegc_enabled(mp)) + return; + + if (xfs_inodegc_want_queue_work(ip, items)) { + trace_xfs_inodegc_queue(mp, __return_address); + queue_work(mp->m_inodegc_wq, &gc->work); + } + + if (xfs_inodegc_want_flush_work(ip, items)) { + trace_xfs_inodegc_throttle(mp, __return_address); + flush_work(&gc->work); + } +} + +/* + * Fold the dead CPU inodegc queue into the current CPUs queue. + */ +void +xfs_inodegc_cpu_dead( + struct xfs_mount *mp, + unsigned int dead_cpu) +{ + struct xfs_inodegc *dead_gc, *gc; + struct llist_node *first, *last; + unsigned int count = 0; + + dead_gc = per_cpu_ptr(mp->m_inodegc, dead_cpu); + cancel_work_sync(&dead_gc->work); + + if (llist_empty(&dead_gc->list)) + return; + + first = dead_gc->list.first; + last = first; + while (last->next) { + last = last->next; + count++; + } + dead_gc->list.first = NULL; + dead_gc->items = 0; + + /* Add pending work to current CPU */ + gc = get_cpu_ptr(mp->m_inodegc); + llist_add_batch(first, last, &gc->list); + count += READ_ONCE(gc->items); + WRITE_ONCE(gc->items, count); + put_cpu_ptr(gc); + + if (xfs_is_inodegc_enabled(mp)) { + trace_xfs_inodegc_queue(mp, __return_address); + queue_work(mp->m_inodegc_wq, &gc->work); + } +} + +/* + * We set the inode flag atomically with the radix tree tag. Once we get tag + * lookups on the radix tree, this inode flag can go away. + * + * We always use background reclaim here because even if the inode is clean, it + * still may be under IO and hence we have wait for IO completion to occur + * before we can reclaim the inode. The background reclaim path handles this + * more efficiently than we can here, so simply let background reclaim tear down + * all inodes. + */ +void +xfs_inode_mark_reclaimable( + struct xfs_inode *ip) +{ + struct xfs_mount *mp = ip->i_mount; + bool need_inactive; + + XFS_STATS_INC(mp, vn_reclaim); + + /* + * We should never get here with any of the reclaim flags already set. + */ + ASSERT_ALWAYS(!xfs_iflags_test(ip, XFS_ALL_IRECLAIM_FLAGS)); + + need_inactive = xfs_inode_needs_inactive(ip); + if (need_inactive) { + xfs_inodegc_queue(ip); + return; + } + + /* Going straight to reclaim, so drop the dquots. */ + xfs_qm_dqdetach(ip); + xfs_inodegc_set_reclaimable(ip); +} diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index d0062ebb3f7a..8175148afd50 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -74,4 +74,10 @@ int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp, void xfs_blockgc_stop(struct xfs_mount *mp); void xfs_blockgc_start(struct xfs_mount *mp); +void xfs_inodegc_worker(struct work_struct *work); +void xfs_inodegc_flush(struct xfs_mount *mp); +void xfs_inodegc_stop(struct xfs_mount *mp); +void xfs_inodegc_start(struct xfs_mount *mp); +void xfs_inodegc_cpu_dead(struct xfs_mount *mp, unsigned int cpu); + #endif diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index e3137bbc7b14..1f62b481d8c5 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -42,6 +42,7 @@ typedef struct xfs_inode { mrlock_t i_lock; /* inode lock */ mrlock_t i_mmaplock; /* inode mmap IO lock */ atomic_t i_pincount; /* inode pin count */ + struct llist_node i_gclist; /* deferred inactivation list */ /* * Bitsets of inode metadata that have been checked and/or are sick. @@ -240,6 +241,7 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip) #define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */ #define XFS_IPINNED (1 << __XFS_IPINNED_BIT) #define XFS_IEOFBLOCKS (1 << 9) /* has the preallocblocks tag set */ +#define XFS_NEED_INACTIVE (1 << 10) /* see XFS_INACTIVATING below */ /* * If this unlinked inode is in the middle of recovery, don't let drop_inode * truncate and free the inode. This can happen if we iget the inode during @@ -248,6 +250,21 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip) #define XFS_IRECOVERY (1 << 11) #define XFS_ICOWBLOCKS (1 << 12)/* has the cowblocks tag set */ +/* + * If we need to update on-disk metadata before this IRECLAIMABLE inode can be + * freed, then NEED_INACTIVE will be set. Once we start the updates, the + * INACTIVATING bit will be set to keep iget away from this inode. After the + * inactivation completes, both flags will be cleared and the inode is a + * plain old IRECLAIMABLE inode. + */ +#define XFS_INACTIVATING (1 << 13) + +/* All inode state flags related to inode reclaim. */ +#define XFS_ALL_IRECLAIM_FLAGS (XFS_IRECLAIMABLE | \ + XFS_IRECLAIM | \ + XFS_NEED_INACTIVE | \ + XFS_INACTIVATING) + /* * Per-lifetime flags need to be reset when re-using a reclaimable inode during * inode lookup. This prevents unintended behaviour on the new inode from @@ -255,7 +272,8 @@ static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip) */ #define XFS_IRECLAIM_RESET_FLAGS \ (XFS_IRECLAIMABLE | XFS_IRECLAIM | \ - XFS_IDIRTY_RELEASE | XFS_ITRUNCATED) + XFS_IDIRTY_RELEASE | XFS_ITRUNCATED | XFS_NEED_INACTIVE | \ + XFS_INACTIVATING) /* * Flags for inode locking. diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1721fce2ec94..a98d2429d795 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2786,6 +2786,13 @@ xlog_recover_process_iunlinks( } xfs_buf_rele(agibp); } + + /* + * Flush the pending unlinked inodes to ensure that the inactivations + * are fully completed on disk and the incore inodes can be reclaimed + * before we signal that recovery is complete. + */ + xfs_inodegc_flush(mp); } STATIC void diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index baf7b323cb15..1f7e9a608f38 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -514,7 +514,8 @@ xfs_check_summary_counts( * Flush and reclaim dirty inodes in preparation for unmount. Inodes and * internal inode structures can be sitting in the CIL and AIL at this point, * so we need to unpin them, write them back and/or reclaim them before unmount - * can proceed. + * can proceed. In other words, callers are required to have inactivated all + * inodes. * * An inode cluster that has been freed can have its buffer still pinned in * memory because the transaction is still sitting in a iclog. The stale inodes @@ -546,6 +547,7 @@ xfs_unmount_flush_inodes( mp->m_flags |= XFS_MOUNT_UNMOUNTING; xfs_ail_push_all_sync(mp->m_ail); + xfs_inodegc_stop(mp); cancel_delayed_work_sync(&mp->m_reclaim_work); xfs_reclaim_inodes(mp); xfs_health_unmount(mp); @@ -782,6 +784,9 @@ xfs_mountfs( if (error) goto out_log_dealloc; + /* Enable background inode inactivation workers. */ + xfs_inodegc_start(mp); + /* * Get and sanity-check the root inode. * Save the pointer to it in the mount structure. @@ -942,6 +947,15 @@ xfs_mountfs( xfs_irele(rip); /* Clean out dquots that might be in memory after quotacheck. */ xfs_qm_unmount(mp); + + /* + * Inactivate all inodes that might still be in memory after a log + * intent recovery failure so that reclaim can free them. Metadata + * inodes and the root directory shouldn't need inactivation, but the + * mount failed for some reason, so pull down all the state and flee. + */ + xfs_inodegc_flush(mp); + /* * Flush all inode reclamation work and flush the log. * We have to do this /after/ rtunmount and qm_unmount because those @@ -989,6 +1003,16 @@ xfs_unmountfs( uint64_t resblks; int error; + /* + * Perform all on-disk metadata updates required to inactivate inodes + * that the VFS evicted earlier in the unmount process. Freeing inodes + * and discarding CoW fork preallocations can cause shape changes to + * the free inode and refcount btrees, respectively, so we must finish + * this before we discard the metadata space reservations. Metadata + * inodes and the root directory do not require inactivation. + */ + xfs_inodegc_flush(mp); + xfs_blockgc_stop(mp); xfs_fs_unreserve_ag_blocks(mp); xfs_qm_unmount_quotas(mp); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index ed7064596f94..e6f8675e7a40 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -56,6 +56,17 @@ struct xfs_error_cfg { long retry_timeout; /* in jiffies, -1 = infinite */ }; +/* + * Per-cpu deferred inode inactivation GC lists. + */ +struct xfs_inodegc { + struct llist_head list; + struct work_struct work; + + /* approximate count of inodes in the list */ + unsigned int items; +}; + /* * The struct xfsmount layout is optimised to separate read-mostly variables * from variables that are frequently modified. We put the read-mostly variables @@ -83,6 +94,8 @@ typedef struct xfs_mount { xfs_buftarg_t *m_logdev_targp;/* ptr to log device */ xfs_buftarg_t *m_rtdev_targp; /* ptr to rt device */ struct list_head m_mount_list; /* global mount list */ + void __percpu *m_inodegc; /* percpu inodegc structures */ + /* * Optional cache of rt summary level per bitmap block with the * invariant that m_rsum_cache[bbno] <= the minimum i for which @@ -95,8 +108,9 @@ typedef struct xfs_mount { struct workqueue_struct *m_unwritten_workqueue; struct workqueue_struct *m_cil_workqueue; struct workqueue_struct *m_reclaim_workqueue; - struct workqueue_struct *m_gc_workqueue; struct workqueue_struct *m_sync_workqueue; + struct workqueue_struct *m_blockgc_wq; + struct workqueue_struct *m_inodegc_wq; int m_bsize; /* fs logical block size */ uint8_t m_blkbit_log; /* blocklog + NBBY */ @@ -137,6 +151,7 @@ typedef struct xfs_mount { struct xfs_ino_geometry m_ino_geo; /* inode geometry */ struct xfs_trans_resv m_resv; /* precomputed res values */ /* low free space thresholds */ + unsigned long m_opstate; /* dynamic state flags */ bool m_always_cow; bool m_fail_unmount; bool m_finobt_nores; /* no per-AG finobt resv. */ @@ -259,6 +274,32 @@ typedef struct xfs_mount { #define XFS_MOUNT_DAX_ALWAYS (1ULL << 26) #define XFS_MOUNT_DAX_NEVER (1ULL << 27) +/* + * If set, inactivation worker threads will be scheduled to process queued + * inodegc work. If not, queued inodes remain in memory waiting to be + * processed. + */ +#define XFS_OPSTATE_INODEGC_ENABLED 0 + +#define __XFS_IS_OPSTATE(name, NAME) \ +static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ +{ \ + return test_bit(XFS_OPSTATE_ ## NAME, &mp->m_opstate); \ +} \ +static inline bool xfs_clear_ ## name (struct xfs_mount *mp) \ +{ \ + return test_and_clear_bit(XFS_OPSTATE_ ## NAME, &mp->m_opstate); \ +} \ +static inline bool xfs_set_ ## name (struct xfs_mount *mp) \ +{ \ + return test_and_set_bit(XFS_OPSTATE_ ## NAME, &mp->m_opstate); \ +} + +__XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) + +#define XFS_OPSTATE_STRINGS \ + { (1UL << XFS_OPSTATE_INODEGC_ENABLED), "inodegc" } + /* * Max and min values for mount-option defined I/O * preallocation sizes. diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e0b97e4c8e16..fd39b97c7bb4 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -530,21 +530,29 @@ xfs_init_mount_workqueues( if (!mp->m_reclaim_workqueue) goto out_destroy_cil; - mp->m_gc_workqueue = alloc_workqueue("xfs-gc/%s", - WQ_SYSFS | WQ_UNBOUND | WQ_FREEZABLE | WQ_MEM_RECLAIM, + mp->m_blockgc_wq = alloc_workqueue("xfs-blockgc/%s", + XFS_WQFLAGS(WQ_UNBOUND | WQ_FREEZABLE | WQ_MEM_RECLAIM), 0, mp->m_super->s_id); - if (!mp->m_gc_workqueue) + if (!mp->m_blockgc_wq) goto out_destroy_reclaim; + mp->m_inodegc_wq = alloc_workqueue("xfs-inodegc/%s", + XFS_WQFLAGS(WQ_FREEZABLE | WQ_MEM_RECLAIM), + 1, mp->m_super->s_id); + if (!mp->m_inodegc_wq) + goto out_destroy_blockgc; + mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", XFS_WQFLAGS(WQ_FREEZABLE), 0, mp->m_super->s_id); if (!mp->m_sync_workqueue) - goto out_destroy_eofb; + goto out_destroy_inodegc; return 0; -out_destroy_eofb: - destroy_workqueue(mp->m_gc_workqueue); +out_destroy_inodegc: + destroy_workqueue(mp->m_inodegc_wq); +out_destroy_blockgc: + destroy_workqueue(mp->m_blockgc_wq); out_destroy_reclaim: destroy_workqueue(mp->m_reclaim_workqueue); out_destroy_cil: @@ -562,7 +570,8 @@ xfs_destroy_mount_workqueues( struct xfs_mount *mp) { destroy_workqueue(mp->m_sync_workqueue); - destroy_workqueue(mp->m_gc_workqueue); + destroy_workqueue(mp->m_blockgc_wq); + destroy_workqueue(mp->m_inodegc_wq); destroy_workqueue(mp->m_reclaim_workqueue); destroy_workqueue(mp->m_cil_workqueue); destroy_workqueue(mp->m_unwritten_workqueue); @@ -724,6 +733,8 @@ xfs_fs_sync_fs( { struct xfs_mount *mp = XFS_M(sb); + trace_xfs_fs_sync_fs(mp, __return_address); + /* * Doing anything during the async pass would be counterproductive. */ @@ -740,6 +751,22 @@ xfs_fs_sync_fs( flush_delayed_work(&mp->m_log->l_work); } + /* + * If we are called with page faults frozen out, it means we are about + * to freeze the transaction subsystem. Take the opportunity to shut + * down inodegc because once SB_FREEZE_FS is set it's too late to + * prevent inactivation races with freeze. The fs doesn't get called + * again by the freezing process until after SB_FREEZE_FS has been set, + * so it's now or never. + * + * We don't care if this is a normal syncfs call that does this or + * freeze that does this - we can run this multiple times without issue + * and we won't race with a restart because a restart can only occur + * when the state is either SB_FREEZE_FS or SB_FREEZE_COMPLETE. + */ + if (sb->s_writers.frozen == SB_FREEZE_PAGEFAULT) + xfs_inodegc_stop(mp); + return 0; } @@ -857,6 +884,17 @@ xfs_fs_freeze( xfs_save_resvblks(mp); ret = xfs_log_quiesce(mp); memalloc_nofs_restore(flags); + + /* + * For read-write filesystems, we need to restart the inodegc on error + * because we stopped it at SB_FREEZE_PAGEFAULT level and a thaw is not + * going to be run to restart it now. We are at SB_FREEZE_FS level + * here, so we can restart safely without racing with a stop in + * xfs_fs_sync_fs(). + */ + if (ret && !(mp->m_flags & XFS_MOUNT_RDONLY)) + xfs_inodegc_start(mp); + return ret; } @@ -869,6 +907,14 @@ xfs_fs_unfreeze( xfs_restore_resvblks(mp); xfs_log_work_queue(mp); xfs_blockgc_start(mp); + + /* + * Don't reactivate the inodegc worker on a readonly filesystem because + * inodes are sent directly to reclaim. + */ + if (!(mp->m_flags & XFS_MOUNT_RDONLY)) + xfs_inodegc_start(mp); + return 0; } @@ -994,6 +1040,35 @@ xfs_destroy_percpu_counters( percpu_counter_destroy(&mp->m_delalloc_blks); } +static int +xfs_inodegc_init_percpu( + struct xfs_mount *mp) +{ + struct xfs_inodegc *gc; + int cpu; + + mp->m_inodegc = alloc_percpu(struct xfs_inodegc); + if (!mp->m_inodegc) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + init_llist_head(&gc->list); + gc->items = 0; + INIT_WORK(&gc->work, xfs_inodegc_worker); + } + return 0; +} + +static void +xfs_inodegc_free_percpu( + struct xfs_mount *mp) +{ + if (!mp->m_inodegc) + return; + free_percpu(mp->m_inodegc); +} + static void xfs_fs_put_super( struct super_block *sb) @@ -1011,6 +1086,7 @@ xfs_fs_put_super( xfs_freesb(mp); free_percpu(mp->m_stats.xs_stats); xfs_mount_list_del(mp); + xfs_inodegc_free_percpu(mp); xfs_destroy_percpu_counters(mp); xfs_destroy_mount_workqueues(mp); xfs_close_devices(mp); @@ -1382,6 +1458,10 @@ xfs_fs_fill_super( if (error) goto out_destroy_workqueues; + error = xfs_inodegc_init_percpu(mp); + if (error) + goto out_destroy_counters; + /* * All percpu data structures requiring cleanup when a cpu goes offline * must be allocated before adding this @mp to the cpu-dead handler's @@ -1393,7 +1473,7 @@ xfs_fs_fill_super( mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); if (!mp->m_stats.xs_stats) { error = -ENOMEM; - goto out_destroy_counters; + goto out_destroy_inodegc; } error = xfs_readsb(mp, flags); @@ -1596,8 +1676,10 @@ xfs_fs_fill_super( xfs_freesb(mp); out_free_stats: free_percpu(mp->m_stats.xs_stats); - out_destroy_counters: + out_destroy_inodegc: xfs_mount_list_del(mp); + xfs_inodegc_free_percpu(mp); + out_destroy_counters: xfs_destroy_percpu_counters(mp); out_destroy_workqueues: xfs_destroy_mount_workqueues(mp); @@ -1680,6 +1762,9 @@ xfs_remount_rw( if (error && error != -ENOSPC) return error; + /* Re-enable the background inode inactivation worker. */ + xfs_inodegc_start(mp); + return 0; } @@ -1702,6 +1787,15 @@ xfs_remount_ro( return error; } + /* + * Stop the inodegc background worker. xfs_fs_reconfigure already + * flushed all pending inodegc work when it sync'd the filesystem. + * The VFS holds s_umount, so we know that inodes cannot enter + * xfs_fs_destroy_inode during a remount operation. In readonly mode + * we send inodes straight to reclaim, so no inodes will be queued. + */ + xfs_inodegc_stop(mp); + /* Free the per-AG metadata reservation pool. */ error = xfs_fs_unreserve_ag_blocks(mp); if (error) { @@ -2102,7 +2196,7 @@ xfs_cpu_dead( spin_lock(&xfs_mount_list_lock); list_for_each_entry_safe(mp, n, &xfs_mount_list, m_mount_list) { spin_unlock(&xfs_mount_list_lock); - /* xfs_subsys_dead(mp, cpu); */ + xfs_inodegc_cpu_dead(mp, cpu); spin_lock(&xfs_mount_list_lock); } spin_unlock(&xfs_mount_list_lock); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 19260291ff8b..cd56ac7c39a6 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -157,6 +157,45 @@ DEFINE_PERAG_REF_EVENT(xfs_perag_put); DEFINE_PERAG_REF_EVENT(xfs_perag_set_inode_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_clear_inode_tag); +DECLARE_EVENT_CLASS(xfs_fs_class, + TP_PROTO(struct xfs_mount *mp, void *caller_ip), + TP_ARGS(mp, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long long, mflags) + __field(unsigned long, opstate) + __field(unsigned long, sbflags) + __field(void *, caller_ip) + ), + TP_fast_assign( + if (mp) { + __entry->dev = mp->m_super->s_dev; + __entry->mflags = mp->m_flags; + __entry->opstate = mp->m_opstate; + __entry->sbflags = mp->m_super->s_flags; + } + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d m_flags 0x%llx opstate (%s) s_flags 0x%lx caller %pS", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->mflags, + __print_flags(__entry->opstate, "|", XFS_OPSTATE_STRINGS), + __entry->sbflags, + __entry->caller_ip) +); + +#define DEFINE_FS_EVENT(name) \ +DEFINE_EVENT(xfs_fs_class, name, \ + TP_PROTO(struct xfs_mount *mp, void *caller_ip), \ + TP_ARGS(mp, caller_ip)) +DEFINE_FS_EVENT(xfs_inodegc_flush); +DEFINE_FS_EVENT(xfs_inodegc_start); +DEFINE_FS_EVENT(xfs_inodegc_stop); +DEFINE_FS_EVENT(xfs_inodegc_worker); +DEFINE_FS_EVENT(xfs_inodegc_queue); +DEFINE_FS_EVENT(xfs_inodegc_throttle); +DEFINE_FS_EVENT(xfs_fs_sync_fs); + DECLARE_EVENT_CLASS(xfs_ag_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno), TP_ARGS(mp, agno), @@ -616,14 +655,17 @@ DECLARE_EVENT_CLASS(xfs_inode_class, TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) + __field(unsigned long, iflags) ), TP_fast_assign( __entry->dev = VFS_I(ip)->i_sb->s_dev; __entry->ino = ip->i_ino; + __entry->iflags = ip->i_flags; ), - TP_printk("dev %d:%d ino 0x%llx", + TP_printk("dev %d:%d ino 0x%llx iflags 0x%lx", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->ino) + __entry->ino, + __entry->iflags) ) #define DEFINE_INODE_EVENT(name) \ @@ -667,6 +709,10 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); DEFINE_INODE_EVENT(xfs_inode_set_cowblocks_tag); DEFINE_INODE_EVENT(xfs_inode_clear_cowblocks_tag); DEFINE_INODE_EVENT(xfs_inode_free_cowblocks_invalid); +DEFINE_INODE_EVENT(xfs_inode_set_reclaimable); +DEFINE_INODE_EVENT(xfs_inode_reclaiming); +DEFINE_INODE_EVENT(xfs_inode_set_need_inactive); +DEFINE_INODE_EVENT(xfs_inode_inactivating); /* * ftrace's __print_symbolic requires that all enum values be wrapped in the -- cgit v1.2.3-70-g09d2 From 5c2f387b48f063dd8a0c119d3659df8f3e2d88bb Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 26 Jul 2021 16:49:49 +0200 Subject: MAINTAINERS: repair Miquel Raynal's email address Commit d70c6b026069 ("MAINTAINERS: Add PL353 NAND controller entry") and commit 813d52799ad2 ("MAINTAINERS: Add PL353 SMC entry") adds Miquel Raynal as maintainer with an obvious invalid email address, which can be easily fixed. Repair this copy-and-paste error in Miquel Raynal's email address. Signed-off-by: Lukas Bulwahn Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210726144949.10439-1-lukas.bulwahn@gmail.com --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..10d3fafe056c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1475,7 +1475,7 @@ F: drivers/amba/ F: include/linux/amba/bus.h ARM PRIMECELL PL35X NAND CONTROLLER DRIVER -M: Miquel Raynal +M: Miquel Raynal M: Naga Sureshkumar Relli L: linux-mtd@lists.infradead.org S: Maintained @@ -1483,7 +1483,7 @@ F: Documentation/devicetree/bindings/mtd/arm,pl353-nand-r2p1.yaml F: drivers/mtd/nand/raw/pl35x-nand-controller.c ARM PRIMECELL PL35X SMC DRIVER -M: Miquel Raynal +M: Miquel Raynal M: Naga Sureshkumar Relli L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained -- cgit v1.2.3-70-g09d2 From df12a75a2be915e7c419707bc71fba0fa7548d81 Mon Sep 17 00:00:00 2001 From: Daniel Palmer Date: Thu, 17 Jun 2021 20:08:42 +0900 Subject: mtd: spinand: core: Properly fill the OOB area. The comment in spinand_write_to_cache_op() says that spinand_ondie_ecc_prepare_io_req() should 0xff fill the OOB area but it doesn't. This causes the OOB area to get filled with zeros and anytime the first page in a block the bad block marker is cleared and it becomes a bad block on the next boot. This was observed on Longsys FORSEE branded parts and might be specific to these parts. Signed-off-by: Daniel Palmer Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210617110842.2358461-1-daniel@0x0f.com --- drivers/mtd/nand/spi/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 4af32cfcbd96..2c8685f1f2fa 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -288,6 +288,8 @@ static int spinand_ondie_ecc_prepare_io_req(struct nand_device *nand, struct spinand_device *spinand = nand_to_spinand(nand); bool enable = (req->mode != MTD_OPS_RAW); + memset(spinand->oobbuf, 0xff, nanddev_per_page_oobsize(nand)); + /* Only enable or disable the engine */ return spinand_ecc_enable(spinand, enable); } -- cgit v1.2.3-70-g09d2 From 014665ffd7e84bb2f18912f7285190090e218e4c Mon Sep 17 00:00:00 2001 From: Vladimir Molokov Date: Sun, 1 Aug 2021 22:59:09 +0200 Subject: mtd: rawnand: omap: Fix kernel doc warning on 'calcuate' typo Fix a trivial typo which is reported after enabling W=1 level of warnings: drivers/mtd/nand/raw/omap2.c:927: warning: expecting prototype for omap_calcuate_ecc(). Prototype was for omap_calculate_ecc() instead Signed-off-by: Vladimir Molokov Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210801205909.7102-1-vladimir@molokov.se --- drivers/mtd/nand/raw/omap2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c index b1839eef5b65..b26d4947af02 100644 --- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c @@ -911,7 +911,7 @@ static int omap_correct_data(struct nand_chip *chip, u_char *dat, } /** - * omap_calcuate_ecc - Generate non-inverted ECC bytes. + * omap_calculate_ecc - Generate non-inverted ECC bytes. * @chip: NAND chip object * @dat: The pointer to data on which ecc is computed * @ecc_code: The ecc_code buffer -- cgit v1.2.3-70-g09d2 From 74a021a632b07dd990e85e815b8757921b23db4b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 3 Aug 2021 19:33:00 +0800 Subject: mtd: rawnand: remove never changed ret variable The ret variable used for returning value in the function `meson_nfc_rw_cmd_prepare_and_execute` is never change after initialising. Therefore, we can remove it safely and return 0 at the end of the function. Signed-off-by: Jason Wang Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210803113300.24230-1-wangborong@cdjrlc.com --- drivers/mtd/nand/raw/meson_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 817bddccb775..ac3be92872d0 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -580,7 +580,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, u32 *addrs = nfc->cmdfifo.rw.addrs; u32 cs = nfc->param.chip_select; u32 cmd0, cmd_num, row_start; - int ret = 0, i; + int i; cmd_num = sizeof(struct nand_rw_cmd) / sizeof(int); @@ -620,7 +620,7 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand, meson_nfc_cmd_idle(nfc, nfc->timing.tadl); } - return ret; + return 0; } static int meson_nfc_write_page_sub(struct nand_chip *nand, -- cgit v1.2.3-70-g09d2 From 6bc219b7b2cdd9d45ea15926d32c5e5c1d63881e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Sun, 1 Aug 2021 20:45:07 -0300 Subject: mtdblock: Update old JFFS2 mention in Kconfig JFFS2 can be mounted without 'mtdblock' since a really, really long time. Some git-log archaeology shows that in 2006 it was possible to use 'root=' to mount a JFFS2 rootfs: commit e9482b4374e2596e6f3f1ab30c4ea469f4ac6311 Author: Joern Engel Date: Tue May 30 14:25:46 2006 +0200 [MTD] Allow alternate JFFS2 mount variant for root filesystem. With this patch, "root=mtd3" and "root=mtd:foo" work for a JFFS2 rootfs. However, there are still plenty of tutorials that mention mtdblock, so users are still taking this route. Update the Kconfig to reflect this is no longer needed. Signed-off-by: Ezequiel Garcia Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210801234509.18774-6-ezequiel@collabora.com --- drivers/mtd/Kconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 8bab6f8718a9..3a1f87def25b 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -45,10 +45,9 @@ config MTD_BLOCK on RAM chips in this manner. This block device is a user of MTD devices performing that function. - At the moment, it is also required for the Journalling Flash File - System(s) to obtain a handle on the MTD device when it's mounted - (although JFFS and JFFS2 don't actually use any of the functionality - of the mtdblock device). + Note that mounting a JFFS2 filesystem doesn't require using mtdblock. + It's possible to mount a rootfs using the MTD device on the "root=" + bootargs as "root=mtd2" or "root=mtd:name_of_device". Later, it may be extended to perform read/erase/modify/write cycles on flash chips to emulate a smaller block size. Needless to say, -- cgit v1.2.3-70-g09d2 From 42ba8c3b426342b39341e1b7a97f2387821bff86 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Sun, 1 Aug 2021 20:45:08 -0300 Subject: mtdblock: Add comment about UBI block devices There is a surprisingly large number of tutorials that suggest using mtdblock to mount SquashFS filesystems on flash devices, including NAND devices. Given this approach is suboptimal than using UBI, and given the UBI block device layer was introduced many years ago specifically with this use case in mind, add a small comment inviting users and developers to consider UBI block. Signed-off-by: Ezequiel Garcia Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20210801234509.18774-7-ezequiel@collabora.com --- drivers/mtd/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 3a1f87def25b..796a2eccbef0 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -69,6 +69,9 @@ config MTD_BLOCK_RO You do not need this option for use with the DiskOnChip devices. For those, enable NFTL support (CONFIG_NFTL) instead. +comment "Note that in some cases UBI block is preferred. See MTD_UBI_BLOCK." + depends on MTD_BLOCK || MTD_BLOCK_RO + config FTL tristate "FTL (Flash Translation Layer) support" depends on BLOCK -- cgit v1.2.3-70-g09d2 From 0b9159d0ff21bc281dbb9ede06ad566330ac0943 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Thu, 17 Jun 2021 15:16:18 -0700 Subject: cxl/pci: Store memory capacity values The Identify Memory Device command returns information about the volatile only and persistent only memory capacities. Store those values in the cxl_mem structure for later use. While at it, reuse those calculations to calculate the ram and pmem ranges. Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/20210617221620.1904031-2-ira.weiny@intel.com Signed-off-by: Dan Williams --- drivers/cxl/cxlmem.h | 4 ++++ drivers/cxl/pci.c | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 25345ece25f8..22344fda8ca5 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -95,5 +95,9 @@ struct cxl_mem { struct range pmem_range; struct range ram_range; + u64 total_bytes; + u64 volatile_only_bytes; + u64 persistent_only_bytes; + u64 partition_align_bytes; }; #endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 47315bb2db10..cf4f593f426e 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -64,6 +64,15 @@ enum opcode { CXL_MBOX_OP_MAX = 0x10000 }; +/* + * CXL 2.0 - Memory capacity multiplier + * See Section 8.2.9.5 + * + * Volatile, Persistent, and Partition capacities are specified to be in + * multiples of 256MB - define a multiplier to convert to/from bytes. + */ +#define CXL_CAPACITY_MULTIPLIER SZ_256M + /** * struct mbox_cmd - A command to be submitted to hardware. * @opcode: (input) The command set and command submitted to hardware. @@ -1350,16 +1359,37 @@ static int cxl_mem_identify(struct cxl_mem *cxlm) if (rc < 0) return rc; + cxlm->total_bytes = le64_to_cpu(id.total_capacity); + cxlm->total_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->volatile_only_bytes = le64_to_cpu(id.volatile_capacity); + cxlm->volatile_only_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->persistent_only_bytes = le64_to_cpu(id.persistent_capacity); + cxlm->persistent_only_bytes *= CXL_CAPACITY_MULTIPLIER; + + cxlm->partition_align_bytes = le64_to_cpu(id.partition_align); + cxlm->partition_align_bytes *= CXL_CAPACITY_MULTIPLIER; + + dev_dbg(&cxlm->pdev->dev, "Identify Memory Device\n" + " total_bytes = %#llx\n" + " volatile_only_bytes = %#llx\n" + " persistent_only_bytes = %#llx\n" + " partition_align_bytes = %#llx\n", + cxlm->total_bytes, + cxlm->volatile_only_bytes, + cxlm->persistent_only_bytes, + cxlm->partition_align_bytes); + /* * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias. * For now, only the capacity is exported in sysfs */ cxlm->ram_range.start = 0; - cxlm->ram_range.end = le64_to_cpu(id.volatile_capacity) * SZ_256M - 1; + cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; cxlm->pmem_range.start = 0; - cxlm->pmem_range.end = - le64_to_cpu(id.persistent_capacity) * SZ_256M - 1; + cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1; cxlm->lsa_size = le32_to_cpu(id.lsa_size); memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision)); -- cgit v1.2.3-70-g09d2 From e71ec0bc06038cdfa18cbd23f5cea71fe4785d35 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 30 Jul 2021 10:58:56 +0100 Subject: scripts: coccinelle: allow list_entry_is_head() to use pos Currently use_after_iter.cocci generates false positives for code of the following form: ~~~ list_for_each_entry(d, &ddata->irq_list, node) { if (irq == d->irq) break; } if (list_entry_is_head(d, &ddata->irq_list, node)) return IRQ_NONE; ~~~ [This specific example comes from drivers/power/supply/cpcap-battery.c] Most list macros use list_entry_is_head() as loop exit condition meaning it is not unsafe to reuse pos (a.k.a. d) in the code above. Let's avoid reporting these cases. Signed-off-by: Daniel Thompson Signed-off-by: Julia Lawall --- scripts/coccinelle/iterators/use_after_iter.cocci | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/coccinelle/iterators/use_after_iter.cocci b/scripts/coccinelle/iterators/use_after_iter.cocci index 9be48b520879..676edd562eef 100644 --- a/scripts/coccinelle/iterators/use_after_iter.cocci +++ b/scripts/coccinelle/iterators/use_after_iter.cocci @@ -123,6 +123,8 @@ hlist_for_each_entry_safe(c,...) S | list_remove_head(x,c,...) | +list_entry_is_head(c,...) +| sizeof(<+...c...+>) | &c->member -- cgit v1.2.3-70-g09d2 From 9050ad816f5205c0d069e3e492eb849265ae5167 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 2 Aug 2021 01:33:14 +0200 Subject: mfd: db8500-prcmu: Handle missing FW variant There was an "unknown" firmware variant turning up in the wild causing problems in the clock driver. Add this missing variant and clarify that varian 11 and 15 are Samsung variants, as this is now very well known from released products. Signed-off-by: Linus Walleij Acked-by: Stephen Boyd Signed-off-by: Lee Jones --- drivers/clk/ux500/u8500_of_clk.c | 3 ++- drivers/mfd/db8500-prcmu.c | 6 ++++-- include/linux/mfd/dbx500-prcmu.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 0aedd42fad52..528c5bb397cc 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -99,10 +99,11 @@ static void u8500_clk_init(struct device_node *np) if (fw_version != NULL) { switch (fw_version->project) { case PRCMU_FW_PROJECT_U8500_C2: - case PRCMU_FW_PROJECT_U8500_MBL: + case PRCMU_FW_PROJECT_U8500_SSG1: case PRCMU_FW_PROJECT_U8520: case PRCMU_FW_PROJECT_U8420: case PRCMU_FW_PROJECT_U8420_SYSCLK: + case PRCMU_FW_PROJECT_U8500_SSG2: sgaclk_parent = "soc0_pll"; break; default: diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 82058d11099f..75049cf38832 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -2565,14 +2565,16 @@ static char *fw_project_name(u32 project) return "U8500 C4"; case PRCMU_FW_PROJECT_U9500_MBL: return "U9500 MBL"; - case PRCMU_FW_PROJECT_U8500_MBL: - return "U8500 MBL"; + case PRCMU_FW_PROJECT_U8500_SSG1: + return "U8500 Samsung 1"; case PRCMU_FW_PROJECT_U8500_MBL2: return "U8500 MBL2"; case PRCMU_FW_PROJECT_U8520: return "U8520 MBL"; case PRCMU_FW_PROJECT_U8420: return "U8420"; + case PRCMU_FW_PROJECT_U8500_SSG2: + return "U8500 Samsung 2"; case PRCMU_FW_PROJECT_U8420_SYSCLK: return "U8420-sysclk"; case PRCMU_FW_PROJECT_U9540: diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index e6ee2ec35de9..cbf9d7619493 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -186,10 +186,11 @@ enum ddr_pwrst { #define PRCMU_FW_PROJECT_U8500_C3 8 #define PRCMU_FW_PROJECT_U8500_C4 9 #define PRCMU_FW_PROJECT_U9500_MBL 10 -#define PRCMU_FW_PROJECT_U8500_MBL 11 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8500_SSG1 11 /* Samsung specific */ #define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */ #define PRCMU_FW_PROJECT_U8520 13 #define PRCMU_FW_PROJECT_U8420 14 +#define PRCMU_FW_PROJECT_U8500_SSG2 15 /* Samsung specific */ #define PRCMU_FW_PROJECT_U8420_SYSCLK 17 #define PRCMU_FW_PROJECT_A9420 20 /* [32..63] 9540 and derivatives */ -- cgit v1.2.3-70-g09d2 From 09590463036385a1806a2422807da057519207e1 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:32:55 -0700 Subject: perf bench futex: Group test parameters cleanup Do this across all futex-bench tests such that all program parameters neatly share a common structure, which is nicer than how we have them now. No changes in program behavior are expected. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-2-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-hash.c | 55 ++++++++++++++-------------- tools/perf/bench/futex-lock-pi.c | 53 +++++++++++++-------------- tools/perf/bench/futex-requeue.c | 65 ++++++++++++++++++---------------- tools/perf/bench/futex-wake-parallel.c | 58 +++++++++++++++--------------- tools/perf/bench/futex-wake.c | 57 +++++++++++++++-------------- tools/perf/bench/futex.h | 11 ++++++ 6 files changed, 162 insertions(+), 137 deletions(-) diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index b65373ce5c4f..ddca7558e559 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -29,11 +29,7 @@ #include -static unsigned int nthreads = 0; -static unsigned int nsecs = 10; -/* amount of futexes per thread */ -static unsigned int nfutexes = 1024; -static bool fshared = false, done = false, silent = false; +static bool done = false; static int futex_flag = 0; struct timeval bench__start, bench__end, bench__runtime; @@ -49,12 +45,17 @@ struct worker { unsigned long ops; }; +static struct bench_futex_parameters params = { + .nfutexes = 1024, + .runtime = 10, +}; + static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), - OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), - OPT_UINTEGER('f', "futexes", &nfutexes, "Specify amount of futexes per threads"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads"), + OPT_UINTEGER('r', "runtime", ¶ms.runtime, "Specify runtime (in seconds)"), + OPT_UINTEGER('f', "futexes", ¶ms.nfutexes, "Specify amount of futexes per threads"), + OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_END() }; @@ -78,7 +79,7 @@ static void *workerfn(void *arg) pthread_mutex_unlock(&thread_lock); do { - for (i = 0; i < nfutexes; i++, ops++) { + for (i = 0; i < params.nfutexes; i++, ops++) { /* * We want the futex calls to fail in order to stress * the hashing of uaddr and not measure other steps, @@ -86,7 +87,7 @@ static void *workerfn(void *arg) * the critical region protected by hb->lock. */ ret = futex_wait(&w->futex[i], 1234, NULL, futex_flag); - if (!silent && + if (!params.silent && (!ret || errno != EAGAIN || errno != EWOULDBLOCK)) warn("Non-expected futex return call"); } @@ -112,7 +113,7 @@ static void print_summary(void) double stddev = stddev_stats(&throughput_stats); printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", - !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), + !params.silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), (int)bench__runtime.tv_sec); } @@ -141,30 +142,30 @@ int bench_futex_hash(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - if (!nthreads) /* default to the number of CPUs */ - nthreads = cpu->nr; + if (!params.nthreads) /* default to the number of CPUs */ + params.nthreads = cpu->nr; - worker = calloc(nthreads, sizeof(*worker)); + worker = calloc(params.nthreads, sizeof(*worker)); if (!worker) goto errmem; - if (!fshared) + if (!params.fshared) futex_flag = FUTEX_PRIVATE_FLAG; printf("Run summary [PID %d]: %d threads, each operating on %d [%s] futexes for %d secs.\n\n", - getpid(), nthreads, nfutexes, fshared ? "shared":"private", nsecs); + getpid(), params.nthreads, params.nfutexes, params.fshared ? "shared":"private", params.runtime); init_stats(&throughput_stats); pthread_mutex_init(&thread_lock, NULL); pthread_cond_init(&thread_parent, NULL); pthread_cond_init(&thread_worker, NULL); - threads_starting = nthreads; + threads_starting = params.nthreads; pthread_attr_init(&thread_attr); gettimeofday(&bench__start, NULL); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { worker[i].tid = i; - worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex)); + worker[i].futex = calloc(params.nfutexes, sizeof(*worker[i].futex)); if (!worker[i].futex) goto errmem; @@ -189,10 +190,10 @@ int bench_futex_hash(int argc, const char **argv) pthread_cond_broadcast(&thread_worker); pthread_mutex_unlock(&thread_lock); - sleep(nsecs); + sleep(params.runtime); toggle_done(0, NULL, NULL); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { ret = pthread_join(worker[i].thread, NULL); if (ret) err(EXIT_FAILURE, "pthread_join"); @@ -203,18 +204,18 @@ int bench_futex_hash(int argc, const char **argv) pthread_cond_destroy(&thread_worker); pthread_mutex_destroy(&thread_lock); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { unsigned long t = bench__runtime.tv_sec > 0 ? worker[i].ops / bench__runtime.tv_sec : 0; update_stats(&throughput_stats, t); - if (!silent) { - if (nfutexes == 1) + if (!params.silent) { + if (params.nfutexes == 1) printf("[thread %2d] futex: %p [ %ld ops/sec ]\n", worker[i].tid, &worker[i].futex[0], t); else printf("[thread %2d] futexes: %p ... %p [ %ld ops/sec ]\n", worker[i].tid, &worker[i].futex[0], - &worker[i].futex[nfutexes-1], t); + &worker[i].futex[params.nfutexes-1], t); } zfree(&worker[i].futex); diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 89c6d160379c..ce980df23bb0 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -31,22 +31,23 @@ struct worker { static u_int32_t global_futex = 0; static struct worker *worker; -static unsigned int nsecs = 10; -static bool silent = false, multi = false; -static bool done = false, fshared = false; -static unsigned int nthreads = 0; +static bool done = false; static int futex_flag = 0; static pthread_mutex_t thread_lock; static unsigned int threads_starting; static struct stats throughput_stats; static pthread_cond_t thread_parent, thread_worker; +static struct bench_futex_parameters params = { + .runtime = 10, +}; + static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), - OPT_UINTEGER('r', "runtime", &nsecs, "Specify runtime (in seconds)"), - OPT_BOOLEAN( 'M', "multi", &multi, "Use multiple futexes"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads"), + OPT_UINTEGER('r', "runtime", ¶ms.runtime, "Specify runtime (in seconds)"), + OPT_BOOLEAN( 'M', "multi", ¶ms.multi, "Use multiple futexes"), + OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_END() }; @@ -61,7 +62,7 @@ static void print_summary(void) double stddev = stddev_stats(&throughput_stats); printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n", - !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), + !params.silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg), (int)bench__runtime.tv_sec); } @@ -93,7 +94,7 @@ static void *workerfn(void *arg) ret = futex_lock_pi(w->futex, NULL, futex_flag); if (ret) { /* handle lock acquisition */ - if (!silent) + if (!params.silent) warn("thread %d: Could not lock pi-lock for %p (%d)", w->tid, w->futex, ret); if (done) @@ -104,7 +105,7 @@ static void *workerfn(void *arg) usleep(1); ret = futex_unlock_pi(w->futex, futex_flag); - if (ret && !silent) + if (ret && !params.silent) warn("thread %d: Could not unlock pi-lock for %p (%d)", w->tid, w->futex, ret); ops++; /* account for thread's share of work */ @@ -120,12 +121,12 @@ static void create_threads(struct worker *w, pthread_attr_t thread_attr, cpu_set_t cpuset; unsigned int i; - threads_starting = nthreads; + threads_starting = params.nthreads; - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { worker[i].tid = i; - if (multi) { + if (params.multi) { worker[i].futex = calloc(1, sizeof(u_int32_t)); if (!worker[i].futex) err(EXIT_FAILURE, "calloc"); @@ -164,25 +165,25 @@ int bench_futex_lock_pi(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - if (!nthreads) - nthreads = cpu->nr; + if (!params.nthreads) + params.nthreads = cpu->nr; - worker = calloc(nthreads, sizeof(*worker)); + worker = calloc(params.nthreads, sizeof(*worker)); if (!worker) err(EXIT_FAILURE, "calloc"); - if (!fshared) + if (!params.fshared) futex_flag = FUTEX_PRIVATE_FLAG; printf("Run summary [PID %d]: %d threads doing pi lock/unlock pairing for %d secs.\n\n", - getpid(), nthreads, nsecs); + getpid(), params.nthreads, params.runtime); init_stats(&throughput_stats); pthread_mutex_init(&thread_lock, NULL); pthread_cond_init(&thread_parent, NULL); pthread_cond_init(&thread_worker, NULL); - threads_starting = nthreads; + threads_starting = params.nthreads; pthread_attr_init(&thread_attr); gettimeofday(&bench__start, NULL); @@ -195,10 +196,10 @@ int bench_futex_lock_pi(int argc, const char **argv) pthread_cond_broadcast(&thread_worker); pthread_mutex_unlock(&thread_lock); - sleep(nsecs); + sleep(params.runtime); toggle_done(0, NULL, NULL); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { ret = pthread_join(worker[i].thread, NULL); if (ret) err(EXIT_FAILURE, "pthread_join"); @@ -209,16 +210,16 @@ int bench_futex_lock_pi(int argc, const char **argv) pthread_cond_destroy(&thread_worker); pthread_mutex_destroy(&thread_lock); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { unsigned long t = bench__runtime.tv_sec > 0 ? worker[i].ops / bench__runtime.tv_sec : 0; update_stats(&throughput_stats, t); - if (!silent) + if (!params.silent) printf("[thread %3d] futex: %p [ %ld ops/sec ]\n", worker[i].tid, worker[i].futex, t); - if (multi) + if (params.multi) zfree(&worker[i].futex); } diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 5fa23295ee5f..66747bfe22cf 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -30,25 +30,27 @@ static u_int32_t futex1 = 0, futex2 = 0; -/* - * How many tasks to requeue at a time. - * Default to 1 in order to make the kernel work more. - */ -static unsigned int nrequeue = 1; - static pthread_t *worker; -static bool done = false, silent = false, fshared = false; +static bool done = false; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static struct stats requeuetime_stats, requeued_stats; -static unsigned int threads_starting, nthreads = 0; +static unsigned int threads_starting; static int futex_flag = 0; +static struct bench_futex_parameters params = { + /* + * How many tasks to requeue at a time. + * Default to 1 in order to make the kernel work more. + */ + .nrequeue = 1, +}; + static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), - OPT_UINTEGER('q', "nrequeue", &nrequeue, "Specify amount of threads to requeue at once"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads"), + OPT_UINTEGER('q', "nrequeue", ¶ms.nrequeue, "Specify amount of threads to requeue at once"), + OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_END() }; @@ -65,7 +67,7 @@ static void print_summary(void) printf("Requeued %d of %d threads in %.4f ms (+-%.2f%%)\n", requeued_avg, - nthreads, + params.nthreads, requeuetime_avg / USEC_PER_MSEC, rel_stddev_stats(requeuetime_stddev, requeuetime_avg)); } @@ -89,10 +91,10 @@ static void block_threads(pthread_t *w, cpu_set_t cpuset; unsigned int i; - threads_starting = nthreads; + threads_starting = params.nthreads; /* create and block all threads */ - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { CPU_ZERO(&cpuset); CPU_SET(cpu->map[i % cpu->nr], &cpuset); @@ -132,22 +134,22 @@ int bench_futex_requeue(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - if (!nthreads) - nthreads = cpu->nr; + if (!params.nthreads) + params.nthreads = cpu->nr; - worker = calloc(nthreads, sizeof(*worker)); + worker = calloc(params.nthreads, sizeof(*worker)); if (!worker) err(EXIT_FAILURE, "calloc"); - if (!fshared) + if (!params.fshared) futex_flag = FUTEX_PRIVATE_FLAG; - if (nrequeue > nthreads) - nrequeue = nthreads; + if (params.nrequeue > params.nthreads) + params.nrequeue = params.nthreads; printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " - "%d at a time.\n\n", getpid(), nthreads, - fshared ? "shared":"private", &futex1, &futex2, nrequeue); + "%d at a time.\n\n", getpid(), params.nthreads, + params.fshared ? "shared":"private", &futex1, &futex2, params.nrequeue); init_stats(&requeued_stats); init_stats(&requeuetime_stats); @@ -174,13 +176,14 @@ int bench_futex_requeue(int argc, const char **argv) /* Ok, all threads are patiently blocked, start requeueing */ gettimeofday(&start, NULL); - while (nrequeued < nthreads) { + while (nrequeued < params.nthreads) { /* * Do not wakeup any tasks blocked on futex1, allowing * us to really measure futex_wait functionality. */ nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0, - nrequeue, futex_flag); + params.nrequeue, + futex_flag); } gettimeofday(&end, NULL); @@ -189,17 +192,19 @@ int bench_futex_requeue(int argc, const char **argv) update_stats(&requeued_stats, nrequeued); update_stats(&requeuetime_stats, runtime.tv_usec); - if (!silent) { + if (!params.silent) { printf("[Run %d]: Requeued %d of %d threads in %.4f ms\n", - j + 1, nrequeued, nthreads, runtime.tv_usec / (double)USEC_PER_MSEC); + j + 1, nrequeued, params.nthreads, + runtime.tv_usec / (double)USEC_PER_MSEC); } /* everybody should be blocked on futex2, wake'em up */ nrequeued = futex_wake(&futex2, nrequeued, futex_flag); - if (nthreads != nrequeued) - warnx("couldn't wakeup all tasks (%d/%d)", nrequeued, nthreads); + if (params.nthreads != nrequeued) + warnx("couldn't wakeup all tasks (%d/%d)", + nrequeued, params.nthreads); - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { ret = pthread_join(worker[i], NULL); if (ret) err(EXIT_FAILURE, "pthread_join"); diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 6e6f5247e1fe..958372ad159c 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -47,8 +47,7 @@ static unsigned int nwakes = 1; static u_int32_t futex = 0; static pthread_t *blocked_worker; -static bool done = false, silent = false, fshared = false; -static unsigned int nblocked_threads = 0, nwaking_threads = 0; +static bool done = false; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static pthread_barrier_t barrier; @@ -56,11 +55,13 @@ static struct stats waketime_stats, wakeup_stats; static unsigned int threads_starting; static int futex_flag = 0; +static struct bench_futex_parameters params; + static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nblocked_threads, "Specify amount of threads"), - OPT_UINTEGER('w', "nwakers", &nwaking_threads, "Specify amount of waking threads"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads"), + OPT_UINTEGER('w', "nwakers", ¶ms.nwakes, "Specify amount of waking threads"), + OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_END() }; @@ -96,10 +97,10 @@ static void wakeup_threads(struct thread_data *td, pthread_attr_t thread_attr) pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); - pthread_barrier_init(&barrier, NULL, nwaking_threads + 1); + pthread_barrier_init(&barrier, NULL, params.nwakes + 1); /* create and block all threads */ - for (i = 0; i < nwaking_threads; i++) { + for (i = 0; i < params.nwakes; i++) { /* * Thread creation order will impact per-thread latency * as it will affect the order to acquire the hb spinlock. @@ -112,7 +113,7 @@ static void wakeup_threads(struct thread_data *td, pthread_attr_t thread_attr) pthread_barrier_wait(&barrier); - for (i = 0; i < nwaking_threads; i++) + for (i = 0; i < params.nwakes; i++) if (pthread_join(td[i].worker, NULL)) err(EXIT_FAILURE, "pthread_join"); @@ -143,10 +144,10 @@ static void block_threads(pthread_t *w, pthread_attr_t thread_attr, cpu_set_t cpuset; unsigned int i; - threads_starting = nblocked_threads; + threads_starting = params.nthreads; /* create and block all threads */ - for (i = 0; i < nblocked_threads; i++) { + for (i = 0; i < params.nthreads; i++) { CPU_ZERO(&cpuset); CPU_SET(cpu->map[i % cpu->nr], &cpuset); @@ -167,7 +168,7 @@ static void print_run(struct thread_data *waking_worker, unsigned int run_num) init_stats(&__wakeup_stats); init_stats(&__waketime_stats); - for (i = 0; i < nwaking_threads; i++) { + for (i = 0; i < params.nwakes; i++) { update_stats(&__waketime_stats, waking_worker[i].runtime.tv_usec); update_stats(&__wakeup_stats, waking_worker[i].nwoken); } @@ -178,7 +179,7 @@ static void print_run(struct thread_data *waking_worker, unsigned int run_num) printf("[Run %d]: Avg per-thread latency (waking %d/%d threads) " "in %.4f ms (+-%.2f%%)\n", run_num + 1, wakeup_avg, - nblocked_threads, waketime_avg / USEC_PER_MSEC, + params.nthreads, waketime_avg / USEC_PER_MSEC, rel_stddev_stats(waketime_stddev, waketime_avg)); } @@ -193,7 +194,7 @@ static void print_summary(void) printf("Avg per-thread latency (waking %d/%d threads) in %.4f ms (+-%.2f%%)\n", wakeup_avg, - nblocked_threads, + params.nthreads, waketime_avg / USEC_PER_MSEC, rel_stddev_stats(waketime_stddev, waketime_avg)); } @@ -203,7 +204,7 @@ static void do_run_stats(struct thread_data *waking_worker) { unsigned int i; - for (i = 0; i < nwaking_threads; i++) { + for (i = 0; i < params.nwakes; i++) { update_stats(&waketime_stats, waking_worker[i].runtime.tv_usec); update_stats(&wakeup_stats, waking_worker[i].nwoken); } @@ -242,32 +243,33 @@ int bench_futex_wake_parallel(int argc, const char **argv) if (!cpu) err(EXIT_FAILURE, "calloc"); - if (!nblocked_threads) - nblocked_threads = cpu->nr; + if (!params.nthreads) + params.nthreads = cpu->nr; /* some sanity checks */ - if (nwaking_threads > nblocked_threads || !nwaking_threads) - nwaking_threads = nblocked_threads; + if (params.nwakes > params.nthreads || + !params.nwakes) + params.nwakes = params.nthreads; - if (nblocked_threads % nwaking_threads) + if (params.nthreads % params.nwakes) errx(EXIT_FAILURE, "Must be perfectly divisible"); /* * Each thread will wakeup nwakes tasks in * a single futex_wait call. */ - nwakes = nblocked_threads/nwaking_threads; + nwakes = params.nthreads/params.nwakes; - blocked_worker = calloc(nblocked_threads, sizeof(*blocked_worker)); + blocked_worker = calloc(params.nthreads, sizeof(*blocked_worker)); if (!blocked_worker) err(EXIT_FAILURE, "calloc"); - if (!fshared) + if (!params.fshared) futex_flag = FUTEX_PRIVATE_FLAG; printf("Run summary [PID %d]: blocking on %d threads (at [%s] " "futex %p), %d threads waking up %d at a time.\n\n", - getpid(), nblocked_threads, fshared ? "shared":"private", - &futex, nwaking_threads, nwakes); + getpid(), params.nthreads, params.fshared ? "shared":"private", + &futex, params.nwakes, nwakes); init_stats(&wakeup_stats); init_stats(&waketime_stats); @@ -278,7 +280,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) pthread_cond_init(&thread_worker, NULL); for (j = 0; j < bench_repeat && !done; j++) { - waking_worker = calloc(nwaking_threads, sizeof(*waking_worker)); + waking_worker = calloc(params.nwakes, sizeof(*waking_worker)); if (!waking_worker) err(EXIT_FAILURE, "calloc"); @@ -297,14 +299,14 @@ int bench_futex_wake_parallel(int argc, const char **argv) /* Ok, all threads are patiently blocked, start waking folks up */ wakeup_threads(waking_worker, thread_attr); - for (i = 0; i < nblocked_threads; i++) { + for (i = 0; i < params.nthreads; i++) { ret = pthread_join(blocked_worker[i], NULL); if (ret) err(EXIT_FAILURE, "pthread_join"); } do_run_stats(waking_worker); - if (!silent) + if (!params.silent) print_run(waking_worker, j); free(waking_worker); diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 6d217868f53c..9ed4d65416f3 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -31,25 +31,27 @@ /* all threads will block on the same futex */ static u_int32_t futex1 = 0; -/* - * How many wakeups to do at a time. - * Default to 1 in order to make the kernel work more. - */ -static unsigned int nwakes = 1; - -pthread_t *worker; -static bool done = false, silent = false, fshared = false; +static pthread_t *worker; +static bool done = false; static pthread_mutex_t thread_lock; static pthread_cond_t thread_parent, thread_worker; static struct stats waketime_stats, wakeup_stats; -static unsigned int threads_starting, nthreads = 0; +static unsigned int threads_starting; static int futex_flag = 0; +static struct bench_futex_parameters params = { + /* + * How many wakeups to do at a time. + * Default to 1 in order to make the kernel work more. + */ + .nwakes = 1, +}; + static const struct option options[] = { - OPT_UINTEGER('t', "threads", &nthreads, "Specify amount of threads"), - OPT_UINTEGER('w', "nwakes", &nwakes, "Specify amount of threads to wake at once"), - OPT_BOOLEAN( 's', "silent", &silent, "Silent mode: do not display data/details"), - OPT_BOOLEAN( 'S', "shared", &fshared, "Use shared futexes instead of private ones"), + OPT_UINTEGER('t', "threads", ¶ms.nthreads, "Specify amount of threads"), + OPT_UINTEGER('w', "nwakes", ¶ms.nwakes, "Specify amount of threads to wake at once"), + OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), + OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_END() }; @@ -84,7 +86,7 @@ static void print_summary(void) printf("Wokeup %d of %d threads in %.4f ms (+-%.2f%%)\n", wakeup_avg, - nthreads, + params.nthreads, waketime_avg / USEC_PER_MSEC, rel_stddev_stats(waketime_stddev, waketime_avg)); } @@ -95,10 +97,10 @@ static void block_threads(pthread_t *w, cpu_set_t cpuset; unsigned int i; - threads_starting = nthreads; + threads_starting = params.nthreads; /* create and block all threads */ - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { CPU_ZERO(&cpuset); CPU_SET(cpu->map[i % cpu->nr], &cpuset); @@ -140,19 +142,20 @@ int bench_futex_wake(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); - if (!nthreads) - nthreads = cpu->nr; + if (!params.nthreads) + params.nthreads = cpu->nr; - worker = calloc(nthreads, sizeof(*worker)); + worker = calloc(params.nthreads, sizeof(*worker)); if (!worker) err(EXIT_FAILURE, "calloc"); - if (!fshared) + if (!params.fshared) futex_flag = FUTEX_PRIVATE_FLAG; printf("Run summary [PID %d]: blocking on %d threads (at [%s] futex %p), " "waking up %d at a time.\n\n", - getpid(), nthreads, fshared ? "shared":"private", &futex1, nwakes); + getpid(), params.nthreads, params.fshared ? "shared":"private", + &futex1, params.nwakes); init_stats(&wakeup_stats); init_stats(&waketime_stats); @@ -179,20 +182,22 @@ int bench_futex_wake(int argc, const char **argv) /* Ok, all threads are patiently blocked, start waking folks up */ gettimeofday(&start, NULL); - while (nwoken != nthreads) - nwoken += futex_wake(&futex1, nwakes, futex_flag); + while (nwoken != params.nthreads) + nwoken += futex_wake(&futex1, + params.nwakes, futex_flag); gettimeofday(&end, NULL); timersub(&end, &start, &runtime); update_stats(&wakeup_stats, nwoken); update_stats(&waketime_stats, runtime.tv_usec); - if (!silent) { + if (!params.silent) { printf("[Run %d]: Wokeup %d of %d threads in %.4f ms\n", - j + 1, nwoken, nthreads, runtime.tv_usec / (double)USEC_PER_MSEC); + j + 1, nwoken, params.nthreads, + runtime.tv_usec / (double)USEC_PER_MSEC); } - for (i = 0; i < nthreads; i++) { + for (i = 0; i < params.nthreads; i++) { ret = pthread_join(worker[i], NULL); if (ret) err(EXIT_FAILURE, "pthread_join"); diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index 31b53cc7d5bc..5f98653e6bb3 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -13,6 +13,17 @@ #include #include +struct bench_futex_parameters { + bool silent; + bool fshared; + bool multi; /* lock-pi */ + unsigned int runtime; /* seconds*/ + unsigned int nthreads; + unsigned int nfutexes; + unsigned int nwakes; + unsigned int nrequeue; +}; + /** * futex() - SYS_futex syscall wrapper * @uaddr: address of first futex -- cgit v1.2.3-70-g09d2 From b2105a75703ebe098710beedc7a1685f67010675 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:32:56 -0700 Subject: perf bench futex: Remove bogus backslash from comment It obviously doesn't belong there. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-3-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index 5f98653e6bb3..6f8b85b67348 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -31,7 +31,7 @@ struct bench_futex_parameters { * @val: typically expected value of uaddr, but varies by op * @timeout: typically an absolute struct timespec (except where noted * otherwise). Overloaded by some ops - * @uaddr2: address of second futex for some ops\ + * @uaddr2: address of second futex for some ops * @val3: varies by op * @opflags: flags to be bitwise OR'd with op, such as FUTEX_PRIVATE_FLAG * -- cgit v1.2.3-70-g09d2 From 9f9a3ffe94f263388b99cb75e4ec374e31aaeb0f Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:32:58 -0700 Subject: perf bench futex: Add --mlockall parameter This adds, across all futex benchmarks, the -m/--mlockall option which is a common operation for realtime workloads by not incurring in page faults in paths that want determinism. As such, threads started after a call to mlockall(2) will generate page faults immediately since the new stack is immediately forced to memory, due to the MCL_FUTURE flag. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-5-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-hash.c | 7 +++++++ tools/perf/bench/futex-lock-pi.c | 7 +++++++ tools/perf/bench/futex-requeue.c | 7 +++++++ tools/perf/bench/futex-wake-parallel.c | 8 ++++++++ tools/perf/bench/futex-wake.c | 8 ++++++++ tools/perf/bench/futex.h | 1 + 6 files changed, 38 insertions(+) diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index ddca7558e559..fcdea3e44937 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "../util/stat.h" @@ -56,6 +57,7 @@ static const struct option options[] = { OPT_UINTEGER('f', "futexes", ¶ms.nfutexes, "Specify amount of futexes per threads"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), OPT_END() }; @@ -142,6 +144,11 @@ int bench_futex_hash(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); + if (params.mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + err(EXIT_FAILURE, "mlockall"); + } + if (!params.nthreads) /* default to the number of CPUs */ params.nthreads = cpu->nr; diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index ce980df23bb0..5d1fe9c35807 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -21,6 +21,7 @@ #include #include #include +#include struct worker { int tid; @@ -48,6 +49,7 @@ static const struct option options[] = { OPT_BOOLEAN( 'M', "multi", ¶ms.multi, "Use multiple futexes"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), OPT_END() }; @@ -165,6 +167,11 @@ int bench_futex_lock_pi(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); + if (params.mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + err(EXIT_FAILURE, "mlockall"); + } + if (!params.nthreads) params.nthreads = cpu->nr; diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 66747bfe22cf..73d4a6c3fe52 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -27,6 +27,7 @@ #include #include #include +#include static u_int32_t futex1 = 0, futex2 = 0; @@ -51,6 +52,7 @@ static const struct option options[] = { OPT_UINTEGER('q', "nrequeue", ¶ms.nrequeue, "Specify amount of threads to requeue at once"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), OPT_END() }; @@ -134,6 +136,11 @@ int bench_futex_requeue(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); + if (params.mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + err(EXIT_FAILURE, "mlockall"); + } + if (!params.nthreads) params.nthreads = cpu->nr; diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 958372ad159c..e970e6b9ad53 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -34,6 +34,7 @@ int bench_futex_wake_parallel(int argc __maybe_unused, const char **argv __maybe #include #include #include +#include struct thread_data { pthread_t worker; @@ -62,6 +63,8 @@ static const struct option options[] = { OPT_UINTEGER('w', "nwakers", ¶ms.nwakes, "Specify amount of waking threads"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), + OPT_END() }; @@ -239,6 +242,11 @@ int bench_futex_wake_parallel(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); + if (params.mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + err(EXIT_FAILURE, "mlockall"); + } + cpu = perf_cpu_map__new(NULL); if (!cpu) err(EXIT_FAILURE, "calloc"); diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 9ed4d65416f3..77f058a47790 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -27,6 +27,7 @@ #include #include #include +#include /* all threads will block on the same futex */ static u_int32_t futex1 = 0; @@ -52,6 +53,8 @@ static const struct option options[] = { OPT_UINTEGER('w', "nwakes", ¶ms.nwakes, "Specify amount of threads to wake at once"), OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), + OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), + OPT_END() }; @@ -142,6 +145,11 @@ int bench_futex_wake(int argc, const char **argv) act.sa_sigaction = toggle_done; sigaction(SIGINT, &act, NULL); + if (params.mlockall) { + if (mlockall(MCL_CURRENT | MCL_FUTURE)) + err(EXIT_FAILURE, "mlockall"); + } + if (!params.nthreads) params.nthreads = cpu->nr; diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index 6f8b85b67348..fca4eee5e040 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -16,6 +16,7 @@ struct bench_futex_parameters { bool silent; bool fshared; + bool mlockall; bool multi; /* lock-pi */ unsigned int runtime; /* seconds*/ unsigned int nthreads; -- cgit v1.2.3-70-g09d2 From d262e6a93b3ceb3db7e6388d89352801f02c3260 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:32:59 -0700 Subject: perf bench futex, requeue: Add --broadcast option Such that all threads are requeued to uaddr2 in a single futex_cmp_requeue(), unlike the default, which is 1. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-6-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-requeue.c | 4 ++++ tools/perf/bench/futex.h | 1 + 2 files changed, 5 insertions(+) diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 73d4a6c3fe52..6606569e7ccc 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -53,6 +53,7 @@ static const struct option options[] = { OPT_BOOLEAN( 's', "silent", ¶ms.silent, "Silent mode: do not display data/details"), OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), + OPT_BOOLEAN( 'B', "broadcast", ¶ms.broadcast, "Requeue all threads at once"), OPT_END() }; @@ -154,6 +155,9 @@ int bench_futex_requeue(int argc, const char **argv) if (params.nrequeue > params.nthreads) params.nrequeue = params.nthreads; + if (params.broadcast) + params.nrequeue = params.nthreads; + printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " "%d at a time.\n\n", getpid(), params.nthreads, params.fshared ? "shared":"private", &futex1, &futex2, params.nrequeue); diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index fca4eee5e040..40a89f192c53 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -18,6 +18,7 @@ struct bench_futex_parameters { bool fshared; bool mlockall; bool multi; /* lock-pi */ + bool broadcast; /* requeue */ unsigned int runtime; /* seconds*/ unsigned int nthreads; unsigned int nfutexes; -- cgit v1.2.3-70-g09d2 From 6f9661b25b1741b180bdaeb85853905078cfd9d8 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:33:00 -0700 Subject: perf bench futex, requeue: Robustify futex_wait() handling Do not assume success and account for EAGAIN or any other return value, however unlikely. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-7-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-requeue.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 6606569e7ccc..e23a08037de2 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -77,6 +77,8 @@ static void print_summary(void) static void *workerfn(void *arg __maybe_unused) { + int ret; + pthread_mutex_lock(&thread_lock); threads_starting--; if (!threads_starting) @@ -84,7 +86,18 @@ static void *workerfn(void *arg __maybe_unused) pthread_cond_wait(&thread_worker, &thread_lock); pthread_mutex_unlock(&thread_lock); - futex_wait(&futex1, 0, NULL, futex_flag); + while (1) { + ret = futex_wait(&futex1, 0, NULL, futex_flag); + if (!ret) + break; + + if (ret && errno != EAGAIN) { + if (!params.silent) + warn("futex_wait"); + break; + } + } + return NULL; } -- cgit v1.2.3-70-g09d2 From 46f815323b5a8f0e7156f50ea87c354424210e97 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Sun, 8 Aug 2021 21:33:01 -0700 Subject: perf bench futex, requeue: Add --pi parameter This extends the program to measure WAIT_REQUEUE_PI+CMP_REQUEUE_PI pairs, which are the underlying machinery behind priority-inheritance aware condition variables. The defaults are the same as with the regular non-pi version, requeueing one task at a time, with the exception that PI will always wakeup the first waiter. Signed-off-by: Davidlohr Bueso Cc: Davidlohr Bueso Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lore.kernel.org/lkml/20210809043301.66002-8-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/futex-requeue.c | 100 +++++++++++++++++++++++++++++---------- tools/perf/bench/futex.h | 37 ++++++++++++++- 2 files changed, 111 insertions(+), 26 deletions(-) diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index e23a08037de2..97fe31fd3a23 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -6,7 +6,8 @@ * on futex2, N at a time. * * This program is particularly useful to measure the latency of nthread - * requeues without waking up any tasks -- thus mimicking a regular futex_wait. + * requeues without waking up any tasks (in the non-pi case) -- thus + * mimicking a regular futex_wait. */ /* For the CLR_() macros */ @@ -54,6 +55,8 @@ static const struct option options[] = { OPT_BOOLEAN( 'S', "shared", ¶ms.fshared, "Use shared futexes instead of private ones"), OPT_BOOLEAN( 'm', "mlockall", ¶ms.mlockall, "Lock all current and future memory"), OPT_BOOLEAN( 'B', "broadcast", ¶ms.broadcast, "Requeue all threads at once"), + OPT_BOOLEAN( 'p', "pi", ¶ms.pi, "Use PI-aware variants of FUTEX_CMP_REQUEUE"), + OPT_END() }; @@ -87,14 +90,30 @@ static void *workerfn(void *arg __maybe_unused) pthread_mutex_unlock(&thread_lock); while (1) { - ret = futex_wait(&futex1, 0, NULL, futex_flag); - if (!ret) - break; - - if (ret && errno != EAGAIN) { - if (!params.silent) - warn("futex_wait"); - break; + if (!params.pi) { + ret = futex_wait(&futex1, 0, NULL, futex_flag); + if (!ret) + break; + + if (ret && errno != EAGAIN) { + if (!params.silent) + warnx("futex_wait"); + break; + } + } else { + ret = futex_wait_requeue_pi(&futex1, 0, &futex2, + NULL, futex_flag); + if (!ret) { + /* got the lock at futex2 */ + futex_unlock_pi(&futex2, futex_flag); + break; + } + + if (ret && errno != EAGAIN) { + if (!params.silent) + warnx("futex_wait_requeue_pi"); + break; + } } } @@ -171,9 +190,10 @@ int bench_futex_requeue(int argc, const char **argv) if (params.broadcast) params.nrequeue = params.nthreads; - printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %p), " + printf("Run summary [PID %d]: Requeuing %d threads (from [%s] %p to %s%p), " "%d at a time.\n\n", getpid(), params.nthreads, - params.fshared ? "shared":"private", &futex1, &futex2, params.nrequeue); + params.fshared ? "shared":"private", &futex1, + params.pi ? "PI ": "", &futex2, params.nrequeue); init_stats(&requeued_stats); init_stats(&requeuetime_stats); @@ -183,7 +203,7 @@ int bench_futex_requeue(int argc, const char **argv) pthread_cond_init(&thread_worker, NULL); for (j = 0; j < bench_repeat && !done; j++) { - unsigned int nrequeued = 0; + unsigned int nrequeued = 0, wakeups = 0; struct timeval start, end, runtime; /* create, launch & block all threads */ @@ -201,13 +221,30 @@ int bench_futex_requeue(int argc, const char **argv) /* Ok, all threads are patiently blocked, start requeueing */ gettimeofday(&start, NULL); while (nrequeued < params.nthreads) { + int r; + /* - * Do not wakeup any tasks blocked on futex1, allowing - * us to really measure futex_wait functionality. + * For the regular non-pi case, do not wakeup any tasks + * blocked on futex1, allowing us to really measure + * futex_wait functionality. For the PI case the first + * waiter is always awoken. */ - nrequeued += futex_cmp_requeue(&futex1, 0, &futex2, 0, - params.nrequeue, - futex_flag); + if (!params.pi) { + r = futex_cmp_requeue(&futex1, 0, &futex2, 0, + params.nrequeue, + futex_flag); + } else { + r = futex_cmp_requeue_pi(&futex1, 0, &futex2, + params.nrequeue, + futex_flag); + wakeups++; /* assume no error */ + } + + if (r < 0) + err(EXIT_FAILURE, "couldn't requeue from %p to %p", + &futex1, &futex2); + + nrequeued += r; } gettimeofday(&end, NULL); @@ -217,16 +254,29 @@ int bench_futex_requeue(int argc, const char **argv) update_stats(&requeuetime_stats, runtime.tv_usec); if (!params.silent) { - printf("[Run %d]: Requeued %d of %d threads in %.4f ms\n", - j + 1, nrequeued, params.nthreads, - runtime.tv_usec / (double)USEC_PER_MSEC); + if (!params.pi) + printf("[Run %d]: Requeued %d of %d threads in " + "%.4f ms\n", j + 1, nrequeued, + params.nthreads, + runtime.tv_usec / (double)USEC_PER_MSEC); + else { + nrequeued -= wakeups; + printf("[Run %d]: Awoke and Requeued (%d+%d) of " + "%d threads in %.4f ms\n", + j + 1, wakeups, nrequeued, + params.nthreads, + runtime.tv_usec / (double)USEC_PER_MSEC); + } + } - /* everybody should be blocked on futex2, wake'em up */ - nrequeued = futex_wake(&futex2, nrequeued, futex_flag); - if (params.nthreads != nrequeued) - warnx("couldn't wakeup all tasks (%d/%d)", - nrequeued, params.nthreads); + if (!params.pi) { + /* everybody should be blocked on futex2, wake'em up */ + nrequeued = futex_wake(&futex2, nrequeued, futex_flag); + if (params.nthreads != nrequeued) + warnx("couldn't wakeup all tasks (%d/%d)", + nrequeued, params.nthreads); + } for (i = 0; i < params.nthreads; i++) { ret = pthread_join(worker[i], NULL); diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index 40a89f192c53..b3853aac3021 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -18,6 +18,7 @@ struct bench_futex_parameters { bool fshared; bool mlockall; bool multi; /* lock-pi */ + bool pi; /* requeue-pi */ bool broadcast; /* requeue */ unsigned int runtime; /* seconds*/ unsigned int nthreads; @@ -90,7 +91,7 @@ futex_unlock_pi(u_int32_t *uaddr, int opflags) /** * futex_cmp_requeue() - requeue tasks from uaddr to uaddr2 * @nr_wake: wake up to this many tasks -* @nr_requeue: requeue up to this many tasks +* @nr_requeue: requeue up to this many tasks */ static inline int futex_cmp_requeue(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, int nr_wake, @@ -99,4 +100,38 @@ futex_cmp_requeue(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, int nr_wak return futex(uaddr, FUTEX_CMP_REQUEUE, nr_wake, nr_requeue, uaddr2, val, opflags); } + +/** + * futex_wait_requeue_pi() - block on uaddr and prepare to requeue to uaddr2 + * @uaddr: non-PI futex source + * @uaddr2: PI futex target + * + * This is the first half of the requeue_pi mechanism. It shall always be + * paired with futex_cmp_requeue_pi(). + */ +static inline int +futex_wait_requeue_pi(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, + struct timespec *timeout, int opflags) +{ + return futex(uaddr, FUTEX_WAIT_REQUEUE_PI, val, timeout, uaddr2, 0, + opflags); +} + +/** + * futex_cmp_requeue_pi() - requeue tasks from uaddr to uaddr2 + * @uaddr: non-PI futex source + * @uaddr2: PI futex target + * @nr_requeue: requeue up to this many tasks + * + * This is the second half of the requeue_pi mechanism. It shall always be + * paired with futex_wait_requeue_pi(). The first waker is always awoken. + */ +static inline int +futex_cmp_requeue_pi(u_int32_t *uaddr, u_int32_t val, u_int32_t *uaddr2, + int nr_requeue, int opflags) +{ + return futex(uaddr, FUTEX_CMP_REQUEUE_PI, 1, nr_requeue, uaddr2, + val, opflags); +} + #endif /* _FUTEX_H */ -- cgit v1.2.3-70-g09d2 From 1d7db834a027ecfb5ac93be2e8bb45bfcbbf6eaa Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Thu, 22 Jul 2021 18:55:12 +0800 Subject: dma-debug: use memory_intersects() directly There is already a memory_intersects() helper in sections.h, use memory_intersects() directly instead of private overlap(). Signed-off-by: Kefeng Wang Signed-off-by: Christoph Hellwig --- kernel/dma/debug.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index dadae6255d05..fe6efd181614 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -1064,20 +1064,10 @@ static void check_for_stack(struct device *dev, } } -static inline bool overlap(void *addr, unsigned long len, void *start, void *end) -{ - unsigned long a1 = (unsigned long)addr; - unsigned long b1 = a1 + len; - unsigned long a2 = (unsigned long)start; - unsigned long b2 = (unsigned long)end; - - return !(b1 <= a2 || a1 >= b2); -} - static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len) { - if (overlap(addr, len, _stext, _etext) || - overlap(addr, len, __start_rodata, __end_rodata)) + if (memory_intersects(_stext, _etext, addr, len) || + memory_intersects(__start_rodata, __end_rodata, addr, len)) err_printk(dev, NULL, "device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len); } -- cgit v1.2.3-70-g09d2 From 173735c346c412d9f084825ecb04f24ada0e2986 Mon Sep 17 00:00:00 2001 From: Anthony Iliopoulos Date: Thu, 22 Jul 2021 16:10:55 +0200 Subject: dma-debug: fix debugfs initialization order Due to link order, dma_debug_init is called before debugfs has a chance to initialize (via debugfs_init which also happens in the core initcall stage), so the directories for dma-debug are never created. Decouple dma_debug_fs_init from dma_debug_init and defer its init until core_initcall_sync (after debugfs has been initialized) while letting dma-debug initialization occur as soon as possible to catch any early mappings, as suggested in [1]. [1] https://lore.kernel.org/linux-iommu/YIgGa6yF%2Fadg8OSN@kroah.com/ Fixes: 15b28bbcd567 ("dma-debug: move initialization to common code") Signed-off-by: Anthony Iliopoulos Signed-off-by: Christoph Hellwig --- kernel/dma/debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index fe6efd181614..6c90c69e5311 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -792,7 +792,7 @@ static int dump_show(struct seq_file *seq, void *v) } DEFINE_SHOW_ATTRIBUTE(dump); -static void dma_debug_fs_init(void) +static int __init dma_debug_fs_init(void) { struct dentry *dentry = debugfs_create_dir("dma-api", NULL); @@ -805,7 +805,10 @@ static void dma_debug_fs_init(void) debugfs_create_u32("nr_total_entries", 0444, dentry, &nr_total_entries); debugfs_create_file("driver_filter", 0644, dentry, NULL, &filter_fops); debugfs_create_file("dump", 0444, dentry, NULL, &dump_fops); + + return 0; } +core_initcall_sync(dma_debug_fs_init); static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry) { @@ -890,8 +893,6 @@ static int dma_debug_init(void) spin_lock_init(&dma_entry_hash[i].lock); } - dma_debug_fs_init(); - nr_pages = DIV_ROUND_UP(nr_prealloc_entries, DMA_DEBUG_DYNAMIC_ENTRIES); for (i = 0; i < nr_pages; ++i) dma_debug_create_entries(GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From fffe3cc8c2194f60c4af4fac7f27d25e8828f001 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:19 -0600 Subject: dma-mapping: allow map_sg() ops to return negative error codes Allow dma_map_sgtable() to pass errors from the map_sg() ops. This will be required for returning appropriate error codes when mapping P2PDMA memory. Introduce __dma_map_sg_attrs() which will return the raw error code from the map_sg operation (whether it be negative or zero). Then add a dma_map_sg_attrs() wrapper to convert any negative errors to zero to satisfy the existing calling convention. dma_map_sgtable() defines three error codes that .map_sg implementations are allowed to return: -EINVAL, -ENOMEM and -EIO. The latter of which is a generic return for cases that are passing DMA_MAPPING_ERROR through. dma_map_sgtable() will convert a zero error return for old map_sg() ops into a -EIO return and return any negative errors as reported. This allows map_sg implementations to start returning multiple negative error codes. Legacy map_sg implementations can continue to return zero until they are all converted. Signed-off-by: Logan Gunthorpe Signed-off-by: Christoph Hellwig --- include/linux/dma-map-ops.h | 5 +-- include/linux/dma-mapping.h | 35 ++++--------------- kernel/dma/mapping.c | 82 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 84 insertions(+), 38 deletions(-) diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index 0d53a96a3d64..2f842498c448 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -41,8 +41,9 @@ struct dma_map_ops { size_t size, enum dma_data_direction dir, unsigned long attrs); /* - * map_sg returns 0 on error and a value > 0 on success. - * It should never return a value < 0. + * map_sg should return a negative error code on error. See + * dma_map_sgtable() for a list of appropriate error codes + * and their meanings. */ int (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 183e7103a66d..daa1e360f0ee 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -110,6 +110,8 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs); +int dma_map_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs); dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size, enum dma_data_direction dir, unsigned long attrs); void dma_unmap_resource(struct device *dev, dma_addr_t addr, size_t size, @@ -174,6 +176,11 @@ static inline void dma_unmap_sg_attrs(struct device *dev, unsigned long attrs) { } +static inline int dma_map_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs) +{ + return -EOPNOTSUPP; +} static inline dma_addr_t dma_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) @@ -343,34 +350,6 @@ static inline void dma_sync_single_range_for_device(struct device *dev, return dma_sync_single_for_device(dev, addr + offset, size, dir); } -/** - * dma_map_sgtable - Map the given buffer for DMA - * @dev: The device for which to perform the DMA operation - * @sgt: The sg_table object describing the buffer - * @dir: DMA direction - * @attrs: Optional DMA attributes for the map operation - * - * Maps a buffer described by a scatterlist stored in the given sg_table - * object for the @dir DMA operation by the @dev device. After success the - * ownership for the buffer is transferred to the DMA domain. One has to - * call dma_sync_sgtable_for_cpu() or dma_unmap_sgtable() to move the - * ownership of the buffer back to the CPU domain before touching the - * buffer by the CPU. - * - * Returns 0 on success or -EINVAL on error during mapping the buffer. - */ -static inline int dma_map_sgtable(struct device *dev, struct sg_table *sgt, - enum dma_data_direction dir, unsigned long attrs) -{ - int nents; - - nents = dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); - if (nents <= 0) - return -EINVAL; - sgt->nents = nents; - return 0; -} - /** * dma_unmap_sgtable - Unmap the given buffer for DMA * @dev: The device for which to perform the DMA operation diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 2b06a809d0b9..21e550076be5 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -177,12 +177,8 @@ void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr, size_t size, } EXPORT_SYMBOL(dma_unmap_page_attrs); -/* - * dma_maps_sg_attrs returns 0 on error and > 0 on success. - * It should never return a value < 0. - */ -int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction dir, unsigned long attrs) +static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, unsigned long attrs) { const struct dma_map_ops *ops = get_dma_ops(dev); int ents; @@ -197,13 +193,83 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, ents = dma_direct_map_sg(dev, sg, nents, dir, attrs); else ents = ops->map_sg(dev, sg, nents, dir, attrs); - BUG_ON(ents < 0); - debug_dma_map_sg(dev, sg, nents, ents, dir); + + if (ents > 0) + debug_dma_map_sg(dev, sg, nents, ents, dir); + else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM && + ents != -EIO && ents != 0)) + return -EIO; return ents; } + +/** + * dma_map_sg_attrs - Map the given buffer for DMA + * @dev: The device for which to perform the DMA operation + * @sg: The sg_table object describing the buffer + * @dir: DMA direction + * @attrs: Optional DMA attributes for the map operation + * + * Maps a buffer described by a scatterlist passed in the sg argument with + * nents segments for the @dir DMA operation by the @dev device. + * + * Returns the number of mapped entries (which can be less than nents) + * on success. Zero is returned for any error. + * + * dma_unmap_sg_attrs() should be used to unmap the buffer with the + * original sg and original nents (not the value returned by this funciton). + */ +int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction dir, unsigned long attrs) +{ + int ret; + + ret = __dma_map_sg_attrs(dev, sg, nents, dir, attrs); + if (ret < 0) + return 0; + return ret; +} EXPORT_SYMBOL(dma_map_sg_attrs); +/** + * dma_map_sgtable - Map the given buffer for DMA + * @dev: The device for which to perform the DMA operation + * @sgt: The sg_table object describing the buffer + * @dir: DMA direction + * @attrs: Optional DMA attributes for the map operation + * + * Maps a buffer described by a scatterlist stored in the given sg_table + * object for the @dir DMA operation by the @dev device. After success, the + * ownership for the buffer is transferred to the DMA domain. One has to + * call dma_sync_sgtable_for_cpu() or dma_unmap_sgtable() to move the + * ownership of the buffer back to the CPU domain before touching the + * buffer by the CPU. + * + * Returns 0 on success or a negative error code on error. The following + * error codes are supported with the given meaning: + * + * -EINVAL - An invalid argument, unaligned access or other error + * in usage. Will not succeed if retried. + * -ENOMEM - Insufficient resources (like memory or IOVA space) to + * complete the mapping. Should succeed if retried later. + * -EIO - Legacy error code with an unknown meaning. eg. this is + * returned if a lower level call returned DMA_MAPPING_ERROR. + */ +int dma_map_sgtable(struct device *dev, struct sg_table *sgt, + enum dma_data_direction dir, unsigned long attrs) +{ + int nents; + + nents = __dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); + if (nents == 0) + return -EIO; + if (nents < 0) + return nents; + sgt->nents = nents; + return 0; +} +EXPORT_SYMBOL_GPL(dma_map_sgtable); + void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs) -- cgit v1.2.3-70-g09d2 From c81be74e7d790f090d3c8a52e20a334dc2506a3f Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:20 -0600 Subject: dma-direct: return appropriate error code from dma_direct_map_sg() Now that the map_sg() op expects error codes instead of return zero on error, convert dma_direct_map_sg() to return an error code. Per the documentation for dma_map_sgtable(), -EIO is returned due to an DMA_MAPPING_ERROR with unknown cause. Signed-off-by: Logan Gunthorpe Signed-off-by: Christoph Hellwig --- kernel/dma/direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index f737e3347059..f33ceb68aef2 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -411,7 +411,7 @@ int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, int nents, out_unmap: dma_direct_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); - return 0; + return -EIO; } dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr, -- cgit v1.2.3-70-g09d2 From ad8f36e4b6b1c826a0daa5fda2c5839205b5aa8b Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:21 -0600 Subject: iommu: return full error code from iommu_map_sg[_atomic]() Convert to ssize_t return code so the return code from __iommu_map() can be returned all the way down through dma_iommu_map_sg(). Signed-off-by: Logan Gunthorpe Cc: Joerg Roedel Cc: Will Deacon Signed-off-by: Christoph Hellwig --- drivers/iommu/iommu.c | 15 +++++++-------- include/linux/iommu.h | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 5419c4b9f27a..bf971b4e34aa 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2567,9 +2567,9 @@ size_t iommu_unmap_fast(struct iommu_domain *domain, } EXPORT_SYMBOL_GPL(iommu_unmap_fast); -static size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot, - gfp_t gfp) +static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot, + gfp_t gfp) { const struct iommu_ops *ops = domain->ops; size_t len = 0, mapped = 0; @@ -2610,19 +2610,18 @@ out_err: /* undo mappings already done */ iommu_unmap(domain, iova, mapped); - return 0; - + return ret; } -size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot) +ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot) { might_sleep(); return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_KERNEL); } EXPORT_SYMBOL_GPL(iommu_map_sg); -size_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova, +ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot) { return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 32d448050bf7..9369458ba1bd 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -414,11 +414,11 @@ extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, extern size_t iommu_unmap_fast(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather); -extern size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg,unsigned int nents, int prot); -extern size_t iommu_map_sg_atomic(struct iommu_domain *domain, - unsigned long iova, struct scatterlist *sg, - unsigned int nents, int prot); +extern ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot); +extern ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, + unsigned long iova, struct scatterlist *sg, + unsigned int nents, int prot); extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova); extern void iommu_set_fault_handler(struct iommu_domain *domain, iommu_fault_handler_t handler, void *token); @@ -679,18 +679,18 @@ static inline size_t iommu_unmap_fast(struct iommu_domain *domain, return 0; } -static inline size_t iommu_map_sg(struct iommu_domain *domain, - unsigned long iova, struct scatterlist *sg, - unsigned int nents, int prot) +static inline ssize_t iommu_map_sg(struct iommu_domain *domain, + unsigned long iova, struct scatterlist *sg, + unsigned int nents, int prot) { - return 0; + return -ENODEV; } -static inline size_t iommu_map_sg_atomic(struct iommu_domain *domain, +static inline ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova, struct scatterlist *sg, unsigned int nents, int prot) { - return 0; + return -ENODEV; } static inline void iommu_flush_iotlb_all(struct iommu_domain *domain) -- cgit v1.2.3-70-g09d2 From dabb16f67215918c48cf3ff1fc4bc36ca421da2b Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:22 -0600 Subject: iommu/dma: return error code from iommu_dma_map_sg() Return appropriate error codes EINVAL or ENOMEM from iommup_dma_map_sg(). If lower level code returns ENOMEM, then we return it, other errors are coalesced into EINVAL. iommu_dma_map_sg_swiotlb() returns -EIO as its an unknown error from a call that returns DMA_MAPPING_ERROR. Signed-off-by: Logan Gunthorpe Cc: Joerg Roedel Cc: Will Deacon Signed-off-by: Christoph Hellwig --- drivers/iommu/dma-iommu.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 98ba927aee1a..168434cf920a 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -972,7 +972,7 @@ static int iommu_dma_map_sg_swiotlb(struct device *dev, struct scatterlist *sg, out_unmap: iommu_dma_unmap_sg_swiotlb(dev, sg, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); - return 0; + return -EIO; } /* @@ -993,11 +993,13 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, dma_addr_t iova; size_t iova_len = 0; unsigned long mask = dma_get_seg_boundary(dev); + ssize_t ret; int i; - if (static_branch_unlikely(&iommu_deferred_attach_enabled) && - iommu_deferred_attach(dev, domain)) - return 0; + if (static_branch_unlikely(&iommu_deferred_attach_enabled)) { + ret = iommu_deferred_attach(dev, domain); + goto out; + } if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) iommu_dma_sync_sg_for_device(dev, sg, nents, dir); @@ -1045,14 +1047,17 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, } iova = iommu_dma_alloc_iova(domain, iova_len, dma_get_mask(dev), dev); - if (!iova) + if (!iova) { + ret = -ENOMEM; goto out_restore_sg; + } /* * We'll leave any physical concatenation to the IOMMU driver's * implementation - it knows better than we do. */ - if (iommu_map_sg_atomic(domain, iova, sg, nents, prot) < iova_len) + ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot); + if (ret < iova_len) goto out_free_iova; return __finalise_sg(dev, sg, nents, iova); @@ -1061,7 +1066,10 @@ out_free_iova: iommu_dma_free_iova(cookie, iova, iova_len, NULL); out_restore_sg: __invalidate_sg(sg, nents); - return 0; +out: + if (ret != -ENOMEM) + return -EINVAL; + return ret; } static void iommu_dma_unmap_sg(struct device *dev, struct scatterlist *sg, -- cgit v1.2.3-70-g09d2 From ca33d26ac640bdf74e5fd0fcd711dbc5ab9f36c0 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:23 -0600 Subject: alpha: return error code from alpha_pci_map_sg() The .map_sg() op now expects an error code instead of zero on failure. pci_map_single_1() can fail for different reasons, but since the only supported type of error return is DMA_MAPPING_ERROR, we coalesce those errors into EIO. ENOMEM is returned when no page tables can be allocated. Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Signed-off-by: Christoph Hellwig --- arch/alpha/kernel/pci_iommu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 35d7b3096d6e..21f9ac101324 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -649,7 +649,9 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg, sg->dma_address = pci_map_single_1(pdev, SG_ENT_VIRT_ADDRESS(sg), sg->length, dac_allowed); - return sg->dma_address != DMA_MAPPING_ERROR; + if (sg->dma_address == DMA_MAPPING_ERROR) + return -EIO; + return 1; } start = sg; @@ -685,8 +687,10 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg, if (out < end) out->dma_length = 0; - if (out - start == 0) + if (out - start == 0) { printk(KERN_WARNING "pci_map_sg failed: no entries?\n"); + return -ENOMEM; + } DBGA("pci_map_sg: %ld entries\n", out - start); return out - start; @@ -699,7 +703,7 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg, entries. Unmap them now. */ if (out > start) pci_unmap_sg(pdev, start, out - start, dir); - return 0; + return -ENOMEM; } /* Unmap a set of streaming mode DMA translations. Again, cpu read -- cgit v1.2.3-70-g09d2 From 6506932b3268001ff15c081aceb47c7f9aa9fb2d Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:24 -0600 Subject: ARM/dma-mapping: return error code from .map_sg() ops The .map_sg() op now expects an error code instead of zero on failure. In the case of a DMA_MAPPING_ERROR, -EIO is returned. Otherwise, -ENOMEM or -EINVAL is returned depending on the error from __map_sg_chunk(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Russell King Cc: Thomas Bogendoerfer Signed-off-by: Christoph Hellwig --- arch/arm/mm/dma-mapping.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c4b8df2ad328..113b9cb3701b 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -980,7 +980,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, { const struct dma_map_ops *ops = get_dma_ops(dev); struct scatterlist *s; - int i, j; + int i, j, ret; for_each_sg(sg, s, nents, i) { #ifdef CONFIG_NEED_SG_DMA_LENGTH @@ -988,15 +988,17 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #endif s->dma_address = ops->map_page(dev, sg_page(s), s->offset, s->length, dir, attrs); - if (dma_mapping_error(dev, s->dma_address)) + if (dma_mapping_error(dev, s->dma_address)) { + ret = -EIO; goto bad_mapping; + } } return nents; bad_mapping: for_each_sg(sg, s, i, j) ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs); - return 0; + return ret; } /** @@ -1622,7 +1624,7 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, bool is_coherent) { struct scatterlist *s = sg, *dma = sg, *start = sg; - int i, count = 0; + int i, count = 0, ret; unsigned int offset = s->offset; unsigned int size = s->offset + s->length; unsigned int max = dma_get_max_seg_size(dev); @@ -1634,8 +1636,10 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, s->dma_length = 0; if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { - if (__map_sg_chunk(dev, start, size, &dma->dma_address, - dir, attrs, is_coherent) < 0) + ret = __map_sg_chunk(dev, start, size, + &dma->dma_address, dir, attrs, + is_coherent); + if (ret < 0) goto bad_mapping; dma->dma_address += offset; @@ -1648,8 +1652,9 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, } size += s->length; } - if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs, - is_coherent) < 0) + ret = __map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs, + is_coherent); + if (ret < 0) goto bad_mapping; dma->dma_address += offset; @@ -1660,7 +1665,9 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, bad_mapping: for_each_sg(sg, s, count, i) __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s)); - return 0; + if (ret == -ENOMEM) + return ret; + return -EINVAL; } /** -- cgit v1.2.3-70-g09d2 From 9cf88ec5e0e876c959389b1e695438f98663b92d Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:25 -0600 Subject: ARM/dma-mapping: don't set failed sg dma_address to DMA_MAPPING_ERROR Setting the ->dma_address to DMA_MAPPING_ERROR is not part of the ->map_sg calling convention, so remove it. Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345@lst.de/ Suggested-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe Cc: Russell King Cc: Thomas Bogendoerfer Signed-off-by: Christoph Hellwig --- arch/arm/mm/dma-mapping.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 113b9cb3701b..4b61541853ea 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1632,7 +1632,6 @@ static int __iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents, for (i = 1; i < nents; i++) { s = sg_next(s); - s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { -- cgit v1.2.3-70-g09d2 From 62af5ca50c29a9be266656dfb88db6d439d129a1 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:26 -0600 Subject: ia64/sba_iommu: return error code from sba_map_sg_attrs() The .map_sg() op now expects an error code instead of zero on failure. In the case of a dma_mapping_error() return -EIO as the actual cause is opaque here. sba_coalesce_chunks() may only presently fail if sba_alloc_range() fails, which in turn only fails if the iommu is out of mapping resources, hence a -ENOMEM is used in that case. Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Michael Ellerman Cc: Niklas Schnelle Cc: Thomas Bogendoerfer Signed-off-by: Christoph Hellwig --- arch/ia64/hp/common/sba_iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 9148ddbf02e5..8ad6946521d8 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1459,7 +1459,7 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, sglist->dma_address = sba_map_page(dev, sg_page(sglist), sglist->offset, sglist->length, dir, attrs); if (dma_mapping_error(dev, sglist->dma_address)) - return 0; + return -EIO; return 1; } @@ -1486,7 +1486,7 @@ static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents); if (coalesced < 0) { sba_unmap_sg_attrs(dev, sglist, nents, dir, attrs); - return 0; + return -ENOMEM; } /* -- cgit v1.2.3-70-g09d2 From af82fe85665d49bdb72dba66cd57e3bf95b71895 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:27 -0600 Subject: MIPS/jazzdma: return error code from jazz_dma_map_sg() The .map_sg() op now expects an error code instead of zero on failure. vdma_alloc() may fail for different reasons, but since it only supports indicating an error via a return of DMA_MAPPING_ERROR, we coalesce the different reasons into -EIO as is documented on dma_map_sgtable(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Thomas Bogendoerfer Signed-off-by: Christoph Hellwig --- arch/mips/jazz/jazzdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 461457b28982..eabddb89d221 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -552,7 +552,7 @@ static int jazz_dma_map_sg(struct device *dev, struct scatterlist *sglist, dir); sg->dma_address = vdma_alloc(sg_phys(sg), sg->length); if (sg->dma_address == DMA_MAPPING_ERROR) - return 0; + return -EIO; sg_dma_len(sg) = sg->length; } -- cgit v1.2.3-70-g09d2 From c4e0e892ab0579d4de3ca6d260d537fc16b39790 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:28 -0600 Subject: powerpc/iommu: return error code from .map_sg() ops The .map_sg() op now expects an error code instead of zero on failure. Propagate the error up if vio_dma_iommu_map_sg() fails. ppc_iommu_map_sg() may fail either because of iommu_range_alloc() or because of tbl->it_ops->set(). The former only supports returning an error with DMA_MAPPING_ERROR and an examination of the latter indicates that it may return arch-specific errors (for example, tce_buildmulti_pSeriesLP()). Hence, coalesce all of those errors into -EIO, per the documentation on dma_map_sgtable(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Geoff Levand Signed-off-by: Christoph Hellwig --- arch/powerpc/kernel/iommu.c | 4 ++-- arch/powerpc/platforms/ps3/system-bus.c | 2 +- arch/powerpc/platforms/pseries/vio.c | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 2af89a5e379f..a8ec4fe42817 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -473,7 +473,7 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl, BUG_ON(direction == DMA_NONE); if ((nelems == 0) || !tbl) - return 0; + return -EINVAL; outs = s = segstart = &sglist[0]; outcount = 1; @@ -599,7 +599,7 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl, if (s == outs) break; } - return 0; + return -EIO; } diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 1a5665875165..c54eb46f0cfb 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -663,7 +663,7 @@ static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, unsigned long attrs) { BUG(); - return 0; + return -EINVAL; } static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg, diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index e00f3725ec96..e31e59c54f30 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -560,7 +560,8 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, for_each_sg(sglist, sgl, nelems, count) alloc_size += roundup(sgl->length, IOMMU_PAGE_SIZE(tbl)); - if (vio_cmo_alloc(viodev, alloc_size)) + ret = vio_cmo_alloc(viodev, alloc_size); + if (ret) goto out_fail; ret = ppc_iommu_map_sg(dev, tbl, sglist, nelems, dma_get_mask(dev), direction, attrs); @@ -577,7 +578,7 @@ out_deallocate: vio_cmo_dealloc(viodev, alloc_size); out_fail: atomic_inc(&viodev->cmo.allocs_failed); - return 0; + return ret; } static void vio_dma_iommu_unmap_sg(struct device *dev, -- cgit v1.2.3-70-g09d2 From eb86ef3b2d7e06b1447d4979e282977a845b611b Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:29 -0600 Subject: powerpc/iommu: don't set failed sg dma_address to DMA_MAPPING_ERROR Setting the ->dma_address to DMA_MAPPING_ERROR is not part of the ->map_sg calling convention, so remove it. Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345@lst.de/ Suggested-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Geoff Levand Signed-off-by: Christoph Hellwig --- arch/powerpc/kernel/iommu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index a8ec4fe42817..30b7736f0896 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -575,7 +575,6 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl, */ if (outcount < incount) { outs = sg_next(outs); - outs->dma_address = DMA_MAPPING_ERROR; outs->dma_length = 0; } @@ -593,7 +592,6 @@ int ppc_iommu_map_sg(struct device *dev, struct iommu_table *tbl, npages = iommu_num_pages(s->dma_address, s->dma_length, IOMMU_PAGE_SIZE(tbl)); __iommu_free(tbl, vaddr, npages); - s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; } if (s == outs) -- cgit v1.2.3-70-g09d2 From 911ace0ba628424637e42826c8a8b63b89bd5611 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:30 -0600 Subject: s390/pci: return error code from s390_dma_map_sg() The .map_sg() op now expects an error code instead of zero on failure. So propagate the error from __s390_dma_map_sg() up. __s390_dma_map_sg() returns either -ENOMEM on allocation failure or -EINVAL which is the same as what's expected by dma_map_sgtable(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Acked-by: Niklas Schnelle Cc: Gerald Schaefer Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Signed-off-by: Christoph Hellwig --- arch/s390/pci/pci_dma.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index ebc9a49523aa..c78b02012764 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -487,7 +487,7 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg, unsigned int max = dma_get_max_seg_size(dev); unsigned int size = s->offset + s->length; unsigned int offset = s->offset; - int count = 0, i; + int count = 0, i, ret; for (i = 1; i < nr_elements; i++) { s = sg_next(s); @@ -497,8 +497,9 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg, if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) { - if (__s390_dma_map_sg(dev, start, size, - &dma->dma_address, dir)) + ret = __s390_dma_map_sg(dev, start, size, + &dma->dma_address, dir); + if (ret) goto unmap; dma->dma_address += offset; @@ -511,7 +512,8 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg, } size += s->length; } - if (__s390_dma_map_sg(dev, start, size, &dma->dma_address, dir)) + ret = __s390_dma_map_sg(dev, start, size, &dma->dma_address, dir); + if (ret) goto unmap; dma->dma_address += offset; @@ -523,7 +525,7 @@ unmap: s390_dma_unmap_pages(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs); - return 0; + return ret; } static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, -- cgit v1.2.3-70-g09d2 From 7e4e7d4c54ecc9986041aae84e04280413f2435b Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:31 -0600 Subject: s390/pci: don't set failed sg dma_address to DMA_MAPPING_ERROR Setting the ->dma_address to DMA_MAPPING_ERROR is not part of the ->map_sg calling convention, so remove it. Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345@lst.de/ Suggested-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe Cc: Niklas Schnelle Cc: Gerald Schaefer Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Christian Borntraeger Signed-off-by: Christoph Hellwig --- arch/s390/pci/pci_dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index c78b02012764..be48e5b5bfcf 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -492,7 +492,6 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg, for (i = 1; i < nr_elements; i++) { s = sg_next(s); - s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; if (s->offset || (size & ~PAGE_MASK) || -- cgit v1.2.3-70-g09d2 From e02373fddb0ea86ce3962bb5d38e20ea0b6c8a05 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:32 -0600 Subject: sparc/iommu: return error codes from .map_sg() ops The .map_sg() op now expects an error code instead of zero on failure. Returning an errno from __sbus_iommu_map_sg() results in sbus_iommu_map_sg_gflush() and sbus_iommu_map_sg_pflush() returning an errno, as those functions are wrappers around __sbus_iommu_map_sg(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: "David S. Miller" Cc: Niklas Schnelle Cc: Michael Ellerman Signed-off-by: Christoph Hellwig --- arch/sparc/kernel/iommu.c | 4 ++-- arch/sparc/kernel/pci_sun4v.c | 4 ++-- arch/sparc/mm/iommu.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index a034f571d869..0589acd34201 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -448,7 +448,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, iommu = dev->archdata.iommu; strbuf = dev->archdata.stc; if (nelems == 0 || !iommu) - return 0; + return -EINVAL; spin_lock_irqsave(&iommu->lock, flags); @@ -580,7 +580,7 @@ iommu_map_failed: } spin_unlock_irqrestore(&iommu->lock, flags); - return 0; + return -EINVAL; } /* If contexts are being used, they are the same in all of the mappings diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 9de57e88f7a1..d90e80fa5705 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -486,7 +486,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, iommu = dev->archdata.iommu; if (nelems == 0 || !iommu) - return 0; + return -EINVAL; atu = iommu->atu; prot = HV_PCI_MAP_ATTR_READ; @@ -619,7 +619,7 @@ iommu_map_failed: } local_irq_restore(flags); - return 0; + return -EINVAL; } static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 0c0342e5b10d..9e3f6933ca13 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -256,7 +256,7 @@ static int __sbus_iommu_map_sg(struct device *dev, struct scatterlist *sgl, sg->dma_address =__sbus_iommu_map_page(dev, sg_page(sg), sg->offset, sg->length, per_page_flush); if (sg->dma_address == DMA_MAPPING_ERROR) - return 0; + return -EIO; sg->dma_length = sg->length; } -- cgit v1.2.3-70-g09d2 From ba3a0482db879f33863348b81ed9770888d727a9 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:33 -0600 Subject: sparc/iommu: don't set failed sg dma_address to DMA_MAPPING_ERROR Setting the ->dma_address to DMA_MAPPING_ERROR is not part of the ->map_sg calling convention, so remove it. Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345@lst.de/ Suggested-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe Cc: "David S. Miller" Cc: Niklas Schnelle Cc: Michael Ellerman Signed-off-by: Christoph Hellwig --- arch/sparc/kernel/iommu.c | 2 -- arch/sparc/kernel/pci_sun4v.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 0589acd34201..da0363692528 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -546,7 +546,6 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, if (outcount < incount) { outs = sg_next(outs); - outs->dma_address = DMA_MAPPING_ERROR; outs->dma_length = 0; } @@ -572,7 +571,6 @@ iommu_map_failed: iommu_tbl_range_free(&iommu->tbl, vaddr, npages, IOMMU_ERROR_CODE); - s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; } if (s == outs) diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index d90e80fa5705..384480971805 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -594,7 +594,6 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, if (outcount < incount) { outs = sg_next(outs); - outs->dma_address = DMA_MAPPING_ERROR; outs->dma_length = 0; } @@ -611,7 +610,6 @@ iommu_map_failed: iommu_tbl_range_free(tbl, vaddr, npages, IOMMU_ERROR_CODE); /* XXX demap? XXX */ - s->dma_address = DMA_MAPPING_ERROR; s->dma_length = 0; } if (s == outs) -- cgit v1.2.3-70-g09d2 From 9a22f2f3435184df2882b8c6d6999e6ef022331b Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:34 -0600 Subject: parisc: return error code from .map_sg() ops The .map_sg() op now expects an error code instead of zero on failure. Return -EINVAL if the ioc cannot be obtained. Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: "James E.J. Bottomley" Cc: Helge Deller Signed-off-by: Christoph Hellwig --- drivers/parisc/ccio-dma.c | 2 +- drivers/parisc/sba_iommu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index b5f9ee81a46c..452e72b7bd01 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -918,7 +918,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, BUG_ON(!dev); ioc = GET_IOC(dev); if (!ioc) - return 0; + return -EINVAL; DBG_RUN_SG("%s() START %d entries\n", __func__, nents); diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index dce4cdf786cd..e60690d38d67 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -947,7 +947,7 @@ sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, ioc = GET_IOC(dev); if (!ioc) - return 0; + return -EINVAL; /* Fast path single entry scatterlists. */ if (nents == 1) { -- cgit v1.2.3-70-g09d2 From 2c647ebe17140f1f5de09d4e30817b1b00a3b588 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:35 -0600 Subject: xen: swiotlb: return error code from xen_swiotlb_map_sg() The .map_sg() op now expects an error code instead of zero on failure. xen_swiotlb_map_sg() may only fail if xen_swiotlb_map_page() fails, but xen_swiotlb_map_page() only supports returning errors as DMA_MAPPING_ERROR. So coalesce all errors into EIO per the documentation for dma_map_sgtable(). Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Reviewed-by: Boris Ostrovsky Cc: Konrad Rzeszutek Wilk Cc: Juergen Gross Cc: Stefano Stabellini Signed-off-by: Christoph Hellwig --- drivers/xen/swiotlb-xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 24d11861ac7d..85d58b720a24 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -509,7 +509,7 @@ xen_swiotlb_map_sg(struct device *dev, struct scatterlist *sgl, int nelems, out_unmap: xen_swiotlb_unmap_sg(dev, sgl, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC); sg_dma_len(sgl) = 0; - return 0; + return -EIO; } static void -- cgit v1.2.3-70-g09d2 From fcacc8a614391d3bf009319509c846fef47d9352 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:36 -0600 Subject: x86/amd_gart: return error code from gart_map_sg() The .map_sg() op now expects an error code instead of zero on failure. So make __dma_map_cont() return a valid errno (which is then propagated to gart_map_sg() via dma_map_cont()) and return it in case of failure. Also, return -EINVAL in case of invalid nents. Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Niklas Schnelle Cc: Thomas Bogendoerfer Cc: Michael Ellerman Signed-off-by: Christoph Hellwig --- arch/x86/kernel/amd_gart_64.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index 9ac696487b13..46aea9a4f26b 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -331,7 +331,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, int i; if (iommu_start == -1) - return -1; + return -ENOMEM; for_each_sg(start, s, nelems, i) { unsigned long pages, addr; @@ -380,13 +380,13 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs) { struct scatterlist *s, *ps, *start_sg, *sgmap; - int need = 0, nextneed, i, out, start; + int need = 0, nextneed, i, out, start, ret; unsigned long pages = 0; unsigned int seg_size; unsigned int max_seg_size; if (nents == 0) - return 0; + return -EINVAL; out = 0; start = 0; @@ -414,8 +414,9 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, if (!iommu_merge || !nextneed || !need || s->offset || (s->length + seg_size > max_seg_size) || (ps->offset + ps->length) % PAGE_SIZE) { - if (dma_map_cont(dev, start_sg, i - start, - sgmap, pages, need) < 0) + ret = dma_map_cont(dev, start_sg, i - start, + sgmap, pages, need); + if (ret < 0) goto error; out++; @@ -432,7 +433,8 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE); ps = s; } - if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0) + ret = dma_map_cont(dev, start_sg, i - start, sgmap, pages, need); + if (ret < 0) goto error; out++; flush_gart(); @@ -458,7 +460,7 @@ error: iommu_full(dev, pages << PAGE_SHIFT, dir); for_each_sg(sg, s, nents, i) s->dma_address = DMA_MAPPING_ERROR; - return 0; + return ret; } /* allocate and map a coherent mapping */ -- cgit v1.2.3-70-g09d2 From 183dc86335e69f516b94f169afd784cf97cb8421 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Thu, 29 Jul 2021 14:15:37 -0600 Subject: x86/amd_gart: don't set failed sg dma_address to DMA_MAPPING_ERROR Setting the ->dma_address to DMA_MAPPING_ERROR is not part of the ->map_sg calling convention, so remove it. Link: https://lore.kernel.org/linux-mips/20210716063241.GC13345@lst.de/ Suggested-by: Christoph Hellwig Signed-off-by: Logan Gunthorpe Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Niklas Schnelle Cc: Thomas Bogendoerfer Cc: Michael Ellerman Signed-off-by: Christoph Hellwig --- arch/x86/kernel/amd_gart_64.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index 46aea9a4f26b..ed837383de5c 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -458,8 +458,6 @@ error: panic("dma_map_sg: overflow on %lu pages\n", pages); iommu_full(dev, pages << PAGE_SHIFT, dir); - for_each_sg(sg, s, nents, i) - s->dma_address = DMA_MAPPING_ERROR; return ret; } -- cgit v1.2.3-70-g09d2 From 66ab63104f9cab09209851fef168f5972d791903 Mon Sep 17 00:00:00 2001 From: Martin Oliveira Date: Thu, 29 Jul 2021 14:15:38 -0600 Subject: dma-mapping: return error code from dma_dummy_map_sg() The .map_sg() op now expects an error code instead of zero on failure. The only errno to return is -EINVAL in the case when DMA is not supported. Signed-off-by: Martin Oliveira Signed-off-by: Logan Gunthorpe Signed-off-by: Christoph Hellwig --- kernel/dma/dummy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/dma/dummy.c b/kernel/dma/dummy.c index eacd4c5b10bf..b492d59ac77e 100644 --- a/kernel/dma/dummy.c +++ b/kernel/dma/dummy.c @@ -22,7 +22,7 @@ static int dma_dummy_map_sg(struct device *dev, struct scatterlist *sgl, int nelems, enum dma_data_direction dir, unsigned long attrs) { - return 0; + return -EINVAL; } static int dma_dummy_supported(struct device *hwdev, u64 mask) -- cgit v1.2.3-70-g09d2 From d03c54419274f96434e2ad74e59e67ec6d54ca86 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Mon, 9 Aug 2021 17:13:31 +0200 Subject: dma-mapping: disallow .map_sg operations from returning zero on error Now that all the .map_sg operations have been converted to returning proper error codes, drop the code to handle a zero return value, add a warning if a zero is returned. Signed-off-by: Logan Gunthorpe Signed-off-by: Christoph Hellwig --- kernel/dma/mapping.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 21e550076be5..967b62692102 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -197,7 +197,7 @@ static int __dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, if (ents > 0) debug_dma_map_sg(dev, sg, nents, ents, dir); else if (WARN_ON_ONCE(ents != -EINVAL && ents != -ENOMEM && - ents != -EIO && ents != 0)) + ents != -EIO)) return -EIO; return ents; @@ -261,8 +261,6 @@ int dma_map_sgtable(struct device *dev, struct sg_table *sgt, int nents; nents = __dma_map_sg_attrs(dev, sgt->sgl, sgt->orig_nents, dir, attrs); - if (nents == 0) - return -EIO; if (nents < 0) return nents; sgt->nents = nents; -- cgit v1.2.3-70-g09d2 From a08e67a0280215f74eccf14fda81dd7fed6596ba Mon Sep 17 00:00:00 2001 From: Huang Jianan Date: Thu, 5 Aug 2021 08:35:59 +0800 Subject: erofs: iomap support for non-tailpacking DIO Add iomap support for non-tailpacking uncompressed data in order to support DIO and DAX. Direct I/O is useful in certain scenarios for uncompressed files. For example, double pagecache can be avoid by direct I/O when loop device is used for uncompressed files containing upper layer compressed filesystem. This adds iomap DIO support for non-tailpacking cases first and tail-packing inline files are handled in the follow-up patch. Link: https://lore.kernel.org/r/20210805003601.183063-2-hsiangkao@linux.alibaba.com Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Huang Jianan Signed-off-by: Gao Xiang --- fs/erofs/Kconfig | 1 + fs/erofs/data.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/erofs/inode.c | 5 ++- fs/erofs/internal.h | 1 + 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig index 906af0c1998c..14b747026742 100644 --- a/fs/erofs/Kconfig +++ b/fs/erofs/Kconfig @@ -3,6 +3,7 @@ config EROFS_FS tristate "EROFS filesystem support" depends on BLOCK + select FS_IOMAP select LIBCRC32C help EROFS (Enhanced Read-Only File System) is a lightweight diff --git a/fs/erofs/data.c b/fs/erofs/data.c index 3787a5fb0a42..4158572c9e1e 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -5,6 +5,7 @@ */ #include "internal.h" #include +#include #include @@ -308,9 +309,102 @@ static sector_t erofs_bmap(struct address_space *mapping, sector_t block) return 0; } +static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, + unsigned int flags, struct iomap *iomap, struct iomap *srcmap) +{ + int ret; + struct erofs_map_blocks map; + + map.m_la = offset; + map.m_llen = length; + + ret = erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW); + if (ret < 0) + return ret; + + iomap->bdev = inode->i_sb->s_bdev; + iomap->offset = map.m_la; + iomap->length = map.m_llen; + iomap->flags = 0; + + if (!(map.m_flags & EROFS_MAP_MAPPED)) { + iomap->type = IOMAP_HOLE; + iomap->addr = IOMAP_NULL_ADDR; + if (!iomap->length) + iomap->length = length; + return 0; + } + + /* that shouldn't happen for now */ + if (map.m_flags & EROFS_MAP_META) { + DBG_BUGON(1); + return -ENOTBLK; + } + iomap->type = IOMAP_MAPPED; + iomap->addr = map.m_pa; + return 0; +} + +static const struct iomap_ops erofs_iomap_ops = { + .iomap_begin = erofs_iomap_begin, +}; + +static int erofs_prepare_dio(struct kiocb *iocb, struct iov_iter *to) +{ + struct inode *inode = file_inode(iocb->ki_filp); + loff_t align = iocb->ki_pos | iov_iter_count(to) | + iov_iter_alignment(to); + struct block_device *bdev = inode->i_sb->s_bdev; + unsigned int blksize_mask; + + if (bdev) + blksize_mask = (1 << ilog2(bdev_logical_block_size(bdev))) - 1; + else + blksize_mask = (1 << inode->i_blkbits) - 1; + + if (align & blksize_mask) + return -EINVAL; + + /* + * Temporarily fall back tail-packing inline to buffered I/O instead + * since tail-packing inline support relies on an iomap core update. + */ + if (EROFS_I(inode)->datalayout == EROFS_INODE_FLAT_INLINE && + iocb->ki_pos + iov_iter_count(to) > + rounddown(inode->i_size, EROFS_BLKSIZ)) + return 1; + return 0; +} + +static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + /* no need taking (shared) inode lock since it's a ro filesystem */ + if (!iov_iter_count(to)) + return 0; + + if (iocb->ki_flags & IOCB_DIRECT) { + int err = erofs_prepare_dio(iocb, to); + + if (!err) + return iomap_dio_rw(iocb, to, &erofs_iomap_ops, + NULL, 0); + if (err < 0) + return err; + } + return filemap_read(iocb, to, 0); +} + /* for uncompressed (aligned) files and raw access for other files */ const struct address_space_operations erofs_raw_access_aops = { .readpage = erofs_raw_access_readpage, .readahead = erofs_raw_access_readahead, .bmap = erofs_bmap, + .direct_IO = noop_direct_IO, +}; + +const struct file_operations erofs_file_fops = { + .llseek = generic_file_llseek, + .read_iter = erofs_file_read_iter, + .mmap = generic_file_readonly_mmap, + .splice_read = generic_file_splice_read, }; diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index aa8a0d770ba3..f296e1a2661e 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -247,7 +247,10 @@ static int erofs_fill_inode(struct inode *inode, int isdir) switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &erofs_generic_iops; - inode->i_fop = &generic_ro_fops; + if (erofs_inode_is_data_compressed(vi->datalayout)) + inode->i_fop = &generic_ro_fops; + else + inode->i_fop = &erofs_file_fops; break; case S_IFDIR: inode->i_op = &erofs_dir_iops; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 543c2ff97d30..2669c785d548 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -371,6 +371,7 @@ static inline int z_erofs_map_blocks_iter(struct inode *inode, #endif /* !CONFIG_EROFS_FS_ZIP */ /* data.c */ +extern const struct file_operations erofs_file_fops; struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr); /* inode.c */ -- cgit v1.2.3-70-g09d2 From 06252e9ce05b94b587e522667b85848a30197b15 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Thu, 5 Aug 2021 08:36:00 +0800 Subject: erofs: dax support for non-tailpacking regular file DAX is quite useful for some VM use cases in order to save guest memory extremely with minimal lightweight EROFS. In order to prepare for such use cases, add preliminary dax support for non-tailpacking regular files for now. Tested with the DRAM-emulated PMEM and the EROFS image generated by "mkfs.erofs -Enoinline_data enwik9.fsdax.img enwik9" Link: https://lore.kernel.org/r/20210805003601.183063-3-hsiangkao@linux.alibaba.com Cc: nvdimm@lists.linux.dev Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- Documentation/filesystems/erofs.rst | 3 ++ fs/erofs/data.c | 42 ++++++++++++++++++++++++-- fs/erofs/inode.c | 4 +++ fs/erofs/internal.h | 3 ++ fs/erofs/super.c | 59 +++++++++++++++++++++++++++++++++++-- 5 files changed, 107 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst index 832839fcf4c3..868e3972227f 100644 --- a/Documentation/filesystems/erofs.rst +++ b/Documentation/filesystems/erofs.rst @@ -84,6 +84,9 @@ cache_strategy=%s Select a strategy for cached decompression from now on: It still does in-place I/O decompression for the rest compressed physical clusters. ========== ============================================= +dax={always,never} Use direct access (no page cache). See + Documentation/filesystems/dax.rst. +dax A legacy option which is an alias for ``dax=always``. =================== ========================================================= On-disk details diff --git a/fs/erofs/data.c b/fs/erofs/data.c index 4158572c9e1e..fb2e554c861b 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -6,7 +6,7 @@ #include "internal.h" #include #include - +#include #include static void erofs_readendio(struct bio *bio) @@ -323,6 +323,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, return ret; iomap->bdev = inode->i_sb->s_bdev; + iomap->dax_dev = EROFS_I_SB(inode)->dax_dev; iomap->offset = map.m_la; iomap->length = map.m_llen; iomap->flags = 0; @@ -382,6 +383,10 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) if (!iov_iter_count(to)) return 0; +#ifdef CONFIG_FS_DAX + if (IS_DAX(iocb->ki_filp->f_mapping->host)) + return dax_iomap_rw(iocb, to, &erofs_iomap_ops); +#endif if (iocb->ki_flags & IOCB_DIRECT) { int err = erofs_prepare_dio(iocb, to); @@ -402,9 +407,42 @@ const struct address_space_operations erofs_raw_access_aops = { .direct_IO = noop_direct_IO, }; +#ifdef CONFIG_FS_DAX +static vm_fault_t erofs_dax_huge_fault(struct vm_fault *vmf, + enum page_entry_size pe_size) +{ + return dax_iomap_fault(vmf, pe_size, NULL, NULL, &erofs_iomap_ops); +} + +static vm_fault_t erofs_dax_fault(struct vm_fault *vmf) +{ + return erofs_dax_huge_fault(vmf, PE_SIZE_PTE); +} + +static const struct vm_operations_struct erofs_dax_vm_ops = { + .fault = erofs_dax_fault, + .huge_fault = erofs_dax_huge_fault, +}; + +static int erofs_file_mmap(struct file *file, struct vm_area_struct *vma) +{ + if (!IS_DAX(file_inode(file))) + return generic_file_readonly_mmap(file, vma); + + if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) + return -EINVAL; + + vma->vm_ops = &erofs_dax_vm_ops; + vma->vm_flags |= VM_HUGEPAGE; + return 0; +} +#else +#define erofs_file_mmap generic_file_readonly_mmap +#endif + const struct file_operations erofs_file_fops = { .llseek = generic_file_llseek, .read_iter = erofs_file_read_iter, - .mmap = generic_file_readonly_mmap, + .mmap = erofs_file_mmap, .splice_read = generic_file_splice_read, }; diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index f296e1a2661e..92728da1d206 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -174,6 +174,10 @@ static struct page *erofs_read_inode(struct inode *inode, inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec; inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec; + inode->i_flags &= ~S_DAX; + if (test_opt(&sbi->ctx, DAX_ALWAYS) && S_ISREG(inode->i_mode) && + vi->datalayout == EROFS_INODE_FLAT_PLAIN) + inode->i_flags |= S_DAX; if (!nblks) /* measure inode.i_blocks as generic filesystems */ inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 2669c785d548..7c9abfc93109 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -83,6 +83,7 @@ struct erofs_sb_info { struct erofs_sb_lz4_info lz4; #endif /* CONFIG_EROFS_FS_ZIP */ + struct dax_device *dax_dev; u32 blocks; u32 meta_blkaddr; #ifdef CONFIG_EROFS_FS_XATTR @@ -115,6 +116,8 @@ struct erofs_sb_info { /* Mount flags set via mount options or defaults */ #define EROFS_MOUNT_XATTR_USER 0x00000010 #define EROFS_MOUNT_POSIX_ACL 0x00000020 +#define EROFS_MOUNT_DAX_ALWAYS 0x00000040 +#define EROFS_MOUNT_DAX_NEVER 0x00000080 #define clear_opt(ctx, option) ((ctx)->mount_opt &= ~EROFS_MOUNT_##option) #define set_opt(ctx, option) ((ctx)->mount_opt |= EROFS_MOUNT_##option) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 8fc6c04b54f4..e8de689c94f4 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "xattr.h" #define CREATE_TRACE_POINTS @@ -355,6 +356,8 @@ enum { Opt_user_xattr, Opt_acl, Opt_cache_strategy, + Opt_dax, + Opt_dax_enum, Opt_err }; @@ -365,14 +368,47 @@ static const struct constant_table erofs_param_cache_strategy[] = { {} }; +static const struct constant_table erofs_dax_param_enums[] = { + {"always", EROFS_MOUNT_DAX_ALWAYS}, + {"never", EROFS_MOUNT_DAX_NEVER}, + {} +}; + static const struct fs_parameter_spec erofs_fs_parameters[] = { fsparam_flag_no("user_xattr", Opt_user_xattr), fsparam_flag_no("acl", Opt_acl), fsparam_enum("cache_strategy", Opt_cache_strategy, erofs_param_cache_strategy), + fsparam_flag("dax", Opt_dax), + fsparam_enum("dax", Opt_dax_enum, erofs_dax_param_enums), {} }; +static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode) +{ +#ifdef CONFIG_FS_DAX + struct erofs_fs_context *ctx = fc->fs_private; + + switch (mode) { + case EROFS_MOUNT_DAX_ALWAYS: + warnfc(fc, "DAX enabled. Warning: EXPERIMENTAL, use at your own risk"); + set_opt(ctx, DAX_ALWAYS); + clear_opt(ctx, DAX_NEVER); + return true; + case EROFS_MOUNT_DAX_NEVER: + set_opt(ctx, DAX_NEVER); + clear_opt(ctx, DAX_ALWAYS); + return true; + default: + DBG_BUGON(1); + return false; + } +#else + errorfc(fc, "dax options not supported"); + return false; +#endif +} + static int erofs_fc_parse_param(struct fs_context *fc, struct fs_parameter *param) { @@ -412,6 +448,14 @@ static int erofs_fc_parse_param(struct fs_context *fc, errorfc(fc, "compression not supported, cache_strategy ignored"); #endif break; + case Opt_dax: + if (!erofs_fc_set_dax_mode(fc, EROFS_MOUNT_DAX_ALWAYS)) + return -EINVAL; + break; + case Opt_dax_enum: + if (!erofs_fc_set_dax_mode(fc, result.uint_32)) + return -EINVAL; + break; default: return -ENOPARAM; } @@ -496,10 +540,16 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) return -ENOMEM; sb->s_fs_info = sbi; + sbi->dax_dev = fs_dax_get_by_bdev(sb->s_bdev); err = erofs_read_superblock(sb); if (err) return err; + if (test_opt(ctx, DAX_ALWAYS) && + !bdev_dax_supported(sb->s_bdev, EROFS_BLKSIZ)) { + errorfc(fc, "DAX unsupported by block device. Turning off DAX."); + clear_opt(ctx, DAX_ALWAYS); + } sb->s_flags |= SB_RDONLY | SB_NOATIME; sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_time_gran = 1; @@ -609,6 +659,7 @@ static void erofs_kill_sb(struct super_block *sb) sbi = EROFS_SB(sb); if (!sbi) return; + fs_put_dax(sbi->dax_dev); kfree(sbi); sb->s_fs_info = NULL; } @@ -711,8 +762,8 @@ static int erofs_statfs(struct dentry *dentry, struct kstatfs *buf) static int erofs_show_options(struct seq_file *seq, struct dentry *root) { - struct erofs_sb_info *sbi __maybe_unused = EROFS_SB(root->d_sb); - struct erofs_fs_context *ctx __maybe_unused = &sbi->ctx; + struct erofs_sb_info *sbi = EROFS_SB(root->d_sb); + struct erofs_fs_context *ctx = &sbi->ctx; #ifdef CONFIG_EROFS_FS_XATTR if (test_opt(ctx, XATTR_USER)) @@ -734,6 +785,10 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root) else if (ctx->cache_strategy == EROFS_ZIP_CACHE_READAROUND) seq_puts(seq, ",cache_strategy=readaround"); #endif + if (test_opt(ctx, DAX_ALWAYS)) + seq_puts(seq, ",dax=always"); + if (test_opt(ctx, DAX_NEVER)) + seq_puts(seq, ",dax=never"); return 0; } -- cgit v1.2.3-70-g09d2 From 771c994ea51f572539ca3961c6a7706862b147e2 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Thu, 5 Aug 2021 08:36:01 +0800 Subject: erofs: convert all uncompressed cases to iomap Since tail-packing inline has been supported by iomap now, let's convert all EROFS uncompressed data I/O to iomap, which is pretty straight-forward. Link: https://lore.kernel.org/r/20210805003601.183063-4-hsiangkao@linux.alibaba.com Cc: linux-fsdevel@vger.kernel.org Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- fs/erofs/data.c | 290 ++++++++++---------------------------------------------- 1 file changed, 51 insertions(+), 239 deletions(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index fb2e554c861b..b2a22aabc9bc 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -9,29 +9,6 @@ #include #include -static void erofs_readendio(struct bio *bio) -{ - struct bio_vec *bvec; - blk_status_t err = bio->bi_status; - struct bvec_iter_all iter_all; - - bio_for_each_segment_all(bvec, bio, iter_all) { - struct page *page = bvec->bv_page; - - /* page is already locked */ - DBG_BUGON(PageUptodate(page)); - - if (err) - SetPageError(page); - else - SetPageUptodate(page); - - unlock_page(page); - /* page could be reclaimed now */ - } - bio_put(bio); -} - struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr) { struct address_space *const mapping = sb->s_bdev->bd_inode->i_mapping; @@ -109,206 +86,6 @@ err_out: return err; } -static inline struct bio *erofs_read_raw_page(struct bio *bio, - struct address_space *mapping, - struct page *page, - erofs_off_t *last_block, - unsigned int nblocks, - unsigned int *eblks, - bool ra) -{ - struct inode *const inode = mapping->host; - struct super_block *const sb = inode->i_sb; - erofs_off_t current_block = (erofs_off_t)page->index; - int err; - - DBG_BUGON(!nblocks); - - if (PageUptodate(page)) { - err = 0; - goto has_updated; - } - - /* note that for readpage case, bio also equals to NULL */ - if (bio && - (*last_block + 1 != current_block || !*eblks)) { -submit_bio_retry: - submit_bio(bio); - bio = NULL; - } - - if (!bio) { - struct erofs_map_blocks map = { - .m_la = blknr_to_addr(current_block), - }; - erofs_blk_t blknr; - unsigned int blkoff; - - err = erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW); - if (err) - goto err_out; - - /* zero out the holed page */ - if (!(map.m_flags & EROFS_MAP_MAPPED)) { - zero_user_segment(page, 0, PAGE_SIZE); - SetPageUptodate(page); - - /* imply err = 0, see erofs_map_blocks */ - goto has_updated; - } - - /* for RAW access mode, m_plen must be equal to m_llen */ - DBG_BUGON(map.m_plen != map.m_llen); - - blknr = erofs_blknr(map.m_pa); - blkoff = erofs_blkoff(map.m_pa); - - /* deal with inline page */ - if (map.m_flags & EROFS_MAP_META) { - void *vsrc, *vto; - struct page *ipage; - - DBG_BUGON(map.m_plen > PAGE_SIZE); - - ipage = erofs_get_meta_page(inode->i_sb, blknr); - - if (IS_ERR(ipage)) { - err = PTR_ERR(ipage); - goto err_out; - } - - vsrc = kmap_atomic(ipage); - vto = kmap_atomic(page); - memcpy(vto, vsrc + blkoff, map.m_plen); - memset(vto + map.m_plen, 0, PAGE_SIZE - map.m_plen); - kunmap_atomic(vto); - kunmap_atomic(vsrc); - flush_dcache_page(page); - - SetPageUptodate(page); - /* TODO: could we unlock the page earlier? */ - unlock_page(ipage); - put_page(ipage); - - /* imply err = 0, see erofs_map_blocks */ - goto has_updated; - } - - /* pa must be block-aligned for raw reading */ - DBG_BUGON(erofs_blkoff(map.m_pa)); - - /* max # of continuous pages */ - if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) - nblocks = DIV_ROUND_UP(map.m_plen, PAGE_SIZE); - - *eblks = bio_max_segs(nblocks); - bio = bio_alloc(GFP_NOIO, *eblks); - - bio->bi_end_io = erofs_readendio; - bio_set_dev(bio, sb->s_bdev); - bio->bi_iter.bi_sector = (sector_t)blknr << - LOG_SECTORS_PER_BLOCK; - bio->bi_opf = REQ_OP_READ | (ra ? REQ_RAHEAD : 0); - } - - err = bio_add_page(bio, page, PAGE_SIZE, 0); - /* out of the extent or bio is full */ - if (err < PAGE_SIZE) - goto submit_bio_retry; - --*eblks; - *last_block = current_block; - return bio; - -err_out: - /* for sync reading, set page error immediately */ - if (!ra) { - SetPageError(page); - ClearPageUptodate(page); - } -has_updated: - unlock_page(page); - - /* if updated manually, continuous pages has a gap */ - if (bio) - submit_bio(bio); - return err ? ERR_PTR(err) : NULL; -} - -/* - * since we dont have write or truncate flows, so no inode - * locking needs to be held at the moment. - */ -static int erofs_raw_access_readpage(struct file *file, struct page *page) -{ - erofs_off_t last_block; - unsigned int eblks; - struct bio *bio; - - trace_erofs_readpage(page, true); - - bio = erofs_read_raw_page(NULL, page->mapping, - page, &last_block, 1, &eblks, false); - - if (IS_ERR(bio)) - return PTR_ERR(bio); - - if (bio) - submit_bio(bio); - return 0; -} - -static void erofs_raw_access_readahead(struct readahead_control *rac) -{ - erofs_off_t last_block; - unsigned int eblks; - struct bio *bio = NULL; - struct page *page; - - trace_erofs_readpages(rac->mapping->host, readahead_index(rac), - readahead_count(rac), true); - - while ((page = readahead_page(rac))) { - prefetchw(&page->flags); - - bio = erofs_read_raw_page(bio, rac->mapping, page, &last_block, - readahead_count(rac), &eblks, true); - - /* all the page errors are ignored when readahead */ - if (IS_ERR(bio)) { - pr_err("%s, readahead error at page %lu of nid %llu\n", - __func__, page->index, - EROFS_I(rac->mapping->host)->nid); - - bio = NULL; - } - - put_page(page); - } - - if (bio) - submit_bio(bio); -} - -static sector_t erofs_bmap(struct address_space *mapping, sector_t block) -{ - struct inode *inode = mapping->host; - struct erofs_map_blocks map = { - .m_la = blknr_to_addr(block), - }; - - if (EROFS_I(inode)->datalayout == EROFS_INODE_FLAT_INLINE) { - erofs_blk_t blks = i_size_read(inode) >> LOG_BLOCK_SIZE; - - if (block >> LOG_SECTORS_PER_BLOCK >= blks) - return 0; - } - - if (!erofs_map_blocks_flatmode(inode, &map, EROFS_GET_BLOCKS_RAW)) - return erofs_blknr(map.m_pa); - - return 0; -} - static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, unsigned int flags, struct iomap *iomap, struct iomap *srcmap) { @@ -327,6 +104,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, iomap->offset = map.m_la; iomap->length = map.m_llen; iomap->flags = 0; + iomap->private = NULL; if (!(map.m_flags & EROFS_MAP_MAPPED)) { iomap->type = IOMAP_HOLE; @@ -336,20 +114,63 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, return 0; } - /* that shouldn't happen for now */ if (map.m_flags & EROFS_MAP_META) { - DBG_BUGON(1); - return -ENOTBLK; + struct page *ipage; + + iomap->type = IOMAP_INLINE; + ipage = erofs_get_meta_page(inode->i_sb, + erofs_blknr(map.m_pa)); + if (IS_ERR(ipage)) + return PTR_ERR(ipage); + iomap->inline_data = page_address(ipage) + + erofs_blkoff(map.m_pa); + iomap->private = ipage; + } else { + iomap->type = IOMAP_MAPPED; + iomap->addr = map.m_pa; } - iomap->type = IOMAP_MAPPED; - iomap->addr = map.m_pa; return 0; } +static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length, + ssize_t written, unsigned int flags, struct iomap *iomap) +{ + struct page *ipage = iomap->private; + + if (ipage) { + DBG_BUGON(iomap->type != IOMAP_INLINE); + unlock_page(ipage); + put_page(ipage); + } else { + DBG_BUGON(iomap->type == IOMAP_INLINE); + } + return written; +} + static const struct iomap_ops erofs_iomap_ops = { .iomap_begin = erofs_iomap_begin, + .iomap_end = erofs_iomap_end, }; +/* + * since we dont have write or truncate flows, so no inode + * locking needs to be held at the moment. + */ +static int erofs_readpage(struct file *file, struct page *page) +{ + return iomap_readpage(page, &erofs_iomap_ops); +} + +static void erofs_readahead(struct readahead_control *rac) +{ + return iomap_readahead(rac, &erofs_iomap_ops); +} + +static sector_t erofs_bmap(struct address_space *mapping, sector_t block) +{ + return iomap_bmap(mapping, block, &erofs_iomap_ops); +} + static int erofs_prepare_dio(struct kiocb *iocb, struct iov_iter *to) { struct inode *inode = file_inode(iocb->ki_filp); @@ -365,15 +186,6 @@ static int erofs_prepare_dio(struct kiocb *iocb, struct iov_iter *to) if (align & blksize_mask) return -EINVAL; - - /* - * Temporarily fall back tail-packing inline to buffered I/O instead - * since tail-packing inline support relies on an iomap core update. - */ - if (EROFS_I(inode)->datalayout == EROFS_INODE_FLAT_INLINE && - iocb->ki_pos + iov_iter_count(to) > - rounddown(inode->i_size, EROFS_BLKSIZ)) - return 1; return 0; } @@ -401,8 +213,8 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) /* for uncompressed (aligned) files and raw access for other files */ const struct address_space_operations erofs_raw_access_aops = { - .readpage = erofs_raw_access_readpage, - .readahead = erofs_raw_access_readahead, + .readpage = erofs_readpage, + .readahead = erofs_readahead, .bmap = erofs_bmap, .direct_IO = noop_direct_IO, }; -- cgit v1.2.3-70-g09d2 From 7d6f07d2c5ad9fce298889eeed317d512a2df8cd Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:40 -0700 Subject: xfs: queue inactivation immediately when free space is tight Now that we have made the inactivation of unlinked inodes a background task to increase the throughput of file deletions, we need to be a little more careful about how long of a delay we can tolerate. On a mostly empty filesystem, the risk of the allocator making poor decisions due to fragmentation of the free space on account a lengthy delay in background updates is minimal because there's plenty of space. However, if free space is tight, we want to deallocate unlinked inodes as quickly as possible to avoid fallocate ENOSPC and to give the allocator the best shot at optimal allocations for new writes. Therefore, queue the percpu worker immediately if the filesystem is more than 95% full. This follows the same principle that XFS becomes less aggressive about speculative allocations and lazy cleanup (and more precise about accounting) when nearing full. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 6 ++++++ fs/xfs/xfs_mount.c | 8 -------- fs/xfs/xfs_mount.h | 9 +++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 7d93edb331fb..8b2ac969c60c 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1920,6 +1920,7 @@ xfs_inodegc_start( * Schedule the inactivation worker when: * * - We've accumulated more than one inode cluster buffer's worth of inodes. + * - There is less than 5% free space left. */ static inline bool xfs_inodegc_want_queue_work( @@ -1931,6 +1932,11 @@ xfs_inodegc_want_queue_work( if (items > mp->m_ino_geo.inodes_per_cluster) return true; + if (__percpu_counter_compare(&mp->m_fdblocks, + mp->m_low_space[XFS_LOWSP_5_PCNT], + XFS_FDBLOCKS_BATCH) < 0) + return true; + return false; } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 1f7e9a608f38..5fe6f1db4fe9 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1077,14 +1077,6 @@ xfs_fs_writable( return true; } -/* - * Deltas for the block count can vary from 1 to very large, but lock contention - * only occurs on frequent small block count updates such as in the delayed - * allocation path for buffered writes (page a time updates). Hence we set - * a large batch count (1024) to minimise global counter updates except when - * we get near to ENOSPC and we have to be very accurate with our updates. - */ -#define XFS_FDBLOCKS_BATCH 1024 int xfs_mod_fdblocks( struct xfs_mount *mp, diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index e6f8675e7a40..60468a2a5e67 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -348,6 +348,15 @@ extern uint64_t xfs_default_resblks(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp); extern void xfs_unmountfs(xfs_mount_t *); +/* + * Deltas for the block count can vary from 1 to very large, but lock contention + * only occurs on frequent small block count updates such as in the delayed + * allocation path for buffered writes (page a time updates). Hence we set + * a large batch count (1024) to minimise global counter updates except when + * we get near to ENOSPC and we have to be very accurate with our updates. + */ +#define XFS_FDBLOCKS_BATCH 1024 + extern int xfs_mod_fdblocks(struct xfs_mount *mp, int64_t delta, bool reserved); extern int xfs_mod_frextents(struct xfs_mount *mp, int64_t delta); -- cgit v1.2.3-70-g09d2 From 108523b8de676a45cef1f6c8566c444222b85de0 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:40 -0700 Subject: xfs: queue inactivation immediately when quota is nearing enforcement Now that we have made the inactivation of unlinked inodes a background task to increase the throughput of file deletions, we need to be a little more careful about how long of a delay we can tolerate. Specifically, if the dquots attached to the inode being inactivated are nearing any kind of enforcement boundary, we want to queue that inactivation work immediately so that users don't get EDQUOT/ENOSPC errors even after they deleted a bunch of files to stay within quota. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_dquot.h | 10 ++++++++++ fs/xfs/xfs_icache.c | 10 ++++++++++ fs/xfs/xfs_qm.c | 34 ++++++++++++++++++++++++++++++++++ fs/xfs/xfs_quota.h | 2 ++ 4 files changed, 56 insertions(+) diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h index f642884a6834..6b5e3cf40c8b 100644 --- a/fs/xfs/xfs_dquot.h +++ b/fs/xfs/xfs_dquot.h @@ -54,6 +54,16 @@ struct xfs_dquot_res { xfs_qwarncnt_t warnings; }; +static inline bool +xfs_dquot_res_over_limits( + const struct xfs_dquot_res *qres) +{ + if ((qres->softlimit && qres->softlimit < qres->reserved) || + (qres->hardlimit && qres->hardlimit < qres->reserved)) + return true; + return false; +} + /* * The incore dquot structure */ diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 8b2ac969c60c..0bea604f320a 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1921,6 +1921,7 @@ xfs_inodegc_start( * * - We've accumulated more than one inode cluster buffer's worth of inodes. * - There is less than 5% free space left. + * - Any of the quotas for this inode are near an enforcement limit. */ static inline bool xfs_inodegc_want_queue_work( @@ -1937,6 +1938,15 @@ xfs_inodegc_want_queue_work( XFS_FDBLOCKS_BATCH) < 0) return true; + if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_USER)) + return true; + + if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_GROUP)) + return true; + + if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_PROJ)) + return true; + return false; } diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 351d99bc52e5..2bef4735d030 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -1882,3 +1882,37 @@ xfs_qm_vop_create_dqattach( } } +/* Decide if this inode's dquot is near an enforcement boundary. */ +bool +xfs_inode_near_dquot_enforcement( + struct xfs_inode *ip, + xfs_dqtype_t type) +{ + struct xfs_dquot *dqp; + int64_t freesp; + + /* We only care for quotas that are enabled and enforced. */ + dqp = xfs_inode_dquot(ip, type); + if (!dqp || !xfs_dquot_is_enforced(dqp)) + return false; + + if (xfs_dquot_res_over_limits(&dqp->q_ino) || + xfs_dquot_res_over_limits(&dqp->q_rtb)) + return true; + + /* For space on the data device, check the various thresholds. */ + if (!dqp->q_prealloc_hi_wmark) + return false; + + if (dqp->q_blk.reserved < dqp->q_prealloc_lo_wmark) + return false; + + if (dqp->q_blk.reserved >= dqp->q_prealloc_hi_wmark) + return true; + + freesp = dqp->q_prealloc_hi_wmark - dqp->q_blk.reserved; + if (freesp < dqp->q_low_space[XFS_QLOWSP_5_PCNT]) + return true; + + return false; +} diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index d00d01302545..dcc785fdd345 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -113,6 +113,7 @@ xfs_quota_reserve_blkres(struct xfs_inode *ip, int64_t blocks) { return xfs_trans_reserve_quota_nblks(NULL, ip, blocks, 0, false); } +bool xfs_inode_near_dquot_enforcement(struct xfs_inode *ip, xfs_dqtype_t type); #else static inline int xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t kuid, kgid_t kgid, @@ -168,6 +169,7 @@ xfs_trans_reserve_quota_icreate(struct xfs_trans *tp, struct xfs_dquot *udqp, #define xfs_qm_mount_quotas(mp) #define xfs_qm_unmount(mp) #define xfs_qm_unmount_quotas(mp) +#define xfs_inode_near_dquot_enforcement(ip, type) (false) #endif /* CONFIG_XFS_QUOTA */ static inline int -- cgit v1.2.3-70-g09d2 From 65f03d8652b240aa66b99a07e3c423a51e967568 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:41 -0700 Subject: xfs: queue inactivation immediately when free realtime extents are tight Now that we have made the inactivation of unlinked inodes a background task to increase the throughput of file deletions, we need to be a little more careful about how long of a delay we can tolerate. Similar to the patch doing this for free space on the data device, if the file being inactivated is a realtime file and the realtime volume is running low on free extents, we want to run the worker ASAP so that the realtime allocator can make better decisions. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 21 +++++++++++++++++++++ fs/xfs/xfs_mount.c | 13 ++++++++----- fs/xfs/xfs_mount.h | 3 ++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0bea604f320a..0ca0b1981de9 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1916,6 +1916,24 @@ xfs_inodegc_start( xfs_inodegc_queue_all(mp); } +#ifdef CONFIG_XFS_RT +static inline bool +xfs_inodegc_want_queue_rt_file( + struct xfs_inode *ip) +{ + struct xfs_mount *mp = ip->i_mount; + uint64_t freertx; + + if (!XFS_IS_REALTIME_INODE(ip)) + return false; + + freertx = READ_ONCE(mp->m_sb.sb_frextents); + return freertx < mp->m_low_rtexts[XFS_LOWSP_5_PCNT]; +} +#else +# define xfs_inodegc_want_queue_rt_file(ip) (false) +#endif /* CONFIG_XFS_RT */ + /* * Schedule the inactivation worker when: * @@ -1938,6 +1956,9 @@ xfs_inodegc_want_queue_work( XFS_FDBLOCKS_BATCH) < 0) return true; + if (xfs_inodegc_want_queue_rt_file(ip)) + return true; + if (xfs_inode_near_dquot_enforcement(ip, XFS_DQTYPE_USER)) return true; diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5fe6f1db4fe9..ed1e7e3dce7e 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -365,13 +365,16 @@ void xfs_set_low_space_thresholds( struct xfs_mount *mp) { - int i; + uint64_t dblocks = mp->m_sb.sb_dblocks; + uint64_t rtexts = mp->m_sb.sb_rextents; + int i; - for (i = 0; i < XFS_LOWSP_MAX; i++) { - uint64_t space = mp->m_sb.sb_dblocks; + do_div(dblocks, 100); + do_div(rtexts, 100); - do_div(space, 100); - mp->m_low_space[i] = space * (i + 1); + for (i = 0; i < XFS_LOWSP_MAX; i++) { + mp->m_low_space[i] = dblocks * (i + 1); + mp->m_low_rtexts[i] = rtexts * (i + 1); } } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 60468a2a5e67..fbb18c2f00bd 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -147,7 +147,8 @@ typedef struct xfs_mount { int m_fixedfsid[2]; /* unchanged for life of FS */ uint m_qflags; /* quota status flags */ uint64_t m_flags; /* global mount flags */ - int64_t m_low_space[XFS_LOWSP_MAX]; + uint64_t m_low_space[XFS_LOWSP_MAX]; + uint64_t m_low_rtexts[XFS_LOWSP_MAX]; struct xfs_ino_geometry m_ino_geo; /* inode geometry */ struct xfs_trans_resv m_resv; /* precomputed res values */ /* low free space thresholds */ -- cgit v1.2.3-70-g09d2 From 2eb665027b6528c1a8e9158c2f722a6ec0af359d Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:41 -0700 Subject: xfs: inactivate inodes any time we try to free speculative preallocations Other parts of XFS have learned to call xfs_blockgc_free_{space,quota} to try to free speculative preallocations when space is tight. This means that file writes, transaction reservation failures, quota limit enforcement, and the EOFBLOCKS ioctl all call this function to free space when things are tight. Since inode inactivation is now a background task, this means that the filesystem can be hanging on to unlinked but not yet freed space. Add this to the list of things that xfs_blockgc_free_* makes writer threads scan for when they cannot reserve space. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0ca0b1981de9..9ba537c82d07 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1468,16 +1468,24 @@ xfs_blockgc_worker( } /* - * Try to free space in the filesystem by purging eofblocks and cowblocks. + * Try to free space in the filesystem by purging inactive inodes, eofblocks + * and cowblocks. */ int xfs_blockgc_free_space( struct xfs_mount *mp, struct xfs_icwalk *icw) { + int error; + trace_xfs_blockgc_free_space(mp, icw, _RET_IP_); - return xfs_icwalk(mp, XFS_ICWALK_BLOCKGC, icw); + error = xfs_icwalk(mp, XFS_ICWALK_BLOCKGC, icw); + if (error) + return error; + + xfs_inodegc_flush(mp); + return 0; } /* -- cgit v1.2.3-70-g09d2 From 01e8f379a4895a9a173391408db4fb49ec91e148 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:42 -0700 Subject: xfs: flush inode inactivation work when compiling usage statistics Users have come to expect that the space accounting information in statfs and getquota reports are fairly accurate. Now that we inactivate inodes from a background queue, these numbers can be thrown off by whatever resources are singly-owned by the inodes in the queue. Flush the pending inactivations when userspace asks for a space usage report. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_qm_syscalls.c | 8 ++++++++ fs/xfs/xfs_super.c | 3 +++ 2 files changed, 11 insertions(+) diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 982cd6613a4c..c6902f9d064c 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -481,6 +481,10 @@ xfs_qm_scall_getquota( struct xfs_dquot *dqp; int error; + /* Flush inodegc work at the start of a quota reporting scan. */ + if (id == 0) + xfs_inodegc_flush(mp); + /* * Try to get the dquot. We don't want it allocated on disk, so don't * set doalloc. If it doesn't exist, we'll get ENOENT back. @@ -519,6 +523,10 @@ xfs_qm_scall_getquota_next( struct xfs_dquot *dqp; int error; + /* Flush inodegc work at the start of a quota reporting scan. */ + if (*id == 0) + xfs_inodegc_flush(mp); + error = xfs_qm_dqget_next(mp, *id, type, &dqp); if (error) return error; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index fd39b97c7bb4..d142aaaa50ef 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -785,6 +785,9 @@ xfs_fs_statfs( xfs_extlen_t lsize; int64_t ffree; + /* Wait for whatever inactivations are in progress. */ + xfs_inodegc_flush(mp); + statp->f_type = XFS_SUPER_MAGIC; statp->f_namelen = MAXNAMELEN - 1; -- cgit v1.2.3-70-g09d2 From 6f6490914d9b712004ddad648e47b1bf22647978 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:42 -0700 Subject: xfs: don't run speculative preallocation gc when fs is frozen Now that we have the infrastructure to switch background workers on and off at will, fix the block gc worker code so that we don't actually run the worker when the filesystem is frozen, same as we do for deferred inactivation. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/scrub/common.c | 9 +++++---- fs/xfs/xfs_icache.c | 20 ++++++++++++++++---- fs/xfs/xfs_mount.c | 1 + fs/xfs/xfs_mount.h | 10 +++++++++- fs/xfs/xfs_super.c | 21 ++++++++++++++------- fs/xfs/xfs_trace.h | 3 +++ 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 06b697f72f23..e86854171b0c 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -893,11 +893,12 @@ xchk_start_reaping( struct xfs_scrub *sc) { /* - * Readonly filesystems do not perform inactivation, so there's no - * need to restart the worker. + * Readonly filesystems do not perform inactivation or speculative + * preallocation, so there's no need to restart the workers. */ - if (!(sc->mp->m_flags & XFS_MOUNT_RDONLY)) + if (!(sc->mp->m_flags & XFS_MOUNT_RDONLY)) { xfs_inodegc_start(sc->mp); - xfs_blockgc_start(sc->mp); + xfs_blockgc_start(sc->mp); + } sc->flags &= ~XCHK_REAPING_DISABLED; } diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 9ba537c82d07..41bd84fd9e87 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -211,6 +211,11 @@ static inline void xfs_blockgc_queue( struct xfs_perag *pag) { + struct xfs_mount *mp = pag->pag_mount; + + if (!xfs_is_blockgc_enabled(mp)) + return; + rcu_read_lock(); if (radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_BLOCKGC_TAG)) queue_delayed_work(pag->pag_mount->m_blockgc_wq, @@ -1366,8 +1371,12 @@ xfs_blockgc_stop( struct xfs_perag *pag; xfs_agnumber_t agno; - for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) + if (!xfs_clear_blockgc_enabled(mp)) + return; + + for_each_perag(mp, agno, pag) cancel_delayed_work_sync(&pag->pag_blockgc_work); + trace_xfs_blockgc_stop(mp, __return_address); } /* Enable post-EOF and CoW block auto-reclamation. */ @@ -1378,6 +1387,10 @@ xfs_blockgc_start( struct xfs_perag *pag; xfs_agnumber_t agno; + if (xfs_set_blockgc_enabled(mp)) + return; + + trace_xfs_blockgc_start(mp, __return_address); for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) xfs_blockgc_queue(pag); } @@ -1457,13 +1470,12 @@ xfs_blockgc_worker( struct xfs_mount *mp = pag->pag_mount; int error; - if (!sb_start_write_trylock(mp->m_super)) - return; + trace_xfs_blockgc_worker(mp, __return_address); + error = xfs_icwalk_ag(pag, XFS_ICWALK_BLOCKGC, NULL); if (error) xfs_info(mp, "AG %u preallocation gc worker failed, err=%d", pag->pag_agno, error); - sb_end_write(mp->m_super); xfs_blockgc_queue(pag); } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index ed1e7e3dce7e..b81f2fc734bd 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -789,6 +789,7 @@ xfs_mountfs( /* Enable background inode inactivation workers. */ xfs_inodegc_start(mp); + xfs_blockgc_start(mp); /* * Get and sanity-check the root inode. diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index fbb18c2f00bd..4b3ce6109e7a 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -281,6 +281,12 @@ typedef struct xfs_mount { * processed. */ #define XFS_OPSTATE_INODEGC_ENABLED 0 +/* + * If set, background speculative prealloc gc worker threads will be scheduled + * to process queued blockgc work. If not, inodes retain their preallocations + * until explicitly deleted. + */ +#define XFS_OPSTATE_BLOCKGC_ENABLED 1 #define __XFS_IS_OPSTATE(name, NAME) \ static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ @@ -297,9 +303,11 @@ static inline bool xfs_set_ ## name (struct xfs_mount *mp) \ } __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) +__XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) #define XFS_OPSTATE_STRINGS \ - { (1UL << XFS_OPSTATE_INODEGC_ENABLED), "inodegc" } + { (1UL << XFS_OPSTATE_INODEGC_ENABLED), "inodegc" }, \ + { (1UL << XFS_OPSTATE_BLOCKGC_ENABLED), "blockgc" } /* * Max and min values for mount-option defined I/O diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index d142aaaa50ef..1c6f9c9e8f14 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -757,15 +757,18 @@ xfs_fs_sync_fs( * down inodegc because once SB_FREEZE_FS is set it's too late to * prevent inactivation races with freeze. The fs doesn't get called * again by the freezing process until after SB_FREEZE_FS has been set, - * so it's now or never. + * so it's now or never. Same logic applies to speculative allocation + * garbage collection. * * We don't care if this is a normal syncfs call that does this or * freeze that does this - we can run this multiple times without issue * and we won't race with a restart because a restart can only occur * when the state is either SB_FREEZE_FS or SB_FREEZE_COMPLETE. */ - if (sb->s_writers.frozen == SB_FREEZE_PAGEFAULT) + if (sb->s_writers.frozen == SB_FREEZE_PAGEFAULT) { xfs_inodegc_stop(mp); + xfs_blockgc_stop(mp); + } return 0; } @@ -883,7 +886,6 @@ xfs_fs_freeze( * set a GFP_NOFS context here to avoid recursion deadlocks. */ flags = memalloc_nofs_save(); - xfs_blockgc_stop(mp); xfs_save_resvblks(mp); ret = xfs_log_quiesce(mp); memalloc_nofs_restore(flags); @@ -895,8 +897,10 @@ xfs_fs_freeze( * here, so we can restart safely without racing with a stop in * xfs_fs_sync_fs(). */ - if (ret && !(mp->m_flags & XFS_MOUNT_RDONLY)) + if (ret && !(mp->m_flags & XFS_MOUNT_RDONLY)) { + xfs_blockgc_start(mp); xfs_inodegc_start(mp); + } return ret; } @@ -909,14 +913,17 @@ xfs_fs_unfreeze( xfs_restore_resvblks(mp); xfs_log_work_queue(mp); - xfs_blockgc_start(mp); /* * Don't reactivate the inodegc worker on a readonly filesystem because - * inodes are sent directly to reclaim. + * inodes are sent directly to reclaim. Don't reactivate the blockgc + * worker because there are no speculative preallocations on a readonly + * filesystem. */ - if (!(mp->m_flags & XFS_MOUNT_RDONLY)) + if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { + xfs_blockgc_start(mp); xfs_inodegc_start(mp); + } return 0; } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index cd56ac7c39a6..3440046facc7 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -195,6 +195,9 @@ DEFINE_FS_EVENT(xfs_inodegc_worker); DEFINE_FS_EVENT(xfs_inodegc_queue); DEFINE_FS_EVENT(xfs_inodegc_throttle); DEFINE_FS_EVENT(xfs_fs_sync_fs); +DEFINE_FS_EVENT(xfs_blockgc_start); +DEFINE_FS_EVENT(xfs_blockgc_stop); +DEFINE_FS_EVENT(xfs_blockgc_worker); DECLARE_EVENT_CLASS(xfs_ag_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno), -- cgit v1.2.3-70-g09d2 From e8d04c2abcebd66bdbacd53bb273d824d4e27080 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:42 -0700 Subject: xfs: use background worker pool when transactions can't get free space In xfs_trans_alloc, if the block reservation call returns ENOSPC, we call xfs_blockgc_free_space with a NULL icwalk structure to try to free space. Each frontend thread that encounters this situation starts its own walk of the inode cache to see if it can find anything, which is wasteful since we don't have any additional selection criteria. For this one common case, create a function that reschedules all pending background work immediately and flushes the workqueue so that the scan can run in parallel. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 28 ++++++++++++++++++++++++++++ fs/xfs/xfs_icache.h | 1 + fs/xfs/xfs_trace.h | 1 + fs/xfs/xfs_trans.c | 5 +---- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 41bd84fd9e87..93ab83dfa36e 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1500,6 +1500,34 @@ xfs_blockgc_free_space( return 0; } +/* + * Reclaim all the free space that we can by scheduling the background blockgc + * and inodegc workers immediately and waiting for them all to clear. + */ +void +xfs_blockgc_flush_all( + struct xfs_mount *mp) +{ + struct xfs_perag *pag; + xfs_agnumber_t agno; + + trace_xfs_blockgc_flush_all(mp, __return_address); + + /* + * For each blockgc worker, move its queue time up to now. If it + * wasn't queued, it will not be requeued. Then flush whatever's + * left. + */ + for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) + mod_delayed_work(pag->pag_mount->m_blockgc_wq, + &pag->pag_blockgc_work, 0); + + for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG) + flush_delayed_work(&pag->pag_blockgc_work); + + xfs_inodegc_flush(mp); +} + /* * Run cow/eofblocks scans on the supplied dquots. We don't know exactly which * quota caused an allocation failure, so we make a best effort by including diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 8175148afd50..18c2d224aa78 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -59,6 +59,7 @@ int xfs_blockgc_free_dquots(struct xfs_mount *mp, struct xfs_dquot *udqp, unsigned int iwalk_flags); int xfs_blockgc_free_quota(struct xfs_inode *ip, unsigned int iwalk_flags); int xfs_blockgc_free_space(struct xfs_mount *mp, struct xfs_icwalk *icm); +void xfs_blockgc_flush_all(struct xfs_mount *mp); void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 3440046facc7..4a6616490315 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -198,6 +198,7 @@ DEFINE_FS_EVENT(xfs_fs_sync_fs); DEFINE_FS_EVENT(xfs_blockgc_start); DEFINE_FS_EVENT(xfs_blockgc_stop); DEFINE_FS_EVENT(xfs_blockgc_worker); +DEFINE_FS_EVENT(xfs_blockgc_flush_all); DECLARE_EVENT_CLASS(xfs_ag_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno), diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 87bffd12c20c..83abaa219616 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -295,10 +295,7 @@ retry: * Do not perform a synchronous scan because callers can hold * other locks. */ - error = xfs_blockgc_free_space(mp, NULL); - if (error) - return error; - + xfs_blockgc_flush_all(mp); want_retry = false; goto retry; } -- cgit v1.2.3-70-g09d2 From a6343e4d9278b3919c809fab9945c4d8f04fadf5 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:43 -0700 Subject: xfs: avoid buffer deadlocks when walking fs inodes When we're servicing an INUMBERS or BULKSTAT request or running quotacheck, grab an empty transaction so that we can use its inherent recursive buffer locking abilities to detect inode btree cycles without hitting ABBA buffer deadlocks. This patch requires the deferred inode inactivation patchset because xfs_irele cannot directly call xfs_inactive when the iwalk itself has an (empty) transaction. Found by fuzzing an inode btree pointer to introduce a cycle into the tree (xfs/365). Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_itable.c | 42 +++++++++++++++++++++++++++++++++++++----- fs/xfs/xfs_iwalk.c | 33 ++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index f331975a16de..84c17a9f9869 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -19,6 +19,7 @@ #include "xfs_error.h" #include "xfs_icache.h" #include "xfs_health.h" +#include "xfs_trans.h" /* * Bulk Stat @@ -163,6 +164,7 @@ xfs_bulkstat_one( .formatter = formatter, .breq = breq, }; + struct xfs_trans *tp; int error; if (breq->mnt_userns != &init_user_ns) { @@ -178,9 +180,18 @@ xfs_bulkstat_one( if (!bc.buf) return -ENOMEM; - error = xfs_bulkstat_one_int(breq->mp, breq->mnt_userns, NULL, - breq->startino, &bc); + /* + * Grab an empty transaction so that we can use its recursive buffer + * locking abilities to detect cycles in the inobt without deadlocking. + */ + error = xfs_trans_alloc_empty(breq->mp, &tp); + if (error) + goto out; + error = xfs_bulkstat_one_int(breq->mp, breq->mnt_userns, tp, + breq->startino, &bc); + xfs_trans_cancel(tp); +out: kmem_free(bc.buf); /* @@ -244,6 +255,7 @@ xfs_bulkstat( .formatter = formatter, .breq = breq, }; + struct xfs_trans *tp; int error; if (breq->mnt_userns != &init_user_ns) { @@ -259,9 +271,18 @@ xfs_bulkstat( if (!bc.buf) return -ENOMEM; - error = xfs_iwalk(breq->mp, NULL, breq->startino, breq->flags, - xfs_bulkstat_iwalk, breq->icount, &bc); + /* + * Grab an empty transaction so that we can use its recursive buffer + * locking abilities to detect cycles in the inobt without deadlocking. + */ + error = xfs_trans_alloc_empty(breq->mp, &tp); + if (error) + goto out; + error = xfs_iwalk(breq->mp, tp, breq->startino, breq->flags, + xfs_bulkstat_iwalk, breq->icount, &bc); + xfs_trans_cancel(tp); +out: kmem_free(bc.buf); /* @@ -374,13 +395,24 @@ xfs_inumbers( .formatter = formatter, .breq = breq, }; + struct xfs_trans *tp; int error = 0; if (xfs_bulkstat_already_done(breq->mp, breq->startino)) return 0; - error = xfs_inobt_walk(breq->mp, NULL, breq->startino, breq->flags, + /* + * Grab an empty transaction so that we can use its recursive buffer + * locking abilities to detect cycles in the inobt without deadlocking. + */ + error = xfs_trans_alloc_empty(breq->mp, &tp); + if (error) + goto out; + + error = xfs_inobt_walk(breq->mp, tp, breq->startino, breq->flags, xfs_inumbers_walk, breq->icount, &ic); + xfs_trans_cancel(tp); +out: /* * We found some inode groups, so clear the error status and return diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index 917d51eefee3..7558486f4937 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -83,6 +83,9 @@ struct xfs_iwalk_ag { /* Skip empty inobt records? */ unsigned int skip_empty:1; + + /* Drop the (hopefully empty) transaction when calling iwalk_fn. */ + unsigned int drop_trans:1; }; /* @@ -352,7 +355,6 @@ xfs_iwalk_run_callbacks( int *has_more) { struct xfs_mount *mp = iwag->mp; - struct xfs_trans *tp = iwag->tp; struct xfs_inobt_rec_incore *irec; xfs_agino_t next_agino; int error; @@ -362,10 +364,15 @@ xfs_iwalk_run_callbacks( ASSERT(iwag->nr_recs > 0); /* Delete cursor but remember the last record we cached... */ - xfs_iwalk_del_inobt(tp, curpp, agi_bpp, 0); + xfs_iwalk_del_inobt(iwag->tp, curpp, agi_bpp, 0); irec = &iwag->recs[iwag->nr_recs - 1]; ASSERT(next_agino >= irec->ir_startino + XFS_INODES_PER_CHUNK); + if (iwag->drop_trans) { + xfs_trans_cancel(iwag->tp); + iwag->tp = NULL; + } + error = xfs_iwalk_ag_recs(iwag); if (error) return error; @@ -376,8 +383,15 @@ xfs_iwalk_run_callbacks( if (!has_more) return 0; + if (iwag->drop_trans) { + error = xfs_trans_alloc_empty(mp, &iwag->tp); + if (error) + return error; + } + /* ...and recreate the cursor just past where we left off. */ - error = xfs_inobt_cur(mp, tp, iwag->pag, XFS_BTNUM_INO, curpp, agi_bpp); + error = xfs_inobt_cur(mp, iwag->tp, iwag->pag, XFS_BTNUM_INO, curpp, + agi_bpp); if (error) return error; @@ -390,7 +404,6 @@ xfs_iwalk_ag( struct xfs_iwalk_ag *iwag) { struct xfs_mount *mp = iwag->mp; - struct xfs_trans *tp = iwag->tp; struct xfs_perag *pag = iwag->pag; struct xfs_buf *agi_bp = NULL; struct xfs_btree_cur *cur = NULL; @@ -469,7 +482,7 @@ xfs_iwalk_ag( error = xfs_iwalk_run_callbacks(iwag, &cur, &agi_bp, &has_more); out: - xfs_iwalk_del_inobt(tp, &cur, &agi_bp, error); + xfs_iwalk_del_inobt(iwag->tp, &cur, &agi_bp, error); return error; } @@ -599,8 +612,18 @@ xfs_iwalk_ag_work( error = xfs_iwalk_alloc(iwag); if (error) goto out; + /* + * Grab an empty transaction so that we can use its recursive buffer + * locking abilities to detect cycles in the inobt without deadlocking. + */ + error = xfs_trans_alloc_empty(mp, &iwag->tp); + if (error) + goto out; + iwag->drop_trans = 1; error = xfs_iwalk_ag(iwag); + if (iwag->tp) + xfs_trans_cancel(iwag->tp); xfs_iwalk_free(iwag); out: xfs_perag_put(iwag->pag); -- cgit v1.2.3-70-g09d2 From 40b1de007aca4f9ec4ee4322c29f026ebb60ac96 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:43 -0700 Subject: xfs: throttle inode inactivation queuing on memory reclaim Now that we defer inode inactivation, we've decoupled the process of unlinking or closing an inode from the process of inactivating it. In theory this should lead to better throughput since we now inactivate the queued inodes in batches instead of one at a time. Unfortunately, one of the primary risks with this decoupling is the loss of rate control feedback between the frontend and background threads. In other words, a rm -rf /* thread can run the system out of memory if it can queue inodes for inactivation and jump to a new CPU faster than the background threads can actually clear the deferred work. The workers can get scheduled off the CPU if they have to do IO, etc. To solve this problem, we configure a shrinker so that it will activate the /second/ time the shrinkers are called. The custom shrinker will queue all percpu deferred inactivation workers immediately and set a flag to force frontend callers who are releasing a vfs inode to wait for the inactivation workers. On my test VM with 560M of RAM and a 2TB filesystem, this seems to solve most of the OOMing problem when deleting 10 million inodes. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_icache.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/xfs_icache.h | 1 + fs/xfs/xfs_mount.c | 9 ++++- fs/xfs/xfs_mount.h | 3 ++ fs/xfs/xfs_trace.h | 37 ++++++++++++++++++- 5 files changed, 147 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 93ab83dfa36e..e7e69e55b768 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1893,8 +1893,9 @@ xfs_inodegc_worker( return; ip = llist_entry(node, struct xfs_inode, i_gclist); - trace_xfs_inodegc_worker(ip->i_mount, __return_address); + trace_xfs_inodegc_worker(ip->i_mount, READ_ONCE(gc->shrinker_hits)); + WRITE_ONCE(gc->shrinker_hits, 0); llist_for_each_entry_safe(ip, n, node, i_gclist) { xfs_iflags_set(ip, XFS_INACTIVATING); xfs_inodegc_inactivate(ip); @@ -2028,6 +2029,7 @@ xfs_inodegc_want_queue_work( /* * Make the frontend wait for inactivations when: * + * - Memory shrinkers queued the inactivation worker and it hasn't finished. * - The queue depth exceeds the maximum allowable percpu backlog. * * Note: If the current thread is running a transaction, we don't ever want to @@ -2036,11 +2038,15 @@ xfs_inodegc_want_queue_work( static inline bool xfs_inodegc_want_flush_work( struct xfs_inode *ip, - unsigned int items) + unsigned int items, + unsigned int shrinker_hits) { if (current->journal_info) return false; + if (shrinker_hits > 0) + return true; + if (items > XFS_INODEGC_MAX_BACKLOG) return true; @@ -2059,6 +2065,7 @@ xfs_inodegc_queue( struct xfs_mount *mp = ip->i_mount; struct xfs_inodegc *gc; int items; + unsigned int shrinker_hits; trace_xfs_inode_set_need_inactive(ip); spin_lock(&ip->i_flags_lock); @@ -2069,6 +2076,7 @@ xfs_inodegc_queue( llist_add(&ip->i_gclist, &gc->list); items = READ_ONCE(gc->items); WRITE_ONCE(gc->items, items + 1); + shrinker_hits = READ_ONCE(gc->shrinker_hits); put_cpu_ptr(gc); if (!xfs_is_inodegc_enabled(mp)) @@ -2079,7 +2087,7 @@ xfs_inodegc_queue( queue_work(mp->m_inodegc_wq, &gc->work); } - if (xfs_inodegc_want_flush_work(ip, items)) { + if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { trace_xfs_inodegc_throttle(mp, __return_address); flush_work(&gc->work); } @@ -2159,3 +2167,91 @@ xfs_inode_mark_reclaimable( xfs_qm_dqdetach(ip); xfs_inodegc_set_reclaimable(ip); } + +/* + * Register a phony shrinker so that we can run background inodegc sooner when + * there's memory pressure. Inactivation does not itself free any memory but + * it does make inodes reclaimable, which eventually frees memory. + * + * The count function, seek value, and batch value are crafted to trigger the + * scan function during the second round of scanning. Hopefully this means + * that we reclaimed enough memory that initiating metadata transactions won't + * make things worse. + */ +#define XFS_INODEGC_SHRINKER_COUNT (1UL << DEF_PRIORITY) +#define XFS_INODEGC_SHRINKER_BATCH ((XFS_INODEGC_SHRINKER_COUNT / 2) + 1) + +static unsigned long +xfs_inodegc_shrinker_count( + struct shrinker *shrink, + struct shrink_control *sc) +{ + struct xfs_mount *mp = container_of(shrink, struct xfs_mount, + m_inodegc_shrinker); + struct xfs_inodegc *gc; + int cpu; + + if (!xfs_is_inodegc_enabled(mp)) + return 0; + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + if (!llist_empty(&gc->list)) + return XFS_INODEGC_SHRINKER_COUNT; + } + + return 0; +} + +static unsigned long +xfs_inodegc_shrinker_scan( + struct shrinker *shrink, + struct shrink_control *sc) +{ + struct xfs_mount *mp = container_of(shrink, struct xfs_mount, + m_inodegc_shrinker); + struct xfs_inodegc *gc; + int cpu; + bool no_items = true; + + if (!xfs_is_inodegc_enabled(mp)) + return SHRINK_STOP; + + trace_xfs_inodegc_shrinker_scan(mp, sc, __return_address); + + for_each_online_cpu(cpu) { + gc = per_cpu_ptr(mp->m_inodegc, cpu); + if (!llist_empty(&gc->list)) { + unsigned int h = READ_ONCE(gc->shrinker_hits); + + WRITE_ONCE(gc->shrinker_hits, h + 1); + queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); + no_items = false; + } + } + + /* + * If there are no inodes to inactivate, we don't want the shrinker + * to think there's deferred work to call us back about. + */ + if (no_items) + return LONG_MAX; + + return SHRINK_STOP; +} + +/* Register a shrinker so we can accelerate inodegc and throttle queuing. */ +int +xfs_inodegc_register_shrinker( + struct xfs_mount *mp) +{ + struct shrinker *shrink = &mp->m_inodegc_shrinker; + + shrink->count_objects = xfs_inodegc_shrinker_count; + shrink->scan_objects = xfs_inodegc_shrinker_scan; + shrink->seeks = 0; + shrink->flags = SHRINKER_NONSLAB; + shrink->batch = XFS_INODEGC_SHRINKER_BATCH; + + return register_shrinker(shrink); +} diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 18c2d224aa78..2e4cfddf8b8e 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -80,5 +80,6 @@ void xfs_inodegc_flush(struct xfs_mount *mp); void xfs_inodegc_stop(struct xfs_mount *mp); void xfs_inodegc_start(struct xfs_mount *mp); void xfs_inodegc_cpu_dead(struct xfs_mount *mp, unsigned int cpu); +int xfs_inodegc_register_shrinker(struct xfs_mount *mp); #endif diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b81f2fc734bd..ff08192d8d2a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -769,6 +769,10 @@ xfs_mountfs( goto out_free_perag; } + error = xfs_inodegc_register_shrinker(mp); + if (error) + goto out_fail_wait; + /* * Log's mount-time initialization. The first part of recovery can place * some items on the AIL, to be handled when recovery is finished or @@ -779,7 +783,7 @@ xfs_mountfs( XFS_FSB_TO_BB(mp, sbp->sb_logblocks)); if (error) { xfs_warn(mp, "log mount failed"); - goto out_fail_wait; + goto out_inodegc_shrinker; } /* Make sure the summary counts are ok. */ @@ -974,6 +978,8 @@ xfs_mountfs( xfs_unmount_flush_inodes(mp); out_log_dealloc: xfs_log_mount_cancel(mp); + out_inodegc_shrinker: + unregister_shrinker(&mp->m_inodegc_shrinker); out_fail_wait: if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) xfs_buftarg_drain(mp->m_logdev_targp); @@ -1054,6 +1060,7 @@ xfs_unmountfs( #if defined(DEBUG) xfs_errortag_clearall(mp); #endif + unregister_shrinker(&mp->m_inodegc_shrinker); xfs_free_perag(mp); xfs_errortag_del(mp); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 4b3ce6109e7a..91a10233d04c 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -65,6 +65,7 @@ struct xfs_inodegc { /* approximate count of inodes in the list */ unsigned int items; + unsigned int shrinker_hits; }; /* @@ -210,6 +211,8 @@ typedef struct xfs_mount { xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ spinlock_t m_agirotor_lock;/* .. and lock protecting it */ + /* Memory shrinker to throttle and reprioritize inodegc */ + struct shrinker m_inodegc_shrinker; /* * Workqueue item so that we can coalesce multiple inode flush attempts * into a single flush. diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 4a6616490315..57ce91dcc0a6 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -157,6 +157,22 @@ DEFINE_PERAG_REF_EVENT(xfs_perag_put); DEFINE_PERAG_REF_EVENT(xfs_perag_set_inode_tag); DEFINE_PERAG_REF_EVENT(xfs_perag_clear_inode_tag); +TRACE_EVENT(xfs_inodegc_worker, + TP_PROTO(struct xfs_mount *mp, unsigned int shrinker_hits), + TP_ARGS(mp, shrinker_hits), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned int, shrinker_hits) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->shrinker_hits = shrinker_hits; + ), + TP_printk("dev %d:%d shrinker_hits %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->shrinker_hits) +); + DECLARE_EVENT_CLASS(xfs_fs_class, TP_PROTO(struct xfs_mount *mp, void *caller_ip), TP_ARGS(mp, caller_ip), @@ -191,7 +207,6 @@ DEFINE_EVENT(xfs_fs_class, name, \ DEFINE_FS_EVENT(xfs_inodegc_flush); DEFINE_FS_EVENT(xfs_inodegc_start); DEFINE_FS_EVENT(xfs_inodegc_stop); -DEFINE_FS_EVENT(xfs_inodegc_worker); DEFINE_FS_EVENT(xfs_inodegc_queue); DEFINE_FS_EVENT(xfs_inodegc_throttle); DEFINE_FS_EVENT(xfs_fs_sync_fs); @@ -200,6 +215,26 @@ DEFINE_FS_EVENT(xfs_blockgc_stop); DEFINE_FS_EVENT(xfs_blockgc_worker); DEFINE_FS_EVENT(xfs_blockgc_flush_all); +TRACE_EVENT(xfs_inodegc_shrinker_scan, + TP_PROTO(struct xfs_mount *mp, struct shrink_control *sc, + void *caller_ip), + TP_ARGS(mp, sc, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long, nr_to_scan) + __field(void *, caller_ip) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->nr_to_scan = sc->nr_to_scan; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d nr_to_scan %lu caller %pS", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->nr_to_scan, + __entry->caller_ip) +); + DECLARE_EVENT_CLASS(xfs_ag_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno), TP_ARGS(mp, agno), -- cgit v1.2.3-70-g09d2 From b7df7630cccd103671b14b946bcdb3b14be75d68 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:44 -0700 Subject: xfs: fix silly whitespace problems with kernel libxfs Fix a few whitespace errors such as spaces at the end of the line, etc. This gets us back to something more closely resembling parity. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_format.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 2 +- fs/xfs/libxfs/xfs_rmap_btree.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b910bd209949..b277e0511cdd 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -576,7 +576,7 @@ xfs_attr_shortform_bytesfit( switch (dp->i_df.if_format) { case XFS_DINODE_FMT_EXTENTS: /* - * If there is no attr fork and the data fork is extents, + * If there is no attr fork and the data fork is extents, * determine if creating the default attr fork will result * in the extents form migrating to btree. If so, the * minimum offset only needs to be the space required for diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 76e2461b9e66..37570cf0537e 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -9,7 +9,7 @@ /* * XFS On Disk Format Definitions * - * This header file defines all the on-disk format definitions for + * This header file defines all the on-disk format definitions for * general XFS objects. Directory and attribute related objects are defined in * xfs_da_format.h, which log and log item formats are defined in * xfs_log_format.h. Everything else goes here. diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index aaf8805a82df..19eb7ec0103f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1994,7 +1994,7 @@ xfs_difree_inobt( goto error0; } - /* + /* * Change the inode free counts and log the ag/sb changes. */ be32_add_cpu(&agi->agi_freecount, 1); diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 88d8d18788a2..f2eee6572af4 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -59,4 +59,4 @@ extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp, extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_perag *pag, xfs_extlen_t *ask, xfs_extlen_t *used); -#endif /* __XFS_RMAP_BTREE_H__ */ +#endif /* __XFS_RMAP_BTREE_H__ */ -- cgit v1.2.3-70-g09d2 From f19ee6bb1a72e7e1ecbd25d99a48513bc6061832 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:05:44 -0700 Subject: xfs: drop experimental warnings for bigtime and inobtcount These two features were merged a year ago, userspace tooling have been merged, and no serious errors have been reported by the developers. Drop the experimental tag to encourage wider testing. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Carlos Maiolino Reviewed-by: Bill O'Donnell Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_super.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 1c6f9c9e8f14..16a3ea6eae13 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1600,10 +1600,6 @@ xfs_fs_fill_super( if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) sb->s_flags |= SB_I_VERSION; - if (xfs_sb_version_hasbigtime(&mp->m_sb)) - xfs_warn(mp, - "EXPERIMENTAL big timestamp feature in use. Use at your own risk!"); - if (mp->m_flags & XFS_MOUNT_DAX_ALWAYS) { bool rtdev_is_dax = false, datadev_is_dax; @@ -1659,10 +1655,6 @@ xfs_fs_fill_super( goto out_filestream_unmount; } - if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) - xfs_warn(mp, - "EXPERIMENTAL inode btree counters feature in use. Use at your own risk!"); - error = xfs_mountfs(mp); if (error) goto out_filestream_unmount; -- cgit v1.2.3-70-g09d2 From 48c6615cc557593e4190415a6945b7aca7c8db31 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:06:35 -0700 Subject: xfs: grab active perag ref when reading AG headers This patch prepares scrub to deal with the possibility of tearing down entire AGs by changing the order of resource acquisition to match the rest of the XFS codebase. In other words, scrub now grabs AG resources in order of: perag structure, then AGI/AGF/AGFL buffers, then btree cursors; and releases them in reverse order. This requires us to distinguish xchk_ag_init callers -- some are responding to a user request to check AG metadata, in which case we can return ENOENT to userspace; but other callers have an ondisk reference to an AG that they're trying to cross-reference. In this second case, the lack of an AG means there's ondisk corruption, since ondisk metadata cannot point into nonexistent space. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R --- fs/xfs/scrub/agheader.c | 23 ++++++++++++++------ fs/xfs/scrub/agheader_repair.c | 3 --- fs/xfs/scrub/bmap.c | 2 +- fs/xfs/scrub/btree.c | 2 +- fs/xfs/scrub/common.c | 48 +++++++++++++++++------------------------- fs/xfs/scrub/common.h | 18 +++++++++++++++- fs/xfs/scrub/fscounters.c | 2 +- fs/xfs/scrub/inode.c | 2 +- 8 files changed, 56 insertions(+), 44 deletions(-) diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index be1a7e1e65f7..6152ce01c057 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -36,7 +36,7 @@ xchk_superblock_xref( agbno = XFS_SB_BLOCK(mp); - error = xchk_ag_init(sc, agno, &sc->sa); + error = xchk_ag_init_existing(sc, agno, &sc->sa); if (!xchk_xref_process_error(sc, agno, agbno, &error)) return; @@ -63,6 +63,7 @@ xchk_superblock( struct xfs_mount *mp = sc->mp; struct xfs_buf *bp; struct xfs_dsb *sb; + struct xfs_perag *pag; xfs_agnumber_t agno; uint32_t v2_ok; __be32 features_mask; @@ -73,6 +74,15 @@ xchk_superblock( if (agno == 0) return 0; + /* + * Grab an active reference to the perag structure. If we can't get + * it, we're racing with something that's tearing down the AG, so + * signal that the AG no longer exists. + */ + pag = xfs_perag_get(mp, agno); + if (!pag) + return -ENOENT; + error = xfs_sb_read_secondary(mp, sc->tp, agno, &bp); /* * The superblock verifier can return several different error codes @@ -92,7 +102,7 @@ xchk_superblock( break; } if (!xchk_process_error(sc, agno, XFS_SB_BLOCK(mp), &error)) - return error; + goto out_pag; sb = bp->b_addr; @@ -336,7 +346,8 @@ xchk_superblock( xchk_block_set_corrupt(sc, bp); xchk_superblock_xref(sc, bp); - +out_pag: + xfs_perag_put(pag); return error; } @@ -527,6 +538,7 @@ xchk_agf( xchk_buffer_recheck(sc, sc->sa.agf_bp); agf = sc->sa.agf_bp->b_addr; + pag = sc->sa.pag; /* Check the AG length */ eoag = be32_to_cpu(agf->agf_length); @@ -582,7 +594,6 @@ xchk_agf( xchk_block_set_corrupt(sc, sc->sa.agf_bp); /* Do the incore counters match? */ - pag = xfs_perag_get(mp, agno); if (pag->pagf_freeblks != be32_to_cpu(agf->agf_freeblks)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); if (pag->pagf_flcount != be32_to_cpu(agf->agf_flcount)) @@ -590,7 +601,6 @@ xchk_agf( if (xfs_sb_version_haslazysbcount(&sc->mp->m_sb) && pag->pagf_btreeblks != be32_to_cpu(agf->agf_btreeblks)) xchk_block_set_corrupt(sc, sc->sa.agf_bp); - xfs_perag_put(pag); xchk_agf_xref(sc); out: @@ -857,6 +867,7 @@ xchk_agi( xchk_buffer_recheck(sc, sc->sa.agi_bp); agi = sc->sa.agi_bp->b_addr; + pag = sc->sa.pag; /* Check the AG length */ eoag = be32_to_cpu(agi->agi_length); @@ -909,12 +920,10 @@ xchk_agi( xchk_block_set_corrupt(sc, sc->sa.agi_bp); /* Do the incore counters match? */ - pag = xfs_perag_get(mp, agno); if (pag->pagi_count != be32_to_cpu(agi->agi_count)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); if (pag->pagi_freecount != be32_to_cpu(agi->agi_freecount)) xchk_block_set_corrupt(sc, sc->sa.agi_bp); - xfs_perag_put(pag); xchk_agi_xref(sc); out: diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index e95f8c98f0f7..f122f2e20e79 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -366,7 +366,6 @@ xrep_agf( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return -EOPNOTSUPP; - xchk_perag_get(sc->mp, &sc->sa); /* * Make sure we have the AGF buffer, as scrub might have decided it * was corrupt after xfs_alloc_read_agf failed with -EFSCORRUPTED. @@ -641,7 +640,6 @@ xrep_agfl( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return -EOPNOTSUPP; - xchk_perag_get(sc->mp, &sc->sa); xbitmap_init(&agfl_extents); /* @@ -896,7 +894,6 @@ xrep_agi( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return -EOPNOTSUPP; - xchk_perag_get(sc->mp, &sc->sa); /* * Make sure we have the AGI buffer, as scrub might have decided it * was corrupt after xfs_ialloc_read_agi failed with -EFSCORRUPTED. diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c index 1d146c9d9de1..678afceeb16b 100644 --- a/fs/xfs/scrub/bmap.c +++ b/fs/xfs/scrub/bmap.c @@ -260,7 +260,7 @@ xchk_bmap_iextent_xref( agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock); len = irec->br_blockcount; - error = xchk_ag_init(info->sc, agno, &info->sc->sa); + error = xchk_ag_init_existing(info->sc, agno, &info->sc->sa); if (!xchk_fblock_process_error(info->sc, info->whichfork, irec->br_startoff, &error)) return; diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index bd1172358964..c044e0a8da7f 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -374,7 +374,7 @@ xchk_btree_check_block_owner( init_sa = bs->cur->bc_flags & XFS_BTREE_LONG_PTRS; if (init_sa) { - error = xchk_ag_init(bs->sc, agno, &bs->sc->sa); + error = xchk_ag_init_existing(bs->sc, agno, &bs->sc->sa); if (!xchk_btree_xref_process_error(bs->sc, bs->cur, level, &error)) return error; diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index e86854171b0c..0ef96ed71017 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -394,11 +394,11 @@ want_ag_read_header_failure( } /* - * Grab all the headers for an AG. + * Grab the perag structure and all the headers for an AG. * - * The headers should be released by xchk_ag_free, but as a fail - * safe we attach all the buffers we grab to the scrub transaction so - * they'll all be freed when we cancel it. + * The headers should be released by xchk_ag_free, but as a fail safe we attach + * all the buffers we grab to the scrub transaction so they'll all be freed + * when we cancel it. Returns ENOENT if we can't grab the perag structure. */ int xchk_ag_read_headers( @@ -409,22 +409,26 @@ xchk_ag_read_headers( struct xfs_mount *mp = sc->mp; int error; + ASSERT(!sa->pag); + sa->pag = xfs_perag_get(mp, agno); + if (!sa->pag) + return -ENOENT; + sa->agno = agno; error = xfs_ialloc_read_agi(mp, sc->tp, agno, &sa->agi_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI)) - goto out; + return error; error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &sa->agf_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGF)) - goto out; + return error; error = xfs_alloc_read_agfl(mp, sc->tp, agno, &sa->agfl_bp); if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGFL)) - goto out; - error = 0; -out: - return error; + return error; + + return 0; } /* Release all the AG btree cursors. */ @@ -461,7 +465,6 @@ xchk_ag_btcur_init( { struct xfs_mount *mp = sc->mp; - xchk_perag_get(sc->mp, sa); if (sa->agf_bp && xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_BNO)) { /* Set up a bnobt cursor for cross-referencing. */ @@ -532,11 +535,11 @@ xchk_ag_free( } /* - * For scrub, grab the AGI and the AGF headers, in that order. Locking - * order requires us to get the AGI before the AGF. We use the - * transaction to avoid deadlocking on crosslinked metadata buffers; - * either the caller passes one in (bmap scrub) or we have to create a - * transaction ourselves. + * For scrub, grab the perag structure, the AGI, and the AGF headers, in that + * order. Locking order requires us to get the AGI before the AGF. We use the + * transaction to avoid deadlocking on crosslinked metadata buffers; either the + * caller passes one in (bmap scrub) or we have to create a transaction + * ourselves. Returns ENOENT if the perag struct cannot be grabbed. */ int xchk_ag_init( @@ -554,19 +557,6 @@ xchk_ag_init( return 0; } -/* - * Grab the per-ag structure if we haven't already gotten it. Teardown of the - * xchk_ag will release it for us. - */ -void -xchk_perag_get( - struct xfs_mount *mp, - struct xchk_ag *sa) -{ - if (!sa->pag) - sa->pag = xfs_perag_get(mp, sa->agno); -} - /* Per-scrubber setup functions */ /* diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 0410faf7d735..454145db10e7 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -107,7 +107,23 @@ int xchk_setup_fscounters(struct xfs_scrub *sc); void xchk_ag_free(struct xfs_scrub *sc, struct xchk_ag *sa); int xchk_ag_init(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa); -void xchk_perag_get(struct xfs_mount *mp, struct xchk_ag *sa); + +/* + * Grab all AG resources, treating the inability to grab the perag structure as + * a fs corruption. This is intended for callers checking an ondisk reference + * to a given AG, which means that the AG must still exist. + */ +static inline int +xchk_ag_init_existing( + struct xfs_scrub *sc, + xfs_agnumber_t agno, + struct xchk_ag *sa) +{ + int error = xchk_ag_init(sc, agno, sa); + + return error == -ENOENT ? -EFSCORRUPTED : error; +} + int xchk_ag_read_headers(struct xfs_scrub *sc, xfs_agnumber_t agno, struct xchk_ag *sa); void xchk_ag_btcur_free(struct xchk_ag *sa); diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index fd7941e04ae1..b88ee69625d4 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -148,7 +148,7 @@ xchk_fscount_btreeblks( xfs_extlen_t blocks; int error; - error = xchk_ag_init(sc, agno, &sc->sa); + error = xchk_ag_init_existing(sc, agno, &sc->sa); if (error) return error; diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c index 76fbc7ca4cec..a6a68ba19f0a 100644 --- a/fs/xfs/scrub/inode.c +++ b/fs/xfs/scrub/inode.c @@ -532,7 +532,7 @@ xchk_inode_xref( agno = XFS_INO_TO_AGNO(sc->mp, ino); agbno = XFS_INO_TO_AGBNO(sc->mp, ino); - error = xchk_ag_init(sc, agno, &sc->sa); + error = xchk_ag_init_existing(sc, agno, &sc->sa); if (!xchk_xref_process_error(sc, agno, agbno, &error)) return; -- cgit v1.2.3-70-g09d2 From 43059d5416c9441aad8f50b96e00f3e8a8a49673 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 6 Aug 2021 11:06:35 -0700 Subject: xfs: dump log intent items that cannot be recovered due to corruption If we try to recover a log intent item and the operation fails due to filesystem corruption, dump the contents of the item to the log for further analysis. Signed-off-by: Darrick J. Wong Reviewed-by: Chandan Babu R Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_bmap_item.c | 3 +++ fs/xfs/xfs_extfree_item.c | 3 +++ fs/xfs/xfs_refcount_item.c | 3 +++ fs/xfs/xfs_rmap_item.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index e3a691937e92..3d6f70da8820 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -522,6 +522,9 @@ xfs_bui_item_recover( error = xfs_trans_log_finish_bmap_update(tp, budp, bui_type, ip, whichfork, bmap->me_startoff, bmap->me_startblock, &count, state); + if (error == -EFSCORRUPTED) + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bmap, + sizeof(*bmap)); if (error) goto err_cancel; diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 2424230ca2c3..3f8a0713573a 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -629,6 +629,9 @@ xfs_efi_item_recover( error = xfs_trans_free_extent(tp, efdp, extp->ext_start, extp->ext_len, &XFS_RMAP_OINFO_ANY_OWNER, false); + if (error == -EFSCORRUPTED) + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + extp, sizeof(*extp)); if (error) goto abort_error; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 746f4eda724c..163615285b18 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -522,6 +522,9 @@ xfs_cui_item_recover( error = xfs_trans_log_finish_refcount_update(tp, cudp, type, refc->pe_startblock, refc->pe_len, &new_fsb, &new_len, &rcur); + if (error == -EFSCORRUPTED) + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + refc, sizeof(*refc)); if (error) goto abort_error; diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c index dc4f0c9f0897..9b91a788722a 100644 --- a/fs/xfs/xfs_rmap_item.c +++ b/fs/xfs/xfs_rmap_item.c @@ -578,6 +578,9 @@ xfs_rui_item_recover( rmap->me_owner, whichfork, rmap->me_startoff, rmap->me_startblock, rmap->me_len, state, &rcur); + if (error == -EFSCORRUPTED) + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + rmap, sizeof(*rmap)); if (error) goto abort_error; -- cgit v1.2.3-70-g09d2 From 6303049d16f0e69d0449c3c80d0e3695d4f02f94 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 15 Jul 2021 16:59:57 -0500 Subject: PCI/VPD: Reject resource tags with invalid size VPD is limited in size by the 15-bit VPD Address field in the VPD Capability. Each resource tag includes a length that determines the overall size of the resource. Reject any resources that would extend past the maximum VPD size. Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 05e4df0a84d3..850deff0dd43 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -72,11 +72,11 @@ EXPORT_SYMBOL(pci_write_vpd); */ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) { - size_t off = 0; - unsigned char header[1+2]; /* 1 byte tag, 2 bytes length */ + size_t off = 0, size; + unsigned char tag, header[1+2]; /* 1 byte tag, 2 bytes length */ while (off < old_size && pci_read_vpd(dev, off, 1, header) == 1) { - unsigned char tag; + size = 0; if (off == 0 && (header[0] == 0x00 || header[0] == 0xff)) goto error; @@ -94,8 +94,11 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) off + 1); return 0; } - off += PCI_VPD_LRDT_TAG_SIZE + - pci_vpd_lrdt_size(header); + size = pci_vpd_lrdt_size(header); + if (off + size > PCI_VPD_MAX_SIZE) + goto error; + + off += PCI_VPD_LRDT_TAG_SIZE + size; } else { pci_warn(dev, "invalid large VPD tag %02x at offset %zu\n", tag, off); @@ -103,9 +106,12 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) } } else { /* Short Resource Data Type Tag */ - off += PCI_VPD_SRDT_TAG_SIZE + - pci_vpd_srdt_size(header); tag = pci_vpd_srdt_tag(header); + size = pci_vpd_srdt_size(header); + if (off + size > PCI_VPD_MAX_SIZE) + goto error; + + off += PCI_VPD_SRDT_TAG_SIZE + size; if (tag == PCI_VPD_STIN_END) /* End tag descriptor */ return off; } @@ -113,8 +119,8 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) return 0; error: - pci_info(dev, "invalid VPD tag %#04x at offset %zu%s\n", - header[0], off, off == 0 ? + pci_info(dev, "invalid VPD tag %#04x (size %zu) at offset %zu%s\n", + header[0], size, off, off == 0 ? "; assume missing optional EEPROM" : ""); return 0; } -- cgit v1.2.3-70-g09d2 From 7fa75dd8c64590850a54991a8bb914667c512b4c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 15 Jul 2021 16:59:58 -0500 Subject: PCI/VPD: Don't check Large Resource Item Names for validity VPD consists of a series of Small and Large Resources. Computing the size of VPD requires only the length of each, which is specified in the generic tag of each resource. We only expect to see ID_STRING, RO_DATA, and RW_DATA in VPD, but it's not a problem if it contains other resource types because all we care about is the size. Drop the validity checking of Large Resource items. Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 850deff0dd43..602d30220ec4 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -83,27 +83,16 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) if (header[0] & PCI_VPD_LRDT) { /* Large Resource Data Type Tag */ - tag = pci_vpd_lrdt_tag(header); - /* Only read length from known tag items */ - if ((tag == PCI_VPD_LTIN_ID_STRING) || - (tag == PCI_VPD_LTIN_RO_DATA) || - (tag == PCI_VPD_LTIN_RW_DATA)) { - if (pci_read_vpd(dev, off+1, 2, - &header[1]) != 2) { - pci_warn(dev, "failed VPD read at offset %zu\n", - off + 1); - return 0; - } - size = pci_vpd_lrdt_size(header); - if (off + size > PCI_VPD_MAX_SIZE) - goto error; - - off += PCI_VPD_LRDT_TAG_SIZE + size; - } else { - pci_warn(dev, "invalid large VPD tag %02x at offset %zu\n", - tag, off); + if (pci_read_vpd(dev, off + 1, 2, &header[1]) != 2) { + pci_warn(dev, "failed VPD read at offset %zu\n", + off + 1); return 0; } + size = pci_vpd_lrdt_size(header); + if (off + size > PCI_VPD_MAX_SIZE) + goto error; + + off += PCI_VPD_LRDT_TAG_SIZE + size; } else { /* Short Resource Data Type Tag */ tag = pci_vpd_srdt_tag(header); -- cgit v1.2.3-70-g09d2 From 5fe204eab174fd474227f23fd47faee4e7a6c000 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 15 Jul 2021 16:59:59 -0500 Subject: PCI/VPD: Allow access to valid parts of VPD if some is invalid Previously, if we found any error in the VPD, we returned size 0, which prevents access to all of VPD. But there may be valid resources in VPD before the error, and there's no reason to prevent access to those. "off" covers only VPD resources known to have valid header tags. In case of error, return "off" (which may be zero if we haven't found any valid header tags at all). Signed-off-by: Bjorn Helgaas Reviewed-by: Hannes Reinecke --- drivers/pci/vpd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 602d30220ec4..a85c8b51703a 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -86,7 +86,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) if (pci_read_vpd(dev, off + 1, 2, &header[1]) != 2) { pci_warn(dev, "failed VPD read at offset %zu\n", off + 1); - return 0; + return off; } size = pci_vpd_lrdt_size(header); if (off + size > PCI_VPD_MAX_SIZE) @@ -105,13 +105,13 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) return off; } } - return 0; + return off; error: pci_info(dev, "invalid VPD tag %#04x (size %zu) at offset %zu%s\n", header[0], size, off, off == 0 ? "; assume missing optional EEPROM" : ""); - return 0; + return off; } /* -- cgit v1.2.3-70-g09d2 From 1285762c07121b449cd60166b813c0084b792736 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 13 May 2021 22:56:09 +0200 Subject: PCI/VPD: Remove pci_vpd_size() old_size argument vpd->len is initialized to PCI_VPD_MAX_SIZE, and if a quirk is used to set a specific VPD size, then pci_vpd_set_size() sets vpd->valid, resulting in pci_vpd_size() not being called. Therefore we can remove the old_size argument. Note that we don't have to check off < PCI_VPD_MAX_SIZE because that's implicitly done by pci_read_vpd(). Link: https://lore.kernel.org/r/ede36c16-5335-6867-43a1-293641348430@gmail.com Signed-off-by: Heiner Kallweit Signed-off-by: Bjorn Helgaas --- drivers/pci/vpd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index a85c8b51703a..4f262f8530ea 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -68,14 +68,13 @@ EXPORT_SYMBOL(pci_write_vpd); /** * pci_vpd_size - determine actual size of Vital Product Data * @dev: pci device struct - * @old_size: current assumed size, also maximum allowed size */ -static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size) +static size_t pci_vpd_size(struct pci_dev *dev) { size_t off = 0, size; unsigned char tag, header[1+2]; /* 1 byte tag, 2 bytes length */ - while (off < old_size && pci_read_vpd(dev, off, 1, header) == 1) { + while (pci_read_vpd(dev, off, 1, header) == 1) { size = 0; if (off == 0 && (header[0] == 0x00 || header[0] == 0xff)) @@ -172,7 +171,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, if (!vpd->valid) { vpd->valid = 1; - vpd->len = pci_vpd_size(dev, vpd->len); + vpd->len = pci_vpd_size(dev); } if (vpd->len == 0) @@ -239,7 +238,7 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, if (!vpd->valid) { vpd->valid = 1; - vpd->len = pci_vpd_size(dev, vpd->len); + vpd->len = pci_vpd_size(dev); } if (vpd->len == 0) @@ -463,6 +462,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev) { if (dev->vpd) { dev->vpd->len = 0; + dev->vpd->valid = 1; pci_warn(dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n"); } } -- cgit v1.2.3-70-g09d2 From 91ab5d9d02a97264368eb1d72efdba2ec18cc0d4 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 13 May 2021 22:56:41 +0200 Subject: PCI/VPD: Make pci_vpd_wait() uninterruptible Reading/writing 4 bytes should be fast enough even on a slow bus, therefore pci_vpd_wait() doesn't have to be interruptible. Making it uninterruptible allows to simplify the code. In addition make VPD writes uninterruptible in general. It's about vital data, and allowing writes to be interruptible may leave the VPD in an inconsistent state. Link: https://lore.kernel.org/r/258bf994-bc2a-2907-9181-2c7a562986d5@gmail.com Signed-off-by: Heiner Kallweit Signed-off-by: Bjorn Helgaas --- drivers/pci/vpd.c | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 4f262f8530ea..3d9223f03a22 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -24,7 +24,6 @@ struct pci_vpd { unsigned int len; u16 flag; u8 cap; - unsigned int busy:1; unsigned int valid:1; }; @@ -129,22 +128,14 @@ static int pci_vpd_wait(struct pci_dev *dev) u16 status; int ret; - if (!vpd->busy) - return 0; - do { ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, &status); if (ret < 0) return ret; - if ((status & PCI_VPD_ADDR_F) == vpd->flag) { - vpd->busy = 0; + if ((status & PCI_VPD_ADDR_F) == vpd->flag) return 0; - } - - if (fatal_signal_pending(current)) - return -EINTR; if (time_after(jiffies, timeout)) break; @@ -162,7 +153,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, void *arg) { struct pci_vpd *vpd = dev->vpd; - int ret; + int ret = 0; loff_t end = pos + count; u8 *buf = arg; @@ -188,19 +179,19 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, if (mutex_lock_killable(&vpd->lock)) return -EINTR; - ret = pci_vpd_wait(dev); - if (ret < 0) - goto out; - while (pos < end) { u32 val; unsigned int i, skip; + if (fatal_signal_pending(current)) { + ret = -EINTR; + break; + } + ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR, pos & ~3); if (ret < 0) break; - vpd->busy = 1; vpd->flag = PCI_VPD_ADDR_F; ret = pci_vpd_wait(dev); if (ret < 0) @@ -220,7 +211,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, val >>= 8; } } -out: + mutex_unlock(&vpd->lock); return ret ? ret : count; } @@ -250,10 +241,6 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, if (mutex_lock_killable(&vpd->lock)) return -EINTR; - ret = pci_vpd_wait(dev); - if (ret < 0) - goto out; - while (pos < end) { u32 val; @@ -270,7 +257,6 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, if (ret < 0) break; - vpd->busy = 1; vpd->flag = 0; ret = pci_vpd_wait(dev); if (ret < 0) @@ -278,7 +264,7 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, pos += sizeof(u32); } -out: + mutex_unlock(&vpd->lock); return ret ? ret : count; } @@ -341,7 +327,6 @@ void pci_vpd_init(struct pci_dev *dev) vpd->ops = &pci_vpd_ops; mutex_init(&vpd->lock); vpd->cap = cap; - vpd->busy = 0; vpd->valid = 0; dev->vpd = vpd; } -- cgit v1.2.3-70-g09d2 From fe943bd8ab75552f2773ee27c7c5ae6b48941582 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 13 May 2021 23:02:01 +0200 Subject: PCI/VPD: Remove struct pci_vpd.flag The struct pci_vpd.flag member was used only to communicate between pci_vpd_wait() and its callers. Remove the flag member and pass the value directly to pci_vpd_wait() to simplify the code. [bhelgaas: commit log] Link: https://lore.kernel.org/r/e4ef6845-6b23-1646-28a0-d5c5a28347b6@gmail.com Signed-off-by: Heiner Kallweit Signed-off-by: Bjorn Helgaas --- drivers/pci/vpd.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c index 3d9223f03a22..d7f705ba6664 100644 --- a/drivers/pci/vpd.c +++ b/drivers/pci/vpd.c @@ -22,7 +22,6 @@ struct pci_vpd { const struct pci_vpd_ops *ops; struct mutex lock; unsigned int len; - u16 flag; u8 cap; unsigned int valid:1; }; @@ -117,10 +116,11 @@ error: * This code has to spin since there is no other notification from the PCI * hardware. Since the VPD is often implemented by serial attachment to an * EEPROM, it may take many milliseconds to complete. + * @set: if true wait for flag to be set, else wait for it to be cleared * * Returns 0 on success, negative values indicate error. */ -static int pci_vpd_wait(struct pci_dev *dev) +static int pci_vpd_wait(struct pci_dev *dev, bool set) { struct pci_vpd *vpd = dev->vpd; unsigned long timeout = jiffies + msecs_to_jiffies(125); @@ -134,7 +134,7 @@ static int pci_vpd_wait(struct pci_dev *dev) if (ret < 0) return ret; - if ((status & PCI_VPD_ADDR_F) == vpd->flag) + if (!!(status & PCI_VPD_ADDR_F) == set) return 0; if (time_after(jiffies, timeout)) @@ -192,8 +192,7 @@ static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count, pos & ~3); if (ret < 0) break; - vpd->flag = PCI_VPD_ADDR_F; - ret = pci_vpd_wait(dev); + ret = pci_vpd_wait(dev, true); if (ret < 0) break; @@ -257,8 +256,7 @@ static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count, if (ret < 0) break; - vpd->flag = 0; - ret = pci_vpd_wait(dev); + ret = pci_vpd_wait(dev, false); if (ret < 0) break; -- cgit v1.2.3-70-g09d2 From b6ac16eed3080169b674bf6e960bd2d272dd1cd3 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 6 Aug 2021 15:54:04 +0800 Subject: perf vendor events: Add metrics for Icelake Server Add JSON metrics for Icelake Server to perf. Based on TMA metrics 4.21 at 01.org. https://download.01.org/perfmon/ Signed-off-by: Jin Yao Reviewed-by: Andi Kleen Reviewed-by: Ian Rogers Cc: Alexander Shishkin Cc: Jin Yao Cc: Jiri Olsa Cc: Kan Liang Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210806075404.31209-1-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/x86/icelakex/icx-metrics.json | 315 +++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json diff --git a/tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json b/tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json new file mode 100644 index 000000000000..57ddbb9f9b31 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/icelakex/icx-metrics.json @@ -0,0 +1,315 @@ +[ + { + "BriefDescription": "Instructions Per Cycle (per Logical Processor)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Summary", + "MetricName": "IPC" + }, + { + "BriefDescription": "Uops Per Instruction", + "MetricExpr": "UOPS_RETIRED.SLOTS / INST_RETIRED.ANY", + "MetricGroup": "Pipeline;Retire", + "MetricName": "UPI" + }, + { + "BriefDescription": "Instruction per taken branch", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_TAKEN", + "MetricGroup": "Branches;FetchBW;PGO", + "MetricName": "IpTB" + }, + { + "BriefDescription": "Cycles Per Instruction (per Logical Processor)", + "MetricExpr": "1 / (INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD)", + "MetricGroup": "Pipeline", + "MetricName": "CPI" + }, + { + "BriefDescription": "Per-Logical Processor actual clocks when the Logical Processor is active.", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Pipeline", + "MetricName": "CLKS" + }, + { + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "Flops", + "MetricName": "FLOPc" + }, + { + "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", + "MetricExpr": "UOPS_EXECUTED.THREAD / (( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 ) if #SMT_on else UOPS_EXECUTED.CORE_CYCLES_GE_1)", + "MetricGroup": "Pipeline;PortsUtil", + "MetricName": "ILP" + }, + { + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "MetricGroup": "BrMispredicts", + "MetricName": "IpMispredict" + }, + { + "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", + "MetricExpr": "CPU_CLK_UNHALTED.DISTRIBUTED", + "MetricGroup": "SMT", + "MetricName": "CORE_CLKS" + }, + { + "BriefDescription": "Instructions per Load (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_LOADS", + "MetricGroup": "InsType", + "MetricName": "IpLoad" + }, + { + "BriefDescription": "Instructions per Store (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_STORES", + "MetricGroup": "InsType", + "MetricName": "IpStore" + }, + { + "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", + "MetricGroup": "Branches;InsType", + "MetricName": "IpBranch" + }, + { + "BriefDescription": "Instructions per (near) call (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_CALL", + "MetricGroup": "Branches", + "MetricName": "IpCall" + }, + { + "BriefDescription": "Branch instructions per taken branch. ", + "MetricExpr": "BR_INST_RETIRED.ALL_BRANCHES / BR_INST_RETIRED.NEAR_TAKEN", + "MetricGroup": "Branches;PGO", + "MetricName": "BpTkBranch" + }, + { + "BriefDescription": "Instructions per Floating Point (FP) Operation (lower number means higher occurrence rate)", + "MetricExpr": "INST_RETIRED.ANY / ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE )", + "MetricGroup": "Flops;FpArith;InsType", + "MetricName": "IpFLOP" + }, + { + "BriefDescription": "Total number of retired Instructions, Sample with: INST_RETIRED.PREC_DIST", + "MetricExpr": "INST_RETIRED.ANY", + "MetricGroup": "Summary;TmaL1", + "MetricName": "Instructions" + }, + { + "BriefDescription": "Fraction of Uops delivered by the LSD (Loop Stream Detector; aka Loop Cache)", + "MetricExpr": "LSD.UOPS / (IDQ.DSB_UOPS + LSD.UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", + "MetricGroup": "LSD", + "MetricName": "LSD_Coverage" + }, + { + "BriefDescription": "Fraction of Uops delivered by the DSB (aka Decoded ICache; or Uop Cache)", + "MetricExpr": "IDQ.DSB_UOPS / (IDQ.DSB_UOPS + LSD.UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", + "MetricGroup": "DSB;FetchBW", + "MetricName": "DSB_Coverage" + }, + { + "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads (in core cycles)", + "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", + "MetricGroup": "MemoryBound;MemoryLat", + "MetricName": "Load_Miss_Real_Latency" + }, + { + "BriefDescription": "Memory-Level-Parallelism (average number of L1 miss demand load when there is at least one such miss. Per-Logical Processor)", + "MetricExpr": "L1D_PEND_MISS.PENDING / L1D_PEND_MISS.PENDING_CYCLES", + "MetricGroup": "MemoryBound;MemoryBW", + "MetricName": "MLP" + }, + { + "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", + "MetricConstraint": "NO_NMI_WATCHDOG", + "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING ) / ( 2 * CPU_CLK_UNHALTED.DISTRIBUTED )", + "MetricGroup": "MemoryTLB", + "MetricName": "Page_Walks_Utilization" + }, + { + "BriefDescription": "Average data fill bandwidth to the L1 data cache [GB / sec]", + "MetricExpr": "64 * L1D.REPLACEMENT / 1000000000 / duration_time", + "MetricGroup": "MemoryBW", + "MetricName": "L1D_Cache_Fill_BW" + }, + { + "BriefDescription": "Average data fill bandwidth to the L2 cache [GB / sec]", + "MetricExpr": "64 * L2_LINES_IN.ALL / 1000000000 / duration_time", + "MetricGroup": "MemoryBW", + "MetricName": "L2_Cache_Fill_BW" + }, + { + "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", + "MetricExpr": "64 * LONGEST_LAT_CACHE.MISS / 1000000000 / duration_time", + "MetricGroup": "MemoryBW", + "MetricName": "L3_Cache_Fill_BW" + }, + { + "BriefDescription": "Average per-core data access bandwidth to the L3 cache [GB / sec]", + "MetricExpr": "64 * OFFCORE_REQUESTS.ALL_REQUESTS / 1000000000 / duration_time", + "MetricGroup": "MemoryBW;Offcore", + "MetricName": "L3_Cache_Access_BW" + }, + { + "BriefDescription": "L1 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L1_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L1MPKI" + }, + { + "BriefDescription": "L2 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L2_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L2MPKI" + }, + { + "BriefDescription": "L2 cache misses per kilo instruction for all request types (including speculative)", + "MetricExpr": "1000 * ( ( OFFCORE_REQUESTS.ALL_DATA_RD - OFFCORE_REQUESTS.DEMAND_DATA_RD ) + L2_RQSTS.ALL_DEMAND_MISS + L2_RQSTS.SWPF_MISS ) / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses;Offcore", + "MetricName": "L2MPKI_All" + }, + { + "BriefDescription": "L3 cache true misses per kilo instruction for retired demand loads", + "MetricExpr": "1000 * MEM_LOAD_RETIRED.L3_MISS / INST_RETIRED.ANY", + "MetricGroup": "CacheMisses", + "MetricName": "L3MPKI" + }, + { + "BriefDescription": "Rate of silent evictions from the L2 cache per Kilo instruction where the evicted lines are dropped (no writeback to L3 or memory)", + "MetricExpr": "1000 * L2_LINES_OUT.SILENT / INST_RETIRED.ANY", + "MetricGroup": "L2Evicts;Server", + "MetricName": "L2_Evictions_Silent_PKI" + }, + { + "BriefDescription": "Rate of non silent evictions from the L2 cache per Kilo instruction", + "MetricExpr": "1000 * L2_LINES_OUT.NON_SILENT / INST_RETIRED.ANY", + "MetricGroup": "L2Evicts;Server", + "MetricName": "L2_Evictions_NonSilent_PKI" + }, + { + "BriefDescription": "Average CPU Utilization", + "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", + "MetricGroup": "HPC;Summary", + "MetricName": "CPU_Utilization" + }, + { + "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", + "MetricExpr": "(CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC) * msr@tsc@ / 1000000000 / duration_time", + "MetricGroup": "Summary;Power", + "MetricName": "Average_Frequency" + }, + { + "BriefDescription": "Giga Floating Point Operations Per Second", + "MetricExpr": "( ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / 1000000000 ) / duration_time", + "MetricGroup": "Flops;HPC", + "MetricName": "GFLOPs" + }, + { + "BriefDescription": "Average Frequency Utilization relative nominal frequency", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC", + "MetricGroup": "Power", + "MetricName": "Turbo_Utilization" + }, + { + "BriefDescription": "Fraction of cycles where both hardware Logical Processors were active", + "MetricExpr": "1 - CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_DISTRIBUTED if #SMT_on else 0", + "MetricGroup": "SMT", + "MetricName": "SMT_2T_Utilization" + }, + { + "BriefDescription": "Fraction of cycles spent in the Operating System (OS) Kernel mode", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD_P:k / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "OS", + "MetricName": "Kernel_Utilization" + }, + { + "BriefDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]", + "MetricExpr": "( 64 * ( uncore_imc@cas_count_read@ + uncore_imc@cas_count_write@ ) / 1000000000 ) / duration_time", + "MetricGroup": "HPC;MemoryBW;SoC", + "MetricName": "DRAM_BW_Use" + }, + { + "BriefDescription": "Average latency of data read request to external memory (in nanoseconds). Accounts for demand loads and L1/L2 prefetches", + "MetricExpr": "1000000000 * ( UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD / UNC_CHA_TOR_INSERTS.IA_MISS_DRD ) / ( cha_0@event\\=0x0@ / duration_time )", + "MetricGroup": "MemoryLat;SoC", + "MetricName": "MEM_Read_Latency" + }, + { + "BriefDescription": "Average number of parallel data read requests to external memory. Accounts for demand loads and L1/L2 prefetches", + "MetricExpr": "UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD / cha@event\\=0x36\\,umask\\=0xC817FE01\\,thresh\\=1@", + "MetricGroup": "MemoryBW;SoC", + "MetricName": "MEM_Parallel_Reads" + }, + { + "BriefDescription": "Average latency of data read request to external 3D X-Point memory [in nanoseconds]. Accounts for demand loads and L1/L2 data-read prefetches", + "MetricExpr": "( 1000000000 * ( UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD_PMM / UNC_CHA_TOR_INSERTS.IA_MISS_DRD_PMM ) / cha_0@event\\=0x0@ )", + "MetricGroup": "MemoryLat;SoC;Server", + "MetricName": "MEM_PMM_Read_Latency" + }, + { + "BriefDescription": "Average 3DXP Memory Bandwidth Use for reads [GB / sec]", + "MetricExpr": "( ( 64 * imc@event\\=0xe3@ / 1000000000 ) / duration_time )", + "MetricGroup": "MemoryBW;SoC;Server", + "MetricName": "PMM_Read_BW" + }, + { + "BriefDescription": "Average 3DXP Memory Bandwidth Use for Writes [GB / sec]", + "MetricExpr": "( ( 64 * imc@event\\=0xe7@ / 1000000000 ) / duration_time )", + "MetricGroup": "MemoryBW;SoC;Server", + "MetricName": "PMM_Write_BW" + }, + { + "BriefDescription": "Average IO (network or disk) Bandwidth Use for Writes [GB / sec]", + "MetricExpr": "UNC_CHA_TOR_INSERTS.IO_PCIRDCUR * 64 / 1000000000 / duration_time", + "MetricGroup": "IoBW;SoC;Server", + "MetricName": "IO_Write_BW" + }, + { + "BriefDescription": "Average IO (network or disk) Bandwidth Use for Reads [GB / sec]", + "MetricExpr": "( UNC_CHA_TOR_INSERTS.IO_HIT_ITOM + UNC_CHA_TOR_INSERTS.IO_MISS_ITOM + UNC_CHA_TOR_INSERTS.IO_HIT_ITOMCACHENEAR + UNC_CHA_TOR_INSERTS.IO_MISS_ITOMCACHENEAR ) * 64 / 1000000000 / duration_time", + "MetricGroup": "IoBW;SoC;Server", + "MetricName": "IO_Read_BW" + }, + { + "BriefDescription": "Socket actual clocks when any core is active on that socket", + "MetricExpr": "cha_0@event\\=0x0@", + "MetricGroup": "SoC", + "MetricName": "Socket_CLKS" + }, + { + "BriefDescription": "Instructions per Far Branch ( Far Branches apply upon transition from application to operating system, handling interrupts, exceptions) [lower number means higher occurrence rate]", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.FAR_BRANCH:u", + "MetricGroup": "Branches;OS", + "MetricName": "IpFarBranch" + }, + { + "BriefDescription": "C1 residency percent per core", + "MetricExpr": "(cstate_core@c1\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C1_Core_Residency" + }, + { + "BriefDescription": "C6 residency percent per core", + "MetricExpr": "(cstate_core@c6\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C6_Core_Residency" + }, + { + "BriefDescription": "C2 residency percent per package", + "MetricExpr": "(cstate_pkg@c2\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C2_Pkg_Residency" + }, + { + "BriefDescription": "C6 residency percent per package", + "MetricExpr": "(cstate_pkg@c6\\-residency@ / msr@tsc@) * 100", + "MetricGroup": "Power", + "MetricName": "C6_Pkg_Residency" + }, +] -- cgit v1.2.3-70-g09d2 From 9c38b671ebd5297d861522806e09cf9e639d0af6 Mon Sep 17 00:00:00 2001 From: James Clark Date: Thu, 5 Aug 2021 14:03:54 +0100 Subject: perf cs-etm: Add warnings for missing DSOs Currently decode will silently fail if no binary data is available for the decode. This is made worse if only partial data is available because the decode will appear to work, but any trace from that missing DSO will silently not be generated. Add a UI popup once if there is any data missing, and then warn in the bottom left for each individual DSO that's missing. Reviewed-by: Leo Yan Signed-off-by: James Clark Cc: Alexander Shishkin Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: http //lore.kernel.org/lkml/20210805130354.878120-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index f4b2bff533f3..b59d234e437d 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -716,8 +716,17 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size); - if (len <= 0) + if (len <= 0) { + ui__warning_once("CS ETM Trace: Missing DSO. Use 'perf archive' or debuginfod to export data from the traced system.\n" + " Enable CONFIG_PROC_KCORE or use option '-k /path/to/vmlinux' for kernel symbols.\n"); + if (!al.map->dso->auxtrace_warned) { + pr_err("CS ETM Trace: Debug data not found for address %#"PRIx64" in %s\n", + address, + al.map->dso->long_name ? al.map->dso->long_name : "Unknown"); + al.map->dso->auxtrace_warned = true; + } return 0; + } return len; } -- cgit v1.2.3-70-g09d2 From b7ae6d43786ed6b834892d444cee28eba24e56f6 Mon Sep 17 00:00:00 2001 From: Stephen Brennan Date: Fri, 6 Aug 2021 13:45:01 -0700 Subject: perf script python: Fix unintended underline The text ranging from "subsystem__event_name" to "raw_syscalls__sys_enter()" is interpreted by asciidoc as a pair of unconstrained text formatting markers. The result is that the manual page displayed this text as underlined, and the HTML pages displayed this text as italicized. Escape the first double-underscore to prevent this. https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/ Signed-off-by: Stephen Brennan Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210806204502.110305-1-stephen.s.brennan@oracle.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script-python.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt index 5e43cfa5ea1e..0250dc61cf98 100644 --- a/tools/perf/Documentation/perf-script-python.txt +++ b/tools/perf/Documentation/perf-script-python.txt @@ -167,7 +167,7 @@ below). Following those are the 'event handler' functions generated one for every event in the 'perf record' output. The handler functions take -the form subsystem__event_name, and contain named parameters, one for +the form subsystem\__event_name, and contain named parameters, one for each field in the event; in this case, there's only one event, raw_syscalls__sys_enter(). (see the EVENT HANDLERS section below for more info on event handlers). -- cgit v1.2.3-70-g09d2 From 1ea3cb159e304f83136ebeb0e56b0cb8a7203cda Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:03 +0800 Subject: perf auxtrace: Use WRITE_ONCE() for updating aux_tail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use WRITE_ONCE() for updating aux_tail, so can avoid unexpected memory behaviour. Signed-off-by: Leo Yan Acked-by: Adrian Hunter Acked-by: Peter Zijlstra Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Borislav Petkov Cc: Daniel Díaz Cc: Frank Ch. Eigler Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Mark Rutland Cc: Mathieu Poirier Cc: Michael Petlan Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Song Liu Cc: Suzuki Poulouse Cc: Thomas Gleixner Cc: coresight@lists.linaro.org Cc: x86@kernel.org Link: http //lore.kernel.org/lkml/20210809111407.596077-6-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index cc1c1b9cec9c..79227b8864cd 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -480,7 +480,7 @@ static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail) /* Ensure all reads are done before we write the tail out */ smp_mb(); #if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT) - pc->aux_tail = tail; + WRITE_ONCE(pc->aux_tail, tail); #else do { old_tail = __sync_val_compare_and_swap(&pc->aux_tail, 0, 0); -- cgit v1.2.3-70-g09d2 From 1fc7e593e2028f5e0949a67050b4c15167698a4f Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:04 +0800 Subject: perf auxtrace: Drop legacy __sync functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main purpose for using __sync built-in functions is to support compat mode for 32-bit perf with 64-bit kernel. But using these built-in functions might cause potential issues. __sync functions originally support Intel Itanium processoer [1] but it cannot promise to support all 32-bit archs. Now these functions have become the legacy functions. Considering __sync functions cannot really fix the 64-bit value atomicity on 32-bit archs, thus this patch drops __sync functions. Credits to Peter for detailed analysis. [1] https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins Suggested-by: Peter Zijlstra Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Borislav Petkov Cc: Daniel Díaz Cc: Frank Ch. Eigler Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Mark Rutland Cc: Mathieu Poirier Cc: Michael Petlan Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Song Liu Cc: Suzuki Poulouse Cc: Thomas Gleixner Cc: coresight@lists.linaro.org Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/20210809111407.596077-7-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 79227b8864cd..4f9176368134 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -440,12 +440,6 @@ struct auxtrace_cache; #ifdef HAVE_AUXTRACE_SUPPORT -/* - * In snapshot mode the mmapped page is read-only which makes using - * __sync_val_compare_and_swap() problematic. However, snapshot mode expects - * the buffer is not updated while the snapshot is made (e.g. Intel PT disables - * the event) so there is not a race anyway. - */ static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm) { struct perf_event_mmap_page *pc = mm->userpg; @@ -459,11 +453,7 @@ static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm) static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm) { struct perf_event_mmap_page *pc = mm->userpg; -#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT) u64 head = READ_ONCE(pc->aux_head); -#else - u64 head = __sync_val_compare_and_swap(&pc->aux_head, 0, 0); -#endif /* Ensure all reads are done after we read the head */ smp_rmb(); @@ -473,19 +463,10 @@ static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm) static inline void auxtrace_mmap__write_tail(struct auxtrace_mmap *mm, u64 tail) { struct perf_event_mmap_page *pc = mm->userpg; -#if BITS_PER_LONG != 64 && defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT) - u64 old_tail; -#endif /* Ensure all reads are done before we write the tail out */ smp_mb(); -#if BITS_PER_LONG == 64 || !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT) WRITE_ONCE(pc->aux_tail, tail); -#else - do { - old_tail = __sync_val_compare_and_swap(&pc->aux_tail, 0, 0); - } while (!__sync_bool_compare_and_swap(&pc->aux_tail, old_tail, tail)); -#endif } int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, -- cgit v1.2.3-70-g09d2 From 9d6450330879791831e6fd3fc20a55990c889a7d Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:05 +0800 Subject: perf auxtrace: Remove auxtrace_mmap__read_snapshot_head() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the function auxtrace_mmap__read_snapshot_head() is exactly same with auxtrace_mmap__read_head(), whether the session is in snapshot mode or not, it's unified to use function auxtrace_mmap__read_head() for reading AUX buffer head. And the function auxtrace_mmap__read_snapshot_head() is unused so this patch removes it. Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Borislav Petkov Cc: Daniel Díaz Cc: Frank Ch. Eigler Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Mark Rutland Cc: Mathieu Poirier Cc: Michael Petlan Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Song Liu Cc: Suzuki Poulouse Cc: Thomas Gleixner Cc: coresight@lists.linaro.org Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/20210809111407.596077-8-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/auxtrace.c | 13 +++++-------- tools/perf/util/auxtrace.h | 10 ---------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index cb19669d2a5b..2dcf3d12ba32 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1686,14 +1686,11 @@ static int __auxtrace_mmap__read(struct mmap *map, union perf_event ev; void *data1, *data2; - if (snapshot) { - head = auxtrace_mmap__read_snapshot_head(mm); - if (auxtrace_record__find_snapshot(itr, mm->idx, mm, data, - &head, &old)) - return -1; - } else { - head = auxtrace_mmap__read_head(mm); - } + head = auxtrace_mmap__read_head(mm); + + if (snapshot && + auxtrace_record__find_snapshot(itr, mm->idx, mm, data, &head, &old)) + return -1; if (old == head) return 0; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index 4f9176368134..d68a5e80b217 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -440,16 +440,6 @@ struct auxtrace_cache; #ifdef HAVE_AUXTRACE_SUPPORT -static inline u64 auxtrace_mmap__read_snapshot_head(struct auxtrace_mmap *mm) -{ - struct perf_event_mmap_page *pc = mm->userpg; - u64 head = READ_ONCE(pc->aux_head); - - /* Ensure all reads are done after we read the head */ - smp_rmb(); - return head; -} - static inline u64 auxtrace_mmap__read_head(struct auxtrace_mmap *mm) { struct perf_event_mmap_page *pc = mm->userpg; -- cgit v1.2.3-70-g09d2 From 65c45afb14691d431a9b9faef10700f740ab1ba0 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:06 +0800 Subject: perf: Cleanup for HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the __sync functions have been dropped, This patch removes unused build and checking for HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT in perf tool. Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Borislav Petkov Cc: Daniel Díaz Cc: Frank Ch. Eigler Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Mark Rutland Cc: Mathieu Poirier Cc: Michael Petlan Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Song Liu Cc: Suzuki Poulouse Cc: Thomas Gleixner Cc: coresight@lists.linaro.org Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/20210809111407.596077-9-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.config | 4 ---- tools/perf/util/auxtrace.c | 5 ----- 2 files changed, 9 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index eb8e487ef90b..4a0d9a6defc7 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -349,10 +349,6 @@ CXXFLAGS += $(INC_FLAGS) LIBPERF_CFLAGS := $(CORE_CFLAGS) $(EXTRA_CFLAGS) -ifeq ($(feature-sync-compare-and-swap), 1) - CFLAGS += -DHAVE_SYNC_COMPARE_AND_SWAP_SUPPORT -endif - ifeq ($(feature-pthread-attr-setaffinity-np), 1) CFLAGS += -DHAVE_PTHREAD_ATTR_SETAFFINITY_NP endif diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 2dcf3d12ba32..f33f09b8b535 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -130,11 +130,6 @@ int auxtrace_mmap__mmap(struct auxtrace_mmap *mm, return 0; } -#if BITS_PER_LONG != 64 && !defined(HAVE_SYNC_COMPARE_AND_SWAP_SUPPORT) - pr_err("Cannot use AUX area tracing mmaps\n"); - return -1; -#endif - pc->aux_offset = mp->offset; pc->aux_size = mp->len; -- cgit v1.2.3-70-g09d2 From 60fa754b2a5a4e0c44669f8d926a5a980c50b1e8 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:07 +0800 Subject: tools: Remove feature-sync-compare-and-swap feature detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the __sync functions have been removed from perf, it's needless for perf tool to test the feature sync-compare-and-swap. The feature test is not used by any other components, remove it. Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Andi Kleen Cc: Andrii Nakryiko Cc: Borislav Petkov Cc: Daniel Díaz Cc: Frank Ch. Eigler Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Mark Rutland Cc: Mathieu Poirier Cc: Michael Petlan Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Sedat Dilek Cc: Song Liu Cc: Suzuki Poulouse Cc: Thomas Gleixner Cc: coresight@lists.linaro.org Cc: x86@kernel.org Link: http://lore.kernel.org/lkml/20210809111407.596077-10-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/build/Makefile.feature | 1 - tools/build/feature/Makefile | 4 ---- tools/build/feature/test-all.c | 4 ---- tools/build/feature/test-sync-compare-and-swap.c | 15 --------------- 4 files changed, 24 deletions(-) delete mode 100644 tools/build/feature/test-sync-compare-and-swap.c diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 04a8e3db8a54..3dd2f68366f9 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -34,7 +34,6 @@ FEATURE_TESTS_BASIC := \ dwarf_getlocations \ eventfd \ fortify-source \ - sync-compare-and-swap \ get_current_dir_name \ gettid \ glibc \ diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index ec203e28407f..eff55d287db1 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -9,7 +9,6 @@ FILES= \ test-dwarf_getlocations.bin \ test-eventfd.bin \ test-fortify-source.bin \ - test-sync-compare-and-swap.bin \ test-get_current_dir_name.bin \ test-glibc.bin \ test-gtk2.bin \ @@ -260,9 +259,6 @@ $(OUTPUT)test-libdw-dwarf-unwind.bin: $(OUTPUT)test-libbabeltrace.bin: $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace) -$(OUTPUT)test-sync-compare-and-swap.bin: - $(BUILD) - $(OUTPUT)test-compile-32.bin: $(CC) -m32 -o $@ test-compile.c diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index 464873883396..920439527291 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -106,10 +106,6 @@ # include "test-libdw-dwarf-unwind.c" #undef main -#define main main_test_sync_compare_and_swap -# include "test-sync-compare-and-swap.c" -#undef main - #define main main_test_zlib # include "test-zlib.c" #undef main diff --git a/tools/build/feature/test-sync-compare-and-swap.c b/tools/build/feature/test-sync-compare-and-swap.c deleted file mode 100644 index 3bc6b0768a53..000000000000 --- a/tools/build/feature/test-sync-compare-and-swap.c +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include - -volatile uint64_t x; - -int main(int argc, char *argv[]) -{ - uint64_t old, new = argc; - - (void)argv; - do { - old = __sync_val_compare_and_swap(&x, 0, 0); - } while (!__sync_bool_compare_and_swap(&x, old, new)); - return old == new; -} -- cgit v1.2.3-70-g09d2 From 7c0223e1ddd7d1c16b76adf8c9c352771856c632 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:27:25 +0800 Subject: perf env: Track kernel 64-bit mode in environment It's useful to know that the kernel is running in 32-bit or 64-bit mode. E.g. We can decide if perf tool is running in compat mode based on the info. This patch adds an item "kernel_is_64_bit" into session's environment structure perf_env, its value is initialized based on the architecture string. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Leo Yan Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Andi Kleen Cc: Catalin Marinas Cc: Jin Yao Cc: Jiri Olsa Cc: John Garry Cc: Li Huafei Cc: Mark Rutland Cc: Mathieu Poirier Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Riccardo Mancini Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Cc: russell king Link: http://lore.kernel.org/lkml/20210809112727.596876-2-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/env.c | 24 +++++++++++++++++++++++- tools/perf/util/env.h | 3 +++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index ab341050be46..8f7ff0035c41 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -219,13 +219,35 @@ void perf_env__exit(struct perf_env *env) zfree(&env->hybrid_cpc_nodes); } -void perf_env__init(struct perf_env *env __maybe_unused) +void perf_env__init(struct perf_env *env) { #ifdef HAVE_LIBBPF_SUPPORT env->bpf_progs.infos = RB_ROOT; env->bpf_progs.btfs = RB_ROOT; init_rwsem(&env->bpf_progs.lock); #endif + env->kernel_is_64_bit = -1; +} + +static void perf_env__init_kernel_mode(struct perf_env *env) +{ + const char *arch = perf_env__raw_arch(env); + + if (!strncmp(arch, "x86_64", 6) || !strncmp(arch, "aarch64", 7) || + !strncmp(arch, "arm64", 5) || !strncmp(arch, "mips64", 6) || + !strncmp(arch, "parisc64", 8) || !strncmp(arch, "riscv64", 7) || + !strncmp(arch, "s390x", 5) || !strncmp(arch, "sparc64", 7)) + env->kernel_is_64_bit = 1; + else + env->kernel_is_64_bit = 0; +} + +int perf_env__kernel_is_64_bit(struct perf_env *env) +{ + if (env->kernel_is_64_bit == -1) + perf_env__init_kernel_mode(env); + + return env->kernel_is_64_bit; } int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]) diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index 6824a7423a2d..1f5175820a05 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -61,6 +61,7 @@ struct perf_env { unsigned long long total_mem; unsigned int msr_pmu_type; unsigned int max_branches; + int kernel_is_64_bit; int nr_cmdline; int nr_sibling_cores; @@ -143,6 +144,8 @@ extern struct perf_env perf_env; void perf_env__exit(struct perf_env *env); +int perf_env__kernel_is_64_bit(struct perf_env *env); + int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[]); int perf_env__read_cpuid(struct perf_env *env); -- cgit v1.2.3-70-g09d2 From aede517207b2bf4e5176492ce3be0e45feb581bd Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:04 -0400 Subject: SUNRPC: Refactor rpc_ping() Make it use the rpc_null_call_helper() so that it can share the new rpc_call_ops structure to be introduced in the next patch. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/clnt.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8b4de70e8ead..ca2000d8cf64 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2694,17 +2694,6 @@ static const struct rpc_procinfo rpcproc_null = { .p_decode = rpcproc_decode_null, }; -static int rpc_ping(struct rpc_clnt *clnt) -{ - struct rpc_message msg = { - .rpc_proc = &rpcproc_null, - }; - int err; - err = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN | - RPC_TASK_NULLCREDS); - return err; -} - static struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt, struct rpc_xprt *xprt, struct rpc_cred *cred, int flags, @@ -2733,6 +2722,19 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int } EXPORT_SYMBOL_GPL(rpc_call_null); +static int rpc_ping(struct rpc_clnt *clnt) +{ + struct rpc_task *task; + int status; + + task = rpc_call_null_helper(clnt, NULL, NULL, 0, NULL, NULL); + if (IS_ERR(task)) + return PTR_ERR(task); + status = task->tk_status; + rpc_put_task(task); + return status; +} + struct rpc_cb_add_xprt_calldata { struct rpc_xprt_switch *xps; struct rpc_xprt *xprt; -- cgit v1.2.3-70-g09d2 From 823c73d0c539a0c1740c7929a7aad3f844e69d70 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:10 -0400 Subject: SUNRPC: Unset RPC_TASK_NO_RETRANS_TIMEOUT for NULL RPCs In some rare failure modes, the server is actually reading the transport, but then just dropping the requests on the floor. TCP_USER_TIMEOUT cannot detect that case. Prevent such a stuck server from pinning client resources indefinitely by ensuring that certain idempotent requests (such as NULL) can time out even if the connection is still operational. Otherwise rpc_bind_new_program(), gss_destroy_cred(), or rpc_clnt_test_and_add_xprt() can wait forever. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/clnt.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index ca2000d8cf64..d34737a8a68a 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2694,6 +2694,18 @@ static const struct rpc_procinfo rpcproc_null = { .p_decode = rpcproc_decode_null, }; +static void +rpc_null_call_prepare(struct rpc_task *task, void *data) +{ + task->tk_flags &= ~RPC_TASK_NO_RETRANS_TIMEOUT; + rpc_call_start(task); +} + +static const struct rpc_call_ops rpc_null_ops = { + .rpc_call_prepare = rpc_null_call_prepare, + .rpc_call_done = rpc_default_callback, +}; + static struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt, struct rpc_xprt *xprt, struct rpc_cred *cred, int flags, @@ -2707,7 +2719,7 @@ struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt, .rpc_xprt = xprt, .rpc_message = &msg, .rpc_op_cred = cred, - .callback_ops = (ops != NULL) ? ops : &rpc_default_ops, + .callback_ops = ops ?: &rpc_null_ops, .callback_data = data, .flags = flags | RPC_TASK_SOFT | RPC_TASK_SOFTCONN | RPC_TASK_NULLCREDS, @@ -2758,6 +2770,7 @@ static void rpc_cb_add_xprt_release(void *calldata) } static const struct rpc_call_ops rpc_cb_add_xprt_call_ops = { + .rpc_call_prepare = rpc_null_call_prepare, .rpc_call_done = rpc_cb_add_xprt_done, .rpc_release = rpc_cb_add_xprt_release, }; -- cgit v1.2.3-70-g09d2 From d480696dc68943538b81a26b0f4f39eb50c41380 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:16 -0400 Subject: SUNRPC: Remove unneeded TRACE_DEFINE_ENUMs Clean up: TRACE_DEFINE_ENUM is needed only for enums, not for C macros. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/sunrpc.h | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 861f199896c6..ea6340129b1b 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -295,21 +295,6 @@ TRACE_EVENT(rpc_request, ) ); -TRACE_DEFINE_ENUM(RPC_TASK_ASYNC); -TRACE_DEFINE_ENUM(RPC_TASK_SWAPPER); -TRACE_DEFINE_ENUM(RPC_TASK_NULLCREDS); -TRACE_DEFINE_ENUM(RPC_CALL_MAJORSEEN); -TRACE_DEFINE_ENUM(RPC_TASK_ROOTCREDS); -TRACE_DEFINE_ENUM(RPC_TASK_DYNAMIC); -TRACE_DEFINE_ENUM(RPC_TASK_NO_ROUND_ROBIN); -TRACE_DEFINE_ENUM(RPC_TASK_SOFT); -TRACE_DEFINE_ENUM(RPC_TASK_SOFTCONN); -TRACE_DEFINE_ENUM(RPC_TASK_SENT); -TRACE_DEFINE_ENUM(RPC_TASK_TIMEOUT); -TRACE_DEFINE_ENUM(RPC_TASK_NOCONNECT); -TRACE_DEFINE_ENUM(RPC_TASK_NO_RETRANS_TIMEOUT); -TRACE_DEFINE_ENUM(RPC_TASK_CRED_NOREF); - #define rpc_show_task_flags(flags) \ __print_flags(flags, "|", \ { RPC_TASK_ASYNC, "ASYNC" }, \ @@ -327,14 +312,6 @@ TRACE_DEFINE_ENUM(RPC_TASK_CRED_NOREF); { RPC_TASK_NO_RETRANS_TIMEOUT, "NORTO" }, \ { RPC_TASK_CRED_NOREF, "CRED_NOREF" }) -TRACE_DEFINE_ENUM(RPC_TASK_RUNNING); -TRACE_DEFINE_ENUM(RPC_TASK_QUEUED); -TRACE_DEFINE_ENUM(RPC_TASK_ACTIVE); -TRACE_DEFINE_ENUM(RPC_TASK_NEED_XMIT); -TRACE_DEFINE_ENUM(RPC_TASK_NEED_RECV); -TRACE_DEFINE_ENUM(RPC_TASK_MSG_PIN_WAIT); -TRACE_DEFINE_ENUM(RPC_TASK_SIGNALLED); - #define rpc_show_runstate(flags) \ __print_flags(flags, "|", \ { (1UL << RPC_TASK_RUNNING), "RUNNING" }, \ @@ -945,17 +922,6 @@ TRACE_EVENT(rpc_socket_nospace, ) ); -TRACE_DEFINE_ENUM(XPRT_LOCKED); -TRACE_DEFINE_ENUM(XPRT_CONNECTED); -TRACE_DEFINE_ENUM(XPRT_CONNECTING); -TRACE_DEFINE_ENUM(XPRT_CLOSE_WAIT); -TRACE_DEFINE_ENUM(XPRT_BOUND); -TRACE_DEFINE_ENUM(XPRT_BINDING); -TRACE_DEFINE_ENUM(XPRT_CLOSING); -TRACE_DEFINE_ENUM(XPRT_CONGESTED); -TRACE_DEFINE_ENUM(XPRT_CWND_WAIT); -TRACE_DEFINE_ENUM(XPRT_WRITE_SPACE); - #define rpc_show_xprt_state(x) \ __print_flags(x, "|", \ { (1UL << XPRT_LOCKED), "LOCKED"}, \ -- cgit v1.2.3-70-g09d2 From f9d091cff80d303dde6182296e0f4d7b8a7880ac Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:22 -0400 Subject: SUNRPC: Update trace flags Recent patches added RPC_TASK_MOVEABLE, XPRT_OFFLINE, and XPRT_REMOVE. Update the tracepoint display macros to display these flags properly. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/sunrpc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index ea6340129b1b..b13130903a50 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -299,6 +299,7 @@ TRACE_EVENT(rpc_request, __print_flags(flags, "|", \ { RPC_TASK_ASYNC, "ASYNC" }, \ { RPC_TASK_SWAPPER, "SWAPPER" }, \ + { RPC_TASK_MOVEABLE, "MOVEABLE" }, \ { RPC_TASK_NULLCREDS, "NULLCREDS" }, \ { RPC_CALL_MAJORSEEN, "MAJORSEEN" }, \ { RPC_TASK_ROOTCREDS, "ROOTCREDS" }, \ @@ -931,6 +932,8 @@ TRACE_EVENT(rpc_socket_nospace, { (1UL << XPRT_BOUND), "BOUND"}, \ { (1UL << XPRT_BINDING), "BINDING"}, \ { (1UL << XPRT_CLOSING), "CLOSING"}, \ + { (1UL << XPRT_OFFLINE), "OFFLINE"}, \ + { (1UL << XPRT_REMOVE), "REMOVE"}, \ { (1UL << XPRT_CONGESTED), "CONGESTED"}, \ { (1UL << XPRT_CWND_WAIT), "CWND_WAIT"}, \ { (1UL << XPRT_WRITE_SPACE), "WRITE_SPACE"}) -- cgit v1.2.3-70-g09d2 From be630b9150b0321e21dbd951d715cff72c73b0c6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:28 -0400 Subject: SUNRPC: xprt_retransmit() displays the the NULL procedure incorrectly Currently: xprt_retransmit: task:11@1 xid=0x55a7ffac nfsv4 (null) ntrans=2 should be: xprt_retransmit: task:11@1 xid=0x55a7ffac nfsv4 NULL ntrans=2 Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/sunrpc.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index b13130903a50..59ad1718496b 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1063,8 +1063,7 @@ TRACE_EVENT(xprt_retransmit, __field(int, version) __string(progname, rqst->rq_task->tk_client->cl_program->name) - __string(procedure, - rqst->rq_task->tk_msg.rpc_proc->p_name) + __string(procname, rpc_proc_name(rqst->rq_task)) ), TP_fast_assign( @@ -1078,14 +1077,15 @@ TRACE_EVENT(xprt_retransmit, __assign_str(progname, task->tk_client->cl_program->name); __entry->version = task->tk_client->cl_vers; - __assign_str(procedure, task->tk_msg.rpc_proc->p_name); + __assign_str(procname, rpc_proc_name(task)); ), TP_printk( "task:%u@%u xid=0x%08x %sv%d %s ntrans=%d", __entry->task_id, __entry->client_id, __entry->xid, - __get_str(progname), __entry->version, __get_str(procedure), - __entry->ntrans) + __get_str(progname), __entry->version, __get_str(procname), + __entry->ntrans + ) ); TRACE_EVENT(xprt_ping, -- cgit v1.2.3-70-g09d2 From be17b8caf3a3a20c4d910265a6287b07ab444795 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 19 Jul 2021 10:48:34 -0400 Subject: SUNRPC: Record timeout value in xprt_retransmit tracepoint The client can alter the timeout value after each retransmit. Record the updated timeout value in the trace log. Suggested-by: Dai Ngo Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/sunrpc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 59ad1718496b..18d552a17c19 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1061,6 +1061,7 @@ TRACE_EVENT(xprt_retransmit, __field(u32, xid) __field(int, ntrans) __field(int, version) + __field(unsigned long, timeout) __string(progname, rqst->rq_task->tk_client->cl_program->name) __string(procname, rpc_proc_name(rqst->rq_task)) @@ -1074,6 +1075,7 @@ TRACE_EVENT(xprt_retransmit, task->tk_client->cl_clid : -1; __entry->xid = be32_to_cpu(rqst->rq_xid); __entry->ntrans = rqst->rq_ntrans; + __entry->timeout = task->tk_timeout; __assign_str(progname, task->tk_client->cl_program->name); __entry->version = task->tk_client->cl_vers; @@ -1081,10 +1083,10 @@ TRACE_EVENT(xprt_retransmit, ), TP_printk( - "task:%u@%u xid=0x%08x %sv%d %s ntrans=%d", + "task:%u@%u xid=0x%08x %sv%d %s ntrans=%d timeout=%lu", __entry->task_id, __entry->client_id, __entry->xid, __get_str(progname), __entry->version, __get_str(procname), - __entry->ntrans + __entry->ntrans, __entry->timeout ) ); -- cgit v1.2.3-70-g09d2 From 1143129e4d0d27740ce680d2fb0161ad4f27aa7e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Aug 2021 14:44:17 -0400 Subject: xprtrdma: Disconnect after an ib_post_send() immediate error ib_post_send() does not disconnect the QP when it returns an immediate error. Thus, the code that posts LocalInv has to explicitly disconnect after an immediate error. This is just like the frwr_send() callers handle it. If a disconnect isn't done here, the transport deadlocks. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/frwr_ops.c | 8 ++++++++ net/sunrpc/xprtrdma/verbs.c | 2 +- net/sunrpc/xprtrdma/xprt_rdma.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 229fcc9a9064..754c5dffe127 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -557,6 +557,10 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) /* On error, the MRs get destroyed once the QP has drained. */ trace_xprtrdma_post_linv_err(req, rc); + + /* Force a connection loss to ensure complete recovery. + */ + rpcrdma_force_disconnect(ep); } /** @@ -653,4 +657,8 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) * retransmission. */ rpcrdma_unpin_rqst(req->rl_reply); + + /* Force a connection loss to ensure complete recovery. + */ + rpcrdma_force_disconnect(ep); } diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 649c23518ec0..c1797ea19418 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -124,7 +124,7 @@ static void rpcrdma_xprt_drain(struct rpcrdma_xprt *r_xprt) * connection is closed or lost. (The important thing is it needs * to be invoked "at least" once). */ -static void rpcrdma_force_disconnect(struct rpcrdma_ep *ep) +void rpcrdma_force_disconnect(struct rpcrdma_ep *ep) { if (atomic_add_unless(&ep->re_force_disconnect, 1, 1)) xprt_force_disconnect(ep->re_xprt); diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 5d231d94e944..927e20a2c04e 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -454,6 +454,7 @@ extern unsigned int xprt_rdma_memreg_strategy; /* * Endpoint calls - xprtrdma/verbs.c */ +void rpcrdma_force_disconnect(struct rpcrdma_ep *ep); void rpcrdma_flush_disconnect(struct rpcrdma_xprt *r_xprt, struct ib_wc *wc); int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt); void rpcrdma_xprt_disconnect(struct rpcrdma_xprt *r_xprt); -- cgit v1.2.3-70-g09d2 From 97480cae13ca3a9c1de3eb6fd66cf9650a60db42 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Aug 2021 14:44:24 -0400 Subject: xprtrdma: Put rpcrdma_reps before waking the tear-down completion Ensure the tear-down completion is awoken only /after/ we've stopped fiddling with rpcrdma_rep objects in rpcrdma_post_recvs(). Fixes: 15788d1d1077 ("xprtrdma: Do not refresh Receive Queue while it is draining") Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/verbs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index c1797ea19418..016f10a781b4 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1416,11 +1416,6 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) rc = ib_post_recv(ep->re_id->qp, wr, (const struct ib_recv_wr **)&bad_wr); - if (atomic_dec_return(&ep->re_receiving) > 0) - complete(&ep->re_done); - -out: - trace_xprtrdma_post_recvs(r_xprt, count, rc); if (rc) { for (wr = bad_wr; wr;) { struct rpcrdma_rep *rep; @@ -1431,6 +1426,11 @@ out: --count; } } + if (atomic_dec_return(&ep->re_receiving) > 0) + complete(&ep->re_done); + +out: + trace_xprtrdma_post_recvs(r_xprt, count, rc); ep->re_receive_count += count; return; } -- cgit v1.2.3-70-g09d2 From 683f31c3ab2e60b323b9b88c0ac389ff9cacec1a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Aug 2021 14:44:30 -0400 Subject: xprtrdma: Add xprtrdma_post_recvs_err() tracepoint In the vast majority of cases, rc=0. Don't record that in the post_recvs tracepoint. Instead, add a separate tracepoint that can be left enabled all the time to capture the very rare immediate errors returned by ib_post_recv(). Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/rpcrdma.h | 41 ++++++++++++++++++++++++++++++++++------- net/sunrpc/xprtrdma/verbs.c | 3 ++- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index bd55908c1bef..d65a84bd040c 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -818,16 +818,14 @@ TRACE_EVENT(xprtrdma_post_recv, TRACE_EVENT(xprtrdma_post_recvs, TP_PROTO( const struct rpcrdma_xprt *r_xprt, - unsigned int count, - int status + unsigned int count ), - TP_ARGS(r_xprt, count, status), + TP_ARGS(r_xprt, count), TP_STRUCT__entry( __field(u32, cq_id) __field(unsigned int, count) - __field(int, status) __field(int, posted) __string(addr, rpcrdma_addrstr(r_xprt)) __string(port, rpcrdma_portstr(r_xprt)) @@ -838,15 +836,44 @@ TRACE_EVENT(xprtrdma_post_recvs, __entry->cq_id = ep->re_attr.recv_cq->res.id; __entry->count = count; - __entry->status = status; __entry->posted = ep->re_receive_count; __assign_str(addr, rpcrdma_addrstr(r_xprt)); __assign_str(port, rpcrdma_portstr(r_xprt)); ), - TP_printk("peer=[%s]:%s cq.id=%d %u new recvs, %d active (rc %d)", + TP_printk("peer=[%s]:%s cq.id=%d %u new recvs, %d active", + __get_str(addr), __get_str(port), __entry->cq_id, + __entry->count, __entry->posted + ) +); + +TRACE_EVENT(xprtrdma_post_recvs_err, + TP_PROTO( + const struct rpcrdma_xprt *r_xprt, + int status + ), + + TP_ARGS(r_xprt, status), + + TP_STRUCT__entry( + __field(u32, cq_id) + __field(int, status) + __string(addr, rpcrdma_addrstr(r_xprt)) + __string(port, rpcrdma_portstr(r_xprt)) + ), + + TP_fast_assign( + const struct rpcrdma_ep *ep = r_xprt->rx_ep; + + __entry->cq_id = ep->re_attr.recv_cq->res.id; + __entry->status = status; + __assign_str(addr, rpcrdma_addrstr(r_xprt)); + __assign_str(port, rpcrdma_portstr(r_xprt)); + ), + + TP_printk("peer=[%s]:%s cq.id=%d rc=%d", __get_str(addr), __get_str(port), __entry->cq_id, - __entry->count, __entry->posted, __entry->status + __entry->status ) ); diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 016f10a781b4..1e9041c022b6 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1417,6 +1417,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) rc = ib_post_recv(ep->re_id->qp, wr, (const struct ib_recv_wr **)&bad_wr); if (rc) { + trace_xprtrdma_post_recvs_err(r_xprt, rc); for (wr = bad_wr; wr;) { struct rpcrdma_rep *rep; @@ -1430,7 +1431,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp) complete(&ep->re_done); out: - trace_xprtrdma_post_recvs(r_xprt, count, rc); + trace_xprtrdma_post_recvs(r_xprt, count); ep->re_receive_count += count; return; } -- cgit v1.2.3-70-g09d2 From d9ae8134f253e8d0e15b1f0127af3b8b5552b90c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Aug 2021 14:44:36 -0400 Subject: xprtrdma: Add an xprtrdma_post_send_err tracepoint Unlike xprtrdma_post_send(), this one can be left enabled all the time, and should almost never fire. But we do want to know about immediate errors when they happen. Note that there is already a similar post_linv_err tracepoint. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/trace/events/rpcrdma.h | 33 +++++++++++++++++++++++++++++++++ net/sunrpc/xprtrdma/frwr_ops.c | 6 +++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h index d65a84bd040c..de4195499592 100644 --- a/include/trace/events/rpcrdma.h +++ b/include/trace/events/rpcrdma.h @@ -793,6 +793,39 @@ TRACE_EVENT(xprtrdma_post_send, ) ); +TRACE_EVENT(xprtrdma_post_send_err, + TP_PROTO( + const struct rpcrdma_xprt *r_xprt, + const struct rpcrdma_req *req, + int rc + ), + + TP_ARGS(r_xprt, req, rc), + + TP_STRUCT__entry( + __field(u32, cq_id) + __field(unsigned int, task_id) + __field(unsigned int, client_id) + __field(int, rc) + ), + + TP_fast_assign( + const struct rpc_rqst *rqst = &req->rl_slot; + const struct rpcrdma_ep *ep = r_xprt->rx_ep; + + __entry->cq_id = ep ? ep->re_attr.recv_cq->res.id : 0; + __entry->task_id = rqst->rq_task->tk_pid; + __entry->client_id = rqst->rq_task->tk_client ? + rqst->rq_task->tk_client->cl_clid : -1; + __entry->rc = rc; + ), + + TP_printk("task:%u@%u cq.id=%u rc=%d", + __entry->task_id, __entry->client_id, + __entry->cq_id, __entry->rc + ) +); + TRACE_EVENT(xprtrdma_post_recv, TP_PROTO( const struct rpcrdma_rep *rep diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c index 754c5dffe127..f700b34a5bfd 100644 --- a/net/sunrpc/xprtrdma/frwr_ops.c +++ b/net/sunrpc/xprtrdma/frwr_ops.c @@ -394,6 +394,7 @@ int frwr_send(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) struct rpcrdma_ep *ep = r_xprt->rx_ep; struct rpcrdma_mr *mr; unsigned int num_wrs; + int ret; num_wrs = 1; post_wr = send_wr; @@ -420,7 +421,10 @@ int frwr_send(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) } trace_xprtrdma_post_send(req); - return ib_post_send(ep->re_id->qp, post_wr, NULL); + ret = ib_post_send(ep->re_id->qp, post_wr, NULL); + if (ret) + trace_xprtrdma_post_send_err(r_xprt, req, ret); + return ret; } /** -- cgit v1.2.3-70-g09d2 From 8d863b1f0541ea540cb47d1454eb060963a79d5f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 2 Aug 2021 14:44:42 -0400 Subject: xprtrdma: Eliminate rpcrdma_post_sends() Clean up. Now that there is only one registration mode, there is only one target "post_send" method: frwr_send(). rpcrdma_post_sends() no longer adds much value, especially since all of its call sites ignore the return code value except to check if it's non-zero. Just have them call frwr_send() directly instead. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/backchannel.c | 2 +- net/sunrpc/xprtrdma/transport.c | 2 +- net/sunrpc/xprtrdma/verbs.c | 15 --------------- net/sunrpc/xprtrdma/xprt_rdma.h | 1 - 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 1151efd09b27..17f174d6ea3b 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -115,7 +115,7 @@ int xprt_rdma_bc_send_reply(struct rpc_rqst *rqst) if (rc < 0) goto failed_marshal; - if (rpcrdma_post_sends(r_xprt, req)) + if (frwr_send(r_xprt, req)) goto drop_connection; return 0; diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 9c2ffc67c0fd..a463400ed5a3 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -661,7 +661,7 @@ xprt_rdma_send_request(struct rpc_rqst *rqst) goto drop_connection; rqst->rq_xtime = ktime_get(); - if (rpcrdma_post_sends(r_xprt, req)) + if (frwr_send(r_xprt, req)) goto drop_connection; rqst->rq_xmit_bytes_sent += rqst->rq_snd_buf.len; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 1e9041c022b6..aaec3c9be8db 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -1349,21 +1349,6 @@ static void rpcrdma_regbuf_free(struct rpcrdma_regbuf *rb) kfree(rb); } -/** - * rpcrdma_post_sends - Post WRs to a transport's Send Queue - * @r_xprt: controlling transport instance - * @req: rpcrdma_req containing the Send WR to post - * - * Returns 0 if the post was successful, otherwise -ENOTCONN - * is returned. - */ -int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) -{ - if (frwr_send(r_xprt, req)) - return -ENOTCONN; - return 0; -} - /** * rpcrdma_post_recvs - Refill the Receive Queue * @r_xprt: controlling transport instance diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 927e20a2c04e..d91f54eae00b 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h @@ -459,7 +459,6 @@ void rpcrdma_flush_disconnect(struct rpcrdma_xprt *r_xprt, struct ib_wc *wc); int rpcrdma_xprt_connect(struct rpcrdma_xprt *r_xprt); void rpcrdma_xprt_disconnect(struct rpcrdma_xprt *r_xprt); -int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req); void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed, bool temp); /* -- cgit v1.2.3-70-g09d2 From 71d3d0ebc894294ef9454e45a3ac2e9ba60b3351 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 08:01:27 -0400 Subject: SUNRPC: Convert rpc_client refcount to use refcount_t There are now tools in the refcount library that allow us to convert the client shutdown code. Reported-by: Xiyu Yang Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- include/linux/sunrpc/clnt.h | 3 ++- net/sunrpc/auth_gss/gss_rpc_upcall.c | 2 +- net/sunrpc/clnt.c | 22 ++++++++++------------ net/sunrpc/debugfs.c | 2 +- net/sunrpc/rpc_pipe.c | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 8b5d5c97553e..b2edd5fc2f0c 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ struct rpc_sysfs_client; * The high-level client handle */ struct rpc_clnt { - atomic_t cl_count; /* Number of references */ + refcount_t cl_count; /* Number of references */ unsigned int cl_clid; /* client id */ struct list_head cl_clients; /* Global list of clients */ struct list_head cl_tasks; /* List of tasks */ diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index d1c003a25b0f..61c276bddaf2 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c @@ -160,7 +160,7 @@ static struct rpc_clnt *get_gssp_clnt(struct sunrpc_net *sn) mutex_lock(&sn->gssp_lock); clnt = sn->gssp_clnt; if (clnt) - atomic_inc(&clnt->cl_count); + refcount_inc(&clnt->cl_count); mutex_unlock(&sn->gssp_lock); return clnt; } diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index d34737a8a68a..a5b7f6e34d15 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -167,7 +167,7 @@ static int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) case RPC_PIPEFS_MOUNT: if (clnt->cl_pipedir_objects.pdh_dentry != NULL) return 1; - if (atomic_read(&clnt->cl_count) == 0) + if (refcount_read(&clnt->cl_count) == 0) return 1; break; case RPC_PIPEFS_UMOUNT: @@ -419,7 +419,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, clnt->cl_rtt = &clnt->cl_rtt_default; rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); - atomic_set(&clnt->cl_count, 1); + refcount_set(&clnt->cl_count, 1); if (nodename == NULL) nodename = utsname()->nodename; @@ -431,7 +431,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, if (err) goto out_no_path; if (parent) - atomic_inc(&parent->cl_count); + refcount_inc(&parent->cl_count); trace_rpc_clnt_new(clnt, xprt, program->name, args->servername); return clnt; @@ -918,18 +918,16 @@ rpc_free_client(struct rpc_clnt *clnt) static struct rpc_clnt * rpc_free_auth(struct rpc_clnt *clnt) { - if (clnt->cl_auth == NULL) - return rpc_free_client(clnt); - /* * Note: RPCSEC_GSS may need to send NULL RPC calls in order to * release remaining GSS contexts. This mechanism ensures * that it can do so safely. */ - atomic_inc(&clnt->cl_count); - rpcauth_release(clnt->cl_auth); - clnt->cl_auth = NULL; - if (atomic_dec_and_test(&clnt->cl_count)) + if (clnt->cl_auth != NULL) { + rpcauth_release(clnt->cl_auth); + clnt->cl_auth = NULL; + } + if (refcount_dec_and_test(&clnt->cl_count)) return rpc_free_client(clnt); return NULL; } @@ -943,7 +941,7 @@ rpc_release_client(struct rpc_clnt *clnt) do { if (list_empty(&clnt->cl_tasks)) wake_up(&destroy_wait); - if (!atomic_dec_and_test(&clnt->cl_count)) + if (refcount_dec_not_one(&clnt->cl_count)) break; clnt = rpc_free_auth(clnt); } while (clnt != NULL); @@ -1082,7 +1080,7 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt) if (clnt != NULL) { rpc_task_set_transport(task, clnt); task->tk_client = clnt; - atomic_inc(&clnt->cl_count); + refcount_inc(&clnt->cl_count); if (clnt->cl_softrtry) task->tk_flags |= RPC_TASK_SOFT; if (clnt->cl_softerr) diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index 56029e3af6ff..79995eb95927 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c @@ -90,7 +90,7 @@ static int tasks_open(struct inode *inode, struct file *filp) struct seq_file *seq = filp->private_data; struct rpc_clnt *clnt = seq->private = inode->i_private; - if (!atomic_inc_not_zero(&clnt->cl_count)) { + if (!refcount_inc_not_zero(&clnt->cl_count)) { seq_release(inode, filp); ret = -EINVAL; } diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 09c000d490a1..ee5336d73fdd 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -423,7 +423,7 @@ rpc_info_open(struct inode *inode, struct file *file) spin_lock(&file->f_path.dentry->d_lock); if (!d_unhashed(file->f_path.dentry)) clnt = RPC_I(inode)->private; - if (clnt != NULL && atomic_inc_not_zero(&clnt->cl_count)) { + if (clnt != NULL && refcount_inc_not_zero(&clnt->cl_count)) { spin_unlock(&file->f_path.dentry->d_lock); m->private = clnt; } else { -- cgit v1.2.3-70-g09d2 From e20772cbdf463c12088837e5a08bde1b876bfd25 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 07:58:49 -0400 Subject: NFSv4/pNFS: Fix a layoutget livelock loop If NFS_LAYOUT_RETURN_REQUESTED is set, but there is no value set for the layout plh_return_seq, we can end up in a livelock loop in which every layout segment retrieved by a new call to layoutget is immediately invalidated by pnfs_layout_need_return(). To get around this, we should just set plh_return_seq to the current value of the layout stateid's seqid. Fixes: d474f96104bd ("NFS: Don't return layout segments that are in use") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/pnfs.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index ef14ea0b6ab8..da5cacad6979 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -347,11 +347,15 @@ pnfs_set_plh_return_info(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode, iomode = IOMODE_ANY; lo->plh_return_iomode = iomode; set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); - if (seq != 0) { - WARN_ON_ONCE(lo->plh_return_seq != 0 && lo->plh_return_seq != seq); + /* + * We must set lo->plh_return_seq to avoid livelocks with + * pnfs_layout_need_return() + */ + if (seq == 0) + seq = be32_to_cpu(lo->plh_stateid.seqid); + if (!lo->plh_return_seq || pnfs_seqid_is_newer(seq, lo->plh_return_seq)) lo->plh_return_seq = seq; - pnfs_barrier_update(lo, seq); - } + pnfs_barrier_update(lo, seq); } static void -- cgit v1.2.3-70-g09d2 From 7c0bbf2d3dcd13c906244e0c2e4a0ba3a33dab6a Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 07:59:20 -0400 Subject: NFSv4/pNFS: Remove dead code Since commit 2b28a7bee453 ("fs, nfs: convert pnfs_layout_hdr.plh_refcount from atomic_t to refcount_t") it has not been legal to bump a zero refcount, so the code that tries to allow it if the NFS_LSEG_VALID flag is still set would cause trouble. Luckily, NFS_LSEG_VALID has its own refcount so we can never hit this bad code snippet in practice. Remove it to avoid confusion. Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/pnfs.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index da5cacad6979..856706180d33 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -596,10 +596,6 @@ pnfs_put_lseg(struct pnfs_layout_segment *lseg) inode = lo->plh_inode; if (refcount_dec_and_lock(&lseg->pls_refcount, &inode->i_lock)) { - if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags)) { - spin_unlock(&inode->i_lock); - return; - } pnfs_get_layout_hdr(lo); pnfs_layout_remove_lseg(lo, lseg); if (pnfs_cache_lseg_for_layoutreturn(lo, lseg)) -- cgit v1.2.3-70-g09d2 From 45baadaad7bf9183651fb74f4ed1200da48505a5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 23 Jul 2021 08:57:20 -0400 Subject: NFSv4/pNFS: Always allow update of a zero valued layout barrier A zero value for the layout barrier indicates that it has been cleared (since seqid '0' is an illegal value), so we should always allow it to be updated. Fixes: d29b468da4f9 ("pNFS/NFSv4: Improve rejection of out-of-order layouts") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 856706180d33..7775f6b5a53a 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -335,7 +335,7 @@ static bool pnfs_seqid_is_newer(u32 s1, u32 s2) static void pnfs_barrier_update(struct pnfs_layout_hdr *lo, u32 newseq) { - if (pnfs_seqid_is_newer(newseq, lo->plh_barrier)) + if (pnfs_seqid_is_newer(newseq, lo->plh_barrier) || !lo->plh_barrier) lo->plh_barrier = newseq; } -- cgit v1.2.3-70-g09d2 From d6236a98b3bab07c0a1455fd1ab46f79c3978cdc Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Fri, 23 Jul 2021 08:57:21 -0400 Subject: NFSv4/pnfs: The layout barrier indicate a minimal value for the seqid The intention of the layout barrier is to ensure that we do not update the layout to match an older value than the current expectation. Fix the test in pnfs_layout_stateid_blocked() to reflect that it is legal for the seqid of the stateid to match that of the barrier. Fixes: aa95edf309ef ("NFSv4/pnfs: Fix the layout barrier update") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 7775f6b5a53a..7c9090a28e5c 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1000,7 +1000,7 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo, { u32 seqid = be32_to_cpu(stateid->seqid); - return !pnfs_seqid_is_newer(seqid, lo->plh_barrier) && lo->plh_barrier; + return lo->plh_barrier && pnfs_seqid_is_newer(lo->plh_barrier, seqid); } /* lget is set to 1 if called from inside send_layoutget call chain */ -- cgit v1.2.3-70-g09d2 From c2dc3e5fad13aca5d7bdf4bcb52b1a1d707c8555 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 07:59:23 -0400 Subject: SUNRPC: Fix potential memory corruption We really should not call rpc_wake_up_queued_task_set_status() with xprt->snd_task as an argument unless we are certain that is actually an rpc_task. Fixes: 0445f92c5d53 ("SUNRPC: Fix disconnection races") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- include/linux/sunrpc/xprt.h | 1 + net/sunrpc/xprt.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index c8c39f22d3b1..59cd97da895b 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -432,6 +432,7 @@ void xprt_release_write(struct rpc_xprt *, struct rpc_task *); #define XPRT_CONGESTED (9) #define XPRT_CWND_WAIT (10) #define XPRT_WRITE_SPACE (11) +#define XPRT_SND_IS_COOKIE (12) static inline void xprt_set_connected(struct rpc_xprt *xprt) { diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index fb6db09725c7..bddd354a0076 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -775,9 +775,9 @@ void xprt_force_disconnect(struct rpc_xprt *xprt) /* Try to schedule an autoclose RPC call */ if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) queue_work(xprtiod_workqueue, &xprt->task_cleanup); - else if (xprt->snd_task) + else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) rpc_wake_up_queued_task_set_status(&xprt->pending, - xprt->snd_task, -ENOTCONN); + xprt->snd_task, -ENOTCONN); spin_unlock(&xprt->transport_lock); } EXPORT_SYMBOL_GPL(xprt_force_disconnect); @@ -866,6 +866,7 @@ bool xprt_lock_connect(struct rpc_xprt *xprt, goto out; if (xprt->snd_task != task) goto out; + set_bit(XPRT_SND_IS_COOKIE, &xprt->state); xprt->snd_task = cookie; ret = true; out: @@ -881,6 +882,7 @@ void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) if (!test_bit(XPRT_LOCKED, &xprt->state)) goto out; xprt->snd_task =NULL; + clear_bit(XPRT_SND_IS_COOKIE, &xprt->state); xprt->ops->release_xprt(xprt, NULL); xprt_schedule_autodisconnect(xprt); out: -- cgit v1.2.3-70-g09d2 From e26d9972720e2484f44cdd94ca4e31cc372ed2ed Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 07:59:24 -0400 Subject: SUNRPC: Clean up scheduling of autoclose Consolidate duplicated code in xprt_force_disconnect() and xprt_conditional_disconnect(). Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- net/sunrpc/xprt.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index bddd354a0076..aae5a328b15b 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -760,6 +760,20 @@ void xprt_disconnect_done(struct rpc_xprt *xprt) } EXPORT_SYMBOL_GPL(xprt_disconnect_done); +/** + * xprt_schedule_autoclose_locked - Try to schedule an autoclose RPC call + * @xprt: transport to disconnect + */ +static void xprt_schedule_autoclose_locked(struct rpc_xprt *xprt) +{ + set_bit(XPRT_CLOSE_WAIT, &xprt->state); + if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) + queue_work(xprtiod_workqueue, &xprt->task_cleanup); + else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) + rpc_wake_up_queued_task_set_status(&xprt->pending, + xprt->snd_task, -ENOTCONN); +} + /** * xprt_force_disconnect - force a transport to disconnect * @xprt: transport to disconnect @@ -771,13 +785,7 @@ void xprt_force_disconnect(struct rpc_xprt *xprt) /* Don't race with the test_bit() in xprt_clear_locked() */ spin_lock(&xprt->transport_lock); - set_bit(XPRT_CLOSE_WAIT, &xprt->state); - /* Try to schedule an autoclose RPC call */ - if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) - queue_work(xprtiod_workqueue, &xprt->task_cleanup); - else if (xprt->snd_task && !test_bit(XPRT_SND_IS_COOKIE, &xprt->state)) - rpc_wake_up_queued_task_set_status(&xprt->pending, - xprt->snd_task, -ENOTCONN); + xprt_schedule_autoclose_locked(xprt); spin_unlock(&xprt->transport_lock); } EXPORT_SYMBOL_GPL(xprt_force_disconnect); @@ -817,11 +825,7 @@ void xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie) goto out; if (test_bit(XPRT_CLOSING, &xprt->state)) goto out; - set_bit(XPRT_CLOSE_WAIT, &xprt->state); - /* Try to schedule an autoclose RPC call */ - if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) - queue_work(xprtiod_workqueue, &xprt->task_cleanup); - xprt_wake_pending_tasks(xprt, -EAGAIN); + xprt_schedule_autoclose_locked(xprt); out: spin_unlock(&xprt->transport_lock); } -- cgit v1.2.3-70-g09d2 From f99fa50880f5300fbbb3c0754ddc7f8738d24fe7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 26 Jul 2021 08:03:12 -0400 Subject: SUNRPC/xprtrdma: Fix reconnection locking The xprtrdma client code currently relies on the task that initiated the connect to hold the XPRT_LOCK for the duration of the connection attempt. If the task is woken early, due to some other event, then that lock could get released early. Avoid races by using the same mechanism that the socket code uses of transferring lock ownership to the RDMA connect worker itself. That frees us to call rpcrdma_xprt_disconnect() directly since we're now guaranteed exclusion w.r.t. other callers. Fixes: 4cf44be6f1e8 ("xprtrdma: Fix recursion into rpcrdma_xprt_disconnect()") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- net/sunrpc/xprt.c | 2 ++ net/sunrpc/xprtrdma/transport.c | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index aae5a328b15b..b88ac8132054 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -877,6 +877,7 @@ out: spin_unlock(&xprt->transport_lock); return ret; } +EXPORT_SYMBOL_GPL(xprt_lock_connect); void xprt_unlock_connect(struct rpc_xprt *xprt, void *cookie) { @@ -893,6 +894,7 @@ out: spin_unlock(&xprt->transport_lock); wake_up_bit(&xprt->state, XPRT_LOCKED); } +EXPORT_SYMBOL_GPL(xprt_unlock_connect); /** * xprt_connect - schedule a transport connect operation diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index a463400ed5a3..16e5696314a4 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -250,12 +250,9 @@ xprt_rdma_connect_worker(struct work_struct *work) xprt->stat.connect_start; xprt_set_connected(xprt); rc = -EAGAIN; - } else { - /* Force a call to xprt_rdma_close to clean up */ - spin_lock(&xprt->transport_lock); - set_bit(XPRT_CLOSE_WAIT, &xprt->state); - spin_unlock(&xprt->transport_lock); - } + } else + rpcrdma_xprt_disconnect(r_xprt); + xprt_unlock_connect(xprt, r_xprt); xprt_wake_pending_tasks(xprt, rc); } @@ -489,6 +486,8 @@ xprt_rdma_connect(struct rpc_xprt *xprt, struct rpc_task *task) struct rpcrdma_ep *ep = r_xprt->rx_ep; unsigned long delay; + WARN_ON_ONCE(!xprt_lock_connect(xprt, task, r_xprt)); + delay = 0; if (ep && ep->re_connect_status != 0) { delay = xprt_reconnect_delay(xprt); -- cgit v1.2.3-70-g09d2 From 5d46dd04cb68771f77ba66dbf6fd323a4a2ce00d Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Tue, 20 Jul 2021 16:04:42 -0400 Subject: sunrpc: Fix return value of get_srcport() Since bc1c56e9bbe9 transport->srcport may by unset, causing get_srcport() to return 0 when called. Fix this by querying the port from the underlying socket instead of the transport. Fixes: bc1c56e9bbe9 (SUNRPC: prevent port reuse on transports which don't request it) Signed-off-by: Anna Schumaker --- net/sunrpc/xprtsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index e573dcecdd66..02b071dbdd22 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -1656,7 +1656,7 @@ static int xs_get_srcport(struct sock_xprt *transport) unsigned short get_srcport(struct rpc_xprt *xprt) { struct sock_xprt *sock = container_of(xprt, struct sock_xprt, xprt); - return sock->srcport; + return xs_sock_getport(sock->sock); } EXPORT_SYMBOL(get_srcport); -- cgit v1.2.3-70-g09d2 From e44773daf851dc2755144355723c1c305e7246a1 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 29 Jul 2021 16:45:23 -0400 Subject: SUNRPC: Add srcaddr as a file in sysfs I don't support changing it right now, but it could be useful information for clients with multiple network cards. Signed-off-by: Anna Schumaker --- net/sunrpc/sysfs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index 64da3bfd28e6..2e7a53504974 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -100,6 +100,28 @@ static ssize_t rpc_sysfs_xprt_dstaddr_show(struct kobject *kobj, return ret + 1; } +static ssize_t rpc_sysfs_xprt_srcaddr_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj); + struct sockaddr_storage saddr; + struct sock_xprt *sock; + ssize_t ret = -1; + + if (!xprt) + return 0; + + sock = container_of(xprt, struct sock_xprt, xprt); + if (kernel_getsockname(sock->sock, (struct sockaddr *)&saddr) < 0) + goto out; + + ret = sprintf(buf, "%pISc\n", &saddr); +out: + xprt_put(xprt); + return ret + 1; +} + static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -376,6 +398,9 @@ static const void *rpc_sysfs_xprt_namespace(struct kobject *kobj) static struct kobj_attribute rpc_sysfs_xprt_dstaddr = __ATTR(dstaddr, 0644, rpc_sysfs_xprt_dstaddr_show, rpc_sysfs_xprt_dstaddr_store); +static struct kobj_attribute rpc_sysfs_xprt_srcaddr = __ATTR(srcaddr, + 0644, rpc_sysfs_xprt_srcaddr_show, NULL); + static struct kobj_attribute rpc_sysfs_xprt_info = __ATTR(xprt_info, 0444, rpc_sysfs_xprt_info_show, NULL); @@ -384,6 +409,7 @@ static struct kobj_attribute rpc_sysfs_xprt_change_state = __ATTR(xprt_state, static struct attribute *rpc_sysfs_xprt_attrs[] = { &rpc_sysfs_xprt_dstaddr.attr, + &rpc_sysfs_xprt_srcaddr.attr, &rpc_sysfs_xprt_info.attr, &rpc_sysfs_xprt_change_state.attr, NULL, -- cgit v1.2.3-70-g09d2 From 69f2cd6df3ee07ae88befafc038d4dd9154e2799 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Thu, 29 Jul 2021 16:46:05 -0400 Subject: SUNRPC: Add dst_port to the sysfs xprt info file This is most likely going to be 2049 for NFS, but some servers might be configured to export on a non-standard port. Let's show this information just in case somebody needs it. Signed-off-by: Anna Schumaker --- net/sunrpc/sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index 2e7a53504974..414c664a3199 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -136,14 +136,16 @@ static ssize_t rpc_sysfs_xprt_info_show(struct kobject *kobj, "max_num_slots=%u\nmin_num_slots=%u\nnum_reqs=%u\n" "binding_q_len=%u\nsending_q_len=%u\npending_q_len=%u\n" "backlog_q_len=%u\nmain_xprt=%d\nsrc_port=%u\n" - "tasks_queuelen=%ld\n", + "tasks_queuelen=%ld\ndst_port=%s\n", xprt->last_used, xprt->cong, xprt->cwnd, xprt->max_reqs, xprt->min_reqs, xprt->num_reqs, xprt->binding.qlen, xprt->sending.qlen, xprt->pending.qlen, xprt->backlog.qlen, xprt->main, (xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) ? get_srcport(xprt) : 0, - atomic_long_read(&xprt->queuelen)); + atomic_long_read(&xprt->queuelen), + (xprt->xprt_class->ident == XPRT_TRANSPORT_TCP) ? + xprt->address_strings[RPC_DISPLAY_PORT] : "0"); xprt_put(xprt); return ret + 1; } -- cgit v1.2.3-70-g09d2 From 1d1bb12a8b1805ddeef9793ebeb920179fb0fa38 Mon Sep 17 00:00:00 2001 From: Cassio Neri Date: Thu, 24 Jun 2021 21:13:43 +0100 Subject: rtc: Improve performance of rtc_time64_to_tm(). Add tests. The current implementation of rtc_time64_to_tm() contains unnecessary loops, branches and look-up tables. The new one uses an arithmetic-based algorithm appeared in [1] and is approximately 4.3 times faster (YMMV). The drawback is that the new code isn't intuitive and contains many 'magic numbers' (not unusual for this type of algorithm). However, [1] justifies all those numbers and, given this function's history, the code is unlikely to need much maintenance, if any at all. Add a KUnit test case that checks every day in a 160,000 years interval starting on 1970-01-01 against the expected result. Add a new config RTC_LIB_KUNIT_TEST symbol to give the option to run this test suite. [1] Neri, Schneider, "Euclidean Affine Functions and Applications to Calendar Algorithms". https://arxiv.org/abs/2102.06959 Signed-off-by: Cassio Neri Reported-by: kernel test robot Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210624201343.85441-1-cassio.neri@gmail.com --- drivers/rtc/Kconfig | 10 +++++ drivers/rtc/Makefile | 1 + drivers/rtc/lib.c | 107 ++++++++++++++++++++++++++++++++++++------------- drivers/rtc/lib_test.c | 79 ++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 drivers/rtc/lib_test.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 12153d5801ce..b3cf3a274c05 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -10,6 +10,16 @@ config RTC_MC146818_LIB bool select RTC_LIB +config RTC_LIB_KUNIT_TEST + tristate "KUnit test for RTC lib functions" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + select RTC_LIB + help + Enable this option to test RTC library functions. + + If unsure, say N. + menuconfig RTC_CLASS bool "Real Time Clock" default n diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2dd0dd956b0e..763d3628c603 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -178,3 +178,4 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o +obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += lib_test.o diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index 23284580df97..fe361652727a 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -6,6 +6,8 @@ * Author: Alessandro Zummo * * based on arch/arm/common/rtctime.c and other bits + * + * Author: Cassio Neri (rtc_time64_to_tm) */ #include @@ -22,8 +24,6 @@ static const unsigned short rtc_ydays[2][13] = { { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; -#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) - /* * The number of days in the month. */ @@ -42,42 +42,95 @@ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) } EXPORT_SYMBOL(rtc_year_days); -/* - * rtc_time64_to_tm - Converts time64_t to rtc_time. - * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. +/** + * rtc_time64_to_tm - converts time64_t to rtc_time. + * + * @time: The number of seconds since 01-01-1970 00:00:00. + * (Must be positive.) + * @tm: Pointer to the struct rtc_time. */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int month, year, secs; + unsigned int secs; int days; + u64 u64tmp; + u32 u32tmp, udays, century, day_of_century, year_of_century, year, + day_of_year, month, day; + bool is_Jan_or_Feb, is_leap_year; + /* time must be positive */ days = div_s64_rem(time, 86400, &secs); /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; - year = 1970 + days / 365; - days -= (year - 1970) * 365 - + LEAPS_THRU_END_OF(year - 1) - - LEAPS_THRU_END_OF(1970 - 1); - while (days < 0) { - year -= 1; - days += 365 + is_leap_year(year); - } - tm->tm_year = year - 1900; - tm->tm_yday = days + 1; - - for (month = 0; month < 11; month++) { - int newdays; - - newdays = days - rtc_month_days(month, year); - if (newdays < 0) - break; - days = newdays; - } - tm->tm_mon = month; - tm->tm_mday = days + 1; + /* + * The following algorithm is, basically, Proposition 6.3 of Neri + * and Schneider [1]. In a few words: it works on the computational + * (fictitious) calendar where the year starts in March, month = 2 + * (*), and finishes in February, month = 13. This calendar is + * mathematically convenient because the day of the year does not + * depend on whether the year is leap or not. For instance: + * + * March 1st 0-th day of the year; + * ... + * April 1st 31-st day of the year; + * ... + * January 1st 306-th day of the year; (Important!) + * ... + * February 28th 364-th day of the year; + * February 29th 365-th day of the year (if it exists). + * + * After having worked out the date in the computational calendar + * (using just arithmetics) it's easy to convert it to the + * corresponding date in the Gregorian calendar. + * + * [1] "Euclidean Affine Functions and Applications to Calendar + * Algorithms". https://arxiv.org/abs/2102.06959 + * + * (*) The numbering of months follows rtc_time more closely and + * thus, is slightly different from [1]. + */ + + udays = ((u32) days) + 719468; + + u32tmp = 4 * udays + 3; + century = u32tmp / 146097; + day_of_century = u32tmp % 146097 / 4; + + u32tmp = 4 * day_of_century + 3; + u64tmp = 2939745ULL * u32tmp; + year_of_century = upper_32_bits(u64tmp); + day_of_year = lower_32_bits(u64tmp) / 2939745 / 4; + + year = 100 * century + year_of_century; + is_leap_year = year_of_century != 0 ? + year_of_century % 4 == 0 : century % 4 == 0; + + u32tmp = 2141 * day_of_year + 132377; + month = u32tmp >> 16; + day = ((u16) u32tmp) / 2141; + + /* + * Recall that January 01 is the 306-th day of the year in the + * computational (not Gregorian) calendar. + */ + is_Jan_or_Feb = day_of_year >= 306; + + /* Converts to the Gregorian calendar. */ + year = year + is_Jan_or_Feb; + month = is_Jan_or_Feb ? month - 12 : month; + day = day + 1; + + day_of_year = is_Jan_or_Feb ? + day_of_year - 306 : day_of_year + 31 + 28 + is_leap_year; + + /* Converts to rtc_time's format. */ + tm->tm_year = (int) (year - 1900); + tm->tm_mon = (int) month; + tm->tm_mday = (int) day; + tm->tm_yday = (int) day_of_year + 1; tm->tm_hour = secs / 3600; secs -= tm->tm_hour * 3600; diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c new file mode 100644 index 000000000000..2124b67a2f43 --- /dev/null +++ b/drivers/rtc/lib_test.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#include +#include + +/* + * Advance a date by one day. + */ +static void advance_date(int *year, int *month, int *mday, int *yday) +{ + if (*mday != rtc_month_days(*month - 1, *year)) { + ++*mday; + ++*yday; + return; + } + + *mday = 1; + if (*month != 12) { + ++*month; + ++*yday; + return; + } + + *month = 1; + *yday = 1; + ++*year; +} + +/* + * Checks every day in a 160000 years interval starting on 1970-01-01 + * against the expected result. + */ +static void rtc_time64_to_tm_test_date_range(struct kunit *test) +{ + /* + * 160000 years = (160000 / 400) * 400 years + * = (160000 / 400) * 146097 days + * = (160000 / 400) * 146097 * 86400 seconds + */ + time64_t total_secs = ((time64_t) 160000) / 400 * 146097 * 86400; + + int year = 1970; + int month = 1; + int mday = 1; + int yday = 1; + + struct rtc_time result; + time64_t secs; + s64 days; + + for (secs = 0; secs <= total_secs; secs += 86400) { + + rtc_time64_to_tm(secs, &result); + + days = div_s64(secs, 86400); + + #define FAIL_MSG "%d/%02d/%02d (%2d) : %ld", \ + year, month, mday, yday, days + + KUNIT_ASSERT_EQ_MSG(test, year - 1900, result.tm_year, FAIL_MSG); + KUNIT_ASSERT_EQ_MSG(test, month - 1, result.tm_mon, FAIL_MSG); + KUNIT_ASSERT_EQ_MSG(test, mday, result.tm_mday, FAIL_MSG); + KUNIT_ASSERT_EQ_MSG(test, yday, result.tm_yday, FAIL_MSG); + + advance_date(&year, &month, &mday, &yday); + } +} + +static struct kunit_case rtc_lib_test_cases[] = { + KUNIT_CASE(rtc_time64_to_tm_test_date_range), + {} +}; + +static struct kunit_suite rtc_lib_test_suite = { + .name = "rtc_lib_test_cases", + .test_cases = rtc_lib_test_cases, +}; + +kunit_test_suite(rtc_lib_test_suite); -- cgit v1.2.3-70-g09d2 From de2860f4636256836450c6543be744a50118fc66 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 9 Aug 2021 10:10:00 -0700 Subject: mm: Add kvrealloc() During log recovery of an XFS filesystem with 64kB directory buffers, rebuilding a buffer split across two log records results in a memory allocation warning from krealloc like this: xfs filesystem being mounted at /mnt/scratch supports timestamps until 2038 (0x7fffffff) XFS (dm-0): Unmounting Filesystem XFS (dm-0): Mounting V5 Filesystem XFS (dm-0): Starting recovery (logdev: internal) ------------[ cut here ]------------ WARNING: CPU: 5 PID: 3435170 at mm/page_alloc.c:3539 get_page_from_freelist+0xdee/0xe40 ..... RIP: 0010:get_page_from_freelist+0xdee/0xe40 Call Trace: ? complete+0x3f/0x50 __alloc_pages+0x16f/0x300 alloc_pages+0x87/0x110 kmalloc_order+0x2c/0x90 kmalloc_order_trace+0x1d/0x90 __kmalloc_track_caller+0x215/0x270 ? xlog_recover_add_to_cont_trans+0x63/0x1f0 krealloc+0x54/0xb0 xlog_recover_add_to_cont_trans+0x63/0x1f0 xlog_recovery_process_trans+0xc1/0xd0 xlog_recover_process_ophdr+0x86/0x130 xlog_recover_process_data+0x9f/0x160 xlog_recover_process+0xa2/0x120 xlog_do_recovery_pass+0x40b/0x7d0 ? __irq_work_queue_local+0x4f/0x60 ? irq_work_queue+0x3a/0x50 xlog_do_log_recovery+0x70/0x150 xlog_do_recover+0x38/0x1d0 xlog_recover+0xd8/0x170 xfs_log_mount+0x181/0x300 xfs_mountfs+0x4a1/0x9b0 xfs_fs_fill_super+0x3c0/0x7b0 get_tree_bdev+0x171/0x270 ? suffix_kstrtoint.constprop.0+0xf0/0xf0 xfs_fs_get_tree+0x15/0x20 vfs_get_tree+0x24/0xc0 path_mount+0x2f5/0xaf0 __x64_sys_mount+0x108/0x140 do_syscall_64+0x3a/0x70 entry_SYSCALL_64_after_hwframe+0x44/0xae Essentially, we are taking a multi-order allocation from kmem_alloc() (which has an open coded no fail, no warn loop) and then reallocating it out to 64kB using krealloc(__GFP_NOFAIL) and that is then triggering the above warning. This is a regression caused by converting this code from an open coded no fail/no warn reallocation loop to using __GFP_NOFAIL. What we actually need here is kvrealloc(), so that if contiguous page allocation fails we fall back to vmalloc() and we don't get nasty warnings happening in XFS. Fixes: 771915c4f688 ("xfs: remove kmem_realloc()") Signed-off-by: Dave Chinner Acked-by: Mel Gorman Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log_recover.c | 4 +++- include/linux/mm.h | 2 ++ mm/util.c | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index a98d2429d795..cc3c2329c4e5 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2062,7 +2062,9 @@ xlog_recover_add_to_cont_trans( old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; old_len = item->ri_buf[item->ri_cnt-1].i_len; - ptr = krealloc(old_ptr, len + old_len, GFP_KERNEL | __GFP_NOFAIL); + ptr = kvrealloc(old_ptr, old_len, len + old_len, GFP_KERNEL); + if (!ptr) + return -ENOMEM; memcpy(&ptr[old_len], dp, len); item->ri_buf[item->ri_cnt-1].i_len += len; item->ri_buf[item->ri_cnt-1].i_addr = ptr; diff --git a/include/linux/mm.h b/include/linux/mm.h index 7ca22e6e694a..e59646a5d44d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -829,6 +829,8 @@ static inline void *kvcalloc(size_t n, size_t size, gfp_t flags) return kvmalloc_array(n, size, flags | __GFP_ZERO); } +extern void *kvrealloc(const void *p, size_t oldsize, size_t newsize, + gfp_t flags); extern void kvfree(const void *addr); extern void kvfree_sensitive(const void *addr, size_t len); diff --git a/mm/util.c b/mm/util.c index 9043d03750a7..db3091116b7c 100644 --- a/mm/util.c +++ b/mm/util.c @@ -635,6 +635,21 @@ void kvfree_sensitive(const void *addr, size_t len) } EXPORT_SYMBOL(kvfree_sensitive); +void *kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags) +{ + void *newp; + + if (oldsize >= newsize) + return (void *)p; + newp = kvmalloc(newsize, flags); + if (!newp) + return NULL; + memcpy(newp, p, oldsize); + kvfree(p); + return newp; +} +EXPORT_SYMBOL(kvrealloc); + static inline void *__page_rmapping(struct page *page) { unsigned long mapping; -- cgit v1.2.3-70-g09d2 From 98fe2c3cef21b784e2efd1d9d891430d95b4f073 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 9 Aug 2021 10:10:01 -0700 Subject: xfs: remove kmem_alloc_io() Since commit 59bb47985c1d ("mm, sl[aou]b: guarantee natural alignment for kmalloc(power-of-two)"), the core slab code now guarantees slab alignment in all situations sufficient for IO purposes (i.e. minimum of 512 byte alignment of >= 512 byte sized heap allocations) we no longer need the workaround in the XFS code to provide this guarantee. Replace the use of kmem_alloc_io() with kmem_alloc() or kmem_alloc_large() appropriately, and remove the kmem_alloc_io() interface altogether. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/kmem.c | 25 ------------------------- fs/xfs/kmem.h | 1 - fs/xfs/xfs_buf.c | 3 +-- fs/xfs/xfs_buf.h | 6 ------ fs/xfs/xfs_log.c | 3 +-- fs/xfs/xfs_log_recover.c | 4 +--- fs/xfs/xfs_trace.h | 1 - 7 files changed, 3 insertions(+), 40 deletions(-) diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index e986b95d94c9..3f2979fd2f2b 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -56,31 +56,6 @@ __kmem_vmalloc(size_t size, xfs_km_flags_t flags) return ptr; } -/* - * Same as kmem_alloc_large, except we guarantee the buffer returned is aligned - * to the @align_mask. We only guarantee alignment up to page size, we'll clamp - * alignment at page size if it is larger. vmalloc always returns a PAGE_SIZE - * aligned region. - */ -void * -kmem_alloc_io(size_t size, int align_mask, xfs_km_flags_t flags) -{ - void *ptr; - - trace_kmem_alloc_io(size, flags, _RET_IP_); - - if (WARN_ON_ONCE(align_mask >= PAGE_SIZE)) - align_mask = PAGE_SIZE - 1; - - ptr = kmem_alloc(size, flags | KM_MAYFAIL); - if (ptr) { - if (!((uintptr_t)ptr & align_mask)) - return ptr; - kfree(ptr); - } - return __kmem_vmalloc(size, flags); -} - void * kmem_alloc_large(size_t size, xfs_km_flags_t flags) { diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index 38007117697e..9ff20047f8b8 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h @@ -57,7 +57,6 @@ kmem_flags_convert(xfs_km_flags_t flags) } extern void *kmem_alloc(size_t, xfs_km_flags_t); -extern void *kmem_alloc_io(size_t size, int align_mask, xfs_km_flags_t flags); extern void *kmem_alloc_large(size_t size, xfs_km_flags_t); static inline void kmem_free(const void *ptr) { diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 8ff42b3585e0..a5ef1f9eb622 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -315,7 +315,6 @@ xfs_buf_alloc_kmem( struct xfs_buf *bp, xfs_buf_flags_t flags) { - int align_mask = xfs_buftarg_dma_alignment(bp->b_target); xfs_km_flags_t kmflag_mask = KM_NOFS; size_t size = BBTOB(bp->b_length); @@ -323,7 +322,7 @@ xfs_buf_alloc_kmem( if (!(flags & XBF_READ)) kmflag_mask |= KM_ZERO; - bp->b_addr = kmem_alloc_io(size, align_mask, kmflag_mask); + bp->b_addr = kmem_alloc(size, kmflag_mask); if (!bp->b_addr) return -ENOMEM; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 464dc548fa23..cfbe37d73293 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -355,12 +355,6 @@ extern int xfs_setsize_buftarg(struct xfs_buftarg *, unsigned int); #define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) -static inline int -xfs_buftarg_dma_alignment(struct xfs_buftarg *bt) -{ - return queue_dma_alignment(bt->bt_bdev->bd_disk->queue); -} - int xfs_buf_reverify(struct xfs_buf *bp, const struct xfs_buf_ops *ops); bool xfs_verify_magic(struct xfs_buf *bp, __be32 dmagic); bool xfs_verify_magic16(struct xfs_buf *bp, __be16 dmagic); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 60ac5fd63f1e..fdc4d0636413 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1476,7 +1476,6 @@ xlog_alloc_log( */ ASSERT(log->l_iclog_size >= 4096); for (i = 0; i < log->l_iclog_bufs; i++) { - int align_mask = xfs_buftarg_dma_alignment(mp->m_logdev_targp); size_t bvec_size = howmany(log->l_iclog_size, PAGE_SIZE) * sizeof(struct bio_vec); @@ -1488,7 +1487,7 @@ xlog_alloc_log( iclog->ic_prev = prev_iclog; prev_iclog = iclog; - iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask, + iclog->ic_data = kmem_alloc_large(log->l_iclog_size, KM_MAYFAIL | KM_ZERO); if (!iclog->ic_data) goto out_free_iclog; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index cc3c2329c4e5..48bb5c31ffd0 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -79,8 +79,6 @@ xlog_alloc_buffer( struct xlog *log, int nbblks) { - int align_mask = xfs_buftarg_dma_alignment(log->l_targ); - /* * Pass log block 0 since we don't have an addr yet, buffer will be * verified on read. @@ -108,7 +106,7 @@ xlog_alloc_buffer( if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; nbblks = round_up(nbblks, log->l_sectBBsize); - return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO); + return kmem_alloc_large(BBTOB(nbblks), KM_MAYFAIL | KM_ZERO); } /* diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 57ce91dcc0a6..2d31e64b46dc 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -3774,7 +3774,6 @@ DEFINE_EVENT(xfs_kmem_class, name, \ TP_PROTO(ssize_t size, int flags, unsigned long caller_ip), \ TP_ARGS(size, flags, caller_ip)) DEFINE_KMEM_EVENT(kmem_alloc); -DEFINE_KMEM_EVENT(kmem_alloc_io); DEFINE_KMEM_EVENT(kmem_alloc_large); TRACE_EVENT(xfs_check_new_dalign, -- cgit v1.2.3-70-g09d2 From d634525db63e9e946c3229fb93c8d9b763afbaf3 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 9 Aug 2021 10:10:01 -0700 Subject: xfs: replace kmem_alloc_large() with kvmalloc() There is no reason for this wrapper existing anymore. All the places that use KM_NOFS allocation are within transaction contexts and hence covered by memalloc_nofs_save/restore contexts. Hence we don't need any special handling of vmalloc for large IOs anymore and so special casing this code isn't necessary. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/kmem.c | 39 --------------------------------------- fs/xfs/kmem.h | 1 - fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/scrub/attr.c | 14 ++++++++------ fs/xfs/scrub/attr.h | 3 --- fs/xfs/xfs_log.c | 4 ++-- fs/xfs/xfs_log_cil.c | 10 +++++++++- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_trace.h | 1 - 9 files changed, 21 insertions(+), 55 deletions(-) diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index 3f2979fd2f2b..6f49bf39183c 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -29,42 +29,3 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } - - -/* - * __vmalloc() will allocate data pages and auxiliary structures (e.g. - * pagetables) with GFP_KERNEL, yet we may be under GFP_NOFS context here. Hence - * we need to tell memory reclaim that we are in such a context via - * PF_MEMALLOC_NOFS to prevent memory reclaim re-entering the filesystem here - * and potentially deadlocking. - */ -static void * -__kmem_vmalloc(size_t size, xfs_km_flags_t flags) -{ - unsigned nofs_flag = 0; - void *ptr; - gfp_t lflags = kmem_flags_convert(flags); - - if (flags & KM_NOFS) - nofs_flag = memalloc_nofs_save(); - - ptr = __vmalloc(size, lflags); - - if (flags & KM_NOFS) - memalloc_nofs_restore(nofs_flag); - - return ptr; -} - -void * -kmem_alloc_large(size_t size, xfs_km_flags_t flags) -{ - void *ptr; - - trace_kmem_alloc_large(size, flags, _RET_IP_); - - ptr = kmem_alloc(size, flags | KM_MAYFAIL); - if (ptr) - return ptr; - return __kmem_vmalloc(size, flags); -} diff --git a/fs/xfs/kmem.h b/fs/xfs/kmem.h index 9ff20047f8b8..54da6d717a06 100644 --- a/fs/xfs/kmem.h +++ b/fs/xfs/kmem.h @@ -57,7 +57,6 @@ kmem_flags_convert(xfs_km_flags_t flags) } extern void *kmem_alloc(size_t, xfs_km_flags_t); -extern void *kmem_alloc_large(size_t size, xfs_km_flags_t); static inline void kmem_free(const void *ptr) { kvfree(ptr); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b277e0511cdd..cdd06213ab44 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -489,7 +489,7 @@ xfs_attr_copy_value( } if (!args->value) { - args->value = kmem_alloc_large(valuelen, KM_NOLOCKDEP); + args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP); if (!args->value) return -ENOMEM; } diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index 552af0cf8482..6c36af6dbd35 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -25,11 +25,11 @@ * reallocating the buffer if necessary. Buffer contents are not preserved * across a reallocation. */ -int +static int xchk_setup_xattr_buf( struct xfs_scrub *sc, size_t value_size, - xfs_km_flags_t flags) + gfp_t flags) { size_t sz; struct xchk_xattr_buf *ab = sc->buf; @@ -57,7 +57,7 @@ xchk_setup_xattr_buf( * Don't zero the buffer upon allocation to avoid runtime overhead. * All users must be careful never to read uninitialized contents. */ - ab = kmem_alloc_large(sizeof(*ab) + sz, flags); + ab = kvmalloc(sizeof(*ab) + sz, flags); if (!ab) return -ENOMEM; @@ -79,7 +79,7 @@ xchk_setup_xattr( * without the inode lock held, which means we can sleep. */ if (sc->flags & XCHK_TRY_HARDER) { - error = xchk_setup_xattr_buf(sc, XATTR_SIZE_MAX, 0); + error = xchk_setup_xattr_buf(sc, XATTR_SIZE_MAX, GFP_KERNEL); if (error) return error; } @@ -138,7 +138,8 @@ xchk_xattr_listent( * doesn't work, we overload the seen_enough variable to convey * the error message back to the main scrub function. */ - error = xchk_setup_xattr_buf(sx->sc, valuelen, KM_MAYFAIL); + error = xchk_setup_xattr_buf(sx->sc, valuelen, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (error == -ENOMEM) error = -EDEADLOCK; if (error) { @@ -323,7 +324,8 @@ xchk_xattr_block( return 0; /* Allocate memory for block usage checking. */ - error = xchk_setup_xattr_buf(ds->sc, 0, KM_MAYFAIL); + error = xchk_setup_xattr_buf(ds->sc, 0, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (error == -ENOMEM) return -EDEADLOCK; if (error) diff --git a/fs/xfs/scrub/attr.h b/fs/xfs/scrub/attr.h index 13a1d2e8424d..1719e1c4da59 100644 --- a/fs/xfs/scrub/attr.h +++ b/fs/xfs/scrub/attr.h @@ -65,7 +65,4 @@ xchk_xattr_dstmap( BITS_TO_LONGS(sc->mp->m_attr_geo->blksize); } -int xchk_setup_xattr_buf(struct xfs_scrub *sc, size_t value_size, - xfs_km_flags_t flags); - #endif /* __XFS_SCRUB_ATTR_H__ */ diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index fdc4d0636413..eb8341027cc7 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1487,8 +1487,8 @@ xlog_alloc_log( iclog->ic_prev = prev_iclog; prev_iclog = iclog; - iclog->ic_data = kmem_alloc_large(log->l_iclog_size, - KM_MAYFAIL | KM_ZERO); + iclog->ic_data = kvzalloc(log->l_iclog_size, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!iclog->ic_data) goto out_free_iclog; #ifdef DEBUG diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 4c44bc3786c0..4e41130f206f 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -185,7 +185,15 @@ xlog_cil_alloc_shadow_bufs( */ kmem_free(lip->li_lv_shadow); - lv = kmem_alloc_large(buf_size, KM_NOFS); + /* + * We are in transaction context, which means this + * allocation will pick up GFP_NOFS from the + * memalloc_nofs_save/restore context the transaction + * holds. This means we can use GFP_KERNEL here so the + * generic kvmalloc() code will run vmalloc on + * contiguous page allocation failure as we require. + */ + lv = kvmalloc(buf_size, GFP_KERNEL); memset(lv, 0, xlog_cil_iovec_space(niovecs)); lv->lv_item = lip; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 48bb5c31ffd0..ea96b5e45364 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -106,7 +106,7 @@ xlog_alloc_buffer( if (nbblks > 1 && log->l_sectBBsize > 1) nbblks += log->l_sectBBsize; nbblks = round_up(nbblks, log->l_sectBBsize); - return kmem_alloc_large(BBTOB(nbblks), KM_MAYFAIL | KM_ZERO); + return kvzalloc(BBTOB(nbblks), GFP_KERNEL | __GFP_RETRY_MAYFAIL); } /* diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 2d31e64b46dc..36d771d00f7f 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -3774,7 +3774,6 @@ DEFINE_EVENT(xfs_kmem_class, name, \ TP_PROTO(ssize_t size, int flags, unsigned long caller_ip), \ TP_ARGS(size, flags, caller_ip)) DEFINE_KMEM_EVENT(kmem_alloc); -DEFINE_KMEM_EVENT(kmem_alloc_large); TRACE_EVENT(xfs_check_new_dalign, TP_PROTO(struct xfs_mount *mp, int new_dalign, xfs_ino_t calc_rootino), -- cgit v1.2.3-70-g09d2 From 908ce71e54f8265fa909200410d6c50ab9a2d302 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 8 Aug 2021 08:27:12 -0700 Subject: xfs: allow setting and clearing of log incompat feature flags Log incompat feature flags in the superblock exist for one purpose: to protect the contents of a dirty log from replay on a kernel that isn't prepared to handle those dirty contents. This means that they can be cleared if (a) we know the log is clean and (b) we know that there aren't any other threads in the system that might be setting or relying upon a log incompat flag. Therefore, clear the log incompat flags when we've finished recovering the log, when we're unmounting cleanly, remounting read-only, or freezing; and provide a function so that subsequent patches can start using this. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson Reviewed-by: Chandan Babu R --- fs/xfs/libxfs/xfs_format.h | 15 +++++++ fs/xfs/xfs_log.c | 14 ++++++ fs/xfs/xfs_log_recover.c | 16 +++++++ fs/xfs/xfs_mount.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 2 + 5 files changed, 157 insertions(+) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 37570cf0537e..5d8a129150d5 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -495,6 +495,21 @@ xfs_sb_has_incompat_log_feature( return (sbp->sb_features_log_incompat & feature) != 0; } +static inline void +xfs_sb_remove_incompat_log_features( + struct xfs_sb *sbp) +{ + sbp->sb_features_log_incompat &= ~XFS_SB_FEAT_INCOMPAT_LOG_ALL; +} + +static inline void +xfs_sb_add_incompat_log_features( + struct xfs_sb *sbp, + unsigned int features) +{ + sbp->sb_features_log_incompat |= features; +} + /* * V5 superblock specific feature checks */ diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index eb8341027cc7..e0d4ffce7a8a 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -972,6 +972,20 @@ int xfs_log_quiesce( struct xfs_mount *mp) { + /* + * Clear log incompat features since we're quiescing the log. Report + * failures, though it's not fatal to have a higher log feature + * protection level than the log contents actually require. + */ + if (xfs_clear_incompat_log_features(mp)) { + int error; + + error = xfs_sync_sb(mp, false); + if (error) + xfs_warn(mp, + "Failed to clear log incompat features on quiesce"); + } + cancel_delayed_work_sync(&mp->m_log->l_work); xfs_log_force(mp, XFS_LOG_SYNC); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index ea96b5e45364..1d324c8bac6b 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3471,6 +3471,22 @@ xlog_recover_finish( */ xfs_log_force(log->l_mp, XFS_LOG_SYNC); + /* + * Now that we've recovered the log and all the intents, we can + * clear the log incompat feature bits in the superblock + * because there's no longer anything to protect. We rely on + * the AIL push to write out the updated superblock after + * everything else. + */ + if (xfs_clear_incompat_log_features(log->l_mp)) { + error = xfs_sync_sb(log->l_mp, false); + if (error < 0) { + xfs_alert(log->l_mp, + "Failed to clear log incompat features on recovery"); + return error; + } + } + xlog_recover_process_iunlinks(log); xlog_recover_check_summary(log); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index ff08192d8d2a..74349eab5b58 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1241,6 +1241,116 @@ xfs_force_summary_recalc( xfs_fs_mark_sick(mp, XFS_SICK_FS_COUNTERS); } +/* + * Enable a log incompat feature flag in the primary superblock. The caller + * cannot have any other transactions in progress. + */ +int +xfs_add_incompat_log_feature( + struct xfs_mount *mp, + uint32_t feature) +{ + struct xfs_dsb *dsb; + int error; + + ASSERT(hweight32(feature) == 1); + ASSERT(!(feature & XFS_SB_FEAT_INCOMPAT_LOG_UNKNOWN)); + + /* + * Force the log to disk and kick the background AIL thread to reduce + * the chances that the bwrite will stall waiting for the AIL to unpin + * the primary superblock buffer. This isn't a data integrity + * operation, so we don't need a synchronous push. + */ + error = xfs_log_force(mp, XFS_LOG_SYNC); + if (error) + return error; + xfs_ail_push_all(mp->m_ail); + + /* + * Lock the primary superblock buffer to serialize all callers that + * are trying to set feature bits. + */ + xfs_buf_lock(mp->m_sb_bp); + xfs_buf_hold(mp->m_sb_bp); + + if (XFS_FORCED_SHUTDOWN(mp)) { + error = -EIO; + goto rele; + } + + if (xfs_sb_has_incompat_log_feature(&mp->m_sb, feature)) + goto rele; + + /* + * Write the primary superblock to disk immediately, because we need + * the log_incompat bit to be set in the primary super now to protect + * the log items that we're going to commit later. + */ + dsb = mp->m_sb_bp->b_addr; + xfs_sb_to_disk(dsb, &mp->m_sb); + dsb->sb_features_log_incompat |= cpu_to_be32(feature); + error = xfs_bwrite(mp->m_sb_bp); + if (error) + goto shutdown; + + /* + * Add the feature bits to the incore superblock before we unlock the + * buffer. + */ + xfs_sb_add_incompat_log_features(&mp->m_sb, feature); + xfs_buf_relse(mp->m_sb_bp); + + /* Log the superblock to disk. */ + return xfs_sync_sb(mp, false); +shutdown: + xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); +rele: + xfs_buf_relse(mp->m_sb_bp); + return error; +} + +/* + * Clear all the log incompat flags from the superblock. + * + * The caller cannot be in a transaction, must ensure that the log does not + * contain any log items protected by any log incompat bit, and must ensure + * that there are no other threads that depend on the state of the log incompat + * feature flags in the primary super. + * + * Returns true if the superblock is dirty. + */ +bool +xfs_clear_incompat_log_features( + struct xfs_mount *mp) +{ + bool ret = false; + + if (!xfs_sb_version_hascrc(&mp->m_sb) || + !xfs_sb_has_incompat_log_feature(&mp->m_sb, + XFS_SB_FEAT_INCOMPAT_LOG_ALL) || + XFS_FORCED_SHUTDOWN(mp)) + return false; + + /* + * Update the incore superblock. We synchronize on the primary super + * buffer lock to be consistent with the add function, though at least + * in theory this shouldn't be necessary. + */ + xfs_buf_lock(mp->m_sb_bp); + xfs_buf_hold(mp->m_sb_bp); + + if (xfs_sb_has_incompat_log_feature(&mp->m_sb, + XFS_SB_FEAT_INCOMPAT_LOG_ALL)) { + xfs_info(mp, "Clearing log incompat feature flags."); + xfs_sb_remove_incompat_log_features(&mp->m_sb); + ret = true; + } + + xfs_buf_relse(mp->m_sb_bp); + return ret; +} + /* * Update the in-core delayed block counter. * diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 91a10233d04c..32143102cc91 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -388,6 +388,8 @@ int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp, int error_class, int error); void xfs_force_summary_recalc(struct xfs_mount *mp); +int xfs_add_incompat_log_feature(struct xfs_mount *mp, uint32_t feature); +bool xfs_clear_incompat_log_features(struct xfs_mount *mp); void xfs_mod_delalloc(struct xfs_mount *mp, int64_t delta); #endif /* __XFS_MOUNT_H__ */ -- cgit v1.2.3-70-g09d2 From 2b73a2c817be58de2190940dbfa38dbf8a3806e6 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 8 Aug 2021 08:27:12 -0700 Subject: xfs: clear log incompat feature bits when the log is idle When there are no ongoing transactions and the log contents have been checkpointed back into the filesystem, the log performs 'covering', which is to say that it log a dummy transaction to record the fact that the tail has caught up with the head. This is a good time to clear log incompat feature flags, because they are flags that are temporarily set to limit the range of kernels that can replay a dirty log. Since it's possible that some other higher level thread is about to start logging items protected by a log incompat flag, we create a rwsem so that upper level threads can coordinate this with the log. It would probably be more performant to use a percpu rwsem, but the ability to /try/ taking the write lock during covering is critical, and percpu rwsems do not provide that. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson Reviewed-by: Chandan Babu R --- fs/xfs/xfs_log.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_log.h | 3 +++ fs/xfs/xfs_log_priv.h | 3 +++ 3 files changed, 55 insertions(+) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index e0d4ffce7a8a..cc2a0ccfcc30 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1362,6 +1362,32 @@ xfs_log_work_queue( msecs_to_jiffies(xfs_syncd_centisecs * 10)); } +/* + * Clear the log incompat flags if we have the opportunity. + * + * This only happens if we're about to log the second dummy transaction as part + * of covering the log and we can get the log incompat feature usage lock. + */ +static inline void +xlog_clear_incompat( + struct xlog *log) +{ + struct xfs_mount *mp = log->l_mp; + + if (!xfs_sb_has_incompat_log_feature(&mp->m_sb, + XFS_SB_FEAT_INCOMPAT_LOG_ALL)) + return; + + if (log->l_covered_state != XLOG_STATE_COVER_DONE2) + return; + + if (!down_write_trylock(&log->l_incompat_users)) + return; + + xfs_clear_incompat_log_features(mp); + up_write(&log->l_incompat_users); +} + /* * Every sync period we need to unpin all items in the AIL and push them to * disk. If there is nothing dirty, then we might need to cover the log to @@ -1388,6 +1414,7 @@ xfs_log_worker( * synchronously log the superblock instead to ensure the * superblock is immediately unpinned and can be written back. */ + xlog_clear_incompat(log); xfs_sync_sb(mp, true); } else xfs_log_force(mp, 0); @@ -1475,6 +1502,8 @@ xlog_alloc_log( } log->l_sectBBsize = 1 << log2_size; + init_rwsem(&log->l_incompat_users); + xlog_get_iclog_buffer_size(mp, log); spin_lock_init(&log->l_icloglock); @@ -3973,3 +4002,23 @@ xfs_log_in_recovery( return log->l_flags & XLOG_ACTIVE_RECOVERY; } + +/* + * Notify the log that we're about to start using a feature that is protected + * by a log incompat feature flag. This will prevent log covering from + * clearing those flags. + */ +void +xlog_use_incompat_feat( + struct xlog *log) +{ + down_read(&log->l_incompat_users); +} + +/* Notify the log that we've finished using log incompat features. */ +void +xlog_drop_incompat_feat( + struct xlog *log) +{ + up_read(&log->l_incompat_users); +} diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 813b972e9788..b274fb9dcd8d 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -142,4 +142,7 @@ bool xfs_log_in_recovery(struct xfs_mount *); xfs_lsn_t xlog_grant_push_threshold(struct xlog *log, int need_bytes); +void xlog_use_incompat_feat(struct xlog *log); +void xlog_drop_incompat_feat(struct xlog *log); + #endif /* __XFS_LOG_H__ */ diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index f3e79a45d60a..6953f86f866c 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -456,6 +456,9 @@ struct xlog { xfs_lsn_t l_recovery_lsn; uint32_t l_iclog_roundoff;/* padding roundoff */ + + /* Users of log incompat features should take a read lock. */ + struct rw_semaphore l_incompat_users; }; #define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ -- cgit v1.2.3-70-g09d2 From 4bc619833f738f4fa8d931a71610795ebf5cec0e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sun, 8 Aug 2021 08:27:13 -0700 Subject: xfs: refactor xfs_iget calls from log intent recovery Hoist the code from xfs_bui_item_recover that igets an inode and marks it as being part of log intent recovery. The next patch will want a common function. Signed-off-by: Darrick J. Wong Reviewed-by: Allison Henderson Reviewed-by: Chandan Babu R --- fs/xfs/libxfs/xfs_log_recover.h | 2 ++ fs/xfs/xfs_bmap_item.c | 11 +---------- fs/xfs/xfs_log_recover.c | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index 3cca2bfe714c..ff69a0000817 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -122,6 +122,8 @@ void xlog_buf_readahead(struct xlog *log, xfs_daddr_t blkno, uint len, const struct xfs_buf_ops *ops); bool xlog_is_buffer_cancelled(struct xlog *log, xfs_daddr_t blkno, uint len); +int xlog_recover_iget(struct xfs_mount *mp, xfs_ino_t ino, + struct xfs_inode **ipp); void xlog_recover_release_intent(struct xlog *log, unsigned short intent_type, uint64_t intent_id); diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index 3d6f70da8820..03159970133f 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -24,7 +24,6 @@ #include "xfs_error.h" #include "xfs_log_priv.h" #include "xfs_log_recover.h" -#include "xfs_quota.h" kmem_zone_t *xfs_bui_zone; kmem_zone_t *xfs_bud_zone; @@ -487,18 +486,10 @@ xfs_bui_item_recover( XFS_ATTR_FORK : XFS_DATA_FORK; bui_type = bmap->me_flags & XFS_BMAP_EXTENT_TYPE_MASK; - /* Grab the inode. */ - error = xfs_iget(mp, NULL, bmap->me_owner, 0, 0, &ip); + error = xlog_recover_iget(mp, bmap->me_owner, &ip); if (error) return error; - error = xfs_qm_dqattach(ip); - if (error) - goto err_rele; - - if (VFS_I(ip)->i_nlink == 0) - xfs_iflags_set(ip, XFS_IRECOVERY); - /* Allocate transaction and do the work. */ error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK), 0, 0, &tp); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1d324c8bac6b..1d4213302078 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -26,6 +26,8 @@ #include "xfs_error.h" #include "xfs_buf_item.h" #include "xfs_ag.h" +#include "xfs_quota.h" + #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) @@ -1754,6 +1756,30 @@ xlog_recover_release_intent( spin_unlock(&ailp->ail_lock); } +int +xlog_recover_iget( + struct xfs_mount *mp, + xfs_ino_t ino, + struct xfs_inode **ipp) +{ + int error; + + error = xfs_iget(mp, NULL, ino, 0, 0, ipp); + if (error) + return error; + + error = xfs_qm_dqattach(*ipp); + if (error) { + xfs_irele(*ipp); + return error; + } + + if (VFS_I(*ipp)->i_nlink == 0) + xfs_iflags_set(*ipp, XFS_IRECOVERY); + + return 0; +} + /****************************************************************************** * * Log recover routines -- cgit v1.2.3-70-g09d2 From df0826312a23e495faa91eee0d6ac31bca35dc09 Mon Sep 17 00:00:00 2001 From: Allison Henderson Date: Sun, 8 Aug 2021 08:27:13 -0700 Subject: xfs: add attr state machine tracepoints This is a quick patch to add a new xfs_attr_*_return tracepoints. We use these to track when ever a new state is set or -EAGAIN is returned Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 31 +++++++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_attr_remote.c | 1 + fs/xfs/xfs_trace.h | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 191d51725988..dec538d336d7 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -335,6 +335,7 @@ xfs_attr_sf_addname( * the attr fork to leaf format and will restart with the leaf * add. */ + trace_xfs_attr_sf_addname_return(XFS_DAS_UNINIT, args->dp); dac->flags |= XFS_DAC_DEFER_FINISH; return -EAGAIN; } @@ -394,6 +395,8 @@ xfs_attr_set_iter( * handling code below */ dac->flags |= XFS_DAC_DEFER_FINISH; + trace_xfs_attr_set_iter_return( + dac->dela_state, args->dp); return -EAGAIN; } else if (error) { return error; @@ -411,6 +414,7 @@ xfs_attr_set_iter( dac->dela_state = XFS_DAS_FOUND_NBLK; } + trace_xfs_attr_set_iter_return(dac->dela_state, args->dp); return -EAGAIN; case XFS_DAS_FOUND_LBLK: /* @@ -438,6 +442,8 @@ xfs_attr_set_iter( error = xfs_attr_rmtval_set_blk(dac); if (error) return error; + trace_xfs_attr_set_iter_return(dac->dela_state, + args->dp); return -EAGAIN; } @@ -472,6 +478,7 @@ xfs_attr_set_iter( * series. */ dac->dela_state = XFS_DAS_FLIP_LFLAG; + trace_xfs_attr_set_iter_return(dac->dela_state, args->dp); return -EAGAIN; case XFS_DAS_FLIP_LFLAG: /* @@ -489,10 +496,14 @@ xfs_attr_set_iter( dac->dela_state = XFS_DAS_RM_LBLK; if (args->rmtblkno) { error = __xfs_attr_rmtval_remove(dac); + if (error == -EAGAIN) + trace_xfs_attr_set_iter_return( + dac->dela_state, args->dp); if (error) return error; dac->dela_state = XFS_DAS_RD_LEAF; + trace_xfs_attr_set_iter_return(dac->dela_state, args->dp); return -EAGAIN; } @@ -542,6 +553,8 @@ xfs_attr_set_iter( error = xfs_attr_rmtval_set_blk(dac); if (error) return error; + trace_xfs_attr_set_iter_return( + dac->dela_state, args->dp); return -EAGAIN; } @@ -577,6 +590,7 @@ xfs_attr_set_iter( * series */ dac->dela_state = XFS_DAS_FLIP_NFLAG; + trace_xfs_attr_set_iter_return(dac->dela_state, args->dp); return -EAGAIN; case XFS_DAS_FLIP_NFLAG: @@ -596,10 +610,15 @@ xfs_attr_set_iter( dac->dela_state = XFS_DAS_RM_NBLK; if (args->rmtblkno) { error = __xfs_attr_rmtval_remove(dac); + if (error == -EAGAIN) + trace_xfs_attr_set_iter_return( + dac->dela_state, args->dp); + if (error) return error; dac->dela_state = XFS_DAS_CLR_FLAG; + trace_xfs_attr_set_iter_return(dac->dela_state, args->dp); return -EAGAIN; } @@ -1176,6 +1195,8 @@ xfs_attr_node_addname( * this point. */ dac->flags |= XFS_DAC_DEFER_FINISH; + trace_xfs_attr_node_addname_return( + dac->dela_state, args->dp); return -EAGAIN; } @@ -1422,10 +1443,13 @@ xfs_attr_remove_iter( * blocks are removed. */ error = __xfs_attr_rmtval_remove(dac); - if (error == -EAGAIN) + if (error == -EAGAIN) { + trace_xfs_attr_remove_iter_return( + dac->dela_state, args->dp); return error; - else if (error) + } else if (error) { goto out; + } /* * Refill the state structure with buffers (the prior @@ -1438,6 +1462,7 @@ xfs_attr_remove_iter( goto out; dac->dela_state = XFS_DAS_RM_NAME; dac->flags |= XFS_DAC_DEFER_FINISH; + trace_xfs_attr_remove_iter_return(dac->dela_state, args->dp); return -EAGAIN; } @@ -1466,6 +1491,8 @@ xfs_attr_remove_iter( dac->flags |= XFS_DAC_DEFER_FINISH; dac->dela_state = XFS_DAS_RM_SHRINK; + trace_xfs_attr_remove_iter_return( + dac->dela_state, args->dp); return -EAGAIN; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 0c8bee3abc3b..70f880da563b 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -696,6 +696,7 @@ __xfs_attr_rmtval_remove( */ if (!done) { dac->flags |= XFS_DAC_DEFER_FINISH; + trace_xfs_attr_rmtval_remove_return(dac->dela_state, args->dp); return -EAGAIN; } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 36d771d00f7f..18a6e07f7dd4 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -4073,6 +4073,30 @@ DEFINE_ICLOG_EVENT(xlog_iclog_want_sync); DEFINE_ICLOG_EVENT(xlog_iclog_wait_on); DEFINE_ICLOG_EVENT(xlog_iclog_write); +DECLARE_EVENT_CLASS(xfs_das_state_class, + TP_PROTO(int das, struct xfs_inode *ip), + TP_ARGS(das, ip), + TP_STRUCT__entry( + __field(int, das) + __field(xfs_ino_t, ino) + ), + TP_fast_assign( + __entry->das = das; + __entry->ino = ip->i_ino; + ), + TP_printk("state change %d ino 0x%llx", + __entry->das, __entry->ino) +) + +#define DEFINE_DAS_STATE_EVENT(name) \ +DEFINE_EVENT(xfs_das_state_class, name, \ + TP_PROTO(int das, struct xfs_inode *ip), \ + TP_ARGS(das, ip)) +DEFINE_DAS_STATE_EVENT(xfs_attr_sf_addname_return); +DEFINE_DAS_STATE_EVENT(xfs_attr_set_iter_return); +DEFINE_DAS_STATE_EVENT(xfs_attr_node_addname_return); +DEFINE_DAS_STATE_EVENT(xfs_attr_remove_iter_return); +DEFINE_DAS_STATE_EVENT(xfs_attr_rmtval_remove_return); #endif /* _TRACE_XFS_H */ #undef TRACE_INCLUDE_PATH -- cgit v1.2.3-70-g09d2 From a325db2d8f1d7e33cdc0152b61c3f14fb06f9893 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Wed, 2 Dec 2020 15:12:39 +0000 Subject: scripts: merge_config: add strict mode to fail upon any redefinition When merging configuration fragments, it might be of interest to identify mismatches (redefinitions) programmatically. Hence add the option -s (strict mode) to instruct merge_config.sh to bail out in case any redefinition has been detected. With strict mode, warnings are emitted as before, but the script terminates with rc=1. If -y is set to define "builtin having precedence over modules", fragments are still allowed to set =m (while the base config has =y). Strict mode will tolerate that as demotions from =y to =m are ignored when setting -y. Signed-off-by: Matthias Maennich Reviewed-by: Lee Jones Signed-off-by: Masahiro Yamada --- scripts/kconfig/merge_config.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh index 63c8565206a4..e5b46980c22a 100755 --- a/scripts/kconfig/merge_config.sh +++ b/scripts/kconfig/merge_config.sh @@ -28,6 +28,7 @@ usage() { echo " -r list redundant entries when merging fragments" echo " -y make builtin have precedence over modules" echo " -O dir to put generated output files. Consider setting \$KCONFIG_CONFIG instead." + echo " -s strict mode. Fail if the fragment redefines any value." echo echo "Used prefix: '$CONFIG_PREFIX'. You can redefine it with \$CONFIG_ environment variable." } @@ -37,6 +38,7 @@ ALLTARGET=alldefconfig WARNREDUN=false BUILTIN=false OUTPUT=. +STRICT=false CONFIG_PREFIX=${CONFIG_-CONFIG_} while true; do @@ -75,6 +77,11 @@ while true; do shift 2 continue ;; + "-s") + STRICT=true + shift + continue + ;; *) break ;; @@ -141,6 +148,9 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo + if [ "$STRICT" = "true" ]; then + STRICT_MODE_VIOLATED=true + fi elif [ "$WARNREDUN" = "true" ]; then echo Value of $CFG is redundant by fragment $ORIG_MERGE_FILE: fi @@ -153,6 +163,11 @@ for ORIG_MERGE_FILE in $MERGE_LIST ; do cat $MERGE_FILE >> $TMP_FILE done +if [ "$STRICT_MODE_VIOLATED" = "true" ]; then + echo "The fragment redefined a value and strict mode had been passed." + exit 1 +fi + if [ "$RUNMAKE" = "false" ]; then cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG" echo "#" -- cgit v1.2.3-70-g09d2 From d8285639550578a1bf2d102391d1a9e08e0586ca Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 25 Jul 2021 03:35:56 +0900 Subject: kbuild: do not require sub-make for separate output tree builds As explained in commit 3204a7fb98a3 ("kbuild: prefix $(srctree)/ to some included Makefiles"), I want to stop using --include-dir some day. I already fixed up the top Makefile, but some arch Makefiles (mips, um, x86) still include check-in Makefiles without $(srctree)/. Fix them up so 'need-sub-make := 1' can go away for this case. Signed-off-by: Masahiro Yamada --- Makefile | 5 ++--- arch/mips/Makefile | 2 +- arch/um/Makefile | 6 +++--- arch/x86/Makefile | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index eae1314a5b86..185ce47d6734 100644 --- a/Makefile +++ b/Makefile @@ -191,10 +191,9 @@ endif ifneq ($(abs_srctree),$(abs_objtree)) # Look for make include files relative to root of kernel src # -# This does not become effective immediately because MAKEFLAGS is re-parsed -# once after the Makefile is read. We need to invoke sub-make. +# --included-dir is added for backward compatibility, but you should not rely on +# it. Please add $(srctree)/ prefix to include Makefiles in the source tree. MAKEFLAGS += --include-dir=$(abs_srctree) -need-sub-make := 1 endif ifneq ($(filter 3.%,$(MAKE_VERSION)),) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 653befc1b176..5fd26d514851 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -254,7 +254,7 @@ endif # # Board-dependent options and extra files # -include arch/mips/Kbuild.platforms +include $(srctree)/arch/mips/Kbuild.platforms ifdef CONFIG_PHYSICAL_START load-y = $(CONFIG_PHYSICAL_START) diff --git a/arch/um/Makefile b/arch/um/Makefile index 12a7acef0357..f2fe63bfd819 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -41,8 +41,8 @@ endif HOST_DIR := arch/$(HEADER_ARCH) -include $(ARCH_DIR)/Makefile-skas -include $(HOST_DIR)/Makefile.um +include $(srctree)/$(ARCH_DIR)/Makefile-skas +include $(srctree)/$(HOST_DIR)/Makefile.um core-y += $(HOST_DIR)/um/ @@ -76,7 +76,7 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \ -idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__ #This will adjust *FLAGS accordingly to the platform. -include $(ARCH_DIR)/Makefile-os-$(OS) +include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/include \ -I$(srctree)/$(HOST_DIR)/include/uapi \ diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 307fd0000a83..0fa7dc73b5d8 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -75,7 +75,7 @@ ifeq ($(CONFIG_X86_32),y) KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align4)) # CPU-specific tuning. Anything which can be shared with UML should go here. - include arch/x86/Makefile_32.cpu + include $(srctree)/arch/x86/Makefile_32.cpu KBUILD_CFLAGS += $(cflags-y) # temporary until string.h is fixed -- cgit v1.2.3-70-g09d2 From 0058d07ec6aac8b1379f817b31839caa4ac8e448 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 28 Jul 2021 00:39:24 +0900 Subject: scripts: make some scripts executable Set the x bit to some scripts to make them directly executable. Especially, scripts/checkdeclares.pl is not hooked by anyone. It should be executable since it is tedious to type 'perl scripts/checkdeclares.pl'. The original patch [1] set the x bit properly, but it was lost when it was merged as commit 21917bded72c ("scripts: a new script for checking duplicate struct declaration"). [1] https://lore.kernel.org/lkml/20210401110943.1010796-1-wanjiabing@vivo.com/ Signed-off-by: Masahiro Yamada --- scripts/checkdeclares.pl | 0 scripts/gcc-plugins/gen-random-seed.sh | 0 scripts/syscallnr.sh | 0 scripts/xen-hypercalls.sh | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/checkdeclares.pl mode change 100644 => 100755 scripts/gcc-plugins/gen-random-seed.sh mode change 100644 => 100755 scripts/syscallnr.sh mode change 100644 => 100755 scripts/xen-hypercalls.sh diff --git a/scripts/checkdeclares.pl b/scripts/checkdeclares.pl old mode 100644 new mode 100755 diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh old mode 100644 new mode 100755 diff --git a/scripts/syscallnr.sh b/scripts/syscallnr.sh old mode 100644 new mode 100755 diff --git a/scripts/xen-hypercalls.sh b/scripts/xen-hypercalls.sh old mode 100644 new mode 100755 -- cgit v1.2.3-70-g09d2 From 6072b2c49d23eb69b6dca06ad095d3a9633b2b80 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 1 Aug 2021 11:53:46 +0900 Subject: kbuild: warn if a different compiler is used for external module builds It is always safe to use the same compiler for the kernel and external modules, but in reality, some distributions such as Fedora release a different version of GCC from the one used for building the kernel. There was a long discussion about mixing different compilers [1]. I do not repeat it here, but at least, showing a heads up in that case is better than nothing. Linus suggested [2]: And a warning might be more palatable even if different compiler version work fine together. Just a heads up on "it looks like you might be mixing compiler versions" is a valid note, and isn't necessarily wrong. Even when they work well together, maybe you want to have people at least _aware_ of it. This commit shows a warning unless the compiler is exactly the same. warning: the compiler differs from the one used to build the kernel The kernel was built by: gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) You are using: gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) Check the difference, and if it is OK with you, please proceed at your risk. To avoid the locale issue as in commit bcbcf50f5218 ("kbuild: fix ld-version.sh to not be affected by locale"), pass LC_ALL=C to "$(CC) --version". [1] https://lore.kernel.org/linux-hardening/efe6b039a544da8215d5e54aa7c4b6d1986fc2b0.1611607264.git.jpoimboe@redhat.com/ [2] https://lore.kernel.org/lkml/CAHk-=wgjwhDy-y4mQh34L+2aF=n6BjzHdqAW2=8wri5x7O04pA@mail.gmail.com/ Acked-by: Josh Poimboeuf Signed-off-by: Masahiro Yamada --- Makefile | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 185ce47d6734..a0376430da20 100644 --- a/Makefile +++ b/Makefile @@ -581,7 +581,7 @@ endif # Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile. # CC_VERSION_TEXT is referenced from Kconfig (so it needs export), # and from include/config/auto.conf.cmd to detect the compiler upgrade. -CC_VERSION_TEXT = $(subst $(pound),,$(shell $(CC) --version 2>/dev/null | head -n 1)) +CC_VERSION_TEXT = $(subst $(pound),,$(shell LC_ALL=C $(CC) --version 2>/dev/null | head -n 1)) ifneq ($(findstring clang,$(CC_VERSION_TEXT)),) ifneq ($(CROSS_COMPILE),) @@ -1739,6 +1739,16 @@ clean-dirs := $(KBUILD_EXTMOD) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ $(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache +PHONY += prepare +# now expand this into a simple variable to reduce the cost of shell evaluations +prepare: CC_VERSION_TEXT := $(CC_VERSION_TEXT) +prepare: + @if [ "$(CC_VERSION_TEXT)" != $(CONFIG_CC_VERSION_TEXT) ]; then \ + echo >&2 "warning: the compiler differs from the one used to build the kernel"; \ + echo >&2 " The kernel was built by: "$(CONFIG_CC_VERSION_TEXT); \ + echo >&2 " You are using: $(CC_VERSION_TEXT)"; \ + fi + PHONY += help help: @echo ' Building external modules.' @@ -1750,7 +1760,7 @@ help: @echo '' # no-op for external module builds -PHONY += prepare modules_prepare +PHONY += modules_prepare endif # KBUILD_EXTMOD -- cgit v1.2.3-70-g09d2 From 6f5b41a2f5a6314614e286274eb8e985248aac60 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 2 Aug 2021 11:39:08 -0700 Subject: Makefile: move initial clang flag handling into scripts/Makefile.clang With some of the changes we'd like to make to CROSS_COMPILE, the initial block of clang flag handling which controls things like the target triple, whether or not to use the integrated assembler and how to find GAS, and erroring on unknown warnings is becoming unwieldy. Move it into its own file under scripts/. Reviewed-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Signed-off-by: Masahiro Yamada --- MAINTAINERS | 1 + Makefile | 15 +-------------- scripts/Makefile.clang | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 14 deletions(-) create mode 100644 scripts/Makefile.clang diff --git a/MAINTAINERS b/MAINTAINERS index c9467d2839f5..3105fc57689e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4501,6 +4501,7 @@ B: https://github.com/ClangBuiltLinux/linux/issues C: irc://chat.freenode.net/clangbuiltlinux F: Documentation/kbuild/llvm.rst F: include/linux/compiler-clang.h +F: scripts/Makefile.clang F: scripts/clang-tools/ K: \b(?i:clang|llvm)\b diff --git a/Makefile b/Makefile index a0376430da20..f5419ce69ce8 100644 --- a/Makefile +++ b/Makefile @@ -584,20 +584,7 @@ endif CC_VERSION_TEXT = $(subst $(pound),,$(shell LC_ALL=C $(CC) --version 2>/dev/null | head -n 1)) ifneq ($(findstring clang,$(CC_VERSION_TEXT)),) -ifneq ($(CROSS_COMPILE),) -CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) -endif -ifeq ($(LLVM_IAS),1) -CLANG_FLAGS += -integrated-as -else -CLANG_FLAGS += -no-integrated-as -GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) -CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) -endif -CLANG_FLAGS += -Werror=unknown-warning-option -KBUILD_CFLAGS += $(CLANG_FLAGS) -KBUILD_AFLAGS += $(CLANG_FLAGS) -export CLANG_FLAGS +include $(srctree)/scripts/Makefile.clang endif # Include this also for config targets because some architectures need diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang new file mode 100644 index 000000000000..297932e973d4 --- /dev/null +++ b/scripts/Makefile.clang @@ -0,0 +1,14 @@ +ifneq ($(CROSS_COMPILE),) +CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) +endif +ifeq ($(LLVM_IAS),1) +CLANG_FLAGS += -integrated-as +else +CLANG_FLAGS += -no-integrated-as +GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) +CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) +endif +CLANG_FLAGS += -Werror=unknown-warning-option +KBUILD_CFLAGS += $(CLANG_FLAGS) +KBUILD_AFLAGS += $(CLANG_FLAGS) +export CLANG_FLAGS -- cgit v1.2.3-70-g09d2 From 231ad7f409f16b9f9505f69e058dff488a7e6bde Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 2 Aug 2021 11:39:09 -0700 Subject: Makefile: infer --target from ARCH for CC=clang We get constant feedback that the command line invocation of make is too long when compiling with LLVM. CROSS_COMPILE is helpful when a toolchain has a prefix of the target triple, or is an absolute path outside of $PATH. Since a Clang binary is generally multi-targeted, we can infer a given target from SRCARCH/ARCH. If CROSS_COMPILE is not set, simply set --target= for CLANG_FLAGS, KBUILD_CFLAGS, and KBUILD_AFLAGS based on $SRCARCH. Previously, we'd cross compile via: $ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make LLVM=1 LLVM_IAS=1 Now: $ ARCH=arm64 make LLVM=1 LLVM_IAS=1 For native builds (not involving cross compilation) we now explicitly specify a target triple rather than rely on the implicit host triple. Link: https://github.com/ClangBuiltLinux/linux/issues/1399 Suggested-by: Arnd Bergmann Suggested-by: Linus Torvalds Suggested-by: Masahiro Yamada Suggested-by: Nathan Chancellor Acked-by: Arnd Bergmann Reviewed-by: Nathan Chancellor Signed-off-by: Nick Desaulniers Acked-by: Miguel Ojeda Signed-off-by: Masahiro Yamada --- scripts/Makefile.clang | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 297932e973d4..1f4e3eb70f88 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -1,6 +1,27 @@ -ifneq ($(CROSS_COMPILE),) +# Individual arch/{arch}/Makefiles should use -EL/-EB to set intended +# endianness and -m32/-m64 to set word size based on Kconfigs instead of +# relying on the target triple. +CLANG_TARGET_FLAGS_arm := arm-linux-gnueabi +CLANG_TARGET_FLAGS_arm64 := aarch64-linux-gnu +CLANG_TARGET_FLAGS_hexagon := hexagon-linux-musl +CLANG_TARGET_FLAGS_m68k := m68k-linux-gnu +CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu +CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu +CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu +CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu +CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu +CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH)) + +ifeq ($(CROSS_COMPILE),) +ifeq ($(CLANG_TARGET_FLAGS),) +$(error Specify CROSS_COMPILE or add '--target=' option to scripts/Makefile.clang) +else +CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS) +endif # CLANG_TARGET_FLAGS +else CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) -endif +endif # CROSS_COMPILE + ifeq ($(LLVM_IAS),1) CLANG_FLAGS += -integrated-as else -- cgit v1.2.3-70-g09d2 From e08831baa032e62786d88b68e26c54389e2486b6 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 2 Aug 2021 11:39:10 -0700 Subject: Documentation/llvm: update CROSS_COMPILE inferencing As noted by Masahiro, document how we can generally infer CROSS_COMPILE (and the more specific details about --target and --prefix) based on ARCH. Change use of env vars to command line parameters. Suggested-by: Masahiro Yamada Reviewed-by: Fangrui Song Signed-off-by: Nick Desaulniers Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- Documentation/kbuild/llvm.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index b18401d2ba82..f8a360958f4c 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -38,7 +38,7 @@ Cross Compiling A single Clang compiler binary will typically contain all supported backends, which can help simplify cross compiling. :: - ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make CC=clang + make ARCH=arm64 CC=clang CROSS_COMPILE=aarch64-linux-gnu- ``CROSS_COMPILE`` is not used to prefix the Clang compiler binary, instead ``CROSS_COMPILE`` is used to set a command line flag: ``--target=``. For @@ -63,6 +63,23 @@ They can be enabled individually. The full list of the parameters: :: Currently, the integrated assembler is disabled by default. You can pass ``LLVM_IAS=1`` to enable it. +Omitting CROSS_COMPILE +---------------------- + +As explained above, ``CROSS_COMPILE`` is used to set ``--target=``. + +Unless ``LLVM_IAS=1`` is specified, ``CROSS_COMPILE`` is also used to derive +``--prefix=`` to search for the GNU assembler and linker. + +If ``CROSS_COMPILE`` is not specified, the ``--target=`` is inferred +from ``ARCH``. + +That means if you use only LLVM tools, ``CROSS_COMPILE`` becomes unnecessary. + +For example, to cross-compile the arm64 kernel:: + + make ARCH=arm64 LLVM=1 LLVM_IAS=1 + Supported Architectures ----------------------- -- cgit v1.2.3-70-g09d2 From 52cc02b910284d6bddba46cce402044ab775f314 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 6 Aug 2021 00:01:02 +0900 Subject: kbuild: check CONFIG_AS_IS_LLVM instead of LLVM_IAS LLVM_IAS is the user interface to set the -(no-)integrated-as flag, and it should be used only for that purpose. LLVM_IAS is checked in some places to determine the assembler type, but it is not precise. For example, $ make CC=gcc LLVM_IAS=1 ... will use the GNU assembler (i.e. binutils) since LLVM_IAS=1 is effective only when $(CC) is clang. Of course, 'CC=gcc LLVM_IAS=1' is an odd combination, but the build system can be more robust against such insane input. Commit ba64beb17493a ("kbuild: check the minimum assembler version in Kconfig") introduced CONFIG_AS_IS_GNU/LLVM, which is more precise because Kconfig checks the version string from the assembler in use. Signed-off-by: Masahiro Yamada Reviewed-by: Nick Desaulniers Reviewed-by: Nathan Chancellor --- Makefile | 2 +- arch/riscv/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index f5419ce69ce8..891866af0787 100644 --- a/Makefile +++ b/Makefile @@ -843,7 +843,7 @@ else DEBUG_CFLAGS += -g endif -ifneq ($(LLVM_IAS),1) +ifndef CONFIG_AS_IS_LLVM KBUILD_AFLAGS += -Wa,-gdwarf-2 endif diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index bc74afdbf31e..dcfbd2a87d41 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -41,7 +41,7 @@ endif ifeq ($(CONFIG_LD_IS_LLD),y) KBUILD_CFLAGS += -mno-relax KBUILD_AFLAGS += -mno-relax -ifneq ($(LLVM_IAS),1) +ifndef CONFIG_AS_IS_LLVM KBUILD_CFLAGS += -Wa,-mno-relax KBUILD_AFLAGS += -Wa,-mno-relax endif -- cgit v1.2.3-70-g09d2 From f12b034afeb3a977bbb1c6584dedc0f3dc666f14 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 6 Aug 2021 10:27:01 -0700 Subject: scripts/Makefile.clang: default to LLVM_IAS=1 LLVM_IAS=1 controls enabling clang's integrated assembler via -integrated-as. This was an explicit opt in until we could enable assembler support in Clang for more architecures. Now we have support and CI coverage of LLVM_IAS=1 for all architecures except a few more bugs affecting s390 and powerpc. This commit flips the default from opt in via LLVM_IAS=1 to opt out via LLVM_IAS=0. CI systems or developers that were previously doing builds with CC=clang or LLVM=1 without explicitly setting LLVM_IAS must now explicitly opt out via LLVM_IAS=0, otherwise they will be implicitly opted-in. This finally shortens the command line invocation when cross compiling with LLVM to simply: $ make ARCH=arm64 LLVM=1 Signed-off-by: Nick Desaulniers Reviewed-by: Nathan Chancellor Signed-off-by: Masahiro Yamada --- Documentation/kbuild/llvm.rst | 14 ++++++++------ scripts/Makefile.clang | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Documentation/kbuild/llvm.rst b/Documentation/kbuild/llvm.rst index f8a360958f4c..e87ed5479963 100644 --- a/Documentation/kbuild/llvm.rst +++ b/Documentation/kbuild/llvm.rst @@ -60,17 +60,14 @@ They can be enabled individually. The full list of the parameters: :: OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump READELF=llvm-readelf \ HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar HOSTLD=ld.lld -Currently, the integrated assembler is disabled by default. You can pass -``LLVM_IAS=1`` to enable it. +The integrated assembler is enabled by default. You can pass ``LLVM_IAS=0`` to +disable it. Omitting CROSS_COMPILE ---------------------- As explained above, ``CROSS_COMPILE`` is used to set ``--target=``. -Unless ``LLVM_IAS=1`` is specified, ``CROSS_COMPILE`` is also used to derive -``--prefix=`` to search for the GNU assembler and linker. - If ``CROSS_COMPILE`` is not specified, the ``--target=`` is inferred from ``ARCH``. @@ -78,7 +75,12 @@ That means if you use only LLVM tools, ``CROSS_COMPILE`` becomes unnecessary. For example, to cross-compile the arm64 kernel:: - make ARCH=arm64 LLVM=1 LLVM_IAS=1 + make ARCH=arm64 LLVM=1 + +If ``LLVM_IAS=0`` is specified, ``CROSS_COMPILE`` is also used to derive +``--prefix=`` to search for the GNU assembler and linker. :: + + make ARCH=arm64 LLVM=1 LLVM_IAS=0 CROSS_COMPILE=aarch64-linux-gnu- Supported Architectures ----------------------- diff --git a/scripts/Makefile.clang b/scripts/Makefile.clang index 1f4e3eb70f88..3ae63bd35582 100644 --- a/scripts/Makefile.clang +++ b/scripts/Makefile.clang @@ -22,12 +22,12 @@ else CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) endif # CROSS_COMPILE -ifeq ($(LLVM_IAS),1) -CLANG_FLAGS += -integrated-as -else +ifeq ($(LLVM_IAS),0) CLANG_FLAGS += -no-integrated-as GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) +else +CLANG_FLAGS += -integrated-as endif CLANG_FLAGS += -Werror=unknown-warning-option KBUILD_CFLAGS += $(CLANG_FLAGS) -- cgit v1.2.3-70-g09d2 From 432bc7caef4eaacc1101ee2569bb870bdfeed7ce Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 27 Jul 2021 13:42:12 +0530 Subject: scsi: mpt3sas: Add io_uring iopoll support Enable the driver to work in non-IRQ mode, i.e. there will not be any MSI-X vectors associated with queues dedicated to polling. The IOC hardware is single submission queue and multiple reply queue. However, using the shared host tagset support it is possible to simulate multiple hardware queues. When poll_queues are enabled through the module parameter, the driver will allocate extra reply queues without an MSI-X association. All I/O completion on these queues will be done through the iopoll interface. Link: https://lore.kernel.org/r/20210727081212.2742-1-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 243 +++++++++++++++++++++++++++++++---- drivers/scsi/mpt3sas/mpt3sas_base.h | 23 ++++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 62 +++++++-- 3 files changed, 296 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index c39955239d1c..90dd18a315b9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -116,6 +116,14 @@ MODULE_PARM_DESC(perf_mode, "\t\tdefault - default perf_mode is 'balanced'" ); +static int poll_queues; +module_param(poll_queues, int, 0444); +MODULE_PARM_DESC(poll_queues, "Number of queues to be use for io_uring poll mode.\n\t\t" + "This parameter is effective only if host_tagset_enable=1. &\n\t\t" + "when poll_queues are enabled then &\n\t\t" + "perf_mode is set to latency mode. &\n\t\t" + ); + enum mpt3sas_perf_mode { MPT_PERF_MODE_DEFAULT = -1, MPT_PERF_MODE_BALANCED = 0, @@ -709,6 +717,7 @@ _base_fault_reset_work(struct work_struct *work) * and this call is safe since dead ioc will never return any * command back from HW. */ + mpt3sas_base_pause_mq_polling(ioc); ioc->schedule_dead_ioc_flush_running_cmds(ioc); /* * Set remove_host flag early since kernel thread will @@ -744,6 +753,7 @@ _base_fault_reset_work(struct work_struct *work) spin_unlock_irqrestore( &ioc->ioc_reset_in_progress_lock, flags); mpt3sas_base_mask_interrupts(ioc); + mpt3sas_base_pause_mq_polling(ioc); _base_clear_outstanding_commands(ioc); } @@ -1547,6 +1557,53 @@ _base_get_cb_idx(struct MPT3SAS_ADAPTER *ioc, u16 smid) return cb_idx; } +/** + * mpt3sas_base_pause_mq_polling - pause polling on the mq poll queues + * when driver is flushing out the IOs. + * @ioc: per adapter object + * + * Pause polling on the mq poll (io uring) queues when driver is flushing + * out the IOs. Otherwise we may see the race condition of completing the same + * IO from two paths. + * + * Returns nothing. + */ +void +mpt3sas_base_pause_mq_polling(struct MPT3SAS_ADAPTER *ioc) +{ + int iopoll_q_count = + ioc->reply_queue_count - ioc->iopoll_q_start_index; + int qid; + + for (qid = 0; qid < iopoll_q_count; qid++) + atomic_set(&ioc->io_uring_poll_queues[qid].pause, 1); + + /* + * wait for current poll to complete. + */ + for (qid = 0; qid < iopoll_q_count; qid++) { + while (atomic_read(&ioc->io_uring_poll_queues[qid].busy)) + udelay(500); + } +} + +/** + * mpt3sas_base_resume_mq_polling - Resume polling on mq poll queues. + * @ioc: per adapter object + * + * Returns nothing. + */ +void +mpt3sas_base_resume_mq_polling(struct MPT3SAS_ADAPTER *ioc) +{ + int iopoll_q_count = + ioc->reply_queue_count - ioc->iopoll_q_start_index; + int qid; + + for (qid = 0; qid < iopoll_q_count; qid++) + atomic_set(&ioc->io_uring_poll_queues[qid].pause, 0); +} + /** * mpt3sas_base_mask_interrupts - disable interrupts * @ioc: per adapter object @@ -1722,7 +1779,8 @@ _base_process_reply_queue(struct adapter_reply_queue *reply_q) MPI2_RPHI_MSIX_INDEX_SHIFT), &ioc->chip->ReplyPostHostIndex); } - if (!reply_q->irq_poll_scheduled) { + if (!reply_q->is_iouring_poll_q && + !reply_q->irq_poll_scheduled) { reply_q->irq_poll_scheduled = true; irq_poll_sched(&reply_q->irqpoll); } @@ -1778,6 +1836,33 @@ _base_process_reply_queue(struct adapter_reply_queue *reply_q) return completed_cmds; } +/** + * mpt3sas_blk_mq_poll - poll the blk mq poll queue + * @shost: Scsi_Host object + * @queue_num: hw ctx queue number + * + * Return number of entries that has been processed from poll queue. + */ +int mpt3sas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) +{ + struct MPT3SAS_ADAPTER *ioc = + (struct MPT3SAS_ADAPTER *)shost->hostdata; + struct adapter_reply_queue *reply_q; + int num_entries = 0; + int qid = queue_num - ioc->iopoll_q_start_index; + + if (atomic_read(&ioc->io_uring_poll_queues[qid].pause) || + !atomic_add_unless(&ioc->io_uring_poll_queues[qid].busy, 1, 1)) + return 0; + + reply_q = ioc->io_uring_poll_queues[qid].reply_q; + + num_entries = _base_process_reply_queue(reply_q); + atomic_dec(&ioc->io_uring_poll_queues[qid].busy); + + return num_entries; +} + /** * _base_interrupt - MPT adapter (IOC) specific interrupt handler. * @irq: irq number (not used) @@ -1851,6 +1936,8 @@ _base_init_irqpolls(struct MPT3SAS_ADAPTER *ioc) return; list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { + if (reply_q->is_iouring_poll_q) + continue; irq_poll_init(&reply_q->irqpoll, ioc->hba_queue_depth/4, _base_irqpoll); reply_q->irq_poll_scheduled = false; @@ -1900,6 +1987,12 @@ mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc, u8 poll) /* TMs are on msix_index == 0 */ if (reply_q->msix_index == 0) continue; + + if (reply_q->is_iouring_poll_q) { + _base_process_reply_queue(reply_q); + continue; + } + synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); if (reply_q->irq_poll_scheduled) { /* Calling irq_poll_disable will wait for any pending @@ -2998,6 +3091,11 @@ _base_free_irq(struct MPT3SAS_ADAPTER *ioc) list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { list_del(&reply_q->list); + if (reply_q->is_iouring_poll_q) { + kfree(reply_q); + continue; + } + if (ioc->smp_affinity_enable) irq_set_affinity_hint(pci_irq_vector(ioc->pdev, reply_q->msix_index), NULL); @@ -3019,7 +3117,7 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index) { struct pci_dev *pdev = ioc->pdev; struct adapter_reply_queue *reply_q; - int r; + int r, qid; reply_q = kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL); if (!reply_q) { @@ -3031,6 +3129,17 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index) reply_q->msix_index = index; atomic_set(&reply_q->busy, 0); + + if (index >= ioc->iopoll_q_start_index) { + qid = index - ioc->iopoll_q_start_index; + snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-mq-poll%d", + ioc->driver_name, ioc->id, qid); + reply_q->is_iouring_poll_q = 1; + ioc->io_uring_poll_queues[qid].reply_q = reply_q; + goto out; + } + + if (ioc->msix_enable) snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", ioc->driver_name, ioc->id, index); @@ -3045,7 +3154,7 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index) kfree(reply_q); return -EBUSY; } - +out: INIT_LIST_HEAD(&reply_q->list); list_add_tail(&reply_q->list, &ioc->reply_queue_list); return 0; @@ -3066,6 +3175,8 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) unsigned int cpu, nr_cpus, nr_msix, index = 0; struct adapter_reply_queue *reply_q; int local_numa_node; + int iopoll_q_count = ioc->reply_queue_count - + ioc->iopoll_q_start_index; if (!_base_is_controller_msix_enabled(ioc)) return; @@ -3099,7 +3210,8 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { const cpumask_t *mask; - if (reply_q->msix_index < ioc->high_iops_queues) + if (reply_q->msix_index < ioc->high_iops_queues || + reply_q->msix_index >= ioc->iopoll_q_start_index) continue; mask = pci_irq_get_affinity(ioc->pdev, @@ -3121,13 +3233,14 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) fall_back: cpu = cpumask_first(cpu_online_mask); - nr_msix -= ioc->high_iops_queues; + nr_msix -= (ioc->high_iops_queues - iopoll_q_count); index = 0; list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { unsigned int i, group = nr_cpus / nr_msix; - if (reply_q->msix_index < ioc->high_iops_queues) + if (reply_q->msix_index < ioc->high_iops_queues || + reply_q->msix_index >= ioc->iopoll_q_start_index) continue; if (cpu >= nr_cpus) @@ -3164,8 +3277,12 @@ _base_check_and_enable_high_iops_queues(struct MPT3SAS_ADAPTER *ioc, { u16 lnksta, speed; + /* + * Disable high iops queues if io uring poll queues are enabled. + */ if (perf_mode == MPT_PERF_MODE_IOPS || - perf_mode == MPT_PERF_MODE_LATENCY) { + perf_mode == MPT_PERF_MODE_LATENCY || + ioc->io_uring_poll_queues) { ioc->high_iops_queues = 0; return; } @@ -3202,6 +3319,7 @@ _base_disable_msix(struct MPT3SAS_ADAPTER *ioc) return; pci_free_irq_vectors(ioc->pdev); ioc->msix_enable = 0; + kfree(ioc->io_uring_poll_queues); } /** @@ -3215,18 +3333,24 @@ _base_alloc_irq_vectors(struct MPT3SAS_ADAPTER *ioc) int i, irq_flags = PCI_IRQ_MSIX; struct irq_affinity desc = { .pre_vectors = ioc->high_iops_queues }; struct irq_affinity *descp = &desc; + /* + * Don't allocate msix vectors for poll_queues. + * msix_vectors is always within a range of FW supported reply queue. + */ + int nr_msix_vectors = ioc->iopoll_q_start_index; + if (ioc->smp_affinity_enable) - irq_flags |= PCI_IRQ_AFFINITY; + irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES; else descp = NULL; - ioc_info(ioc, " %d %d\n", ioc->high_iops_queues, - ioc->reply_queue_count); + ioc_info(ioc, " %d %d %d\n", ioc->high_iops_queues, + ioc->reply_queue_count, nr_msix_vectors); i = pci_alloc_irq_vectors_affinity(ioc->pdev, ioc->high_iops_queues, - ioc->reply_queue_count, irq_flags, descp); + nr_msix_vectors, irq_flags, descp); return i; } @@ -3242,6 +3366,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) int r; int i, local_max_msix_vectors; u8 try_msix = 0; + int iopoll_q_count = 0; ioc->msix_load_balance = false; @@ -3257,22 +3382,16 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "MSI-X vectors supported: %d\n", ioc->msix_vector_count); pr_info("\t no of cores: %d, max_msix_vectors: %d\n", ioc->cpu_count, max_msix_vectors); - if (ioc->is_aero_ioc) - _base_check_and_enable_high_iops_queues(ioc, - ioc->msix_vector_count); + ioc->reply_queue_count = - min_t(int, ioc->cpu_count + ioc->high_iops_queues, - ioc->msix_vector_count); + min_t(int, ioc->cpu_count, ioc->msix_vector_count); if (!ioc->rdpq_array_enable && max_msix_vectors == -1) local_max_msix_vectors = (reset_devices) ? 1 : 8; else local_max_msix_vectors = max_msix_vectors; - if (local_max_msix_vectors > 0) - ioc->reply_queue_count = min_t(int, local_max_msix_vectors, - ioc->reply_queue_count); - else if (local_max_msix_vectors == 0) + if (local_max_msix_vectors == 0) goto try_ioapic; /* @@ -3293,14 +3412,77 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) if (ioc->msix_load_balance) ioc->smp_affinity_enable = 0; + if (!ioc->smp_affinity_enable || ioc->reply_queue_count <= 1) + ioc->shost->host_tagset = 0; + + /* + * Enable io uring poll queues only if host_tagset is enabled. + */ + if (ioc->shost->host_tagset) + iopoll_q_count = poll_queues; + + if (iopoll_q_count) { + ioc->io_uring_poll_queues = kcalloc(iopoll_q_count, + sizeof(struct io_uring_poll_queue), GFP_KERNEL); + if (!ioc->io_uring_poll_queues) + iopoll_q_count = 0; + } + + if (ioc->is_aero_ioc) + _base_check_and_enable_high_iops_queues(ioc, + ioc->msix_vector_count); + + /* + * Add high iops queues count to reply queue count if high iops queues + * are enabled. + */ + ioc->reply_queue_count = min_t(int, + ioc->reply_queue_count + ioc->high_iops_queues, + ioc->msix_vector_count); + + /* + * Adjust the reply queue count incase reply queue count + * exceeds the user provided MSIx vectors count. + */ + if (local_max_msix_vectors > 0) + ioc->reply_queue_count = min_t(int, local_max_msix_vectors, + ioc->reply_queue_count); + /* + * Add io uring poll queues count to reply queues count + * if io uring is enabled in driver. + */ + if (iopoll_q_count) { + if (ioc->reply_queue_count < (iopoll_q_count + MPT3_MIN_IRQS)) + iopoll_q_count = 0; + ioc->reply_queue_count = min_t(int, + ioc->reply_queue_count + iopoll_q_count, + ioc->msix_vector_count); + } + + /* + * Starting index of io uring poll queues in reply queue list. + */ + ioc->iopoll_q_start_index = + ioc->reply_queue_count - iopoll_q_count; + r = _base_alloc_irq_vectors(ioc); if (r < 0) { ioc_info(ioc, "pci_alloc_irq_vectors failed (r=%d) !!!\n", r); goto try_ioapic; } + /* + * Adjust the reply queue count if the allocated + * MSIx vectors is less then the requested number + * of MSIx vectors. + */ + if (r < ioc->iopoll_q_start_index) { + ioc->reply_queue_count = r + iopoll_q_count; + ioc->iopoll_q_start_index = + ioc->reply_queue_count - iopoll_q_count; + } + ioc->msix_enable = 1; - ioc->reply_queue_count = r; for (i = 0; i < ioc->reply_queue_count; i++) { r = _base_request_irq(ioc, i); if (r) { @@ -3320,6 +3502,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) ioc->high_iops_queues = 0; ioc_info(ioc, "High IOPs queues : disabled\n"); ioc->reply_queue_count = 1; + ioc->iopoll_q_start_index = ioc->reply_queue_count - 0; r = pci_alloc_irq_vectors(ioc->pdev, 1, 1, PCI_IRQ_LEGACY); if (r < 0) { dfailprintk(ioc, @@ -3416,6 +3599,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) u64 pio_chip = 0; phys_addr_t chip_phys = 0; struct adapter_reply_queue *reply_q; + int iopoll_q_count = 0; dinitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); @@ -3489,6 +3673,12 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) if (r) goto out_fail; + iopoll_q_count = ioc->reply_queue_count - ioc->iopoll_q_start_index; + for (i = 0; i < iopoll_q_count; i++) { + atomic_set(&ioc->io_uring_poll_queues[i].busy, 0); + atomic_set(&ioc->io_uring_poll_queues[i].pause, 0); + } + if (!ioc->is_driver_loading) _base_init_irqpolls(ioc); /* Use the Combined reply queue feature only for SAS3 C0 & higher @@ -3530,11 +3720,18 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) * 4))); } - list_for_each_entry(reply_q, &ioc->reply_queue_list, list) + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { + if (reply_q->msix_index >= ioc->iopoll_q_start_index) { + pr_info("%s: enabled: index: %d\n", + reply_q->name, reply_q->msix_index); + continue; + } + pr_info("%s: %s enabled: IRQ %d\n", reply_q->name, ioc->msix_enable ? "PCI-MSI-X" : "IO-APIC", pci_irq_vector(ioc->pdev, reply_q->msix_index)); + } ioc_info(ioc, "iomem(%pap), mapped(0x%p), size(%d)\n", &chip_phys, ioc->chip, memap_sz); @@ -8471,6 +8668,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, _base_pre_reset_handler(ioc); mpt3sas_wait_for_commands_to_complete(ioc); mpt3sas_base_mask_interrupts(ioc); + mpt3sas_base_pause_mq_polling(ioc); r = _base_make_ioc_ready(ioc, type); if (r) goto out; @@ -8512,6 +8710,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); ioc->ioc_reset_count++; mutex_unlock(&ioc->reset_in_progress_mutex); + mpt3sas_base_resume_mq_polling(ioc); out_unlocked: if ((r == 0) && is_trigger) { diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index d4834c8ee9c0..ee742794d03f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -354,6 +354,7 @@ struct mpt3sas_nvme_cmd { #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3 12 #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35 16 #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) +#define MPT3_MIN_IRQS 1 /* OEM Identifiers */ #define MFG10_OEM_ID_INVALID (0x00000000) @@ -936,6 +937,8 @@ struct _event_ack_list { * @os_irq: irq number * @irqpoll: irq_poll object * @irq_poll_scheduled: Tells whether irq poll is scheduled or not + * @is_iouring_poll_q: Tells whether reply queues is assigned + * to io uring poll queues or not * @list: this list */ struct adapter_reply_queue { @@ -949,9 +952,22 @@ struct adapter_reply_queue { struct irq_poll irqpoll; bool irq_poll_scheduled; bool irq_line_enable; + bool is_iouring_poll_q; struct list_head list; }; +/** + * struct io_uring_poll_queue - the io uring poll queue structure + * @busy: Tells whether io uring poll queue is busy or not + * @pause: Tells whether IOs are paused on io uring poll queue or not + * @reply_q: reply queue mapped for io uring poll queue + */ +struct io_uring_poll_queue { + atomic_t busy; + atomic_t pause; + struct adapter_reply_queue *reply_q; +}; + typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); /* SAS3.0 support */ @@ -1176,6 +1192,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); * @schedule_dead_ioc_flush_running_cmds: callback to flush pending commands * @thresh_hold: Max number of reply descriptors processed * before updating Host Index + * @iopoll_q_start_index: starting index of io uring poll queues + * in reply queue list * @drv_internal_flags: Bit map internal to driver * @drv_support_bitmap: driver's supported feature bit map * @use_32bit_dma: Flag to use 32 bit consistent dma mask @@ -1372,11 +1390,13 @@ struct MPT3SAS_ADAPTER { bool msix_load_balance; u16 thresh_hold; u8 high_iops_queues; + u8 iopoll_q_start_index; u32 drv_internal_flags; u32 drv_support_bitmap; u32 dma_mask; bool enable_sdev_max_qd; bool use_32bit_dma; + struct io_uring_poll_queue *io_uring_poll_queues; /* internal commands, callback index */ u8 scsi_io_cb_idx; @@ -1730,6 +1750,9 @@ do { ioc_err(ioc, "In func: %s\n", __func__); \ status, mpi_request, sz); } while (0) int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); +int mpt3sas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num); +void mpt3sas_base_pause_mq_polling(struct MPT3SAS_ADAPTER *ioc); +void mpt3sas_base_resume_mq_polling(struct MPT3SAS_ADAPTER *ioc); /* scsih shared API */ struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 866d118f7931..f15c809e22c1 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -11178,8 +11178,10 @@ static void scsih_remove(struct pci_dev *pdev) ioc->remove_host = 1; - if (!pci_device_is_present(pdev)) + if (!pci_device_is_present(pdev)) { + mpt3sas_base_pause_mq_polling(ioc); _scsih_flush_running_cmds(ioc); + } _scsih_fw_event_cleanup_queue(ioc); @@ -11274,8 +11276,10 @@ scsih_shutdown(struct pci_dev *pdev) ioc->remove_host = 1; - if (!pci_device_is_present(pdev)) + if (!pci_device_is_present(pdev)) { + mpt3sas_base_pause_mq_polling(ioc); _scsih_flush_running_cmds(ioc); + } _scsih_fw_event_cleanup_queue(ioc); @@ -11780,12 +11784,41 @@ static int scsih_map_queues(struct Scsi_Host *shost) { struct MPT3SAS_ADAPTER *ioc = (struct MPT3SAS_ADAPTER *)shost->hostdata; + struct blk_mq_queue_map *map; + int i, qoff, offset; + int nr_msix_vectors = ioc->iopoll_q_start_index; + int iopoll_q_count = ioc->reply_queue_count - nr_msix_vectors; - if (ioc->shost->nr_hw_queues == 1) + if (shost->nr_hw_queues == 1) return 0; - return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], - ioc->pdev, ioc->high_iops_queues); + for (i = 0, qoff = 0; i < shost->nr_maps; i++) { + map = &shost->tag_set.map[i]; + map->nr_queues = 0; + offset = 0; + if (i == HCTX_TYPE_DEFAULT) { + map->nr_queues = + nr_msix_vectors - ioc->high_iops_queues; + offset = ioc->high_iops_queues; + } else if (i == HCTX_TYPE_POLL) + map->nr_queues = iopoll_q_count; + + if (!map->nr_queues) + BUG_ON(i == HCTX_TYPE_DEFAULT); + + /* + * The poll queue(s) doesn't have an IRQ (and hence IRQ + * affinity), so use the regular blk-mq cpu mapping + */ + map->queue_offset = qoff; + if (i != HCTX_TYPE_POLL) + blk_mq_pci_map_queues(map, ioc->pdev, offset); + else + blk_mq_map_queues(map); + + qoff += map->nr_queues; + } + return 0; } /* shost template for SAS 2.0 HBA devices */ @@ -11856,6 +11889,7 @@ static struct scsi_host_template mpt3sas_driver_template = { .track_queue_depth = 1, .cmd_size = sizeof(struct scsiio_tracker), .map_queues = scsih_map_queues, + .mq_poll = mpt3sas_blk_mq_poll, }; /* raid transport support for SAS 3.0 HBA devices */ @@ -11952,6 +11986,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct Scsi_Host *shost = NULL; int rv; u16 hba_mpi_version; + int iopoll_q_count = 0; /* Determine in which MPI version class this pci device belongs */ hba_mpi_version = _scsih_determine_hba_mpi_version(pdev); @@ -12199,6 +12234,11 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_thread_fail; } + shost->host_tagset = 0; + + if (ioc->is_gen35_ioc && host_tagset_enable) + shost->host_tagset = 1; + ioc->is_driver_loading = 1; if ((mpt3sas_base_attach(ioc))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", @@ -12221,16 +12261,17 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) } else ioc->hide_drives = 0; - shost->host_tagset = 0; shost->nr_hw_queues = 1; - if (ioc->is_gen35_ioc && ioc->reply_queue_count > 1 && - host_tagset_enable && ioc->smp_affinity_enable) { - - shost->host_tagset = 1; + if (shost->host_tagset) { shost->nr_hw_queues = ioc->reply_queue_count - ioc->high_iops_queues; + iopoll_q_count = + ioc->reply_queue_count - ioc->iopoll_q_start_index; + + shost->nr_maps = iopoll_q_count ? 3 : 1; + dev_info(&ioc->pdev->dev, "Max SCSIIO MPT commands: %d shared with nr_hw_queues = %d\n", shost->can_queue, shost->nr_hw_queues); @@ -12354,6 +12395,7 @@ scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) /* Permanent error, prepare for device removal */ ioc->pci_error_recovery = 1; mpt3sas_base_stop_watchdog(ioc); + mpt3sas_base_pause_mq_polling(ioc); _scsih_flush_running_cmds(ioc); return PCI_ERS_RESULT_DISCONNECT; } -- cgit v1.2.3-70-g09d2 From 44f88ef3c9f1edf4f8229508649965d85bc6f186 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 3 Aug 2021 12:21:34 +0530 Subject: scsi: mpt3sas: Bump driver version to 38.100.00.00 Bump driver version to 38.100.00.00. Link: https://lore.kernel.org/r/20210803065134.19090-1-sreekanth.reddy@broadcom.com Reviewed-by: Lee Duncan Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index ee742794d03f..bfea345e6ea2 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -77,9 +77,9 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "37.101.00.00" -#define MPT3SAS_MAJOR_VERSION 37 -#define MPT3SAS_MINOR_VERSION 101 +#define MPT3SAS_DRIVER_VERSION "38.100.00.00" +#define MPT3SAS_MAJOR_VERSION 38 +#define MPT3SAS_MINOR_VERSION 100 #define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION 00 -- cgit v1.2.3-70-g09d2 From 787f2448c23603d658d955402b166e1dde0dc1e5 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Mon, 9 Aug 2021 12:56:38 +0530 Subject: scsi: mpt3sas: Use firmware recommended queue depth Currently, the mpt3sas driver sets the default queue depth based on the physical interface of the attached device: - SAS : 254 - SATA: 32 - NVMe: 128 The IOC firmware provides a recommended queue depth for each device through SAS IO Unit Page1 for SAS/SATA and PCIe IO Unit Page 1 for NVMe devices. If the host sets the queue depth greater than the firmware recommended value, then the IOC places the I/Os above the recommended queue depth in an internal pending queue. This consumes outstanding host-credit/resources, thereby leading to potential starvation of other devices. To avoid this, use the device depth recommended by the IOC firmware. Link: https://lore.kernel.org/r/20210809072639.21228-2-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 70 +++++++++++++++++++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_base.h | 8 ++++ drivers/scsi/mpt3sas/mpt3sas_config.c | 37 ++++++++++++++++++ drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 ++- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 51 +++++++++++++++++++++++-- 5 files changed, 165 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 90dd18a315b9..54fd9aef21ac 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5365,6 +5365,73 @@ _base_update_diag_trigger_pages(struct MPT3SAS_ADAPTER *ioc) &ioc->diag_trigger_mpi, 1); } +/** + * _base_assign_fw_reported_qd - Get FW reported QD for SAS/SATA devices. + * - On failure set default QD values. + * @ioc : per adapter object + * + * Returns 0 for success, non-zero for failure. + * + */ +static int _base_assign_fw_reported_qd(struct MPT3SAS_ADAPTER *ioc) +{ + Mpi2ConfigReply_t mpi_reply; + Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; + Mpi26PCIeIOUnitPage1_t pcie_iounit_pg1; + int sz; + int rc = 0; + + ioc->max_wideport_qd = MPT3SAS_SAS_QUEUE_DEPTH; + ioc->max_narrowport_qd = MPT3SAS_SAS_QUEUE_DEPTH; + ioc->max_sata_qd = MPT3SAS_SATA_QUEUE_DEPTH; + ioc->max_nvme_qd = MPT3SAS_NVME_QUEUE_DEPTH; + if (!ioc->is_gen35_ioc) + goto out; + /* sas iounit page 1 */ + sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData); + sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); + if (!sas_iounit_pg1) { + pr_err("%s: failure at %s:%d/%s()!\n", + ioc->name, __FILE__, __LINE__, __func__); + return rc; + } + rc = mpt3sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, + sas_iounit_pg1, sz); + if (rc) { + pr_err("%s: failure at %s:%d/%s()!\n", + ioc->name, __FILE__, __LINE__, __func__); + goto out; + } + ioc->max_wideport_qd = + (le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth)) ? + le16_to_cpu(sas_iounit_pg1->SASWideMaxQueueDepth) : + MPT3SAS_SAS_QUEUE_DEPTH; + ioc->max_narrowport_qd = + (le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth)) ? + le16_to_cpu(sas_iounit_pg1->SASNarrowMaxQueueDepth) : + MPT3SAS_SAS_QUEUE_DEPTH; + ioc->max_sata_qd = (sas_iounit_pg1->SATAMaxQDepth) ? + sas_iounit_pg1->SATAMaxQDepth : MPT3SAS_SATA_QUEUE_DEPTH; + /* pcie iounit page 1 */ + rc = mpt3sas_config_get_pcie_iounit_pg1(ioc, &mpi_reply, + &pcie_iounit_pg1, sizeof(Mpi26PCIeIOUnitPage1_t)); + if (rc) { + pr_err("%s: failure at %s:%d/%s()!\n", + ioc->name, __FILE__, __LINE__, __func__); + goto out; + } + ioc->max_nvme_qd = (le16_to_cpu(pcie_iounit_pg1.NVMeMaxQueueDepth)) ? + (le16_to_cpu(pcie_iounit_pg1.NVMeMaxQueueDepth)) : + MPT3SAS_NVME_QUEUE_DEPTH; +out: + dinitprintk(ioc, pr_err( + "MaxWidePortQD: 0x%x MaxNarrowPortQD: 0x%x MaxSataQD: 0x%x MaxNvmeQD: 0x%x\n", + ioc->max_wideport_qd, ioc->max_narrowport_qd, + ioc->max_sata_qd, ioc->max_nvme_qd)); + kfree(sas_iounit_pg1); + return rc; +} + /** * _base_static_config_pages - static start of day config pages * @ioc: per adapter object @@ -5434,6 +5501,9 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) ioc_warn(ioc, "TimeSync Interval in Manuf page-11 is not enabled. Periodic Time-Sync will be disabled\n"); } + rc = _base_assign_fw_reported_qd(ioc); + if (rc) + return rc; rc = mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2); if (rc) return rc; diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index bfea345e6ea2..740b6de23be5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -576,6 +576,7 @@ struct _sas_device { u8 is_chassis_slot_valid; u8 connector_name[5]; struct kref refcount; + u8 port_type; struct hba_port *port; struct sas_rphy *rphy; }; @@ -1443,6 +1444,10 @@ struct MPT3SAS_ADAPTER { u8 tm_custom_handling; u8 nvme_abort_timeout; u16 max_shutdown_latency; + u16 max_wideport_qd; + u16 max_narrowport_qd; + u16 max_nvme_qd; + u8 max_sata_qd; /* static config pages */ struct mpt3sas_facts facts; @@ -1848,6 +1853,9 @@ int mpt3sas_config_get_pcie_device_pg0(struct MPT3SAS_ADAPTER *ioc, int mpt3sas_config_get_pcie_device_pg2(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeDevicePage2_t *config_page, u32 form, u32 handle); +int mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page, + u16 sz); int mpt3sas_config_get_sas_iounit_pg0(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage0_t *config_page, u16 sz); diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 83a5c2172ad4..0563078227de 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -1168,6 +1168,43 @@ out: return r; } +/** + * mpt3sas_config_get_pcie_iounit_pg1 - obtain pcie iounit page 1 + * @ioc: per adapter object + * @mpi_reply: reply mf payload returned from firmware + * @config_page: contents of the config page + * @sz: size of buffer passed in config_page + * Context: sleep. + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt3sas_config_get_pcie_iounit_pg1(struct MPT3SAS_ADAPTER *ioc, + Mpi2ConfigReply_t *mpi_reply, Mpi26PCIeIOUnitPage1_t *config_page, + u16 sz) +{ + Mpi2ConfigRequest_t mpi_request; + int r; + + memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); + mpi_request.Function = MPI2_FUNCTION_CONFIG; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; + mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; + mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_PCIE_IO_UNIT; + mpi_request.Header.PageVersion = MPI26_PCIEIOUNITPAGE1_PAGEVERSION; + mpi_request.Header.PageNumber = 1; + ioc->build_zero_len_sge_mpi(ioc, &mpi_request.PageBufferSGE); + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); + if (r) + goto out; + mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; + r = _config_request(ioc, &mpi_request, mpi_reply, + MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); +out: + return r; +} + /** * mpt3sas_config_get_pcie_device_pg2 - obtain pcie device page 2 * @ioc: per adapter object diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index b66140e4c370..db95cda1fad4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3820,9 +3820,10 @@ enable_sdev_max_qd_store(struct device *cdev, } } else if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) - qdepth = MPT3SAS_NVME_QUEUE_DEPTH; + qdepth = ioc->max_nvme_qd; else - qdepth = MPT3SAS_SAS_QUEUE_DEPTH; + qdepth = (sas_target_priv_data->sas_dev->port_type > 1) ? + ioc->max_wideport_qd : ioc->max_narrowport_qd; mpt3sas_scsih_change_queue_depth(sdev, qdepth); } diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index f15c809e22c1..b30f271888f7 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -1803,7 +1803,7 @@ scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) * limit max device queue for SATA to 32 if enable_sdev_max_qd * is disabled. */ - if (ioc->enable_sdev_max_qd) + if (ioc->enable_sdev_max_qd || ioc->is_gen35_ioc) goto not_sata; sas_device_priv_data = sdev->hostdata; @@ -2657,7 +2657,7 @@ scsih_slave_configure(struct scsi_device *sdev) return 1; } - qdepth = MPT3SAS_NVME_QUEUE_DEPTH; + qdepth = ioc->max_nvme_qd; ds = "NVMe"; sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), wwid(0x%016llx), port(%d)\n", @@ -2709,7 +2709,8 @@ scsih_slave_configure(struct scsi_device *sdev) sas_device->volume_handle = volume_handle; sas_device->volume_wwid = volume_wwid; if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) { - qdepth = MPT3SAS_SAS_QUEUE_DEPTH; + qdepth = (sas_device->port_type > 1) ? + ioc->max_wideport_qd : ioc->max_narrowport_qd; ssp_target = 1; if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SEP) { @@ -2721,7 +2722,7 @@ scsih_slave_configure(struct scsi_device *sdev) } else ds = "SSP"; } else { - qdepth = MPT3SAS_SATA_QUEUE_DEPTH; + qdepth = ioc->max_sata_qd; if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) ds = "STP"; else if (sas_device->device_info & @@ -7371,6 +7372,10 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, /* get device name */ sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName); + sas_device->port_type = sas_device_pg0.MaxPortConnections; + ioc_info(ioc, + "handle(0x%0x) sas_address(0x%016llx) port_type(0x%0x)\n", + handle, sas_device->sas_address, sas_device->port_type); if (ioc->wait_for_discovery_to_complete) _scsih_sas_device_init_add(ioc, sas_device); @@ -9603,6 +9608,42 @@ _scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc) } } +/** + * _scsih_update_device_qdepth - Update QD during Reset. + * @ioc: per adapter object + * + */ +static void +_scsih_update_device_qdepth(struct MPT3SAS_ADAPTER *ioc) +{ + struct MPT3SAS_DEVICE *sas_device_priv_data; + struct MPT3SAS_TARGET *sas_target_priv_data; + struct _sas_device *sas_device; + struct scsi_device *sdev; + u16 qdepth; + + ioc_info(ioc, "Update devices with firmware reported queue depth\n"); + shost_for_each_device(sdev, ioc->shost) { + sas_device_priv_data = sdev->hostdata; + if (sas_device_priv_data && sas_device_priv_data->sas_target) { + sas_target_priv_data = sas_device_priv_data->sas_target; + sas_device = sas_device_priv_data->sas_target->sas_dev; + if (sas_target_priv_data->flags & MPT_TARGET_FLAGS_PCIE_DEVICE) + qdepth = ioc->max_nvme_qd; + else if (sas_device && + sas_device->device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) + qdepth = (sas_device->port_type > 1) ? + ioc->max_wideport_qd : ioc->max_narrowport_qd; + else if (sas_device && + sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) + qdepth = ioc->max_sata_qd; + else + continue; + mpt3sas_scsih_change_queue_depth(sdev, qdepth); + } + } +} + /** * _scsih_mark_responding_sas_device - mark a sas_devices as responding * @ioc: per adapter object @@ -10654,6 +10695,8 @@ _mpt3sas_fw_work(struct MPT3SAS_ADAPTER *ioc, struct fw_event_work *fw_event) _scsih_remove_unresponding_devices(ioc); _scsih_del_dirty_vphy(ioc); _scsih_del_dirty_port_entries(ioc); + if (ioc->is_gen35_ioc) + _scsih_update_device_qdepth(ioc); _scsih_scan_for_devices_after_reset(ioc); /* * If diag reset has occurred during the driver load -- cgit v1.2.3-70-g09d2 From cdc1767698a2ab5334e788cf4303b83490858391 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Mon, 9 Aug 2021 12:56:39 +0530 Subject: scsi: mpt3sas: Update driver version to 39.100.00.00 Update driver version to 39.100.00.00. Link: https://lore.kernel.org/r/20210809072639.21228-3-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 740b6de23be5..3cf2e4615ff5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -77,8 +77,8 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "38.100.00.00" -#define MPT3SAS_MAJOR_VERSION 38 +#define MPT3SAS_DRIVER_VERSION "39.100.00.00" +#define MPT3SAS_MAJOR_VERSION 39 #define MPT3SAS_MINOR_VERSION 100 #define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION 00 -- cgit v1.2.3-70-g09d2 From 4758fd91d5a07d46be1101d6d47b289ed5d904d0 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Sat, 7 Aug 2021 13:18:59 +0900 Subject: scsi: mpt3sas: Introduce sas_ncq_prio_supported sysfs sttribute Similarly to AHCI, introduce the device sysfs attribute sas_ncq_prio_supported to advertise if a SATA device supports the NCQ priority feature. Without this new attribute, the user can only discover if a SATA device supports NCQ priority by trying to enable the feature use with the sas_ncq_prio_enable sysfs device attribute, which fails when the device does not support high prioity commands. Link: https://lore.kernel.org/r/20210807041859.579409-11-damien.lemoal@wdc.com Reviewed-by: Hannes Reinecke Signed-off-by: Damien Le Moal Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index db95cda1fad4..770b241d7bb2 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3919,6 +3919,24 @@ sas_device_handle_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(sas_device_handle); +/** + * sas_ncq_prio_supported_show - Indicate if device supports NCQ priority + * @dev: pointer to embedded device + * @attr: sas_ncq_prio_supported attribute descriptor + * @buf: the buffer returned + * + * A sysfs 'read-only' sdev attribute, only works with SATA + */ +static ssize_t +sas_ncq_prio_supported_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + + return sysfs_emit(buf, "%d\n", scsih_ncq_prio_supp(sdev)); +} +static DEVICE_ATTR_RO(sas_ncq_prio_supported); + /** * sas_ncq_prio_enable_show - send prioritized io commands to device * @dev: pointer to embedded device @@ -3961,6 +3979,7 @@ static DEVICE_ATTR_RW(sas_ncq_prio_enable); struct device_attribute *mpt3sas_dev_attrs[] = { &dev_attr_sas_address, &dev_attr_sas_device_handle, + &dev_attr_sas_ncq_prio_supported, &dev_attr_sas_ncq_prio_enable, NULL, }; -- cgit v1.2.3-70-g09d2 From a5402cdcc2a925835db89ea336909b2b724189df Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 6 Aug 2021 15:43:01 +0100 Subject: scsi: ufs: Fix unsigned int compared with less than zero Variable 'tag' is currently an unsigned int and is being compared to less than zero, this check is always false. Fix this by making 'tag' an int. Link: https://lore.kernel.org/r/20210806144301.19864-1-colin.king@canonical.com Fixes: 4728ab4a8e64 ("scsi: ufs: Remove ufshcd_valid_tag()") Reviewed-by: Bart Van Assche Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Macro compares unsigned to 0") --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 6c263e94144b..38cf516b0c6d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6974,7 +6974,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct ufs_hba *hba = shost_priv(host); - unsigned int tag = cmd->request->tag; + int tag = cmd->request->tag; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; unsigned long flags; int err = FAILED; -- cgit v1.2.3-70-g09d2 From bf25967ac54129ffb676ee0dbe3b8b34af6c6232 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 6 Aug 2021 16:04:41 +0300 Subject: scsi: ufshcd: Fix device links when BOOT WLUN fails to probe Managed device links are deleted by device_del(). However it is possible to add a device link to a consumer before device_add(), and then discovering an error prevents the device from being used. In that case normally references to the device would be dropped and the device would be deleted. However the device link holds a reference to the device, so the device link and device remain indefinitely (unless the supplier is deleted). For UFSHCD, if a LUN fails to probe (e.g. absent BOOT WLUN), the device will not have been registered but can still have a device link holding a reference to the device. The unwanted device link will prevent runtime suspend indefinitely. Amend device link removal to accept removal of a link with an unregistered consumer device (suggested by Rafael), and fix UFSHCD by explicitly deleting the device link when SCSI destroys the SCSI device. Link: https://lore.kernel.org/r/a1c9bac8-b560-b662-f0aa-58c7e000cbbd@intel.com Fixes: b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun") Reviewed-by: Rafael J. Wysocki Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/base/core.c | 2 ++ drivers/scsi/ufs/ufshcd.c | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index cadcade65825..9badd7f7fe62 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -884,6 +884,8 @@ static void device_link_put_kref(struct device_link *link) { if (link->flags & DL_FLAG_STATELESS) kref_put(&link->kref, __device_link_del); + else if (!device_is_registered(link->consumer)) + __device_link_del(&link->kref); else WARN(1, "Unable to drop a managed device link reference\n"); } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 38cf516b0c6d..b408be3c5cb7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5028,6 +5028,7 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) static void ufshcd_slave_destroy(struct scsi_device *sdev) { struct ufs_hba *hba; + unsigned long flags; hba = shost_priv(sdev->host); @@ -5035,11 +5036,29 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) /* Drop the reference as it won't be needed anymore */ if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { - unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); hba->sdev_ufs_device = NULL; spin_unlock_irqrestore(hba->host->host_lock, flags); + } else if (hba->sdev_ufs_device) { + struct device *supplier = NULL; + + /* Ensure UFS Device WLUN exists and does not disappear */ + spin_lock_irqsave(hba->host->host_lock, flags); + if (hba->sdev_ufs_device) { + supplier = &hba->sdev_ufs_device->sdev_gendev; + get_device(supplier); + } + spin_unlock_irqrestore(hba->host->host_lock, flags); + + if (supplier) { + /* + * If a LUN fails to probe (e.g. absent BOOT WLUN), the + * device will not have been registered but can still + * have a device link holding a reference to the device. + */ + device_link_remove(&sdev->sdev_gendev, supplier); + put_device(supplier); + } } } -- cgit v1.2.3-70-g09d2 From e9b1adb7c5e35dccace0341db4d9e9c9fb40eeef Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 6 Aug 2021 12:23:13 +0100 Subject: scsi: snic: Remove redundant assignment to variable ret The variable ret is being initialized with a value that is never read, the assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210806112313.12434-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/snic/snic_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index 6dd0ff188bb4..92f5b65c2a27 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -2383,7 +2383,7 @@ snic_host_reset(struct scsi_cmnd *sc) { struct Scsi_Host *shost = sc->device->host; u32 start_time = jiffies; - int ret = FAILED; + int ret; SNIC_SCSI_DBG(shost, "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n", -- cgit v1.2.3-70-g09d2 From 632c4ae6da1d629eddf9da1e692d7617c568c256 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Thu, 15 Jul 2021 11:26:25 +0800 Subject: scsi: fdomain: Fix error return code in fdomain_probe() If request_region() fails the return value is not set. Return -EBUSY on error. Link: https://lore.kernel.org/r/20210715032625.1395495-1-liwei391@huawei.com Fixes: 8674a8aa2c39 ("scsi: fdomain: Add PCMCIA support") Reported-by: Hulk Robot Signed-off-by: Wei Li Signed-off-by: Martin K. Petersen --- drivers/scsi/pcmcia/fdomain_cs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/pcmcia/fdomain_cs.c b/drivers/scsi/pcmcia/fdomain_cs.c index e42acf314d06..33df6a9ba9b5 100644 --- a/drivers/scsi/pcmcia/fdomain_cs.c +++ b/drivers/scsi/pcmcia/fdomain_cs.c @@ -45,8 +45,10 @@ static int fdomain_probe(struct pcmcia_device *link) goto fail_disable; if (!request_region(link->resource[0]->start, FDOMAIN_REGION_SIZE, - "fdomain_cs")) + "fdomain_cs")) { + ret = -EBUSY; goto fail_disable; + } sh = fdomain_create(link->resource[0]->start, link->irq, 7, &link->dev); if (!sh) { -- cgit v1.2.3-70-g09d2 From e71dd41ea002ad73111c2c77d6ce45724ad58ca6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Aug 2021 14:24:51 +0100 Subject: scsi: elx: efct: Remove redundant initialization of variable 'ret' The variable 'ret' is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210804132451.113086-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/elx/efct/efct_lio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c index e0d798d6baee..bb3b460dc0bc 100644 --- a/drivers/scsi/elx/efct/efct_lio.c +++ b/drivers/scsi/elx/efct/efct_lio.c @@ -780,7 +780,7 @@ efct_lio_npiv_make_nport(struct target_fabric_configfs *tf, { struct efct_lio_vport *lio_vport; struct efct *efct; - int ret = -1; + int ret; u64 p_wwpn, npiv_wwpn, npiv_wwnn; char *p, *pbuf, tmp[128]; struct efct_lio_vport_list_t *vport_list; -- cgit v1.2.3-70-g09d2 From 102851fc9a0d5ac8ea8b3e833f565dc1955b67cc Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Aug 2021 14:32:41 +0100 Subject: scsi: ufs: ufshpb: Remove redundant initialization of variable 'lba' The variable 'lba' is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210804133241.113509-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b408be3c5cb7..6736fb42e2a4 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -360,7 +360,7 @@ static void ufshcd_add_uic_command_trace(struct ufs_hba *hba, static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, enum ufs_trace_str_t str_t) { - u64 lba = -1; + u64 lba; u8 opcode = 0, group_id = 0; u32 intr, doorbell; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; -- cgit v1.2.3-70-g09d2 From 83da6ad6f97e192da49ec479d7811b5f97144d81 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 4 Aug 2021 15:33:19 +0100 Subject: scsi: pm8001: Remove redundant initialization of variable 'rv' The variable 'rv' is being initialized with a value that is never read, it is being updated later on. The assignment is redundant and can be removed. Link: https://lore.kernel.org/r/20210804143319.115340-1-colin.king@canonical.com Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Unused value") --- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 17c0f26e683a..63690508313b 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1323,7 +1323,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, void *pMessage; unsigned long flags; int q_index = circularQ - pm8001_ha->inbnd_q_tbl; - int rv = -1; + int rv; WARN_ON(q_index >= PM8001_MAX_INB_NUM); spin_lock_irqsave(&circularQ->iq_lock, flags); -- cgit v1.2.3-70-g09d2 From 7958f88aa6636f1927513c887a00e83168f12e35 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Tue, 27 Jul 2021 12:23:25 +0100 Subject: dt-bindings: pinctrl: renesas: Add DT bindings for RZ/G2L pinctrl Add device tree binding documentation and header file for Renesas RZ/G2L pinctrl. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210727112328.18809-2-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- .../bindings/pinctrl/renesas,rzg2l-pinctrl.yaml | 155 +++++++++++++++++++++ include/dt-bindings/pinctrl/rzg2l-pinctrl.h | 23 +++ 2 files changed, 178 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml create mode 100644 include/dt-bindings/pinctrl/rzg2l-pinctrl.h diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml new file mode 100644 index 000000000000..ef68dabcf4dc --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml @@ -0,0 +1,155 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/renesas,rzg2l-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas RZ/G2L combined Pin and GPIO controller + +maintainers: + - Geert Uytterhoeven + - Lad Prabhakar + +description: + The Renesas SoCs of the RZ/G2L series feature a combined Pin and GPIO + controller. + Pin multiplexing and GPIO configuration is performed on a per-pin basis. + Each port features up to 8 pins, each of them configurable for GPIO function + (port mode) or in alternate function mode. + Up to 8 different alternate function modes exist for each single pin. + +properties: + compatible: + enum: + - renesas,r9a07g044-pinctrl # RZ/G2{L,LC} + + reg: + maxItems: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + description: + The first cell contains the global GPIO port index, constructed using the + RZG2L_GPIO() helper macro in and the + second cell represents consumer flag as mentioned in ../gpio/gpio.txt + E.g. "RZG2L_GPIO(39, 1)" for P39_1. + + gpio-ranges: + maxItems: 1 + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + + resets: + items: + - description: GPIO_RSTN signal + - description: GPIO_PORT_RESETN signal + - description: GPIO_SPARE_RESETN signal + +additionalProperties: + anyOf: + - type: object + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + description: + Pin controller client devices use pin configuration subnodes (children + and grandchildren) for desired pin configuration. + Client device subnodes use below standard properties. + + properties: + phandle: true + pinmux: + description: + Values are constructed from GPIO port number, pin number, and + alternate function configuration number using the RZG2L_PORT_PINMUX() + helper macro in . + pins: true + drive-strength: + enum: [ 2, 4, 8, 12 ] + power-source: + enum: [ 1800, 2500, 3300 ] + slew-rate: true + gpio-hog: true + gpios: true + input-enable: true + output-high: true + output-low: true + line-name: true + + - type: object + properties: + phandle: true + + additionalProperties: + $ref: "#/additionalProperties/anyOf/0" + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - gpio-ranges + - clocks + - power-domains + - resets + +examples: + - | + #include + #include + + pinctrl: pinctrl@11030000 { + compatible = "renesas,r9a07g044-pinctrl"; + reg = <0x11030000 0x10000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 0 392>; + clocks = <&cpg CPG_MOD R9A07G044_GPIO_HCLK>; + resets = <&cpg R9A07G044_GPIO_RSTN>, + <&cpg R9A07G044_GPIO_PORT_RESETN>, + <&cpg R9A07G044_GPIO_SPARE_RESETN>; + power-domains = <&cpg>; + + scif0_pins: serial0 { + pinmux = , /* Tx */ + ; /* Rx */ + }; + + i2c1_pins: i2c1 { + pins = "RIIC1_SDA", "RIIC1_SCL"; + input-enable; + }; + + sd1-pwr-en-hog { + gpio-hog; + gpios = ; + output-high; + line-name = "sd1_pwr_en"; + }; + + sdhi1_pins: sd1 { + sd1_mux { + pinmux = , /* CD */ + ; /* WP */ + power-source = <3300>; + }; + + sd1_data { + pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; + power-source = <3300>; + }; + + sd1_ctrl { + pins = "SD1_CLK", "SD1_CMD"; + power-source = <3300>; + }; + }; + }; diff --git a/include/dt-bindings/pinctrl/rzg2l-pinctrl.h b/include/dt-bindings/pinctrl/rzg2l-pinctrl.h new file mode 100644 index 000000000000..b48f8c7a5556 --- /dev/null +++ b/include/dt-bindings/pinctrl/rzg2l-pinctrl.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * This header provides constants for Renesas RZ/G2L family pinctrl bindings. + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + */ + +#ifndef __DT_BINDINGS_RZG2L_PINCTRL_H +#define __DT_BINDINGS_RZG2L_PINCTRL_H + +#define RZG2L_PINS_PER_PORT 8 + +/* + * Create the pin index from its bank and position numbers and store in + * the upper 16 bits the alternate function identifier + */ +#define RZG2L_PORT_PINMUX(b, p, f) ((b) * RZG2L_PINS_PER_PORT + (p) | ((f) << 16)) + +/* Convert a port and pin label to its global pin index */ + #define RZG2L_GPIO(port, pin) ((port) * RZG2L_PINS_PER_PORT + (pin)) + +#endif /* __DT_BINDINGS_RZG2L_PINCTRL_H */ -- cgit v1.2.3-70-g09d2 From c755238d2ce0960ced9ffccc2ce14de2cd01b647 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 11 Jul 2021 23:31:43 +0100 Subject: ARM: 9099/1: crypto: rename 'mod_init' & 'mod_exit' functions to be module-specific Rename module_init & module_exit functions that are named "mod_init" and "mod_exit" so that they are unique in both the System.map file and in initcall_debug output instead of showing up as almost anonymous "mod_init". This is helpful for debugging and in determining how long certain module_init calls take to execute. Signed-off-by: Randy Dunlap Cc: Jason A. Donenfeld Cc: linux-arm-kernel@lists.infradead.org Cc: patches@armlinux.org.uk Signed-off-by: Russell King (Oracle) --- arch/arm/crypto/curve25519-glue.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/crypto/curve25519-glue.c b/arch/arm/crypto/curve25519-glue.c index 31eb75b6002f..9bdafd57888c 100644 --- a/arch/arm/crypto/curve25519-glue.c +++ b/arch/arm/crypto/curve25519-glue.c @@ -112,7 +112,7 @@ static struct kpp_alg curve25519_alg = { .max_size = curve25519_max_size, }; -static int __init mod_init(void) +static int __init arm_curve25519_init(void) { if (elf_hwcap & HWCAP_NEON) { static_branch_enable(&have_neon); @@ -122,14 +122,14 @@ static int __init mod_init(void) return 0; } -static void __exit mod_exit(void) +static void __exit arm_curve25519_exit(void) { if (IS_REACHABLE(CONFIG_CRYPTO_KPP) && elf_hwcap & HWCAP_NEON) crypto_unregister_kpp(&curve25519_alg); } -module_init(mod_init); -module_exit(mod_exit); +module_init(arm_curve25519_init); +module_exit(arm_curve25519_exit); MODULE_ALIAS_CRYPTO("curve25519"); MODULE_ALIAS_CRYPTO("curve25519-neon"); -- cgit v1.2.3-70-g09d2 From b08cae33b88e5f80b419a504b9b8e5530dfc9565 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 17 Jul 2021 16:14:40 +0100 Subject: ARM: 9100/1: MAINTAINERS: mark all linux-arm-kernel@infradead list as moderated Consistenly mark all entries of "linux-arm-kernel@lists.infradead.org" as moderated for non-subscribers. Signed-off-by: Randy Dunlap Cc: linux-arm-kernel@lists.infradead.org Cc: patches@armlinux.org.uk Signed-off-by: Russell King (Oracle) --- MAINTAINERS | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..0d0fc0fa3b7c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2306,14 +2306,14 @@ N: oxnas ARM/PALM TREO SUPPORT M: Tomas Cech -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained W: http://hackndev.com F: arch/arm/mach-pxa/palmtreo.* ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT M: Marek Vasut -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained W: http://hackndev.com F: arch/arm/mach-pxa/include/mach/palmld.h @@ -2327,7 +2327,7 @@ F: arch/arm/mach-pxa/palmtx.c ARM/PALMZ72 SUPPORT M: Sergey Lapin -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained W: http://hackndev.com F: arch/arm/mach-pxa/palmz72.* @@ -2497,7 +2497,7 @@ N: s5pv210 ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT M: Andrzej Hajda -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-media@vger.kernel.org S: Maintained F: drivers/media/platform/s5p-g2d/ @@ -2514,14 +2514,14 @@ ARM/SAMSUNG S5P SERIES JPEG CODEC SUPPORT M: Andrzej Pietrasiewicz M: Jacek Anaszewski M: Sylwester Nawrocki -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-media@vger.kernel.org S: Maintained F: drivers/media/platform/s5p-jpeg/ ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT M: Andrzej Hajda -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-media@vger.kernel.org S: Maintained F: drivers/media/platform/s5p-mfc/ @@ -3539,7 +3539,7 @@ BROADCOM BCM5301X ARM ARCHITECTURE M: Hauke Mehrtens M: Rafał Miłecki M: bcm-kernel-feedback-list@broadcom.com -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/boot/dts/bcm470* F: arch/arm/boot/dts/bcm5301* @@ -3549,7 +3549,7 @@ F: arch/arm/mach-bcm/bcm_5301x.c BROADCOM BCM53573 ARM ARCHITECTURE M: Rafał Miłecki L: bcm-kernel-feedback-list@broadcom.com -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/boot/dts/bcm47189* F: arch/arm/boot/dts/bcm53573* @@ -4833,7 +4833,7 @@ CPUIDLE DRIVER - ARM BIG LITTLE M: Lorenzo Pieralisi M: Daniel Lezcano L: linux-pm@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git F: drivers/cpuidle/cpuidle-big_little.c @@ -4853,14 +4853,14 @@ CPUIDLE DRIVER - ARM PSCI M: Lorenzo Pieralisi M: Sudeep Holla L: linux-pm@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: drivers/cpuidle/cpuidle-psci.c CPUIDLE DRIVER - ARM PSCI PM DOMAIN M: Ulf Hansson L: linux-pm@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: drivers/cpuidle/cpuidle-psci.h F: drivers/cpuidle/cpuidle-psci-domain.c @@ -7195,7 +7195,7 @@ F: tools/firewire/ FIRMWARE FRAMEWORK FOR ARMV8-A M: Sudeep Holla -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/firmware/arm_ffa/ F: include/linux/arm_ffa.h @@ -7374,7 +7374,7 @@ F: include/linux/platform_data/video-imxfb.h FREESCALE IMX DDR PMU DRIVER M: Frank Li -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/admin-guide/perf/imx-ddr.rst F: Documentation/devicetree/bindings/perf/fsl-imx-ddr.yaml @@ -7466,7 +7466,7 @@ F: drivers/tty/serial/ucc_uart.c FREESCALE SOC DRIVERS M: Li Yang L: linuxppc-dev@lists.ozlabs.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/misc/fsl,dpaa2-console.yaml F: Documentation/devicetree/bindings/soc/fsl/ @@ -11091,7 +11091,7 @@ F: drivers/net/wireless/marvell/libertas/ MARVELL MACCHIATOBIN SUPPORT M: Russell King -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts @@ -14134,7 +14134,7 @@ F: drivers/pci/controller/pcie-altera.c PCI DRIVER FOR APPLIEDMICRO XGENE M: Toan Le L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci.txt F: drivers/pci/controller/pci-xgene.c @@ -14142,7 +14142,7 @@ F: drivers/pci/controller/pci-xgene.c PCI DRIVER FOR ARM VERSATILE PLATFORM M: Rob Herring L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/pci/versatile.yaml F: drivers/pci/controller/pci-versatile.c @@ -14150,7 +14150,7 @@ F: drivers/pci/controller/pci-versatile.c PCI DRIVER FOR ARMADA 8K M: Thomas Petazzoni L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/controller/dwc/pcie-armada8k.c @@ -14168,7 +14168,7 @@ M: Mingkai Hu M: Roy Zang L: linuxppc-dev@lists.ozlabs.org L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/pci/controller/dwc/*layerscape* @@ -14248,7 +14248,7 @@ F: drivers/pci/controller/pci-tegra.c PCI DRIVER FOR NXP LAYERSCAPE GEN4 CONTROLLER M: Hou Zhiqiang L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/pci/layerscape-pcie-gen4.txt F: drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c @@ -14282,7 +14282,7 @@ PCI DRIVER FOR TI DRA7XX/J721E M: Kishon Vijay Abraham I L: linux-omap@vger.kernel.org L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/pci/ti-pci.txt F: drivers/pci/controller/cadence/pci-j721e.c @@ -14338,7 +14338,7 @@ F: drivers/pci/controller/pcie-altera-msi.c PCI MSI DRIVER FOR APPLIEDMICRO XGENE M: Toan Le L: linux-pci@vger.kernel.org -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/pci/xgene-pci-msi.txt F: drivers/pci/controller/pci-xgene-msi.c @@ -14836,7 +14836,7 @@ F: include/linux/dtpm.h POWER STATE COORDINATION INTERFACE (PSCI) M: Mark Rutland M: Lorenzo Pieralisi -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/firmware/psci/ F: include/linux/psci.h @@ -15356,7 +15356,7 @@ F: arch/hexagon/ QUALCOMM HIDMA DRIVER M: Sinan Kaya -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-msm@vger.kernel.org L: dmaengine@vger.kernel.org S: Supported @@ -17044,7 +17044,7 @@ SECURE MONITOR CALL(SMC) CALLING CONVENTION (SMCCC) M: Mark Rutland M: Lorenzo Pieralisi M: Sudeep Holla -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/firmware/smccc/ F: include/linux/arm-smccc.h @@ -17161,7 +17161,7 @@ F: drivers/media/pci/solo6x10/ SOFTWARE DELEGATED EXCEPTION INTERFACE (SDEI) M: James Morse -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/firmware/sdei.txt F: drivers/firmware/arm_sdei.c @@ -17929,7 +17929,7 @@ F: drivers/mfd/syscon.c SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers M: Sudeep Holla R: Cristian Marussi -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/firmware/arm,sc[mp]i.yaml F: drivers/clk/clk-sc[mp]i.c @@ -18301,7 +18301,7 @@ TEXAS INSTRUMENTS' SYSTEM CONTROL INTERFACE (TISCI) PROTOCOL DRIVER M: Nishanth Menon M: Tero Kristo M: Santosh Shilimkar -L: linux-arm-kernel@lists.infradead.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: Documentation/devicetree/bindings/arm/keystone/ti,k3-sci-common.yaml F: Documentation/devicetree/bindings/arm/keystone/ti,sci.txt -- cgit v1.2.3-70-g09d2 From d7bcc5e22967c96685d03dbbd167e1a1ddf9b910 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 29 Jul 2021 15:03:51 +0100 Subject: ARM: 9102/1: move theinstall rules to arch/arm/Makefile Currently, the (z/u)install targets in arch/arm/Makefile descend into arch/arm/boot/Makefile to invoke the shell script, but there is no good reason to do so. arch/arm/Makefile can run the shell script directly. Signed-off-by: Masahiro Yamada Signed-off-by: Russell King (Oracle) --- arch/arm/Makefile | 3 ++- arch/arm/boot/Makefile | 14 +------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 173da685a52e..847c31e7c368 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -308,7 +308,8 @@ $(BOOT_TARGETS): vmlinux @$(kecho) ' Kernel: $(boot)/$@ is ready' $(INSTALL_TARGETS): - $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ + $(CONFIG_SHELL) $(srctree)/$(boot)/install.sh "$(KERNELRELEASE)" \ + $(boot)/$(patsubst %install,%Image,$@) System.map "$(INSTALL_PATH)" PHONY += vdso_install vdso_install: diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 0b3cd7a33a26..54a09f9464fb 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -96,23 +96,11 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) -PHONY += initrd install zinstall uinstall +PHONY += initrd initrd: @test "$(INITRD_PHYS)" != "" || \ (echo This machine does not support INITRD; exit -1) @test "$(INITRD)" != "" || \ (echo You must specify INITRD; exit -1) -install: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ - $(obj)/Image System.map "$(INSTALL_PATH)" - -zinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ - $(obj)/zImage System.map "$(INSTALL_PATH)" - -uinstall: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ - $(obj)/uImage System.map "$(INSTALL_PATH)" - subdir- := bootp compressed dts -- cgit v1.2.3-70-g09d2 From 6fec92d9b2bfd2fb1a2a4295dc859d9bab16c8fc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 30 Jul 2021 10:43:02 +0100 Subject: ARM: 9103/1: Drop ARCH_NR_GPIOS definition The conditional by the generic header is the same, hence drop unnecessary duplication. Link: https://lore.kernel.org/r/20210510114107.43006-1-andriy.shevchenko@linux.intel.com Signed-off-by: Andy Shevchenko Reviewed-by: Linus Walleij Signed-off-by: Linus Walleij Signed-off-by: Russell King (Oracle) --- arch/arm/include/asm/gpio.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index c50e383358c4..f3bb8a2bf788 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -2,10 +2,6 @@ #ifndef _ARCH_ARM_GPIO_H #define _ARCH_ARM_GPIO_H -#if CONFIG_ARCH_NR_GPIO > 0 -#define ARCH_NR_GPIOS CONFIG_ARCH_NR_GPIO -#endif - /* Note: this may rely upon the value of ARCH_NR_GPIOS set in mach/gpio.h */ #include -- cgit v1.2.3-70-g09d2 From b30d0289de72c62516df03fdad8d53f552c69839 Mon Sep 17 00:00:00 2001 From: David Heidelberg Date: Mon, 9 Aug 2021 19:07:30 +0100 Subject: ARM: 9105/1: atags_to_fdt: don't warn about stack size The merge_fdt_bootargs() function by definition consumes more than 1024 bytes of stack because it has a 1024 byte command line on the stack, meaning that we always get a warning when building this file: arch/arm/boot/compressed/atags_to_fdt.c: In function 'merge_fdt_bootargs': arch/arm/boot/compressed/atags_to_fdt.c:98:1: warning: the frame size of 1032 bytes is larger than 1024 bytes [-Wframe-larger-than=] However, as this is the decompressor and we know that it has a very shallow call chain, and we do not actually risk overflowing the kernel stack at runtime here. This just shuts up the warning by disabling the warning flag for this file. Tested on Nexus 7 2012 builds. Acked-by: Nicolas Pitre Signed-off-by: David Heidelberg Signed-off-by: Arnd Bergmann Cc: Signed-off-by: Russell King (Oracle) --- arch/arm/boot/compressed/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 9d91ae1091b0..91265e7ff672 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -85,6 +85,8 @@ compress-$(CONFIG_KERNEL_LZ4) = lz4 libfdt_objs := fdt_rw.o fdt_ro.o fdt_wip.o fdt.o ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) +CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN} +CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280 OBJS += $(libfdt_objs) atags_to_fdt.o endif ifeq ($(CONFIG_USE_OF),y) -- cgit v1.2.3-70-g09d2 From 182700f258531c75846cb0f070e847e8b4c457b2 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 28 Jun 2021 17:38:51 -0700 Subject: pinctrl: qcom: spmi-gpio: Add pmc8180 & pmc8180c The SC8180x platform comes with PMC8180 and PMC8180c, add support for the GPIO controller in these PMICs. Signed-off-by: Bjorn Andersson Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210629003851.1787673-1-bjorn.andersson@linaro.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 4 ++++ drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 261a1d114253..48cc82d075e2 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -30,6 +30,8 @@ PMIC's from Qualcomm. "qcom,pm8994-gpio" "qcom,pm8998-gpio" "qcom,pma8084-gpio" + "qcom,pmc8180-gpio" + "qcom,pmc8180c-gpio" "qcom,pmi8950-gpio" "qcom,pmi8994-gpio" "qcom,pmi8998-gpio" @@ -122,6 +124,8 @@ to specify in a pin configuration subnode: gpio1-gpio22 for pm8994 gpio1-gpio26 for pm8998 gpio1-gpio22 for pma8084 + gpio1-gpio10 for pmc8180 + gpio1-gpio12 for pmc8180c gpio1-gpio2 for pmi8950 gpio1-gpio10 for pmi8994 gpio1-gpio4 for pmk8350 diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index bbea3499178e..98bf0e2a2a8d 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -1115,10 +1115,12 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8008-gpio", .data = (void *) 2 }, /* pm8150 has 10 GPIOs with holes on 2, 5, 7 and 8 */ { .compatible = "qcom,pm8150-gpio", .data = (void *) 10 }, + { .compatible = "qcom,pmc8180-gpio", .data = (void *) 10 }, /* pm8150b has 12 GPIOs with holes on 3, r and 7 */ { .compatible = "qcom,pm8150b-gpio", .data = (void *) 12 }, /* pm8150l has 12 GPIOs with holes on 7 */ { .compatible = "qcom,pm8150l-gpio", .data = (void *) 12 }, + { .compatible = "qcom,pmc8180c-gpio", .data = (void *) 12 }, { .compatible = "qcom,pm8350-gpio", .data = (void *) 10 }, { .compatible = "qcom,pm8350b-gpio", .data = (void *) 8 }, { .compatible = "qcom,pm8350c-gpio", .data = (void *) 9 }, -- cgit v1.2.3-70-g09d2 From d789a490d32fdf0465275e3607f8a3bc87d3f3ba Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 22 Jul 2021 11:39:29 +0800 Subject: pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry() Fix to return -ENOTSUPP instead of 0 when PCS_HAS_PINCONF is true, which is the same as that returned in pcs_parse_pinconf(). Fixes: 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Link: https://lore.kernel.org/r/20210722033930.4034-2-thunder.leizhen@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index e3aa64798f7d..4fcae8458359 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1224,6 +1224,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, if (PCS_HAS_PINCONF) { dev_err(pcs->dev, "pinconf not supported\n"); + res = -ENOTSUPP; goto free_pingroups; } -- cgit v1.2.3-70-g09d2 From 2ac48d0d486d9dbdcca2e6d945031541d880df3b Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 22 Jul 2021 11:39:30 +0800 Subject: pinctrl: single: Move test PCS_HAS_PINCONF in pcs_parse_bits_in_pinctrl_entry() to the beginning The value of pcs->flags is not overwritten in function pcs_parse_bits_in_pinctrl_entry() and its subfunctions, so moving this check to the beginning of the function eliminates unnecessary rollback operations. Signed-off-by: Zhen Lei Reviewed-by: Tony Lindgren Link: https://lore.kernel.org/r/20210722033930.4034-3-thunder.leizhen@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 4fcae8458359..d8b4dc40f3c6 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1115,7 +1115,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, { const char *name = "pinctrl-single,bits"; struct pcs_func_vals *vals; - int rows, *pins, found = 0, res = -ENOMEM, i, fsel, gsel; + int rows, *pins, found = 0, res = -ENOMEM, i, fsel; int npins_in_row; struct pcs_function *function = NULL; @@ -1125,6 +1125,11 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, return -EINVAL; } + if (PCS_HAS_PINCONF) { + dev_err(pcs->dev, "pinconf not supported\n"); + return -ENOTSUPP; + } + npins_in_row = pcs->width / pcs->bits_per_pin; vals = devm_kzalloc(pcs->dev, @@ -1212,30 +1217,19 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs, goto free_pins; } - gsel = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs); - if (gsel < 0) { - res = gsel; + res = pinctrl_generic_add_group(pcs->pctl, np->name, pins, found, pcs); + if (res < 0) goto free_function; - } (*map)->type = PIN_MAP_TYPE_MUX_GROUP; (*map)->data.mux.group = np->name; (*map)->data.mux.function = np->name; - if (PCS_HAS_PINCONF) { - dev_err(pcs->dev, "pinconf not supported\n"); - res = -ENOTSUPP; - goto free_pingroups; - } - *num_maps = 1; mutex_unlock(&pcs->mutex); return 0; -free_pingroups: - pinctrl_generic_remove_group(pcs->pctl, gsel); - *num_maps = 1; free_function: pinmux_generic_remove_function(pcs->pctl, fsel); free_pins: -- cgit v1.2.3-70-g09d2 From 510fc3487b09ad4a921e18c60de7e3c634eb6e4e Mon Sep 17 00:00:00 2001 From: Alexandre Torgue Date: Fri, 23 Jul 2021 15:28:04 +0200 Subject: dt-bindings: pinctrl: stm32: add new compatible for STM32MP135 SoC New compatible to manage ball out and pin muxing of STM32MP135 SoC. Signed-off-by: Alexandre Torgue Acked-by: Rob Herring Acked-by: Arnd Bergmann --- Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml index 72877544ca78..dfee6d38a701 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml @@ -24,6 +24,7 @@ properties: - st,stm32f746-pinctrl - st,stm32f769-pinctrl - st,stm32h743-pinctrl + - st,stm32mp135-pinctrl - st,stm32mp157-pinctrl - st,stm32mp157-z-pinctrl -- cgit v1.2.3-70-g09d2 From a022135a19a1b2f8ee1f9e90d5d9de419543904c Mon Sep 17 00:00:00 2001 From: Alexandre Torgue Date: Fri, 23 Jul 2021 15:28:05 +0200 Subject: pinctrl: stm32: Add STM32MP135 SoC support STM32MP135 SoC embeds 9 GPIO banks of 16 gpios each. Those GPIO banks contain same features as STM32MP157 GPIO banks except that each GPIO line of the STM32MP135 can be secured. Signed-off-by: Alexandre Torgue Acked-by: Arnd Bergmann --- drivers/pinctrl/stm32/Kconfig | 6 + drivers/pinctrl/stm32/Makefile | 1 + drivers/pinctrl/stm32/pinctrl-stm32mp135.c | 1679 ++++++++++++++++++++++++++++ 3 files changed, 1686 insertions(+) create mode 100644 drivers/pinctrl/stm32/pinctrl-stm32mp135.c diff --git a/drivers/pinctrl/stm32/Kconfig b/drivers/pinctrl/stm32/Kconfig index f36f29113370..d532f3c6f670 100644 --- a/drivers/pinctrl/stm32/Kconfig +++ b/drivers/pinctrl/stm32/Kconfig @@ -40,6 +40,12 @@ config PINCTRL_STM32H743 default MACH_STM32H743 select PINCTRL_STM32 +config PINCTRL_STM32MP135 + bool "STMicroelectronics STM32MP135 pin control" if COMPILE_TEST && !MACH_STM32MP13 + depends on OF && HAS_IOMEM + default MACH_STM32MP13 + select PINCTRL_STM32 + config PINCTRL_STM32MP157 bool "STMicroelectronics STM32MP157 pin control" if COMPILE_TEST && !MACH_STM32MP157 depends on OF && HAS_IOMEM diff --git a/drivers/pinctrl/stm32/Makefile b/drivers/pinctrl/stm32/Makefile index f7c56d4b941c..619629ee9944 100644 --- a/drivers/pinctrl/stm32/Makefile +++ b/drivers/pinctrl/stm32/Makefile @@ -8,4 +8,5 @@ obj-$(CONFIG_PINCTRL_STM32F469) += pinctrl-stm32f469.o obj-$(CONFIG_PINCTRL_STM32F746) += pinctrl-stm32f746.o obj-$(CONFIG_PINCTRL_STM32F769) += pinctrl-stm32f769.o obj-$(CONFIG_PINCTRL_STM32H743) += pinctrl-stm32h743.o +obj-$(CONFIG_PINCTRL_STM32MP135) += pinctrl-stm32mp135.o obj-$(CONFIG_PINCTRL_STM32MP157) += pinctrl-stm32mp157.o diff --git a/drivers/pinctrl/stm32/pinctrl-stm32mp135.c b/drivers/pinctrl/stm32/pinctrl-stm32mp135.c new file mode 100644 index 000000000000..4ab03520c407 --- /dev/null +++ b/drivers/pinctrl/stm32/pinctrl-stm32mp135.c @@ -0,0 +1,1679 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2021 - All Rights Reserved + * Author: Alexandre Torgue for STMicroelectronics. + */ +#include +#include +#include + +#include "pinctrl-stm32.h" + +static const struct stm32_desc_pin stm32mp135_pins[] = { + STM32_PIN( + PINCTRL_PIN(0, "PA0"), + STM32_FUNCTION(0, "GPIOA0"), + STM32_FUNCTION(2, "TIM2_CH1"), + STM32_FUNCTION(3, "TIM5_CH1"), + STM32_FUNCTION(4, "TIM8_ETR"), + STM32_FUNCTION(5, "TIM15_BKIN"), + STM32_FUNCTION(7, "SAI1_SD_B"), + STM32_FUNCTION(9, "UART5_TX"), + STM32_FUNCTION(12, "ETH1_MII_CRS"), + STM32_FUNCTION(13, "ETH2_MII_CRS"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(1, "PA1"), + STM32_FUNCTION(0, "GPIOA1"), + STM32_FUNCTION(2, "TIM2_CH2"), + STM32_FUNCTION(3, "TIM5_CH2"), + STM32_FUNCTION(4, "LPTIM3_OUT"), + STM32_FUNCTION(5, "TIM15_CH1N"), + STM32_FUNCTION(7, "DFSDM1_CKIN0"), + STM32_FUNCTION(8, "USART2_RTS USART2_DE"), + STM32_FUNCTION(12, "ETH1_MII_RX_CLK ETH1_RGMII_RX_CLK ETH1_RMII_REF_CLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(2, "PA2"), + STM32_FUNCTION(0, "GPIOA2"), + STM32_FUNCTION(2, "TIM2_CH3"), + STM32_FUNCTION(3, "TIM5_CH3"), + STM32_FUNCTION(4, "LPTIM4_OUT"), + STM32_FUNCTION(5, "TIM15_CH1"), + STM32_FUNCTION(8, "USART2_TX"), + STM32_FUNCTION(12, "ETH1_MDIO"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(3, "PA3"), + STM32_FUNCTION(0, "GPIOA3"), + STM32_FUNCTION(2, "TIM2_CH4"), + STM32_FUNCTION(3, "TIM5_CH4"), + STM32_FUNCTION(4, "LPTIM5_OUT"), + STM32_FUNCTION(5, "TIM15_CH2"), + STM32_FUNCTION(6, "SPI1_MOSI I2S1_SDO"), + STM32_FUNCTION(7, "SAI1_FS_B"), + STM32_FUNCTION(8, "USART2_RX"), + STM32_FUNCTION(12, "ETH1_MII_COL"), + STM32_FUNCTION(13, "ETH2_MII_COL"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(4, "PA4"), + STM32_FUNCTION(0, "GPIOA4"), + STM32_FUNCTION(3, "TIM5_ETR"), + STM32_FUNCTION(4, "USART2_CK"), + STM32_FUNCTION(5, "SAI1_SCK_B"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "DFSDM1_CKIN1"), + STM32_FUNCTION(11, "ETH1_PPS_OUT"), + STM32_FUNCTION(12, "ETH2_PPS_OUT"), + STM32_FUNCTION(13, "SAI1_SCK_A"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(5, "PA5"), + STM32_FUNCTION(0, "GPIOA5"), + STM32_FUNCTION(2, "TIM2_CH1 TIM2_ETR"), + STM32_FUNCTION(3, "USART2_CK"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(5, "SAI1_D1"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(11, "ETH1_PPS_OUT"), + STM32_FUNCTION(12, "ETH2_PPS_OUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(6, "PA6"), + STM32_FUNCTION(0, "GPIOA6"), + STM32_FUNCTION(2, "TIM1_BKIN"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(4, "TIM8_BKIN"), + STM32_FUNCTION(5, "SAI2_CK2"), + STM32_FUNCTION(6, "SPI1_MISO I2S1_SDI"), + STM32_FUNCTION(8, "USART1_CK"), + STM32_FUNCTION(9, "UART4_RTS UART4_DE"), + STM32_FUNCTION(10, "TIM13_CH1"), + STM32_FUNCTION(13, "SAI2_SCK_A"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(7, "PA7"), + STM32_FUNCTION(0, "GPIOA7"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(5, "SAI2_D1"), + STM32_FUNCTION(6, "SPI1_SCK I2S1_CK"), + STM32_FUNCTION(8, "USART1_CTS USART1_NSS"), + STM32_FUNCTION(10, "TIM14_CH1"), + STM32_FUNCTION(12, "ETH1_MII_RX_DV ETH1_RGMII_RX_CTL ETH1_RMII_CRS_DV"), + STM32_FUNCTION(13, "SAI2_SD_A"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(8, "PA8"), + STM32_FUNCTION(0, "GPIOA8"), + STM32_FUNCTION(1, "MCO1"), + STM32_FUNCTION(3, "SAI2_MCLK_A"), + STM32_FUNCTION(4, "TIM8_BKIN2"), + STM32_FUNCTION(5, "I2C4_SDA"), + STM32_FUNCTION(6, "SPI5_MISO"), + STM32_FUNCTION(7, "SAI2_CK1"), + STM32_FUNCTION(8, "USART1_CK"), + STM32_FUNCTION(9, "SPI2_MOSI I2S2_SDO"), + STM32_FUNCTION(11, "OTG_HS_SOF"), + STM32_FUNCTION(12, "ETH2_MII_RXD3 ETH2_RGMII_RXD3"), + STM32_FUNCTION(13, "FMC_A21"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(9, "PA9"), + STM32_FUNCTION(0, "GPIOA9"), + STM32_FUNCTION(2, "TIM1_CH2"), + STM32_FUNCTION(5, "I2C3_SMBA"), + STM32_FUNCTION(7, "DFSDM1_DATIN0"), + STM32_FUNCTION(8, "USART1_TX"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(11, "FMC_NWAIT"), + STM32_FUNCTION(14, "DCMIPP_D0"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(10, "PA10"), + STM32_FUNCTION(0, "GPIOA10"), + STM32_FUNCTION(2, "TIM1_CH3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(11, "PA11"), + STM32_FUNCTION(0, "GPIOA11"), + STM32_FUNCTION(2, "TIM1_CH4"), + STM32_FUNCTION(5, "I2C5_SCL"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(8, "USART1_CTS USART1_NSS"), + STM32_FUNCTION(11, "ETH2_MII_RXD1 ETH2_RGMII_RXD1 ETH2_RMII_RXD1"), + STM32_FUNCTION(12, "ETH1_CLK"), + STM32_FUNCTION(14, "ETH2_CLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(12, "PA12"), + STM32_FUNCTION(0, "GPIOA12"), + STM32_FUNCTION(2, "TIM1_ETR"), + STM32_FUNCTION(3, "SAI2_MCLK_A"), + STM32_FUNCTION(8, "USART1_RTS USART1_DE"), + STM32_FUNCTION(11, "TSC_G1_IO2"), + STM32_FUNCTION(12, "ETH2_MII_RX_DV ETH2_RGMII_RX_CTL ETH2_RMII_CRS_DV"), + STM32_FUNCTION(13, "FMC_A7"), + STM32_FUNCTION(14, "DCMIPP_D1"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(13, "PA13"), + STM32_FUNCTION(0, "GPIOA13"), + STM32_FUNCTION(1, "DBTRGO"), + STM32_FUNCTION(2, "DBTRGI"), + STM32_FUNCTION(3, "MCO1"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(14, "PA14"), + STM32_FUNCTION(0, "GPIOA14"), + STM32_FUNCTION(1, "DBTRGO"), + STM32_FUNCTION(2, "DBTRGI"), + STM32_FUNCTION(3, "MCO2"), + STM32_FUNCTION(11, "OTG_HS_SOF"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(15, "PA15"), + STM32_FUNCTION(0, "GPIOA15"), + STM32_FUNCTION(1, "TRACED5"), + STM32_FUNCTION(2, "TIM2_CH1"), + STM32_FUNCTION(6, "I2S4_MCK"), + STM32_FUNCTION(8, "UART4_RTS UART4_DE"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(10, "LCD_R0"), + STM32_FUNCTION(11, "TSC_G3_IO1"), + STM32_FUNCTION(12, "LCD_G7"), + STM32_FUNCTION(13, "FMC_A9"), + STM32_FUNCTION(14, "DCMIPP_D14"), + STM32_FUNCTION(15, "DCMIPP_D5"), + STM32_FUNCTION(16, "HDP5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(16, "PB0"), + STM32_FUNCTION(0, "GPIOB0"), + STM32_FUNCTION(1, "DBTRGI"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(3, "TIM3_CH3"), + STM32_FUNCTION(4, "TIM8_CH2N"), + STM32_FUNCTION(5, "USART1_RX"), + STM32_FUNCTION(6, "I2S1_MCK"), + STM32_FUNCTION(7, "SAI2_FS_A"), + STM32_FUNCTION(8, "USART1_CK"), + STM32_FUNCTION(9, "UART4_CTS"), + STM32_FUNCTION(11, "SAI2_D2"), + STM32_FUNCTION(12, "ETH1_MII_RXD2 ETH1_RGMII_RXD2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(17, "PB1"), + STM32_FUNCTION(0, "GPIOB1"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(3, "TIM3_CH4"), + STM32_FUNCTION(4, "TIM8_CH3N"), + STM32_FUNCTION(6, "SPI1_SCK I2S1_CK"), + STM32_FUNCTION(7, "DFSDM1_DATIN1"), + STM32_FUNCTION(8, "UART4_RX"), + STM32_FUNCTION(12, "ETH1_MII_RXD3 ETH1_RGMII_RXD3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(18, "PB2"), + STM32_FUNCTION(0, "GPIOB2"), + STM32_FUNCTION(2, "RTC_OUT2"), + STM32_FUNCTION(3, "SAI1_D1"), + STM32_FUNCTION(6, "I2S_CKIN"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(10, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(12, "ETH2_MDIO"), + STM32_FUNCTION(13, "FMC_A6"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(19, "PB3"), + STM32_FUNCTION(0, "GPIOB3"), + STM32_FUNCTION(1, "TRACED2"), + STM32_FUNCTION(2, "TIM2_CH2"), + STM32_FUNCTION(5, "SAI2_CK1"), + STM32_FUNCTION(6, "SPI4_NSS I2S4_WS"), + STM32_FUNCTION(9, "SDMMC1_D123DIR"), + STM32_FUNCTION(11, "SDMMC2_D2"), + STM32_FUNCTION(12, "LCD_R6"), + STM32_FUNCTION(13, "SAI2_MCLK_A"), + STM32_FUNCTION(14, "UART7_RX"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(20, "PB4"), + STM32_FUNCTION(0, "GPIOB4"), + STM32_FUNCTION(1, "TRACED14"), + STM32_FUNCTION(2, "TIM16_BKIN"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(5, "SAI2_CK2"), + STM32_FUNCTION(6, "SPI4_SCK I2S4_CK"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(11, "SDMMC2_D3"), + STM32_FUNCTION(12, "LCD_G1"), + STM32_FUNCTION(13, "SAI2_SCK_A"), + STM32_FUNCTION(14, "LCD_B6"), + STM32_FUNCTION(15, "LCD_R0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(21, "PB5"), + STM32_FUNCTION(0, "GPIOB5"), + STM32_FUNCTION(1, "TRACED4"), + STM32_FUNCTION(2, "TIM17_BKIN"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(6, "SPI2_MISO I2S2_SDI"), + STM32_FUNCTION(7, "I2C4_SMBA"), + STM32_FUNCTION(9, "SDMMC1_CKIN"), + STM32_FUNCTION(10, "FDCAN2_RX"), + STM32_FUNCTION(12, "UART5_RX"), + STM32_FUNCTION(14, "LCD_B6"), + STM32_FUNCTION(15, "LCD_DE"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(22, "PB6"), + STM32_FUNCTION(0, "GPIOB6"), + STM32_FUNCTION(1, "TRACED6"), + STM32_FUNCTION(2, "TIM16_CH1N"), + STM32_FUNCTION(3, "TIM4_CH1"), + STM32_FUNCTION(4, "TIM8_CH1"), + STM32_FUNCTION(5, "USART1_TX"), + STM32_FUNCTION(7, "SAI1_CK2"), + STM32_FUNCTION(8, "LCD_B6"), + STM32_FUNCTION(10, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(11, "TSC_G1_IO4"), + STM32_FUNCTION(12, "ETH2_MDIO"), + STM32_FUNCTION(13, "FMC_NE3"), + STM32_FUNCTION(14, "DCMIPP_D5"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(16, "HDP6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(23, "PB7"), + STM32_FUNCTION(0, "GPIOB7"), + STM32_FUNCTION(2, "TIM17_CH1N"), + STM32_FUNCTION(3, "TIM4_CH2"), + STM32_FUNCTION(4, "TSC_SYNC"), + STM32_FUNCTION(6, "I2S4_CK"), + STM32_FUNCTION(7, "I2C4_SDA"), + STM32_FUNCTION(11, "FMC_NCE2"), + STM32_FUNCTION(13, "FMC_NL"), + STM32_FUNCTION(14, "DCMIPP_D13"), + STM32_FUNCTION(15, "DCMIPP_PIXCLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(24, "PB8"), + STM32_FUNCTION(0, "GPIOB8"), + STM32_FUNCTION(2, "TIM16_CH1"), + STM32_FUNCTION(3, "TIM4_CH3"), + STM32_FUNCTION(5, "I2C1_SCL"), + STM32_FUNCTION(6, "I2C3_SCL"), + STM32_FUNCTION(7, "DFSDM1_DATIN1"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(11, "SAI1_D1"), + STM32_FUNCTION(13, "FMC_D13 FMC_AD13"), + STM32_FUNCTION(14, "DCMIPP_D6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(25, "PB9"), + STM32_FUNCTION(0, "GPIOB9"), + STM32_FUNCTION(1, "TRACED3"), + STM32_FUNCTION(3, "TIM4_CH4"), + STM32_FUNCTION(7, "I2C4_SDA"), + STM32_FUNCTION(10, "FDCAN1_TX"), + STM32_FUNCTION(11, "SDMMC2_D5"), + STM32_FUNCTION(12, "UART5_TX"), + STM32_FUNCTION(13, "SDMMC1_CDIR"), + STM32_FUNCTION(14, "LCD_DE"), + STM32_FUNCTION(15, "LCD_B1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(26, "PB10"), + STM32_FUNCTION(0, "GPIOB10"), + STM32_FUNCTION(2, "TIM2_CH3"), + STM32_FUNCTION(4, "LPTIM2_IN1"), + STM32_FUNCTION(5, "I2C5_SMBA"), + STM32_FUNCTION(6, "SPI4_NSS I2S4_WS"), + STM32_FUNCTION(7, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(15, "LCD_R3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(27, "PB11"), + STM32_FUNCTION(0, "GPIOB11"), + STM32_FUNCTION(2, "TIM2_CH4"), + STM32_FUNCTION(4, "LPTIM1_OUT"), + STM32_FUNCTION(5, "I2C5_SMBA"), + STM32_FUNCTION(8, "USART3_RX"), + STM32_FUNCTION(12, "ETH1_MII_TX_EN ETH1_RGMII_TX_CTL ETH1_RMII_TX_EN"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(28, "PB12"), + STM32_FUNCTION(0, "GPIOB12"), + STM32_FUNCTION(1, "TRACED10"), + STM32_FUNCTION(5, "I2C2_SMBA"), + STM32_FUNCTION(7, "DFSDM1_DATIN1"), + STM32_FUNCTION(8, "UART7_RTS UART7_DE"), + STM32_FUNCTION(9, "USART3_RX"), + STM32_FUNCTION(12, "UART5_RX"), + STM32_FUNCTION(13, "SDMMC1_D5"), + STM32_FUNCTION(14, "LCD_R3"), + STM32_FUNCTION(15, "LCD_VSYNC"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(29, "PB13"), + STM32_FUNCTION(0, "GPIOB13"), + STM32_FUNCTION(1, "TRACECLK"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(5, "LPTIM2_OUT"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(7, "I2C4_SCL"), + STM32_FUNCTION(9, "SDMMC1_D123DIR"), + STM32_FUNCTION(10, "FDCAN2_TX"), + STM32_FUNCTION(12, "UART5_TX"), + STM32_FUNCTION(14, "LCD_CLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(30, "PB14"), + STM32_FUNCTION(0, "GPIOB14"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(3, "TIM12_CH1"), + STM32_FUNCTION(4, "TIM8_CH2N"), + STM32_FUNCTION(5, "USART1_TX"), + STM32_FUNCTION(11, "SDMMC2_D0"), + STM32_FUNCTION(12, "SDMMC1_D4"), + STM32_FUNCTION(14, "LCD_R0"), + STM32_FUNCTION(15, "LCD_G5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(31, "PB15"), + STM32_FUNCTION(0, "GPIOB15"), + STM32_FUNCTION(1, "RTC_REFIN"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(3, "TIM12_CH2"), + STM32_FUNCTION(4, "TIM8_CH3N"), + STM32_FUNCTION(5, "SAI2_D2"), + STM32_FUNCTION(6, "SPI4_MOSI I2S4_SDO"), + STM32_FUNCTION(7, "DFSDM1_CKIN2"), + STM32_FUNCTION(8, "UART7_CTS"), + STM32_FUNCTION(9, "SDMMC1_CKIN"), + STM32_FUNCTION(11, "SDMMC2_D1"), + STM32_FUNCTION(13, "SAI2_FS_A"), + STM32_FUNCTION(14, "LCD_CLK"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(32, "PC0"), + STM32_FUNCTION(0, "GPIOC0"), + STM32_FUNCTION(3, "SAI1_SCK_A"), + STM32_FUNCTION(5, "SAI1_CK2"), + STM32_FUNCTION(6, "I2S1_MCK"), + STM32_FUNCTION(7, "SPI1_MOSI I2S1_SDO"), + STM32_FUNCTION(8, "USART1_TX"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(33, "PC1"), + STM32_FUNCTION(0, "GPIOC1"), + STM32_FUNCTION(4, "DFSDM1_DATIN0"), + STM32_FUNCTION(7, "SAI1_D3"), + STM32_FUNCTION(11, "ETH1_MII_RX_DV ETH1_RMII_CRS_DV"), + STM32_FUNCTION(12, "ETH1_RGMII_GTX_CLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(34, "PC2"), + STM32_FUNCTION(0, "GPIOC2"), + STM32_FUNCTION(2, "SPI5_NSS"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "SAI2_MCLK_A"), + STM32_FUNCTION(8, "USART1_RTS USART1_DE"), + STM32_FUNCTION(11, "SAI2_CK1"), + STM32_FUNCTION(12, "ETH1_MII_TXD2 ETH1_RGMII_TXD2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(35, "PC3"), + STM32_FUNCTION(0, "GPIOC3"), + STM32_FUNCTION(3, "SAI1_CK1"), + STM32_FUNCTION(4, "DFSDM1_CKOUT"), + STM32_FUNCTION(6, "SPI1_MISO I2S1_SDI"), + STM32_FUNCTION(7, "SPI1_SCK I2S1_CK"), + STM32_FUNCTION(9, "UART5_CTS"), + STM32_FUNCTION(11, "SAI1_MCLK_A"), + STM32_FUNCTION(12, "ETH1_MII_TX_CLK"), + STM32_FUNCTION(13, "ETH2_MII_TX_CLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(36, "PC4"), + STM32_FUNCTION(0, "GPIOC4"), + STM32_FUNCTION(3, "TIM3_ETR"), + STM32_FUNCTION(4, "DFSDM1_CKIN2"), + STM32_FUNCTION(5, "SAI1_D3"), + STM32_FUNCTION(6, "I2S1_MCK"), + STM32_FUNCTION(9, "UART5_RTS UART5_DE"), + STM32_FUNCTION(10, "SPDIFRX_IN2"), + STM32_FUNCTION(12, "ETH1_MII_RXD0 ETH1_RGMII_RXD0 ETH1_RMII_RXD0"), + STM32_FUNCTION(13, "SAI2_D3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(37, "PC5"), + STM32_FUNCTION(0, "GPIOC5"), + STM32_FUNCTION(4, "DFSDM1_DATIN2"), + STM32_FUNCTION(5, "SAI2_D4"), + STM32_FUNCTION(6, "I2S_CKIN"), + STM32_FUNCTION(7, "SAI1_D4"), + STM32_FUNCTION(8, "USART2_CTS USART2_NSS"), + STM32_FUNCTION(10, "SPDIFRX_IN3"), + STM32_FUNCTION(12, "ETH1_MII_RXD1 ETH1_RGMII_RXD1 ETH1_RMII_RXD1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(38, "PC6"), + STM32_FUNCTION(0, "GPIOC6"), + STM32_FUNCTION(1, "TRACED2"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(4, "TIM8_CH1"), + STM32_FUNCTION(5, "DFSDM1_DATIN0"), + STM32_FUNCTION(6, "I2S3_MCK"), + STM32_FUNCTION(8, "USART6_TX"), + STM32_FUNCTION(9, "SDMMC1_D6"), + STM32_FUNCTION(10, "SDMMC2_D0DIR"), + STM32_FUNCTION(11, "SDMMC2_D6"), + STM32_FUNCTION(12, "LCD_B1"), + STM32_FUNCTION(13, "FMC_A19"), + STM32_FUNCTION(14, "LCD_R6"), + STM32_FUNCTION(15, "LCD_HSYNC"), + STM32_FUNCTION(16, "HDP2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(39, "PC7"), + STM32_FUNCTION(0, "GPIOC7"), + STM32_FUNCTION(1, "TRACED4"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(4, "TIM8_CH2"), + STM32_FUNCTION(7, "I2S2_MCK"), + STM32_FUNCTION(8, "USART6_RX"), + STM32_FUNCTION(9, "USART3_CTS"), + STM32_FUNCTION(10, "SDMMC2_CDIR"), + STM32_FUNCTION(11, "SDMMC2_D7"), + STM32_FUNCTION(12, "LCD_R1"), + STM32_FUNCTION(13, "SDMMC1_D7"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(16, "HDP4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(40, "PC8"), + STM32_FUNCTION(0, "GPIOC8"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(3, "TIM3_CH3"), + STM32_FUNCTION(4, "TIM8_CH3"), + STM32_FUNCTION(6, "SPI3_MISO I2S3_SDI"), + STM32_FUNCTION(8, "USART6_CK"), + STM32_FUNCTION(9, "USART3_CTS"), + STM32_FUNCTION(11, "SAI2_FS_B"), + STM32_FUNCTION(12, "UART5_RTS UART5_DE"), + STM32_FUNCTION(13, "SDMMC1_D0"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(41, "PC9"), + STM32_FUNCTION(0, "GPIOC9"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(3, "TIM3_CH4"), + STM32_FUNCTION(4, "TIM8_CH4"), + STM32_FUNCTION(8, "USART3_RTS"), + STM32_FUNCTION(9, "UART5_CTS"), + STM32_FUNCTION(10, "FDCAN1_TX"), + STM32_FUNCTION(13, "SDMMC1_D1"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(42, "PC10"), + STM32_FUNCTION(0, "GPIOC10"), + STM32_FUNCTION(1, "TRACED2"), + STM32_FUNCTION(6, "I2C1_SCL"), + STM32_FUNCTION(7, "SPI3_SCK I2S3_CK"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(13, "SDMMC1_D2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(43, "PC11"), + STM32_FUNCTION(0, "GPIOC11"), + STM32_FUNCTION(1, "TRACED3"), + STM32_FUNCTION(5, "I2C1_SDA"), + STM32_FUNCTION(7, "SPI3_MOSI I2S3_SDO"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(9, "UART5_RX"), + STM32_FUNCTION(11, "SAI2_SCK_B"), + STM32_FUNCTION(13, "SDMMC1_D3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(44, "PC12"), + STM32_FUNCTION(0, "GPIOC12"), + STM32_FUNCTION(1, "TRACECLK"), + STM32_FUNCTION(9, "UART7_TX"), + STM32_FUNCTION(11, "SAI2_SD_B"), + STM32_FUNCTION(13, "SDMMC1_CK"), + STM32_FUNCTION(15, "LCD_DE"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(45, "PC13"), + STM32_FUNCTION(0, "GPIOC13"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(46, "PC14"), + STM32_FUNCTION(0, "GPIOC14"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(47, "PC15"), + STM32_FUNCTION(0, "GPIOC15"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(48, "PD0"), + STM32_FUNCTION(0, "GPIOD0"), + STM32_FUNCTION(3, "SAI1_MCLK_A"), + STM32_FUNCTION(7, "SAI1_CK1"), + STM32_FUNCTION(10, "FDCAN1_RX"), + STM32_FUNCTION(13, "FMC_D2 FMC_AD2"), + STM32_FUNCTION(14, "DCMIPP_D1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(49, "PD1"), + STM32_FUNCTION(0, "GPIOD1"), + STM32_FUNCTION(5, "I2C5_SCL"), + STM32_FUNCTION(6, "SPI4_MOSI I2S4_SDO"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(10, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(12, "LCD_B6"), + STM32_FUNCTION(13, "FMC_D3 FMC_AD3"), + STM32_FUNCTION(14, "DCMIPP_D13"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(50, "PD2"), + STM32_FUNCTION(0, "GPIOD2"), + STM32_FUNCTION(1, "TRACED4"), + STM32_FUNCTION(3, "TIM3_ETR"), + STM32_FUNCTION(5, "I2C1_SMBA"), + STM32_FUNCTION(6, "SPI3_NSS I2S3_WS"), + STM32_FUNCTION(7, "SAI2_D1"), + STM32_FUNCTION(8, "USART3_RX"), + STM32_FUNCTION(13, "SDMMC1_CMD"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(51, "PD3"), + STM32_FUNCTION(0, "GPIOD3"), + STM32_FUNCTION(3, "TIM2_CH1"), + STM32_FUNCTION(4, "USART2_CTS USART2_NSS"), + STM32_FUNCTION(5, "DFSDM1_CKOUT"), + STM32_FUNCTION(6, "I2C1_SDA"), + STM32_FUNCTION(7, "SAI1_D3"), + STM32_FUNCTION(13, "FMC_CLK"), + STM32_FUNCTION(14, "DCMIPP_D5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(52, "PD4"), + STM32_FUNCTION(0, "GPIOD4"), + STM32_FUNCTION(4, "USART2_RTS USART2_DE"), + STM32_FUNCTION(6, "SPI3_MISO I2S3_SDI"), + STM32_FUNCTION(7, "DFSDM1_CKIN0"), + STM32_FUNCTION(10, "QUADSPI_CLK"), + STM32_FUNCTION(12, "LCD_R1"), + STM32_FUNCTION(13, "FMC_NOE"), + STM32_FUNCTION(14, "LCD_R4"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(53, "PD5"), + STM32_FUNCTION(0, "GPIOD5"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(13, "FMC_NWE"), + STM32_FUNCTION(14, "LCD_B0"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(54, "PD6"), + STM32_FUNCTION(0, "GPIOD6"), + STM32_FUNCTION(2, "TIM16_CH1N"), + STM32_FUNCTION(3, "SAI1_D1"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(12, "TSC_G2_IO1"), + STM32_FUNCTION(14, "DCMIPP_D4"), + STM32_FUNCTION(15, "DCMIPP_D0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(55, "PD7"), + STM32_FUNCTION(0, "GPIOD7"), + STM32_FUNCTION(1, "MCO1"), + STM32_FUNCTION(4, "USART2_CK"), + STM32_FUNCTION(5, "I2C2_SCL"), + STM32_FUNCTION(6, "I2C3_SDA"), + STM32_FUNCTION(10, "SPDIFRX_IN0"), + STM32_FUNCTION(11, "ETH1_MII_RX_CLK ETH1_RGMII_RX_CLK ETH1_RMII_REF_CLK"), + STM32_FUNCTION(12, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(13, "FMC_NE1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(56, "PD8"), + STM32_FUNCTION(0, "GPIOD8"), + STM32_FUNCTION(4, "USART2_TX"), + STM32_FUNCTION(6, "I2S4_WS"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(11, "TSC_G1_IO3"), + STM32_FUNCTION(14, "DCMIPP_D9"), + STM32_FUNCTION(15, "DCMIPP_D3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(57, "PD9"), + STM32_FUNCTION(0, "GPIOD9"), + STM32_FUNCTION(1, "TRACECLK"), + STM32_FUNCTION(4, "DFSDM1_DATIN3"), + STM32_FUNCTION(11, "SDMMC2_CDIR"), + STM32_FUNCTION(12, "LCD_B5"), + STM32_FUNCTION(13, "FMC_D14 FMC_AD14"), + STM32_FUNCTION(14, "LCD_CLK"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(58, "PD10"), + STM32_FUNCTION(0, "GPIOD10"), + STM32_FUNCTION(1, "RTC_REFIN"), + STM32_FUNCTION(5, "I2C5_SMBA"), + STM32_FUNCTION(6, "SPI4_NSS I2S4_WS"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(10, "LCD_G5"), + STM32_FUNCTION(11, "TSC_G2_IO2"), + STM32_FUNCTION(12, "LCD_B7"), + STM32_FUNCTION(13, "FMC_D15 FMC_AD15"), + STM32_FUNCTION(14, "DCMIPP_VSYNC"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(59, "PD11"), + STM32_FUNCTION(0, "GPIOD11"), + STM32_FUNCTION(4, "LPTIM2_IN2"), + STM32_FUNCTION(5, "I2C4_SMBA"), + STM32_FUNCTION(8, "USART3_CTS USART3_NSS"), + STM32_FUNCTION(9, "SPDIFRX_IN0"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(11, "ETH2_RGMII_CLK125"), + STM32_FUNCTION(12, "LCD_R7"), + STM32_FUNCTION(13, "FMC_CLE FMC_A16"), + STM32_FUNCTION(14, "UART7_RX"), + STM32_FUNCTION(15, "DCMIPP_D4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(60, "PD12"), + STM32_FUNCTION(0, "GPIOD12"), + STM32_FUNCTION(2, "LPTIM1_IN1"), + STM32_FUNCTION(3, "TIM4_CH1"), + STM32_FUNCTION(6, "I2C1_SCL"), + STM32_FUNCTION(8, "USART3_RTS USART3_DE"), + STM32_FUNCTION(13, "FMC_ALE FMC_A17"), + STM32_FUNCTION(14, "DCMIPP_D6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(61, "PD13"), + STM32_FUNCTION(0, "GPIOD13"), + STM32_FUNCTION(2, "LPTIM2_ETR"), + STM32_FUNCTION(3, "TIM4_CH2"), + STM32_FUNCTION(4, "TIM8_CH2"), + STM32_FUNCTION(5, "SAI1_CK1"), + STM32_FUNCTION(7, "SAI1_MCLK_A"), + STM32_FUNCTION(8, "USART1_RX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(11, "TSC_G2_IO4"), + STM32_FUNCTION(12, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(13, "FMC_A18"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(62, "PD14"), + STM32_FUNCTION(0, "GPIOD14"), + STM32_FUNCTION(3, "TIM4_CH3"), + STM32_FUNCTION(5, "I2C3_SDA"), + STM32_FUNCTION(8, "USART1_RX"), + STM32_FUNCTION(9, "UART8_CTS"), + STM32_FUNCTION(13, "FMC_D0 FMC_AD0"), + STM32_FUNCTION(14, "DCMIPP_D8"), + STM32_FUNCTION(15, "LCD_R4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(63, "PD15"), + STM32_FUNCTION(0, "GPIOD15"), + STM32_FUNCTION(2, "USART2_RX"), + STM32_FUNCTION(3, "TIM4_CH4"), + STM32_FUNCTION(4, "DFSDM1_DATIN2"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(13, "FMC_D1 FMC_AD1"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(64, "PE0"), + STM32_FUNCTION(0, "GPIOE0"), + STM32_FUNCTION(7, "DCMIPP_D12"), + STM32_FUNCTION(9, "UART8_RX"), + STM32_FUNCTION(10, "FDCAN2_RX"), + STM32_FUNCTION(11, "TSC_G4_IO1"), + STM32_FUNCTION(12, "LCD_B1"), + STM32_FUNCTION(13, "FMC_A11"), + STM32_FUNCTION(14, "DCMIPP_D1"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(65, "PE1"), + STM32_FUNCTION(0, "GPIOE1"), + STM32_FUNCTION(2, "LPTIM1_IN2"), + STM32_FUNCTION(4, "TSC_G2_IO3"), + STM32_FUNCTION(9, "UART8_TX"), + STM32_FUNCTION(10, "LCD_HSYNC"), + STM32_FUNCTION(12, "LCD_R4"), + STM32_FUNCTION(13, "FMC_NBL1"), + STM32_FUNCTION(14, "DCMIPP_D3"), + STM32_FUNCTION(15, "DCMIPP_D12"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(66, "PE2"), + STM32_FUNCTION(0, "GPIOE2"), + STM32_FUNCTION(1, "TRACECLK"), + STM32_FUNCTION(2, "TIM2_ETR"), + STM32_FUNCTION(4, "TSC_G5_IO1"), + STM32_FUNCTION(5, "I2C4_SCL"), + STM32_FUNCTION(6, "SPI5_MOSI"), + STM32_FUNCTION(7, "SAI1_FS_B"), + STM32_FUNCTION(8, "USART6_RTS USART6_DE"), + STM32_FUNCTION(10, "SPDIFRX_IN1"), + STM32_FUNCTION(11, "ETH2_MII_RXD1 ETH2_RGMII_RXD1 ETH2_RMII_RXD1"), + STM32_FUNCTION(13, "FMC_A23"), + STM32_FUNCTION(15, "LCD_R1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(67, "PE3"), + STM32_FUNCTION(0, "GPIOE3"), + STM32_FUNCTION(1, "TRACED11"), + STM32_FUNCTION(3, "SAI2_D4"), + STM32_FUNCTION(5, "TIM15_BKIN"), + STM32_FUNCTION(6, "SPI4_MISO I2S4_SDI"), + STM32_FUNCTION(9, "USART3_RTS USART3_DE"), + STM32_FUNCTION(10, "FDCAN1_RX"), + STM32_FUNCTION(11, "SDMMC2_CK"), + STM32_FUNCTION(14, "LCD_R4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(68, "PE4"), + STM32_FUNCTION(0, "GPIOE4"), + STM32_FUNCTION(2, "SPI5_MISO"), + STM32_FUNCTION(3, "SAI1_D2"), + STM32_FUNCTION(4, "DFSDM1_DATIN3"), + STM32_FUNCTION(5, "TIM15_CH1N"), + STM32_FUNCTION(6, "I2S_CKIN"), + STM32_FUNCTION(7, "SAI1_FS_A"), + STM32_FUNCTION(8, "UART7_RTS UART7_DE"), + STM32_FUNCTION(9, "UART8_TX"), + STM32_FUNCTION(10, "QUADSPI_BK2_NCS"), + STM32_FUNCTION(11, "FMC_NCE2"), + STM32_FUNCTION(12, "TSC_G1_IO1"), + STM32_FUNCTION(13, "FMC_A25"), + STM32_FUNCTION(14, "DCMIPP_D3"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(69, "PE5"), + STM32_FUNCTION(0, "GPIOE5"), + STM32_FUNCTION(3, "SAI2_SCK_B"), + STM32_FUNCTION(4, "TIM8_CH3"), + STM32_FUNCTION(5, "TIM15_CH1"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(11, "ETH1_MII_TXD3 ETH1_RGMII_TXD3"), + STM32_FUNCTION(13, "FMC_NE1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(70, "PE6"), + STM32_FUNCTION(0, "GPIOE6"), + STM32_FUNCTION(1, "MCO2"), + STM32_FUNCTION(2, "TIM1_BKIN2"), + STM32_FUNCTION(3, "SAI2_SCK_B"), + STM32_FUNCTION(5, "TIM15_CH2"), + STM32_FUNCTION(6, "I2C3_SMBA"), + STM32_FUNCTION(7, "SAI1_SCK_B"), + STM32_FUNCTION(9, "UART4_RTS UART4_DE"), + STM32_FUNCTION(12, "ETH2_MII_TXD3 ETH2_RGMII_TXD3"), + STM32_FUNCTION(13, "FMC_A22"), + STM32_FUNCTION(14, "DCMIPP_D7"), + STM32_FUNCTION(15, "LCD_G3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(71, "PE7"), + STM32_FUNCTION(0, "GPIOE7"), + STM32_FUNCTION(2, "TIM1_ETR"), + STM32_FUNCTION(5, "LPTIM2_IN1"), + STM32_FUNCTION(9, "UART5_TX"), + STM32_FUNCTION(13, "FMC_D4 FMC_AD4"), + STM32_FUNCTION(14, "LCD_B3"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(72, "PE8"), + STM32_FUNCTION(0, "GPIOE8"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(4, "DFSDM1_CKIN2"), + STM32_FUNCTION(6, "I2C1_SDA"), + STM32_FUNCTION(8, "UART7_TX"), + STM32_FUNCTION(13, "FMC_D5 FMC_AD5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(73, "PE9"), + STM32_FUNCTION(0, "GPIOE9"), + STM32_FUNCTION(2, "TIM1_CH1"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(12, "LCD_HSYNC"), + STM32_FUNCTION(13, "FMC_D6 FMC_AD6"), + STM32_FUNCTION(14, "DCMIPP_D7"), + STM32_FUNCTION(15, "LCD_R7"), + STM32_FUNCTION(16, "HDP3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(74, "PE10"), + STM32_FUNCTION(0, "GPIOE10"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(8, "UART7_RX"), + STM32_FUNCTION(10, "FDCAN1_TX"), + STM32_FUNCTION(13, "FMC_D7 FMC_AD7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(75, "PE11"), + STM32_FUNCTION(0, "GPIOE11"), + STM32_FUNCTION(2, "TIM1_CH2"), + STM32_FUNCTION(3, "USART2_CTS USART2_NSS"), + STM32_FUNCTION(5, "SAI1_D2"), + STM32_FUNCTION(6, "SPI4_MOSI I2S4_SDO"), + STM32_FUNCTION(7, "SAI1_FS_A"), + STM32_FUNCTION(8, "USART6_CK"), + STM32_FUNCTION(10, "LCD_R0"), + STM32_FUNCTION(11, "ETH2_MII_TX_ER"), + STM32_FUNCTION(12, "ETH1_MII_TX_ER"), + STM32_FUNCTION(13, "FMC_D8 FMC_AD8"), + STM32_FUNCTION(14, "DCMIPP_D10"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(76, "PE12"), + STM32_FUNCTION(0, "GPIOE12"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(6, "SPI4_SCK I2S4_CK"), + STM32_FUNCTION(9, "UART8_RTS UART8_DE"), + STM32_FUNCTION(10, "LCD_VSYNC"), + STM32_FUNCTION(11, "TSC_G3_IO2"), + STM32_FUNCTION(12, "LCD_G4"), + STM32_FUNCTION(13, "FMC_D9 FMC_AD9"), + STM32_FUNCTION(14, "DCMIPP_D11"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(16, "HDP4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(77, "PE13"), + STM32_FUNCTION(0, "GPIOE13"), + STM32_FUNCTION(2, "TIM1_CH3"), + STM32_FUNCTION(5, "I2C5_SDA"), + STM32_FUNCTION(6, "SPI4_MISO I2S4_SDI"), + STM32_FUNCTION(12, "LCD_B1"), + STM32_FUNCTION(13, "FMC_D10 FMC_AD10"), + STM32_FUNCTION(14, "DCMIPP_D4"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(78, "PE14"), + STM32_FUNCTION(0, "GPIOE14"), + STM32_FUNCTION(2, "TIM1_BKIN"), + STM32_FUNCTION(5, "SAI1_D4"), + STM32_FUNCTION(9, "UART8_RTS UART8_DE"), + STM32_FUNCTION(10, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(13, "FMC_D11 FMC_AD11"), + STM32_FUNCTION(14, "DCMIPP_D7"), + STM32_FUNCTION(15, "LCD_G0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(79, "PE15"), + STM32_FUNCTION(0, "GPIOE15"), + STM32_FUNCTION(2, "TIM2_ETR"), + STM32_FUNCTION(3, "TIM1_BKIN"), + STM32_FUNCTION(4, "USART2_CTS USART2_NSS"), + STM32_FUNCTION(7, "I2C4_SCL"), + STM32_FUNCTION(13, "FMC_D12 FMC_AD12"), + STM32_FUNCTION(14, "DCMIPP_D10"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(16, "HDP7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(80, "PF0"), + STM32_FUNCTION(0, "GPIOF0"), + STM32_FUNCTION(1, "TRACED13"), + STM32_FUNCTION(4, "DFSDM1_CKOUT"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(11, "SDMMC2_D4"), + STM32_FUNCTION(13, "FMC_A0"), + STM32_FUNCTION(14, "LCD_R6"), + STM32_FUNCTION(15, "LCD_G0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(81, "PF1"), + STM32_FUNCTION(0, "GPIOF1"), + STM32_FUNCTION(1, "TRACED7"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(6, "SPI3_MOSI I2S3_SDO"), + STM32_FUNCTION(13, "FMC_A1"), + STM32_FUNCTION(14, "LCD_B7"), + STM32_FUNCTION(15, "LCD_G1"), + STM32_FUNCTION(16, "HDP7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(82, "PF2"), + STM32_FUNCTION(0, "GPIOF2"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(5, "I2C2_SCL"), + STM32_FUNCTION(7, "DFSDM1_CKIN1"), + STM32_FUNCTION(8, "USART6_CK"), + STM32_FUNCTION(10, "SDMMC2_D0DIR"), + STM32_FUNCTION(12, "SDMMC1_D0DIR"), + STM32_FUNCTION(13, "FMC_A2"), + STM32_FUNCTION(14, "LCD_G4"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(83, "PF3"), + STM32_FUNCTION(0, "GPIOF3"), + STM32_FUNCTION(4, "LPTIM2_IN2"), + STM32_FUNCTION(5, "I2C5_SDA"), + STM32_FUNCTION(6, "SPI4_MISO I2S4_SDI"), + STM32_FUNCTION(7, "SPI3_NSS I2S3_WS"), + STM32_FUNCTION(13, "FMC_A3"), + STM32_FUNCTION(15, "LCD_G3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(84, "PF4"), + STM32_FUNCTION(0, "GPIOF4"), + STM32_FUNCTION(4, "USART2_RX"), + STM32_FUNCTION(11, "TSC_G3_IO3"), + STM32_FUNCTION(12, "ETH2_MII_RXD0 ETH2_RGMII_RXD0 ETH2_RMII_RXD0"), + STM32_FUNCTION(13, "FMC_A4"), + STM32_FUNCTION(14, "DCMIPP_D4"), + STM32_FUNCTION(15, "LCD_B6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(85, "PF5"), + STM32_FUNCTION(0, "GPIOF5"), + STM32_FUNCTION(1, "TRACED12"), + STM32_FUNCTION(5, "DFSDM1_CKIN0"), + STM32_FUNCTION(6, "I2C1_SMBA"), + STM32_FUNCTION(10, "LCD_G0"), + STM32_FUNCTION(13, "FMC_A5"), + STM32_FUNCTION(14, "DCMIPP_D11"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(86, "PF6"), + STM32_FUNCTION(0, "GPIOF6"), + STM32_FUNCTION(2, "TIM16_CH1"), + STM32_FUNCTION(6, "SPI5_NSS"), + STM32_FUNCTION(8, "UART7_RX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(12, "ETH2_MII_TX_EN ETH2_RGMII_TX_CTL ETH2_RMII_TX_EN"), + STM32_FUNCTION(14, "LCD_R7"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(87, "PF7"), + STM32_FUNCTION(0, "GPIOF7"), + STM32_FUNCTION(2, "TIM17_CH1"), + STM32_FUNCTION(8, "UART7_TX"), + STM32_FUNCTION(9, "UART4_CTS"), + STM32_FUNCTION(11, "ETH1_RGMII_CLK125"), + STM32_FUNCTION(12, "ETH2_MII_TXD0 ETH2_RGMII_TXD0 ETH2_RMII_TXD0"), + STM32_FUNCTION(13, "FMC_A18"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(88, "PF8"), + STM32_FUNCTION(0, "GPIOF8"), + STM32_FUNCTION(2, "TIM16_CH1N"), + STM32_FUNCTION(3, "TIM4_CH3"), + STM32_FUNCTION(4, "TIM8_CH3"), + STM32_FUNCTION(7, "SAI1_SCK_B"), + STM32_FUNCTION(8, "USART6_TX"), + STM32_FUNCTION(10, "TIM13_CH1"), + STM32_FUNCTION(11, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(14, "DCMIPP_D15"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(89, "PF9"), + STM32_FUNCTION(0, "GPIOF9"), + STM32_FUNCTION(2, "TIM17_CH1N"), + STM32_FUNCTION(3, "TIM1_CH1"), + STM32_FUNCTION(4, "DFSDM1_CKIN3"), + STM32_FUNCTION(7, "SAI1_D4"), + STM32_FUNCTION(8, "UART7_CTS"), + STM32_FUNCTION(9, "UART8_RX"), + STM32_FUNCTION(10, "TIM14_CH1"), + STM32_FUNCTION(11, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(12, "QUADSPI_BK2_IO3"), + STM32_FUNCTION(13, "FMC_A9"), + STM32_FUNCTION(15, "LCD_B6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(90, "PF10"), + STM32_FUNCTION(0, "GPIOF10"), + STM32_FUNCTION(2, "TIM16_BKIN"), + STM32_FUNCTION(3, "SAI1_D3"), + STM32_FUNCTION(4, "TIM8_BKIN"), + STM32_FUNCTION(6, "SPI5_NSS"), + STM32_FUNCTION(8, "USART6_RTS USART6_DE"), + STM32_FUNCTION(9, "UART7_RTS UART7_DE"), + STM32_FUNCTION(10, "QUADSPI_CLK"), + STM32_FUNCTION(14, "DCMIPP_HSYNC"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(91, "PF11"), + STM32_FUNCTION(0, "GPIOF11"), + STM32_FUNCTION(2, "USART2_TX"), + STM32_FUNCTION(3, "SAI1_D2"), + STM32_FUNCTION(4, "DFSDM1_CKIN3"), + STM32_FUNCTION(7, "SAI1_FS_A"), + STM32_FUNCTION(13, "ETH2_MII_RX_ER"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(92, "PF12"), + STM32_FUNCTION(0, "GPIOF12"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(11, "ETH1_MII_TX_ER"), + STM32_FUNCTION(12, "ETH1_RGMII_CLK125"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(93, "PF13"), + STM32_FUNCTION(0, "GPIOF13"), + STM32_FUNCTION(2, "TIM2_ETR"), + STM32_FUNCTION(3, "SAI1_MCLK_B"), + STM32_FUNCTION(7, "DFSDM1_DATIN3"), + STM32_FUNCTION(8, "USART2_TX"), + STM32_FUNCTION(9, "UART5_RX"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(94, "PF14"), + STM32_FUNCTION(0, "GPIOF14"), + STM32_FUNCTION(1, "JTCK SWCLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(95, "PF15"), + STM32_FUNCTION(0, "GPIOF15"), + STM32_FUNCTION(1, "JTMS SWDIO"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(96, "PG0"), + STM32_FUNCTION(0, "GPIOG0"), + STM32_FUNCTION(10, "FDCAN2_TX"), + STM32_FUNCTION(11, "TSC_G4_IO2"), + STM32_FUNCTION(13, "FMC_A10"), + STM32_FUNCTION(14, "DCMIPP_PIXCLK"), + STM32_FUNCTION(15, "LCD_G5"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(97, "PG1"), + STM32_FUNCTION(0, "GPIOG1"), + STM32_FUNCTION(2, "LPTIM1_ETR"), + STM32_FUNCTION(3, "TIM4_ETR"), + STM32_FUNCTION(4, "SAI2_FS_A"), + STM32_FUNCTION(5, "I2C2_SMBA"), + STM32_FUNCTION(6, "SPI2_MISO I2S2_SDI"), + STM32_FUNCTION(7, "SAI2_D2"), + STM32_FUNCTION(10, "FDCAN2_TX"), + STM32_FUNCTION(11, "ETH2_MII_TXD2 ETH2_RGMII_TXD2"), + STM32_FUNCTION(13, "FMC_NBL0"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(98, "PG2"), + STM32_FUNCTION(0, "GPIOG2"), + STM32_FUNCTION(2, "MCO2"), + STM32_FUNCTION(4, "TIM8_BKIN"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(12, "ETH1_MDC"), + STM32_FUNCTION(14, "DCMIPP_D1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(99, "PG3"), + STM32_FUNCTION(0, "GPIOG3"), + STM32_FUNCTION(4, "TIM8_BKIN2"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(7, "SAI2_SD_B"), + STM32_FUNCTION(10, "FDCAN2_RX"), + STM32_FUNCTION(11, "ETH2_RGMII_GTX_CLK"), + STM32_FUNCTION(12, "ETH1_MDIO"), + STM32_FUNCTION(13, "FMC_A13"), + STM32_FUNCTION(14, "DCMIPP_D15"), + STM32_FUNCTION(15, "DCMIPP_D12"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(100, "PG4"), + STM32_FUNCTION(0, "GPIOG4"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(2, "TIM1_BKIN2"), + STM32_FUNCTION(5, "DFSDM1_CKIN3"), + STM32_FUNCTION(9, "USART3_RX"), + STM32_FUNCTION(11, "SDMMC2_D123DIR"), + STM32_FUNCTION(12, "LCD_VSYNC"), + STM32_FUNCTION(13, "FMC_A14"), + STM32_FUNCTION(14, "DCMIPP_D8"), + STM32_FUNCTION(15, "DCMIPP_D13"), + STM32_FUNCTION(16, "HDP1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(101, "PG5"), + STM32_FUNCTION(0, "GPIOG5"), + STM32_FUNCTION(2, "TIM17_CH1"), + STM32_FUNCTION(11, "ETH2_MDC"), + STM32_FUNCTION(12, "LCD_G4"), + STM32_FUNCTION(13, "FMC_A15"), + STM32_FUNCTION(14, "DCMIPP_VSYNC"), + STM32_FUNCTION(15, "DCMIPP_D3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(102, "PG6"), + STM32_FUNCTION(0, "GPIOG6"), + STM32_FUNCTION(1, "TRACED3"), + STM32_FUNCTION(2, "TIM17_BKIN"), + STM32_FUNCTION(3, "TIM5_CH4"), + STM32_FUNCTION(4, "SAI2_D1"), + STM32_FUNCTION(5, "USART1_RX"), + STM32_FUNCTION(7, "SAI2_SD_A"), + STM32_FUNCTION(11, "SDMMC2_CMD"), + STM32_FUNCTION(12, "LCD_G0"), + STM32_FUNCTION(14, "LCD_DE"), + STM32_FUNCTION(15, "LCD_R7"), + STM32_FUNCTION(16, "HDP3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(103, "PG7"), + STM32_FUNCTION(0, "GPIOG7"), + STM32_FUNCTION(1, "TRACED8"), + STM32_FUNCTION(2, "TIM1_ETR"), + STM32_FUNCTION(6, "SPI3_MISO I2S3_SDI"), + STM32_FUNCTION(9, "UART7_CTS"), + STM32_FUNCTION(11, "SDMMC2_CKIN"), + STM32_FUNCTION(12, "LCD_R1"), + STM32_FUNCTION(14, "LCD_R5"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(104, "PG8"), + STM32_FUNCTION(0, "GPIOG8"), + STM32_FUNCTION(2, "TIM2_CH1"), + STM32_FUNCTION(4, "TIM8_ETR"), + STM32_FUNCTION(6, "SPI5_MISO"), + STM32_FUNCTION(7, "SAI1_MCLK_B"), + STM32_FUNCTION(8, "LCD_B1"), + STM32_FUNCTION(9, "USART3_RTS USART3_DE"), + STM32_FUNCTION(10, "SPDIFRX_IN2"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(12, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(13, "FMC_NE2"), + STM32_FUNCTION(14, "ETH2_CLK"), + STM32_FUNCTION(15, "DCMIPP_D6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(105, "PG9"), + STM32_FUNCTION(0, "GPIOG9"), + STM32_FUNCTION(1, "DBTRGO"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(8, "USART6_RX"), + STM32_FUNCTION(9, "SPDIFRX_IN3"), + STM32_FUNCTION(10, "FDCAN1_RX"), + STM32_FUNCTION(11, "FMC_NE2"), + STM32_FUNCTION(13, "FMC_NCE"), + STM32_FUNCTION(14, "DCMIPP_VSYNC"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(106, "PG10"), + STM32_FUNCTION(0, "GPIOG10"), + STM32_FUNCTION(6, "SPI5_SCK"), + STM32_FUNCTION(7, "SAI1_SD_B"), + STM32_FUNCTION(9, "UART8_CTS"), + STM32_FUNCTION(10, "FDCAN1_TX"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO1"), + STM32_FUNCTION(13, "FMC_NE3"), + STM32_FUNCTION(14, "DCMIPP_D2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(107, "PG11"), + STM32_FUNCTION(0, "GPIOG11"), + STM32_FUNCTION(5, "SAI2_D3"), + STM32_FUNCTION(6, "I2S2_MCK"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(11, "ETH2_MII_TXD1 ETH2_RGMII_TXD1 ETH2_RMII_TXD1"), + STM32_FUNCTION(13, "FMC_A24"), + STM32_FUNCTION(14, "DCMIPP_D14"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(108, "PG12"), + STM32_FUNCTION(0, "GPIOG12"), + STM32_FUNCTION(2, "LPTIM1_IN1"), + STM32_FUNCTION(4, "TSC_G5_IO2"), + STM32_FUNCTION(5, "SAI2_SCK_A"), + STM32_FUNCTION(7, "SAI2_CK2"), + STM32_FUNCTION(8, "USART6_RTS USART6_DE"), + STM32_FUNCTION(9, "USART3_CTS"), + STM32_FUNCTION(11, "ETH2_PHY_INTN"), + STM32_FUNCTION(12, "ETH1_PHY_INTN"), + STM32_FUNCTION(13, "ETH2_MII_RX_DV ETH2_RGMII_RX_CTL ETH2_RMII_CRS_DV"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(109, "PG13"), + STM32_FUNCTION(0, "GPIOG13"), + STM32_FUNCTION(2, "LPTIM1_OUT"), + STM32_FUNCTION(8, "USART6_CTS USART6_NSS"), + STM32_FUNCTION(12, "ETH1_MII_TXD0 ETH1_RGMII_TXD0 ETH1_RMII_TXD0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(110, "PG14"), + STM32_FUNCTION(0, "GPIOG14"), + STM32_FUNCTION(2, "LPTIM1_ETR"), + STM32_FUNCTION(7, "SAI2_D1"), + STM32_FUNCTION(8, "USART6_TX"), + STM32_FUNCTION(11, "SAI2_SD_A"), + STM32_FUNCTION(12, "ETH1_MII_TXD1 ETH1_RGMII_TXD1 ETH1_RMII_TXD1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(111, "PG15"), + STM32_FUNCTION(0, "GPIOG15"), + STM32_FUNCTION(8, "USART6_CTS USART6_NSS"), + STM32_FUNCTION(9, "UART7_CTS"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(11, "ETH2_PHY_INTN"), + STM32_FUNCTION(12, "LCD_B4"), + STM32_FUNCTION(14, "DCMIPP_D10"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(112, "PH0"), + STM32_FUNCTION(0, "GPIOH0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(113, "PH1"), + STM32_FUNCTION(0, "GPIOH1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(114, "PH2"), + STM32_FUNCTION(0, "GPIOH2"), + STM32_FUNCTION(2, "LPTIM1_IN2"), + STM32_FUNCTION(4, "TSC_G4_IO3"), + STM32_FUNCTION(7, "DCMIPP_D9"), + STM32_FUNCTION(8, "LCD_G1"), + STM32_FUNCTION(9, "UART7_TX"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO0"), + STM32_FUNCTION(11, "ETH2_MII_CRS"), + STM32_FUNCTION(12, "ETH1_MII_CRS"), + STM32_FUNCTION(13, "FMC_NE4"), + STM32_FUNCTION(14, "ETH2_RGMII_CLK125"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(115, "PH3"), + STM32_FUNCTION(0, "GPIOH3"), + STM32_FUNCTION(5, "I2C3_SCL"), + STM32_FUNCTION(6, "SPI5_MOSI"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO1"), + STM32_FUNCTION(11, "ETH1_MII_COL"), + STM32_FUNCTION(12, "LCD_R5"), + STM32_FUNCTION(13, "ETH2_MII_COL"), + STM32_FUNCTION(14, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(116, "PH4"), + STM32_FUNCTION(0, "GPIOH4"), + STM32_FUNCTION(1, "JTDI"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(117, "PH5"), + STM32_FUNCTION(0, "GPIOH5"), + STM32_FUNCTION(1, "JTDO"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(118, "PH6"), + STM32_FUNCTION(0, "GPIOH6"), + STM32_FUNCTION(3, "TIM12_CH1"), + STM32_FUNCTION(4, "USART2_CK"), + STM32_FUNCTION(5, "I2C5_SDA"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(11, "ETH1_PHY_INTN"), + STM32_FUNCTION(12, "ETH1_MII_RX_ER"), + STM32_FUNCTION(13, "ETH2_MII_RXD2 ETH2_RGMII_RXD2"), + STM32_FUNCTION(14, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(119, "PH7"), + STM32_FUNCTION(0, "GPIOH7"), + STM32_FUNCTION(3, "SAI2_FS_B"), + STM32_FUNCTION(6, "I2C3_SDA"), + STM32_FUNCTION(7, "SPI5_SCK"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO3"), + STM32_FUNCTION(11, "ETH2_MII_TX_CLK"), + STM32_FUNCTION(12, "ETH1_MII_TX_CLK"), + STM32_FUNCTION(14, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(120, "PH8"), + STM32_FUNCTION(0, "GPIOH8"), + STM32_FUNCTION(1, "TRACED9"), + STM32_FUNCTION(3, "TIM5_ETR"), + STM32_FUNCTION(4, "USART2_RX"), + STM32_FUNCTION(5, "I2C3_SDA"), + STM32_FUNCTION(12, "LCD_R6"), + STM32_FUNCTION(13, "FMC_A8"), + STM32_FUNCTION(14, "DCMIPP_HSYNC"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "HDP2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(121, "PH9"), + STM32_FUNCTION(0, "GPIOH9"), + STM32_FUNCTION(2, "TIM1_CH4"), + STM32_FUNCTION(3, "TIM12_CH2"), + STM32_FUNCTION(4, "TSC_SYNC"), + STM32_FUNCTION(6, "SPI4_SCK I2S4_CK"), + STM32_FUNCTION(7, "DCMIPP_D13"), + STM32_FUNCTION(10, "LCD_B5"), + STM32_FUNCTION(12, "LCD_DE"), + STM32_FUNCTION(13, "FMC_A20"), + STM32_FUNCTION(14, "DCMIPP_D9"), + STM32_FUNCTION(15, "DCMIPP_D8"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(122, "PH10"), + STM32_FUNCTION(0, "GPIOH10"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(3, "TIM5_CH1"), + STM32_FUNCTION(4, "SAI2_D3"), + STM32_FUNCTION(5, "DFSDM1_DATIN2"), + STM32_FUNCTION(6, "I2S3_MCK"), + STM32_FUNCTION(7, "SPI2_MOSI I2S2_SDO"), + STM32_FUNCTION(8, "USART3_CTS USART3_NSS"), + STM32_FUNCTION(9, "SDMMC1_D4"), + STM32_FUNCTION(14, "LCD_HSYNC"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "HDP0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(123, "PH11"), + STM32_FUNCTION(0, "GPIOH11"), + STM32_FUNCTION(2, "SPI5_NSS"), + STM32_FUNCTION(3, "TIM5_CH2"), + STM32_FUNCTION(4, "SAI2_SD_A"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(7, "I2C4_SCL"), + STM32_FUNCTION(8, "USART6_RX"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO0"), + STM32_FUNCTION(12, "ETH2_MII_RX_CLK ETH2_RGMII_RX_CLK ETH2_RMII_REF_CLK"), + STM32_FUNCTION(13, "FMC_A12"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(124, "PH12"), + STM32_FUNCTION(0, "GPIOH12"), + STM32_FUNCTION(2, "USART2_TX"), + STM32_FUNCTION(3, "TIM5_CH3"), + STM32_FUNCTION(4, "DFSDM1_CKIN1"), + STM32_FUNCTION(5, "I2C3_SCL"), + STM32_FUNCTION(6, "SPI5_MOSI"), + STM32_FUNCTION(7, "SAI1_SCK_A"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(11, "SAI1_CK2"), + STM32_FUNCTION(12, "ETH1_MII_CRS"), + STM32_FUNCTION(13, "FMC_A6"), + STM32_FUNCTION(14, "DCMIPP_D3"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(125, "PH13"), + STM32_FUNCTION(0, "GPIOH13"), + STM32_FUNCTION(1, "TRACED15"), + STM32_FUNCTION(3, "USART2_CK"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(5, "I2C5_SCL"), + STM32_FUNCTION(7, "SPI3_SCK I2S3_CK"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(14, "LCD_G3"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(126, "PH14"), + STM32_FUNCTION(0, "GPIOH14"), + STM32_FUNCTION(4, "DFSDM1_DATIN2"), + STM32_FUNCTION(5, "I2C3_SDA"), + STM32_FUNCTION(7, "DCMIPP_D8"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(12, "LCD_B4"), + STM32_FUNCTION(14, "DCMIPP_D2"), + STM32_FUNCTION(15, "DCMIPP_PIXCLK"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(128, "PI0"), + STM32_FUNCTION(0, "GPIOI0"), + STM32_FUNCTION(9, "SPDIFRX_IN0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(129, "PI1"), + STM32_FUNCTION(0, "GPIOI1"), + STM32_FUNCTION(9, "SPDIFRX_IN1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(130, "PI2"), + STM32_FUNCTION(0, "GPIOI2"), + STM32_FUNCTION(9, "SPDIFRX_IN2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(131, "PI3"), + STM32_FUNCTION(0, "GPIOI3"), + STM32_FUNCTION(9, "SPDIFRX_IN3"), + STM32_FUNCTION(12, "ETH1_MII_RX_ER"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(132, "PI4"), + STM32_FUNCTION(0, "GPIOI4"), + STM32_FUNCTION(1, "BOOT0"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(133, "PI5"), + STM32_FUNCTION(0, "GPIOI5"), + STM32_FUNCTION(1, "BOOT1"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(134, "PI6"), + STM32_FUNCTION(0, "GPIOI6"), + STM32_FUNCTION(1, "BOOT2"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(135, "PI7"), + STM32_FUNCTION(0, "GPIOI7"), + STM32_FUNCTION(17, "ANALOG") + ), +}; + +static struct stm32_pinctrl_match_data stm32mp135_match_data = { + .pins = stm32mp135_pins, + .npins = ARRAY_SIZE(stm32mp135_pins), +}; + +static const struct of_device_id stm32mp135_pctrl_match[] = { + { + .compatible = "st,stm32mp135-pinctrl", + .data = &stm32mp135_match_data, + }, + { } +}; + +static const struct dev_pm_ops stm32_pinctrl_dev_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, stm32_pinctrl_resume) +}; + +static struct platform_driver stm32mp135_pinctrl_driver = { + .probe = stm32_pctl_probe, + .driver = { + .name = "stm32mp135-pinctrl", + .of_match_table = stm32mp135_pctrl_match, + .pm = &stm32_pinctrl_dev_pm_ops, + }, +}; + +static int __init stm32mp135_pinctrl_init(void) +{ + return platform_driver_register(&stm32mp135_pinctrl_driver); +} +arch_initcall(stm32mp135_pinctrl_init); -- cgit v1.2.3-70-g09d2 From 1b73e588f47397dee6e4bdfd953e0306c60b5fe5 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 25 Jul 2021 19:08:30 +0100 Subject: pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast Casting a small array of u8 to an unsigned long is *never* OK: - it does funny thing when the array size is less than that of a long, as it accesses random places in the stack - it makes everything even more fun with a BE kernel Fix this by building the unsigned long used as a bitmap byte by byte, in a way that works across endianess and has no undefined behaviours. An extra BUILD_BUG_ON() catches the unlikely case where the array would be larger than a single unsigned long. Fixes: 1490d9f841b1 ("pinctrl: Add STMFX GPIO expander Pinctrl/GPIO driver") Signed-off-by: Marc Zyngier Cc: stable@vger.kernel.org Cc: Amelie Delaunay Cc: Linus Walleij Cc: Maxime Coquelin Cc: Alexandre Torgue Link: https://lore.kernel.org/r/20210725180830.250218-1-maz@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-stmfx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 008c83107a3c..5fa2488fae87 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -566,7 +566,7 @@ static irqreturn_t stmfx_pinctrl_irq_thread_fn(int irq, void *dev_id) u8 pending[NR_GPIO_REGS]; u8 src[NR_GPIO_REGS] = {0, 0, 0}; unsigned long n, status; - int ret; + int i, ret; ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING, &pending, NR_GPIO_REGS); @@ -576,7 +576,9 @@ static irqreturn_t stmfx_pinctrl_irq_thread_fn(int irq, void *dev_id) regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, src, NR_GPIO_REGS); - status = *(unsigned long *)pending; + BUILD_BUG_ON(NR_GPIO_REGS > sizeof(status)); + for (i = 0, status = 0; i < NR_GPIO_REGS; i++) + status |= (unsigned long)pending[i] << (i * 8); for_each_set_bit(n, &status, gc->ngpio) { handle_nested_irq(irq_find_mapping(gc->irq.domain, n)); stmfx_pinctrl_irq_toggle_trigger(pctl, n); -- cgit v1.2.3-70-g09d2 From 09ca497528dac12cbbceab8197011c875a96d053 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Sun, 27 Jun 2021 17:09:18 +0000 Subject: powerpc: Remove in_kernel_text() Last user of in_kernel_text() stopped using in with commit 549e8152de80 ("powerpc: Make the 64-bit kernel as a position-independent executable"). Generic function is_kernel_text() does the same. So remote it. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/2a3a5b6f8cc0ef4e854d7b764f66aa8d2ee270d2.1624813698.git.christophe.leroy@csgroup.eu --- arch/powerpc/include/asm/sections.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index 324d7b298ec3..6e4af4492a14 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h @@ -38,14 +38,6 @@ extern char start_virt_trampolines[]; extern char end_virt_trampolines[]; #endif -static inline int in_kernel_text(unsigned long addr) -{ - if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end) - return 1; - - return 0; -} - static inline unsigned long kernel_toc_addr(void) { /* Defined by the linker, see vmlinux.lds.S */ -- cgit v1.2.3-70-g09d2 From c8a6d91005343dea0d53be0ff0620c66934dcd44 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 5 Jul 2021 12:00:50 +0000 Subject: powerpc/non-smp: Unconditionaly call smp_mb() on switch_mm Commit 3ccfebedd8cf ("powerpc, membarrier: Skip memory barrier in switch_mm()") added some logic to skip the smp_mb() in switch_mm_irqs_off() before the call to switch_mmu_context(). However, on non SMP smp_mb() is just a compiler barrier and doing it unconditionaly is simpler than the logic used to check whether the barrier is needed or not. After the patch: 00000000 : ... c: 7c 04 18 40 cmplw r4,r3 10: 81 24 00 24 lwz r9,36(r4) 14: 91 25 04 c8 stw r9,1224(r5) 18: 4d 82 00 20 beqlr 1c: 48 00 00 00 b 1c 1c: R_PPC_REL24 switch_mmu_context Before the patch: 00000000 : ... c: 7c 04 18 40 cmplw r4,r3 10: 81 24 00 24 lwz r9,36(r4) 14: 91 25 04 c8 stw r9,1224(r5) 18: 4d 82 00 20 beqlr 1c: 81 24 00 28 lwz r9,40(r4) 20: 71 29 00 0a andi. r9,r9,10 24: 40 82 00 34 bne 58 28: 48 00 00 00 b 28 28: R_PPC_REL24 switch_mmu_context ... 58: 2c 03 00 00 cmpwi r3,0 5c: 41 82 ff cc beq 28 60: 48 00 00 00 b 60 60: R_PPC_REL24 switch_mmu_context Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/e9d501da0c59f60ca767b1b3ea4603fce6d02b9e.1625486440.git.christophe.leroy@csgroup.eu --- arch/powerpc/include/asm/membarrier.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/membarrier.h b/arch/powerpc/include/asm/membarrier.h index 6e20bb5c74ea..de7f79157918 100644 --- a/arch/powerpc/include/asm/membarrier.h +++ b/arch/powerpc/include/asm/membarrier.h @@ -12,7 +12,8 @@ static inline void membarrier_arch_switch_mm(struct mm_struct *prev, * when switching from userspace to kernel is not needed after * store to rq->curr. */ - if (likely(!(atomic_read(&next->membarrier_state) & + if (IS_ENABLED(CONFIG_SMP) && + likely(!(atomic_read(&next->membarrier_state) & (MEMBARRIER_STATE_PRIVATE_EXPEDITED | MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev)) return; -- cgit v1.2.3-70-g09d2 From 9c7248bb8de31f51c693bfa6a6ea53b1c07e0fa8 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Tue, 11 May 2021 09:31:36 +0200 Subject: powerpc/numa: Consider the max NUMA node for migratable LPAR When a LPAR is migratable, we should consider the maximum possible NUMA node instead of the number of NUMA nodes from the actual system. The DT property 'ibm,current-associativity-domains' defines the maximum number of nodes the LPAR can see when running on that box. But if the LPAR is being migrated on another box, it may see up to the nodes defined by 'ibm,max-associativity-domains'. So if a LPAR is migratable, that value should be used. Unfortunately, there is no easy way to know if an LPAR is migratable or not. The hypervisor exports the property 'ibm,migratable-partition' in the case it set to migrate partition, but that would not mean that the current partition is migratable. Without this patch, when a LPAR is started on a 2 node box and then migrated to a 3 node box, the hypervisor may spread the LPAR's CPUs on the 3rd node. In that case if a CPU from that 3rd node is added to the LPAR, it will be wrongly assigned to the node because the kernel has been set to use up to 2 nodes (the configuration of the departure node). With this patch applies, the CPU is correctly added to the 3rd node. Fixes: f9f130ff2ec9 ("powerpc/numa: Detect support for coregroup") Signed-off-by: Laurent Dufour Reviewed-by: Srikar Dronamraju Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210511073136.17795-1-ldufour@linux.ibm.com --- arch/powerpc/mm/numa.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index f2bf98bdcea2..094a1076fd1f 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -893,7 +893,7 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn) static void __init find_possible_nodes(void) { struct device_node *rtas; - const __be32 *domains; + const __be32 *domains = NULL; int prop_length, max_nodes; u32 i; @@ -909,9 +909,14 @@ static void __init find_possible_nodes(void) * it doesn't exist, then fallback on ibm,max-associativity-domains. * Current denotes what the platform can support compared to max * which denotes what the Hypervisor can support. + * + * If the LPAR is migratable, new nodes might be activated after a LPM, + * so we should consider the max number in that case. */ - domains = of_get_property(rtas, "ibm,current-associativity-domains", - &prop_length); + if (!of_get_property(of_root, "ibm,migratable-partition", NULL)) + domains = of_get_property(rtas, + "ibm,current-associativity-domains", + &prop_length); if (!domains) { domains = of_get_property(rtas, "ibm,max-associativity-domains", &prop_length); @@ -920,6 +925,8 @@ static void __init find_possible_nodes(void) } max_nodes = of_read_number(&domains[min_common_depth], 1); + pr_info("Partition configured for %d NUMA nodes.\n", max_nodes); + for (i = 0; i < max_nodes; i++) { if (!node_possible(i)) node_set(i, node_possible_map); -- cgit v1.2.3-70-g09d2 From d144f4d5a8a804133d20ff311d7be70bcdbfaac2 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Mon, 17 May 2021 11:06:06 +0200 Subject: pseries/drmem: update LMBs after LPM After a LPM, the device tree node ibm,dynamic-reconfiguration-memory may be updated by the hypervisor in the case the NUMA topology of the LPAR's memory is updated. This is handled by the kernel, but the memory's node is not updated because there is no way to move a memory block between nodes from the Linux kernel point of view. If later a memory block is added or removed, drmem_update_dt() is called and it is overwriting the DT node ibm,dynamic-reconfiguration-memory to match the added or removed LMB. But the LMB's associativity node has not been updated after the DT node update and thus the node is overwritten by the Linux's topology instead of the hypervisor one. Introduce a hook called when the ibm,dynamic-reconfiguration-memory node is updated to force an update of the LMB's associativity. However, ignore the call to that hook when the update has been triggered by drmem_update_dt(). Because, in that case, the LMB tree has been used to set the DT property and thus it doesn't need to be updated back. Since drmem_update_dt() is called under the protection of the device_hotplug_lock and the hook is called in the same context, use a simple boolean variable to detect that call. Signed-off-by: Laurent Dufour Reviewed-by: Nathan Lynch Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210517090606.56930-1-ldufour@linux.ibm.com --- arch/powerpc/include/asm/drmem.h | 1 + arch/powerpc/mm/drmem.c | 46 +++++++++++++++++++++++++ arch/powerpc/platforms/pseries/hotplug-memory.c | 4 +++ 3 files changed, 51 insertions(+) diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h index bf2402fed3e0..4265d5e95c2c 100644 --- a/arch/powerpc/include/asm/drmem.h +++ b/arch/powerpc/include/asm/drmem.h @@ -111,6 +111,7 @@ int drmem_update_dt(void); int __init walk_drmem_lmbs_early(unsigned long node, void *data, int (*func)(struct drmem_lmb *, const __be32 **, void *)); +void drmem_update_lmbs(struct property *prop); #endif static inline void invalidate_lmb_associativity_index(struct drmem_lmb *lmb) diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index 9af3832c9d8d..22197b18d85e 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c @@ -18,6 +18,7 @@ static int n_root_addr_cells, n_root_size_cells; static struct drmem_lmb_info __drmem_info; struct drmem_lmb_info *drmem_info = &__drmem_info; +static bool in_drmem_update; u64 drmem_lmb_memory_max(void) { @@ -178,6 +179,11 @@ int drmem_update_dt(void) if (!memory) return -1; + /* + * Set in_drmem_update to prevent the notifier callback to process the + * DT property back since the change is coming from the LMB tree. + */ + in_drmem_update = true; prop = of_find_property(memory, "ibm,dynamic-memory", NULL); if (prop) { rc = drmem_update_dt_v1(memory, prop); @@ -186,6 +192,7 @@ int drmem_update_dt(void) if (prop) rc = drmem_update_dt_v2(memory, prop); } + in_drmem_update = false; of_node_put(memory); return rc; @@ -307,6 +314,45 @@ int __init walk_drmem_lmbs_early(unsigned long node, void *data, return ret; } +/* + * Update the LMB associativity index. + */ +static int update_lmb(struct drmem_lmb *updated_lmb, + __maybe_unused const __be32 **usm, + __maybe_unused void *data) +{ + struct drmem_lmb *lmb; + + for_each_drmem_lmb(lmb) { + if (lmb->drc_index != updated_lmb->drc_index) + continue; + + lmb->aa_index = updated_lmb->aa_index; + break; + } + return 0; +} + +/* + * Update the LMB associativity index. + * + * This needs to be called when the hypervisor is updating the + * dynamic-reconfiguration-memory node property. + */ +void drmem_update_lmbs(struct property *prop) +{ + /* + * Don't update the LMBs if triggered by the update done in + * drmem_update_dt(), the LMB values have been used to the update the DT + * property in that case. + */ + if (in_drmem_update) + return; + if (!strcmp(prop->name, "ibm,dynamic-memory")) + __walk_drmem_v1_lmbs(prop->value, NULL, NULL, update_lmb); + else if (!strcmp(prop->name, "ibm,dynamic-memory-v2")) + __walk_drmem_v2_lmbs(prop->value, NULL, NULL, update_lmb); +} #endif static int init_drmem_lmb_size(struct device_node *dn) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 377d852f5a9a..0beb3ca2b549 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -979,6 +979,10 @@ static int pseries_memory_notifier(struct notifier_block *nb, case OF_RECONFIG_DETACH_NODE: err = pseries_remove_mem_node(rd->dn); break; + case OF_RECONFIG_UPDATE_PROPERTY: + if (!strcmp(rd->dn->name, + "ibm,dynamic-reconfiguration-memory")) + drmem_update_lmbs(rd->prop); } return notifier_from_errno(err); } -- cgit v1.2.3-70-g09d2 From bd1dd4c5f5286df0148b5b316f37c583b8f55fa1 Mon Sep 17 00:00:00 2001 From: Laurent Dufour Date: Thu, 29 Apr 2021 19:49:08 +0200 Subject: powerpc/pseries: Prevent free CPU ids being reused on another node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a CPU is hot added, the CPU ids are taken from the available mask from the lower possible set. If that set of values was previously used for a CPU attached to a different node, it appears to an application as if these CPUs have migrated from one node to another node which is not expected. To prevent this, it is needed to record the CPU ids used for each node and to not reuse them on another node. However, to prevent CPU hot plug to fail, in the case the CPU ids is starved on a node, the capability to reuse other nodes’ free CPU ids is kept. A warning is displayed in such a case to warn the user. A new CPU bit mask (node_recorded_ids_map) is introduced for each possible node. It is populated with the CPU onlined at boot time, and then when a CPU is hot plugged to a node. The bits in that mask remain when the CPU is hot unplugged, to remind this CPU ids have been used for this node. If no id set was found, a retry is made without removing the ids used on the other nodes to try reusing them. This is the way ids have been allocated prior to this patch. The effect of this patch can be seen by removing and adding CPUs using the Qemu monitor. In the following case, the first CPU from the node 2 is removed, then the first one from the node 1 is removed too. Later, the first CPU of the node 2 is added back. Without that patch, the kernel will number these CPUs using the first CPU ids available which are the ones freed when removing the second CPU of the node 0. This leads to the CPU ids 16-23 to move from the node 1 to the node 2. With the patch applied, the CPU ids 32-39 are used since they are the lowest free ones which have not been used on another node. At boot time: [root@vm40 ~]# numactl -H | grep cpus node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 Vanilla kernel, after the CPU hot unplug/plug operations: [root@vm40 ~]# numactl -H | grep cpus node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 node 1 cpus: 24 25 26 27 28 29 30 31 node 2 cpus: 16 17 18 19 20 21 22 23 40 41 42 43 44 45 46 47 Patched kernel, after the CPU hot unplug/plug operations: [root@vm40 ~]# numactl -H | grep cpus node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 node 1 cpus: 24 25 26 27 28 29 30 31 node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 Signed-off-by: Laurent Dufour Reviewed-by: Nathan Lynch Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210429174908.16613-1-ldufour@linux.ibm.com --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 171 +++++++++++++++++++++------ 1 file changed, 132 insertions(+), 39 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 7e970f81d8ff..e1f224320102 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -39,6 +39,12 @@ /* This version can't take the spinlock, because it never returns */ static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE; +/* + * Record the CPU ids used on each nodes. + * Protected by cpu_add_remove_lock. + */ +static cpumask_var_t node_recorded_ids_map[MAX_NUMNODES]; + static void rtas_stop_self(void) { static struct rtas_args args; @@ -139,72 +145,148 @@ static void pseries_cpu_die(unsigned int cpu) paca_ptrs[cpu]->cpu_start = 0; } +/** + * find_cpu_id_range - found a linear ranger of @nthreads free CPU ids. + * @nthreads : the number of threads (cpu ids) + * @assigned_node : the node it belongs to or NUMA_NO_NODE if free ids from any + * node can be peek. + * @cpu_mask: the returned CPU mask. + * + * Returns 0 on success. + */ +static int find_cpu_id_range(unsigned int nthreads, int assigned_node, + cpumask_var_t *cpu_mask) +{ + cpumask_var_t candidate_mask; + unsigned int cpu, node; + int rc = -ENOSPC; + + if (!zalloc_cpumask_var(&candidate_mask, GFP_KERNEL)) + return -ENOMEM; + + cpumask_clear(*cpu_mask); + for (cpu = 0; cpu < nthreads; cpu++) + cpumask_set_cpu(cpu, *cpu_mask); + + BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask)); + + /* Get a bitmap of unoccupied slots. */ + cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask); + + if (assigned_node != NUMA_NO_NODE) { + /* + * Remove free ids previously assigned on the other nodes. We + * can walk only online nodes because once a node became online + * it is not turned offlined back. + */ + for_each_online_node(node) { + if (node == assigned_node) + continue; + cpumask_andnot(candidate_mask, candidate_mask, + node_recorded_ids_map[node]); + } + } + + if (cpumask_empty(candidate_mask)) + goto out; + + while (!cpumask_empty(*cpu_mask)) { + if (cpumask_subset(*cpu_mask, candidate_mask)) + /* Found a range where we can insert the new cpu(s) */ + break; + cpumask_shift_left(*cpu_mask, *cpu_mask, nthreads); + } + + if (!cpumask_empty(*cpu_mask)) + rc = 0; + +out: + free_cpumask_var(candidate_mask); + return rc; +} + /* * Update cpu_present_mask and paca(s) for a new cpu node. The wrinkle - * here is that a cpu device node may represent up to two logical cpus + * here is that a cpu device node may represent multiple logical cpus * in the SMT case. We must honor the assumption in other code that * the logical ids for sibling SMT threads x and y are adjacent, such * that x^1 == y and y^1 == x. */ static int pseries_add_processor(struct device_node *np) { - unsigned int cpu; - cpumask_var_t candidate_mask, tmp; - int err = -ENOSPC, len, nthreads, i; + int len, nthreads, node, cpu, assigned_node; + int rc = 0; + cpumask_var_t cpu_mask; const __be32 *intserv; intserv = of_get_property(np, "ibm,ppc-interrupt-server#s", &len); if (!intserv) return 0; - zalloc_cpumask_var(&candidate_mask, GFP_KERNEL); - zalloc_cpumask_var(&tmp, GFP_KERNEL); - nthreads = len / sizeof(u32); - for (i = 0; i < nthreads; i++) - cpumask_set_cpu(i, tmp); - cpu_maps_update_begin(); + if (!alloc_cpumask_var(&cpu_mask, GFP_KERNEL)) + return -ENOMEM; - BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask)); + /* + * Fetch from the DT nodes read by dlpar_configure_connector() the NUMA + * node id the added CPU belongs to. + */ + node = of_node_to_nid(np); + if (node < 0 || !node_possible(node)) + node = first_online_node; - /* Get a bitmap of unoccupied slots. */ - cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask); - if (cpumask_empty(candidate_mask)) { - /* If we get here, it most likely means that NR_CPUS is - * less than the partition's max processors setting. + BUG_ON(node == NUMA_NO_NODE); + assigned_node = node; + + cpu_maps_update_begin(); + + rc = find_cpu_id_range(nthreads, node, &cpu_mask); + if (rc && nr_node_ids > 1) { + /* + * Try again, considering the free CPU ids from the other node. */ - printk(KERN_ERR "Cannot add cpu %pOF; this system configuration" - " supports %d logical cpus.\n", np, - num_possible_cpus()); - goto out_unlock; + node = NUMA_NO_NODE; + rc = find_cpu_id_range(nthreads, NUMA_NO_NODE, &cpu_mask); } - while (!cpumask_empty(tmp)) - if (cpumask_subset(tmp, candidate_mask)) - /* Found a range where we can insert the new cpu(s) */ - break; - else - cpumask_shift_left(tmp, tmp, nthreads); - - if (cpumask_empty(tmp)) { - printk(KERN_ERR "Unable to find space in cpu_present_mask for" - " processor %pOFn with %d thread(s)\n", np, - nthreads); - goto out_unlock; + if (rc) { + pr_err("Cannot add cpu %pOF; this system configuration" + " supports %d logical cpus.\n", np, num_possible_cpus()); + goto out; } - for_each_cpu(cpu, tmp) { + for_each_cpu(cpu, cpu_mask) { BUG_ON(cpu_present(cpu)); set_cpu_present(cpu, true); set_hard_smp_processor_id(cpu, be32_to_cpu(*intserv++)); } - err = 0; -out_unlock: + + /* Record the newly used CPU ids for the associate node. */ + cpumask_or(node_recorded_ids_map[assigned_node], + node_recorded_ids_map[assigned_node], cpu_mask); + + /* + * If node is set to NUMA_NO_NODE, CPU ids have be reused from + * another node, remove them from its mask. + */ + if (node == NUMA_NO_NODE) { + cpu = cpumask_first(cpu_mask); + pr_warn("Reusing free CPU ids %d-%d from another node\n", + cpu, cpu + nthreads - 1); + for_each_online_node(node) { + if (node == assigned_node) + continue; + cpumask_andnot(node_recorded_ids_map[node], + node_recorded_ids_map[node], + cpu_mask); + } + } + +out: cpu_maps_update_done(); - free_cpumask_var(candidate_mask); - free_cpumask_var(tmp); - return err; + free_cpumask_var(cpu_mask); + return rc; } /* @@ -908,6 +990,7 @@ static struct notifier_block pseries_smp_nb = { static int __init pseries_cpu_hotplug_init(void) { int qcss_tok; + unsigned int node; #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE ppc_md.cpu_probe = dlpar_cpu_probe; @@ -929,8 +1012,18 @@ static int __init pseries_cpu_hotplug_init(void) smp_ops->cpu_die = pseries_cpu_die; /* Processors can be added/removed only on LPAR */ - if (firmware_has_feature(FW_FEATURE_LPAR)) + if (firmware_has_feature(FW_FEATURE_LPAR)) { + for_each_node(node) { + alloc_bootmem_cpumask_var(&node_recorded_ids_map[node]); + + /* Record ids of CPU added at boot time */ + cpumask_or(node_recorded_ids_map[node], + node_recorded_ids_map[node], + node_to_cpumask_map[node]); + } + of_reconfig_notifier_register(&pseries_smp_nb); + } return 0; } -- cgit v1.2.3-70-g09d2 From c00103abf76fd3916596afd07dd3fdeee0dca15d Mon Sep 17 00:00:00 2001 From: kernel test robot Date: Tue, 3 Aug 2021 16:59:55 +0200 Subject: powerpc/kexec: fix for_each_child.cocci warning for_each_node_by_type should have of_node_put() before return. Generated by: scripts/coccinelle/iterators/for_each_child.cocci Reported-by: kernel test robot Signed-off-by: kernel test robot Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2108031654080.17639@hadrien --- arch/powerpc/kexec/core_64.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kexec/core_64.c b/arch/powerpc/kexec/core_64.c index 84618d3c8013..89c069d664a5 100644 --- a/arch/powerpc/kexec/core_64.c +++ b/arch/powerpc/kexec/core_64.c @@ -64,8 +64,10 @@ int default_machine_kexec_prepare(struct kimage *image) begin = image->segment[i].mem; end = begin + image->segment[i].memsz; - if ((begin < high) && (end > low)) + if ((begin < high) && (end > low)) { + of_node_put(node); return -ETXTBSY; + } } } -- cgit v1.2.3-70-g09d2 From 5ae36401ca4ea2737d779ce7c267444b16530001 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 3 Aug 2021 16:15:46 +0200 Subject: powerpc: Replace deprecated CPU-hotplug functions. The functions get_online_cpus() and put_online_cpus() have been deprecated during the CPU hotplug rework. They map directly to cpus_read_lock() and cpus_read_unlock(). Replace deprecated CPU-hotplug functions with the official version. The behavior remains unchanged. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210803141621.780504-4-bigeasy@linutronix.de --- arch/powerpc/kernel/rtasd.c | 4 ++-- arch/powerpc/kvm/book3s_hv_builtin.c | 10 +++++----- arch/powerpc/platforms/powernv/idle.c | 4 ++-- arch/powerpc/platforms/powernv/opal-imc.c | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 8561dfb33f24..32ee17753eb4 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -429,7 +429,7 @@ static void rtas_event_scan(struct work_struct *w) do_event_scan(); - get_online_cpus(); + cpus_read_lock(); /* raw_ OK because just using CPU as starting point. */ cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask); @@ -451,7 +451,7 @@ static void rtas_event_scan(struct work_struct *w) schedule_delayed_work_on(cpu, &event_scan_work, __round_jiffies_relative(event_scan_delay, cpu)); - put_online_cpus(); + cpus_read_unlock(); } #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index be8ef1c5b1bf..fcf4760a3a0e 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -137,23 +137,23 @@ long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target, * exist in the system. We use a counter of VMs to track this. * * One of the operations we need to block is onlining of secondaries, so we - * protect hv_vm_count with get/put_online_cpus(). + * protect hv_vm_count with cpus_read_lock/unlock(). */ static atomic_t hv_vm_count; void kvm_hv_vm_activated(void) { - get_online_cpus(); + cpus_read_lock(); atomic_inc(&hv_vm_count); - put_online_cpus(); + cpus_read_unlock(); } EXPORT_SYMBOL_GPL(kvm_hv_vm_activated); void kvm_hv_vm_deactivated(void) { - get_online_cpus(); + cpus_read_lock(); atomic_dec(&hv_vm_count); - put_online_cpus(); + cpus_read_unlock(); } EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated); diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 528a7e0cf83a..aa27689b832d 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -199,12 +199,12 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev, */ power7_fastsleep_workaround_exit = false; - get_online_cpus(); + cpus_read_lock(); primary_thread_mask = cpu_online_cores_map(); on_each_cpu_mask(&primary_thread_mask, pnv_fastsleep_workaround_apply, &err, 1); - put_online_cpus(); + cpus_read_unlock(); if (err) { pr_err("fastsleep_workaround_applyonce change failed while running pnv_fastsleep_workaround_apply"); goto fail; diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index 7824cc364bc4..ba02a75c1410 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -186,7 +186,7 @@ static void disable_nest_pmu_counters(void) int nid, cpu; const struct cpumask *l_cpumask; - get_online_cpus(); + cpus_read_lock(); for_each_node_with_cpus(nid) { l_cpumask = cpumask_of_node(nid); cpu = cpumask_first_and(l_cpumask, cpu_online_mask); @@ -195,7 +195,7 @@ static void disable_nest_pmu_counters(void) opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, get_hard_smp_processor_id(cpu)); } - put_online_cpus(); + cpus_read_unlock(); } static void disable_core_pmu_counters(void) @@ -203,7 +203,7 @@ static void disable_core_pmu_counters(void) cpumask_t cores_map; int cpu, rc; - get_online_cpus(); + cpus_read_lock(); /* Disable the IMC Core functions */ cores_map = cpu_online_cores_map(); for_each_cpu(cpu, &cores_map) { @@ -213,7 +213,7 @@ static void disable_core_pmu_counters(void) pr_err("%s: Failed to stop Core (cpu = %d)\n", __FUNCTION__, cpu); } - put_online_cpus(); + cpus_read_unlock(); } int get_max_nest_dev(void) -- cgit v1.2.3-70-g09d2 From 27fd1111051dc218e5b6cb2da5dbb3f342879ff1 Mon Sep 17 00:00:00 2001 From: Jordan Niethe Date: Wed, 4 Aug 2021 11:37:24 +1000 Subject: powerpc: Always inline radix_enabled() to fix build failure This is the same as commit acdad8fb4a15 ("powerpc: Force inlining of mmu_has_feature to fix build failure") but for radix_enabled(). The config in the linked bugzilla causes the following build failure: LD .tmp_vmlinux.kallsyms1 powerpc64-linux-ld: arch/powerpc/mm/pgtable.o: in function `.__ptep_set_access_flags': pgtable.c:(.text+0x17c): undefined reference to `.radix__ptep_set_access_flags' powerpc64-linux-ld: arch/powerpc/mm/pageattr.o: in function `.change_page_attr': pageattr.c:(.text+0xc0): undefined reference to `.radix__flush_tlb_kernel_range' etc. This is due to radix_enabled() not being inlined. See extract from building with -Winline: In file included from arch/powerpc/include/asm/lppaca.h:46, from arch/powerpc/include/asm/paca.h:17, from arch/powerpc/include/asm/current.h:13, from include/linux/thread_info.h:23, from include/asm-generic/preempt.h:5, from ./arch/powerpc/include/generated/asm/preempt.h:1, from include/linux/preempt.h:78, from include/linux/spinlock.h:51, from include/linux/mmzone.h:8, from include/linux/gfp.h:6, from arch/powerpc/mm/pgtable.c:21: arch/powerpc/include/asm/book3s/64/pgtable.h: In function '__ptep_set_access_flags': arch/powerpc/include/asm/mmu.h:327:20: error: inlining failed in call to 'radix_enabled': call is unlikely and code size would grow [-Werror=inline] The code relies on constant folding of MMU_FTRS_POSSIBLE at buildtime and elimination of non possible parts of code at compile time. For this to work radix_enabled() must be inlined so make it __always_inline. Reported-by: Erhard F. Suggested-by: Michael Ellerman Tested-by: Randy Dunlap Signed-off-by: Jordan Niethe [mpe: Trimmed error messages in change log] Signed-off-by: Michael Ellerman Link: https://bugzilla.kernel.org/show_bug.cgi?id=213803 Link: https://lore.kernel.org/r/20210804013724.514468-1-jniethe5@gmail.com --- arch/powerpc/include/asm/mmu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 27016b98ecb2..8abe8e42e045 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -324,7 +324,7 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) } #endif /* !CONFIG_DEBUG_VM */ -static inline bool radix_enabled(void) +static __always_inline bool radix_enabled(void) { return mmu_has_feature(MMU_FTR_TYPE_RADIX); } -- cgit v1.2.3-70-g09d2 From 9b49f979b3d560cb75ea9f1a596baf432d566798 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 5 Aug 2021 11:20:05 +1000 Subject: powerpc/configs: Disable legacy ptys on microwatt defconfig We shouldn't need legacy ptys, and disabling the option improves boot time by about 0.5 seconds. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210805112005.3cb1f412@kryten.localdomain --- arch/powerpc/configs/microwatt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/configs/microwatt_defconfig b/arch/powerpc/configs/microwatt_defconfig index a08b739123da..ebc90aefbc0c 100644 --- a/arch/powerpc/configs/microwatt_defconfig +++ b/arch/powerpc/configs/microwatt_defconfig @@ -57,6 +57,7 @@ CONFIG_NETDEVICES=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set +# CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y -- cgit v1.2.3-70-g09d2 From 2ac78e0c00184a9ba53d507be7549c69a3f566b6 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 5 Aug 2021 17:56:49 +1000 Subject: KVM: PPC: Use arch_get_random_seed_long instead of powernv variant The powernv_get_random_long() does not work in nested KVM (which is pseries) and produces a crash when accessing in_be64(rng->regs) in powernv_get_random_long(). This replaces powernv_get_random_long with the ppc_md machine hook wrapper. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Fabiano Rosas Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210805075649.2086567-1-aik@ozlabs.ru --- arch/powerpc/kvm/book3s_hv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 085fb8ecbf68..9f957ceee58a 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1165,7 +1165,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) break; #endif case H_RANDOM: - if (!powernv_get_random_long(&vcpu->arch.regs.gpr[4])) + if (!arch_get_random_seed_long(&vcpu->arch.regs.gpr[4])) ret = H_HARDWARE; break; case H_RPT_INVALIDATE: -- cgit v1.2.3-70-g09d2 From 786e5b102a0007d81579822eac23cb5bfaa0b65f Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:19 +0200 Subject: powerpc/pseries/pci: Introduce __find_pe_total_msi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will help to size the PCI MSI domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-2-clg@kaod.org --- arch/powerpc/platforms/pseries/msi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 637300330507..d2d090e04745 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -164,12 +164,12 @@ static int check_req_msix(struct pci_dev *pdev, int nvec) /* Quota calculation */ -static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) +static struct device_node *__find_pe_total_msi(struct device_node *node, int *total) { struct device_node *dn; const __be32 *p; - dn = of_node_get(pci_device_to_OF_node(dev)); + dn = of_node_get(node); while (dn) { p = of_get_property(dn, "ibm,pe-total-#msi", NULL); if (p) { @@ -185,6 +185,11 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) return NULL; } +static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) +{ + return __find_pe_total_msi(pci_device_to_OF_node(dev), total); +} + static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) { struct device_node *dn; -- cgit v1.2.3-70-g09d2 From e81202007363bd694b711f307f02320b5f98edaa Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:20 +0200 Subject: powerpc/pseries/pci: Introduce rtas_prepare_msi_irqs() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This splits the routine setting the MSIs in two parts: allocation of MSIs for the PCI device at the FW level (RTAS) and the actual mapping and activation of the IRQs. rtas_prepare_msi_irqs() will serve as a handler for the PCI MSI domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-3-clg@kaod.org --- arch/powerpc/platforms/pseries/msi.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index d2d090e04745..4bf14f27e1aa 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -373,12 +373,11 @@ static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0); } -static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) +static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type, + msi_alloc_info_t *arg) { struct pci_dn *pdn; - int hwirq, virq, i, quota, rc; - struct msi_desc *entry; - struct msi_msg msg; + int quota, rc; int nvec = nvec_in; int use_32bit_msi_hack = 0; @@ -456,6 +455,22 @@ again: return rc; } + return 0; +} + +static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) +{ + struct pci_dn *pdn; + int hwirq, virq, i; + int rc; + struct msi_desc *entry; + struct msi_msg msg; + + rc = rtas_prepare_msi_irqs(pdev, nvec_in, type, NULL); + if (rc) + return rc; + + pdn = pci_get_pdn(pdev); i = 0; for_each_pci_msi_entry(entry, pdev) { hwirq = rtas_query_irq_number(pdn, i++); -- cgit v1.2.3-70-g09d2 From 14be098c5387eb93b794f299f3c3e2ddf6038ec7 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:21 +0200 Subject: powerpc/xive: Add support for IRQ domain hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds handlers to allocate/free IRQs in a domain hierarchy. We could try to use xive_irq_domain_map() in xive_irq_domain_alloc() but we rely on xive_irq_alloc_data() to set the IRQ handler data and duplicating the code is simpler. xive_irq_free_data() needs to be called when IRQ are freed to clear the MMIO mappings and free the XIVE handler data, xive_irq_data structure. This is going to be a problem with MSI domains which we will address later. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-4-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index dbdbbc2f1dc5..420d96deb7b6 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1366,7 +1366,71 @@ static void xive_irq_domain_debug_show(struct seq_file *m, struct irq_domain *d, } #endif +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +static int xive_irq_domain_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + unsigned long *hwirq, + unsigned int *type) +{ + return xive_irq_domain_xlate(d, to_of_node(fwspec->fwnode), + fwspec->param, fwspec->param_count, + hwirq, type); +} + +static int xive_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_fwspec *fwspec = arg; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + int i, rc; + + rc = xive_irq_domain_translate(domain, fwspec, &hwirq, &type); + if (rc) + return rc; + + pr_debug("%s %d/%lx #%d\n", __func__, virq, hwirq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) { + /* TODO: call xive_irq_domain_map() */ + + /* + * Mark interrupts as edge sensitive by default so that resend + * actually works. Will fix that up below if needed. + */ + irq_clear_status_flags(virq, IRQ_LEVEL); + + /* allocates and sets handler data */ + rc = xive_irq_alloc_data(virq + i, hwirq + i); + if (rc) + return rc; + + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &xive_irq_chip, domain->host_data); + irq_set_handler(virq + i, handle_fasteoi_irq); + } + + return 0; +} + +static void xive_irq_domain_free(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs) +{ + int i; + + pr_debug("%s %d #%d\n", __func__, virq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) + xive_irq_free_data(virq + i); +} +#endif + static const struct irq_domain_ops xive_irq_domain_ops = { +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY + .alloc = xive_irq_domain_alloc, + .free = xive_irq_domain_free, + .translate = xive_irq_domain_translate, +#endif .match = xive_irq_domain_match, .map = xive_irq_domain_map, .unmap = xive_irq_domain_unmap, -- cgit v1.2.3-70-g09d2 From 6c2ab2a5d634d4e30445ee5d52d5d1469bf74aa2 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:22 +0200 Subject: powerpc/xive: Ease debugging of xive_irq_set_affinity() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pr_debug() is easier to activate and it helps to know how the kernel configures the HW when tweaking the IRQ subsystem. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-5-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 420d96deb7b6..823f9fe3542a 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -713,7 +713,7 @@ static int xive_irq_set_affinity(struct irq_data *d, u32 target, old_target; int rc = 0; - pr_devel("xive_irq_set_affinity: irq %d\n", d->irq); + pr_debug("%s: irq %d/%x\n", __func__, d->irq, hw_irq); /* Is this valid ? */ if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) @@ -758,7 +758,7 @@ static int xive_irq_set_affinity(struct irq_data *d, return rc; } - pr_devel(" target: 0x%x\n", target); + pr_debug(" target: 0x%x\n", target); xd->target = target; /* Give up previous target */ -- cgit v1.2.3-70-g09d2 From a5f3d2c17b07e69166b93209f34a5fb8271a6810 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:23 +0200 Subject: powerpc/pseries/pci: Add MSI domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two IRQ domains are added on top of default machine IRQ domain. First, the top level "pSeries-PCI-MSI" domain deals with the MSI specificities. In this domain, the HW IRQ numbers are generated by the PCI MSI layer, they compose a unique ID for an MSI source with the PCI device identifier and the MSI vector number. These numbers can be quite large on a pSeries machine running under the IBM Hypervisor and /sys/kernel/irq/ and /proc/interrupts will require small fixes to show them correctly. Second domain is the in-the-middle "pSeries-MSI" domain which acts as a proxy between the PCI MSI subsystem and the machine IRQ subsystem. It usually allocate the MSI vector numbers but, on pSeries machines, this is done by the RTAS FW and RTAS returns IRQ numbers in the IRQ number space of the machine. This is why the in-the-middle "pSeries-MSI" domain has the same HW IRQ numbers as its parent domain. Only the XIVE (P9/P10) parent domain is supported for now. We still need to add support for IRQ domain hierarchy under XICS. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-6-clg@kaod.org --- arch/powerpc/include/asm/pci-bridge.h | 5 + arch/powerpc/kernel/pci-common.c | 6 + arch/powerpc/platforms/pseries/msi.c | 185 +++++++++++++++++++++++++++++++ arch/powerpc/platforms/pseries/pseries.h | 1 + arch/powerpc/platforms/pseries/setup.c | 2 + 5 files changed, 199 insertions(+) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 74424c14515c..90f488fa4c17 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -126,6 +126,11 @@ struct pci_controller { #endif /* CONFIG_PPC64 */ void *private_data; + + /* IRQ domain hierarchy */ + struct irq_domain *dev_domain; + struct irq_domain *msi_domain; + struct fwnode_handle *fwnode; }; /* These are used for config access before all the PCI probing diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 001e90cd8948..c3573430919d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1060,11 +1061,16 @@ void pcibios_bus_add_device(struct pci_dev *dev) int pcibios_add_device(struct pci_dev *dev) { + struct irq_domain *d; + #ifdef CONFIG_PCI_IOV if (ppc_md.pcibios_fixup_sriov) ppc_md.pcibios_fixup_sriov(dev); #endif /* CONFIG_PCI_IOV */ + d = dev_get_msi_domain(&dev->bus->dev); + if (d) + dev_set_msi_domain(&dev->dev, d); return 0; } diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 4bf14f27e1aa..86c6809ebac2 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "pseries.h" @@ -518,6 +519,190 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) return 0; } +static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev, + int nvec, msi_alloc_info_t *arg) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct msi_desc *desc = first_pci_msi_entry(pdev); + int type = desc->msi_attrib.is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI; + + return rtas_prepare_msi_irqs(pdev, nvec, type, arg); +} + +static struct msi_domain_ops pseries_pci_msi_domain_ops = { + .msi_prepare = pseries_msi_ops_prepare, +}; + +static void pseries_msi_shutdown(struct irq_data *d) +{ + d = d->parent_data; + if (d->chip->irq_shutdown) + d->chip->irq_shutdown(d); +} + +static void pseries_msi_mask(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void pseries_msi_unmask(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip pseries_pci_msi_irq_chip = { + .name = "pSeries-PCI-MSI", + .irq_shutdown = pseries_msi_shutdown, + .irq_mask = pseries_msi_mask, + .irq_unmask = pseries_msi_unmask, + .irq_eoi = irq_chip_eoi_parent, +}; + +static struct msi_domain_info pseries_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), + .ops = &pseries_pci_msi_domain_ops, + .chip = &pseries_pci_msi_irq_chip, +}; + +static void pseries_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) +{ + __pci_read_msi_msg(irq_data_get_msi_desc(data), msg); +} + +static struct irq_chip pseries_msi_irq_chip = { + .name = "pSeries-MSI", + .irq_shutdown = pseries_msi_shutdown, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_compose_msi_msg = pseries_msi_compose_msg, +}; + +static int pseries_irq_parent_domain_alloc(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + struct irq_fwspec parent_fwspec; + int ret; + + parent_fwspec.fwnode = domain->parent->fwnode; + parent_fwspec.param_count = 2; + parent_fwspec.param[0] = hwirq; + parent_fwspec.param[1] = IRQ_TYPE_EDGE_RISING; + + ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec); + if (ret) + return ret; + + return 0; +} + +static int pseries_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct pci_controller *phb = domain->host_data; + msi_alloc_info_t *info = arg; + struct msi_desc *desc = info->desc; + struct pci_dev *pdev = msi_desc_to_pci_dev(desc); + int hwirq; + int i, ret; + + hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->msi_attrib.entry_nr); + if (hwirq < 0) { + dev_err(&pdev->dev, "Failed to query HW IRQ: %d\n", hwirq); + return hwirq; + } + + dev_dbg(&pdev->dev, "%s bridge %pOF %d/%x #%d\n", __func__, + phb->dn, virq, hwirq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) { + ret = pseries_irq_parent_domain_alloc(domain, virq + i, hwirq + i); + if (ret) + goto out; + + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &pseries_msi_irq_chip, domain->host_data); + } + + return 0; + +out: + /* TODO: handle RTAS cleanup in ->msi_finish() ? */ + irq_domain_free_irqs_parent(domain, virq, i - 1); + return ret; +} + +static void pseries_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct pci_controller *phb = irq_data_get_irq_chip_data(d); + + pr_debug("%s bridge %pOF %d #%d\n", __func__, phb->dn, virq, nr_irqs); + + irq_domain_free_irqs_parent(domain, virq, nr_irqs); +} + +static const struct irq_domain_ops pseries_irq_domain_ops = { + .alloc = pseries_irq_domain_alloc, + .free = pseries_irq_domain_free, +}; + +static int __pseries_msi_allocate_domains(struct pci_controller *phb, + unsigned int count) +{ + struct irq_domain *parent = irq_get_default_host(); + + phb->fwnode = irq_domain_alloc_named_id_fwnode("pSeries-MSI", + phb->global_number); + if (!phb->fwnode) + return -ENOMEM; + + phb->dev_domain = irq_domain_create_hierarchy(parent, 0, count, + phb->fwnode, + &pseries_irq_domain_ops, phb); + if (!phb->dev_domain) { + pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n", + phb->dn, phb->global_number); + irq_domain_free_fwnode(phb->fwnode); + return -ENOMEM; + } + + phb->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(phb->dn), + &pseries_msi_domain_info, + phb->dev_domain); + if (!phb->msi_domain) { + pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n", + phb->dn, phb->global_number); + irq_domain_free_fwnode(phb->fwnode); + irq_domain_remove(phb->dev_domain); + return -ENOMEM; + } + + return 0; +} + +int pseries_msi_allocate_domains(struct pci_controller *phb) +{ + int count; + + /* Only supported by the XIVE driver */ + if (!xive_enabled()) + return -ENODEV; + + if (!__find_pe_total_msi(phb->dn, &count)) { + pr_err("PCI: failed to find MSIs for bridge %pOF (domain %d)\n", + phb->dn, phb->global_number); + return -ENOSPC; + } + + return __pseries_msi_allocate_domains(phb, count); +} + static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev) { /* No LSI -> leave MSIs (if any) configured */ diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 1f051a786fb3..d9280262588b 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -85,6 +85,7 @@ struct pci_host_bridge; int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); extern struct pci_controller_ops pseries_pci_controller_ops; +int pseries_msi_allocate_domains(struct pci_controller *phb); unsigned long pseries_memory_block_size(void); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 631a0d57b6cd..35724caf8a83 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -486,6 +486,8 @@ static void __init pSeries_discover_phbs(void) /* create pci_dn's for DT nodes under this PHB */ pci_devs_phb_init_dynamic(phb); + + pseries_msi_allocate_domains(phb); } of_node_put(root); -- cgit v1.2.3-70-g09d2 From 5690bcae186084a8544b1819f0d89399268bd0cf Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:24 +0200 Subject: powerpc/xive: Drop unmask of MSIs at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That was a workaround in the XIVE domain because of the lack of MSI domain. This is now handled. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-7-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 823f9fe3542a..356f584cc51b 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -616,16 +616,6 @@ static unsigned int xive_irq_startup(struct irq_data *d) pr_devel("xive_irq_startup: irq %d [0x%x] data @%p\n", d->irq, hw_irq, d); -#ifdef CONFIG_PCI_MSI - /* - * The generic MSI code returns with the interrupt disabled on the - * card, using the MSI mask bits. Firmware doesn't appear to unmask - * at that level, so we do it here by hand. - */ - if (irq_data_get_msi_desc(d)) - pci_msi_unmask_irq(d); -#endif - /* Pick a target */ target = xive_pick_irq_target(d, irq_data_get_affinity_mask(d)); if (target == XIVE_INVALID_TARGET) { -- cgit v1.2.3-70-g09d2 From 292145a6e598c1e6633b8f5f607706b46f552ab9 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:25 +0200 Subject: powerpc/xive: Remove irqd_is_started() check when setting the affinity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the early days of XIVE support, commit cffb717ceb8e ("powerpc/xive: Ensure active irqd when setting affinity") tried to fix an issue related to interrupt migration. If the root cause was related to CPU unplug, it should have been fixed and there is no reason to keep the irqd_is_started() check. This test is also breaking affinity setting of MSIs which can set before starting the associated IRQ. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-8-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 356f584cc51b..0631c97b3a14 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -709,10 +709,6 @@ static int xive_irq_set_affinity(struct irq_data *d, if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) return -EINVAL; - /* Don't do anything if the interrupt isn't started */ - if (!irqd_is_started(d)) - return IRQ_SET_MASK_OK; - /* * If existing target is already in the new mask, and is * online then do nothing. -- cgit v1.2.3-70-g09d2 From 07817a578a7a79638537480b8847dc7a12f293c5 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:26 +0200 Subject: powerpc/pseries/pci: Add a domain_free_irqs() handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RTAS firmware can not disable one MSI at a time. It's all or nothing. We need a custom free IRQ handler for that. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-9-clg@kaod.org --- arch/powerpc/platforms/pseries/msi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 86c6809ebac2..591cee9cbc9e 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -529,8 +529,24 @@ static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev return rtas_prepare_msi_irqs(pdev, nvec, type, arg); } +/* + * RTAS can not disable one MSI at a time. It's all or nothing. Do it + * at the end after all IRQs have been freed. + */ +static void pseries_msi_domain_free_irqs(struct irq_domain *domain, + struct device *dev) +{ + if (WARN_ON_ONCE(!dev_is_pci(dev))) + return; + + __msi_domain_free_irqs(domain, dev); + + rtas_disable_msi(to_pci_dev(dev)); +} + static struct msi_domain_ops pseries_pci_msi_domain_ops = { .msi_prepare = pseries_msi_ops_prepare, + .domain_free_irqs = pseries_msi_domain_free_irqs, }; static void pseries_msi_shutdown(struct irq_data *d) -- cgit v1.2.3-70-g09d2 From 9a014f456881e947bf8cdd8c984a207097e6c096 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:27 +0200 Subject: powerpc/pseries/pci: Add a msi_free() handler to clear XIVE data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MSI domain clears the IRQ with msi_domain_free(), which calls irq_domain_free_irqs_top(), which clears the handler data. This is a problem for the XIVE controller since we need to unmap MMIO pages and free a specific XIVE structure. The 'msi_free()' handler is called before irq_domain_free_irqs_top() when the handler data is still available. Use that to clear the XIVE controller data. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-10-clg@kaod.org --- arch/powerpc/include/asm/xive.h | 1 + arch/powerpc/platforms/pseries/msi.c | 16 +++++++++++++++- arch/powerpc/sysdev/xive/common.c | 5 ++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index aa094a8655b0..20ae50ab083c 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -111,6 +111,7 @@ void xive_native_free_vp_block(u32 vp_base); int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data); void xive_cleanup_irq_data(struct xive_irq_data *xd); +void xive_irq_free_data(unsigned int virq); void xive_native_free_irq(u32 irq); int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq); diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 591cee9cbc9e..f9635b01b2bf 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -529,6 +529,19 @@ static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev return rtas_prepare_msi_irqs(pdev, nvec, type, arg); } +/* + * ->msi_free() is called before irq_domain_free_irqs_top() when the + * handler data is still available. Use that to clear the XIVE + * controller data. + */ +static void pseries_msi_ops_msi_free(struct irq_domain *domain, + struct msi_domain_info *info, + unsigned int irq) +{ + if (xive_enabled()) + xive_irq_free_data(irq); +} + /* * RTAS can not disable one MSI at a time. It's all or nothing. Do it * at the end after all IRQs have been freed. @@ -546,6 +559,7 @@ static void pseries_msi_domain_free_irqs(struct irq_domain *domain, static struct msi_domain_ops pseries_pci_msi_domain_ops = { .msi_prepare = pseries_msi_ops_prepare, + .msi_free = pseries_msi_ops_msi_free, .domain_free_irqs = pseries_msi_domain_free_irqs, }; @@ -660,7 +674,7 @@ static void pseries_irq_domain_free(struct irq_domain *domain, unsigned int virq pr_debug("%s bridge %pOF %d #%d\n", __func__, phb->dn, virq, nr_irqs); - irq_domain_free_irqs_parent(domain, virq, nr_irqs); + /* XIVE domain data is cleared through ->msi_free() */ } static const struct irq_domain_ops pseries_irq_domain_ops = { diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 0631c97b3a14..107f442d3411 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -975,6 +975,8 @@ EXPORT_SYMBOL_GPL(is_xive_irq); void xive_cleanup_irq_data(struct xive_irq_data *xd) { + pr_debug("%s for HW %x\n", __func__, xd->hw_irq); + if (xd->eoi_mmio) { iounmap(xd->eoi_mmio); if (xd->eoi_mmio == xd->trig_mmio) @@ -1016,7 +1018,7 @@ static int xive_irq_alloc_data(unsigned int virq, irq_hw_number_t hw) return 0; } -static void xive_irq_free_data(unsigned int virq) +void xive_irq_free_data(unsigned int virq) { struct xive_irq_data *xd = irq_get_handler_data(virq); @@ -1026,6 +1028,7 @@ static void xive_irq_free_data(unsigned int virq) xive_cleanup_irq_data(xd); kfree(xd); } +EXPORT_SYMBOL_GPL(xive_irq_free_data); #ifdef CONFIG_SMP -- cgit v1.2.3-70-g09d2 From 174db9e7f775ce06fc6949c9abbe758b3eb8171c Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:28 +0200 Subject: powerpc/pseries/pci: Add support of MSI domains to PHB hotplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simply allocate or release the MSI domains when a PHB is inserted in or removed from the machine. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-11-clg@kaod.org --- arch/powerpc/platforms/pseries/msi.c | 10 ++++++++++ arch/powerpc/platforms/pseries/pci_dlpar.c | 4 ++++ arch/powerpc/platforms/pseries/pseries.h | 1 + 3 files changed, 15 insertions(+) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index f9635b01b2bf..e2127a3f7ebd 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -733,6 +733,16 @@ int pseries_msi_allocate_domains(struct pci_controller *phb) return __pseries_msi_allocate_domains(phb, count); } +void pseries_msi_free_domains(struct pci_controller *phb) +{ + if (phb->msi_domain) + irq_domain_remove(phb->msi_domain); + if (phb->dev_domain) + irq_domain_remove(phb->dev_domain); + if (phb->fwnode) + irq_domain_free_fwnode(phb->fwnode); +} + static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev) { /* No LSI -> leave MSIs (if any) configured */ diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index a8f9140a24fa..90c9d3531694 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -33,6 +33,8 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) pci_devs_phb_init_dynamic(phb); + pseries_msi_allocate_domains(phb); + /* Create EEH devices for the PHB */ eeh_phb_pe_create(phb); @@ -74,6 +76,8 @@ int remove_phb_dynamic(struct pci_controller *phb) } } + pseries_msi_free_domains(phb); + /* Remove the PCI bus and unregister the bridge device from sysfs */ phb->bus = NULL; pci_remove_bus(b); diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index d9280262588b..3544778e06d0 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -86,6 +86,7 @@ int pseries_root_bridge_prepare(struct pci_host_bridge *bridge); extern struct pci_controller_ops pseries_pci_controller_ops; int pseries_msi_allocate_domains(struct pci_controller *phb); +void pseries_msi_free_domains(struct pci_controller *phb); unsigned long pseries_memory_block_size(void); -- cgit v1.2.3-70-g09d2 From 2c50d7e99e39eba92b93210e740f3f9e5a06ba54 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:29 +0200 Subject: powerpc/powernv/pci: Introduce __pnv_pci_ioda_msi_setup() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It will be used as a 'compose_msg' handler of the MSI domain introduced later. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-12-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7de464679292..2922674cc934 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2016,15 +2016,17 @@ bool is_pnv_opal_msi(struct irq_chip *chip) } EXPORT_SYMBOL_GPL(is_pnv_opal_msi); -static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int virq, - unsigned int is_64, struct msi_msg *msg) +static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, + unsigned int xive_num, + unsigned int is_64, struct msi_msg *msg) { struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); - unsigned int xive_num = hwirq - phb->msi_base; __be32 data; int rc; + dev_dbg(&dev->dev, "%s: setup %s-bit MSI for vector #%d\n", __func__, + is_64 ? "64" : "32", xive_num); + /* No PE assigned ? bail out ... no MSI for you ! */ if (pe == NULL) return -ENXIO; @@ -2072,12 +2074,28 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, } msg->data = be32_to_cpu(data); + return 0; +} + +static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, + unsigned int hwirq, unsigned int virq, + unsigned int is_64, struct msi_msg *msg) +{ + struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); + unsigned int xive_num = hwirq - phb->msi_base; + int rc; + + rc = __pnv_pci_ioda_msi_setup(phb, dev, xive_num, is_64, msg); + if (rc) + return rc; + + /* P8 only */ pnv_set_msi_irq_chip(phb, virq); pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," " address=%x_%08x data=%x PE# %x\n", pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, - msg->address_hi, msg->address_lo, data, pe->pe_number); + msg->address_hi, msg->address_lo, msg->data, pe->pe_number); return 0; } -- cgit v1.2.3-70-g09d2 From 0fcfe2247e75070361af2b6845030cada92cdbf8 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:30 +0200 Subject: powerpc/powernv/pci: Add MSI domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is very similar to the MSI domains of the pSeries platform. The MSI allocator is directly handled under the Linux PHB in the in-the-middle "PNV-MSI" domain. Only the XIVE (P9/P10) parent domain is supported for now. Support for XICS will come later. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-13-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 188 ++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 2922674cc934..d2a17fcb6002 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -2100,6 +2101,189 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, return 0; } +/* + * The msi_free() op is called before irq_domain_free_irqs_top() when + * the handler data is still available. Use that to clear the XIVE + * controller. + */ +static void pnv_msi_ops_msi_free(struct irq_domain *domain, + struct msi_domain_info *info, + unsigned int irq) +{ + if (xive_enabled()) + xive_irq_free_data(irq); +} + +static struct msi_domain_ops pnv_pci_msi_domain_ops = { + .msi_free = pnv_msi_ops_msi_free, +}; + +static void pnv_msi_shutdown(struct irq_data *d) +{ + d = d->parent_data; + if (d->chip->irq_shutdown) + d->chip->irq_shutdown(d); +} + +static void pnv_msi_mask(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} + +static void pnv_msi_unmask(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip pnv_pci_msi_irq_chip = { + .name = "PNV-PCI-MSI", + .irq_shutdown = pnv_msi_shutdown, + .irq_mask = pnv_msi_mask, + .irq_unmask = pnv_msi_unmask, + .irq_eoi = irq_chip_eoi_parent, +}; + +static struct msi_domain_info pnv_msi_domain_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX), + .ops = &pnv_pci_msi_domain_ops, + .chip = &pnv_pci_msi_irq_chip, +}; + +static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg) +{ + struct msi_desc *entry = irq_data_get_msi_desc(d); + struct pci_dev *pdev = msi_desc_to_pci_dev(entry); + struct pci_controller *hose = irq_data_get_irq_chip_data(d); + struct pnv_phb *phb = hose->private_data; + int rc; + + rc = __pnv_pci_ioda_msi_setup(phb, pdev, d->hwirq, + entry->msi_attrib.is_64, msg); + if (rc) + dev_err(&pdev->dev, "Failed to setup %s-bit MSI #%ld : %d\n", + entry->msi_attrib.is_64 ? "64" : "32", d->hwirq, rc); +} + +static struct irq_chip pnv_msi_irq_chip = { + .name = "PNV-MSI", + .irq_shutdown = pnv_msi_shutdown, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_compose_msi_msg = pnv_msi_compose_msg, +}; + +static int pnv_irq_parent_domain_alloc(struct irq_domain *domain, + unsigned int virq, int hwirq) +{ + struct irq_fwspec parent_fwspec; + int ret; + + parent_fwspec.fwnode = domain->parent->fwnode; + parent_fwspec.param_count = 2; + parent_fwspec.param[0] = hwirq; + parent_fwspec.param[1] = IRQ_TYPE_EDGE_RISING; + + ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec); + if (ret) + return ret; + + return 0; +} + +static int pnv_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct pci_controller *hose = domain->host_data; + struct pnv_phb *phb = hose->private_data; + msi_alloc_info_t *info = arg; + struct pci_dev *pdev = msi_desc_to_pci_dev(info->desc); + int hwirq; + int i, ret; + + hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, nr_irqs); + if (hwirq < 0) { + dev_warn(&pdev->dev, "failed to find a free MSI\n"); + return -ENOSPC; + } + + dev_dbg(&pdev->dev, "%s bridge %pOF %d/%x #%d\n", __func__, + hose->dn, virq, hwirq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) { + ret = pnv_irq_parent_domain_alloc(domain, virq + i, + phb->msi_base + hwirq + i); + if (ret) + goto out; + + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, + &pnv_msi_irq_chip, hose); + } + + return 0; + +out: + irq_domain_free_irqs_parent(domain, virq, i - 1); + msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, nr_irqs); + return ret; +} + +static void pnv_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct pci_controller *hose = irq_data_get_irq_chip_data(d); + struct pnv_phb *phb = hose->private_data; + + pr_debug("%s bridge %pOF %d/%lx #%d\n", __func__, hose->dn, + virq, d->hwirq, nr_irqs); + + msi_bitmap_free_hwirqs(&phb->msi_bmp, d->hwirq, nr_irqs); + /* XIVE domain is cleared through ->msi_free() */ +} + +static const struct irq_domain_ops pnv_irq_domain_ops = { + .alloc = pnv_irq_domain_alloc, + .free = pnv_irq_domain_free, +}; + +static int pnv_msi_allocate_domains(struct pci_controller *hose, unsigned int count) +{ + struct pnv_phb *phb = hose->private_data; + struct irq_domain *parent = irq_get_default_host(); + + hose->fwnode = irq_domain_alloc_named_id_fwnode("PNV-MSI", phb->opal_id); + if (!hose->fwnode) + return -ENOMEM; + + hose->dev_domain = irq_domain_create_hierarchy(parent, 0, count, + hose->fwnode, + &pnv_irq_domain_ops, hose); + if (!hose->dev_domain) { + pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); + irq_domain_free_fwnode(hose->fwnode); + return -ENOMEM; + } + + hose->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(hose->dn), + &pnv_msi_domain_info, + hose->dev_domain); + if (!hose->msi_domain) { + pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); + irq_domain_free_fwnode(hose->fwnode); + irq_domain_remove(hose->dev_domain); + return -ENOMEM; + } + + return 0; +} + static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { unsigned int count; @@ -2124,6 +2308,10 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) phb->msi32_support = 1; pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", count, phb->msi_base); + + /* Only supported by the XIVE driver */ + if (xive_enabled()) + pnv_msi_allocate_domains(phb->hose, count); } static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe, -- cgit v1.2.3-70-g09d2 From ba418a0278265ad65f2f9544e743b7dbff3b994b Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:31 +0200 Subject: KVM: PPC: Book3S HV: Use the new IRQ chip to detect passthrough interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passthrough PCI MSI interrupts are detected in KVM with a check on a specific EOI handler (P8) or on XIVE (P9). We can now check the PCI-MSI IRQ chip which is cleaner. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-14-clg@kaod.org --- arch/powerpc/kvm/book3s_hv.c | 2 +- arch/powerpc/platforms/powernv/pci-ioda.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 9f957ceee58a..1a757c3d33f7 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -5355,7 +5355,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) * what our real-mode EOI code does, or a XIVE interrupt */ chip = irq_data_get_irq_chip(&desc->irq_data); - if (!chip || !(is_pnv_opal_msi(chip) || is_xive_irq(chip))) { + if (!chip || !is_pnv_opal_msi(chip)) { pr_warn("kvmppc_set_passthru_irq_hv: Could not assign IRQ map for (%d,%d)\n", host_irq, guest_gsi); mutex_unlock(&kvm->lock); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index d2a17fcb6002..e77caa4dbbdf 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2007,13 +2007,15 @@ void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq) irq_set_chip(virq, &phb->ioda.irq_chip); } +static struct irq_chip pnv_pci_msi_irq_chip; + /* * Returns true iff chip is something that we could call * pnv_opal_pci_msi_eoi for. */ bool is_pnv_opal_msi(struct irq_chip *chip) { - return chip->irq_eoi == pnv_ioda2_msi_eoi; + return chip->irq_eoi == pnv_ioda2_msi_eoi || chip == &pnv_pci_msi_irq_chip; } EXPORT_SYMBOL_GPL(is_pnv_opal_msi); -- cgit v1.2.3-70-g09d2 From e5e78b15113a73d0294141d9796969fa7b10fa3c Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:32 +0200 Subject: KVM: PPC: Book3S HV: XIVE: Change interface of passthrough interrupt routines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The routine kvmppc_set_passthru_irq() calls kvmppc_xive_set_mapped() and kvmppc_xive_clr_mapped() with an IRQ descriptor. Use directly the host IRQ number to remove a useless conversion. Add some debug. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-15-clg@kaod.org --- arch/powerpc/include/asm/kvm_ppc.h | 4 ++-- arch/powerpc/kvm/book3s_hv.c | 4 ++-- arch/powerpc/kvm/book3s_xive.c | 17 ++++++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 2d88944f9f34..671fbd1a765e 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -664,9 +664,9 @@ extern int kvmppc_xive_connect_vcpu(struct kvm_device *dev, struct kvm_vcpu *vcpu, u32 cpu); extern void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu); extern int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, - struct irq_desc *host_desc); + unsigned long host_irq); extern int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, - struct irq_desc *host_desc); + unsigned long host_irq); extern u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu); extern int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 1a757c3d33f7..05b3a3548c18 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -5398,7 +5398,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) pimap->n_mapped++; if (xics_on_xive()) - rc = kvmppc_xive_set_mapped(kvm, guest_gsi, desc); + rc = kvmppc_xive_set_mapped(kvm, guest_gsi, host_irq); else kvmppc_xics_set_mapped(kvm, guest_gsi, desc->irq_data.hwirq); if (rc) @@ -5439,7 +5439,7 @@ static int kvmppc_clr_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) } if (xics_on_xive()) - rc = kvmppc_xive_clr_mapped(kvm, guest_gsi, pimap->mapped[i].desc); + rc = kvmppc_xive_clr_mapped(kvm, guest_gsi, host_irq); else kvmppc_xics_clr_mapped(kvm, guest_gsi, pimap->mapped[i].r_hwirq); diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 8cfab3547494..45a0434e9d85 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -922,13 +922,12 @@ int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval) } int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, - struct irq_desc *host_desc) + unsigned long host_irq) { struct kvmppc_xive *xive = kvm->arch.xive; struct kvmppc_xive_src_block *sb; struct kvmppc_xive_irq_state *state; - struct irq_data *host_data = irq_desc_get_irq_data(host_desc); - unsigned int host_irq = irq_desc_get_irq(host_desc); + struct irq_data *host_data = irq_get_irq_data(host_irq); unsigned int hw_irq = (unsigned int)irqd_to_hwirq(host_data); u16 idx; u8 prio; @@ -937,7 +936,8 @@ int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, if (!xive) return -ENODEV; - pr_devel("set_mapped girq 0x%lx host HW irq 0x%x...\n",guest_irq, hw_irq); + pr_debug("%s: GIRQ 0x%lx host IRQ %ld XIVE HW IRQ 0x%x\n", + __func__, guest_irq, host_irq, hw_irq); sb = kvmppc_xive_find_source(xive, guest_irq, &idx); if (!sb) @@ -959,7 +959,7 @@ int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, */ rc = irq_set_vcpu_affinity(host_irq, state); if (rc) { - pr_err("Failed to set VCPU affinity for irq %d\n", host_irq); + pr_err("Failed to set VCPU affinity for host IRQ %ld\n", host_irq); return rc; } @@ -1019,12 +1019,11 @@ int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, EXPORT_SYMBOL_GPL(kvmppc_xive_set_mapped); int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, - struct irq_desc *host_desc) + unsigned long host_irq) { struct kvmppc_xive *xive = kvm->arch.xive; struct kvmppc_xive_src_block *sb; struct kvmppc_xive_irq_state *state; - unsigned int host_irq = irq_desc_get_irq(host_desc); u16 idx; u8 prio; int rc; @@ -1032,7 +1031,7 @@ int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, if (!xive) return -ENODEV; - pr_devel("clr_mapped girq 0x%lx...\n", guest_irq); + pr_debug("%s: GIRQ 0x%lx host IRQ %ld\n", __func__, guest_irq, host_irq); sb = kvmppc_xive_find_source(xive, guest_irq, &idx); if (!sb) @@ -1059,7 +1058,7 @@ int kvmppc_xive_clr_mapped(struct kvm *kvm, unsigned long guest_irq, /* Release the passed-through interrupt to the host */ rc = irq_set_vcpu_affinity(host_irq, NULL); if (rc) { - pr_err("Failed to clr VCPU affinity for irq %d\n", host_irq); + pr_err("Failed to clr VCPU affinity for host IRQ %ld\n", host_irq); return rc; } -- cgit v1.2.3-70-g09d2 From 51be9e51a8000ffc6a33083ceca9da9303ed4dc5 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:33 +0200 Subject: KVM: PPC: Book3S HV: XIVE: Fix mapping of passthrough interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCI MSI interrupt numbers are now mapped in a PCI-MSI domain but the underlying calls handling the passthrough of the interrupt in the guest need a number in the XIVE IRQ domain. Use the IRQ data mapped in the XIVE IRQ domain and not the one in the PCI-MSI domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-16-clg@kaod.org --- arch/powerpc/kvm/book3s_xive.c | 3 ++- kernel/irq/irqdomain.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 45a0434e9d85..6878026ee8ec 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -927,7 +927,8 @@ int kvmppc_xive_set_mapped(struct kvm *kvm, unsigned long guest_irq, struct kvmppc_xive *xive = kvm->arch.xive; struct kvmppc_xive_src_block *sb; struct kvmppc_xive_irq_state *state; - struct irq_data *host_data = irq_get_irq_data(host_irq); + struct irq_data *host_data = + irq_domain_get_irq_data(irq_get_default_host(), host_irq); unsigned int hw_irq = (unsigned int)irqd_to_hwirq(host_data); u16 idx; u8 prio; diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 51c483ce2447..0eee4816edac 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -491,6 +491,7 @@ struct irq_domain *irq_get_default_host(void) { return irq_default_domain; } +EXPORT_SYMBOL_GPL(irq_get_default_host); static bool irq_domain_is_nomap(struct irq_domain *domain) { -- cgit v1.2.3-70-g09d2 From 298f6f952885eeb1f25461f085c6c238bcd9fc5e Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:34 +0200 Subject: powerpc/xics: Remove ICS list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always had only one ICS per machine. Simplify the XICS driver by removing the ICS list. The ICS stored in the chip data of the XICS domain becomes useless and we don't need it anymore to migrate away IRQs from a CPU. This will be removed in a subsequent patch. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-17-clg@kaod.org --- arch/powerpc/sysdev/xics/xics-common.c | 45 ++++++++++++++-------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index b14c502e56a8..08c25748efb9 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -38,7 +38,7 @@ DEFINE_PER_CPU(struct xics_cppr, xics_cppr); struct irq_domain *xics_host; -static LIST_HEAD(ics_list); +static struct ics *xics_ics; void xics_update_irq_servers(void) { @@ -111,12 +111,11 @@ void xics_setup_cpu(void) void xics_mask_unknown_vec(unsigned int vec) { - struct ics *ics; - pr_err("Interrupt 0x%x (real) is invalid, disabling it.\n", vec); - list_for_each_entry(ics, &ics_list, link) - ics->mask_unknown(ics, vec); + if (WARN_ON(!xics_ics)) + return; + xics_ics->mask_unknown(xics_ics, vec); } @@ -198,7 +197,6 @@ void xics_migrate_irqs_away(void) struct irq_chip *chip; long server; unsigned long flags; - struct ics *ics; /* We can't set affinity on ISA interrupts */ if (virq < NR_IRQS_LEGACY) @@ -219,13 +217,10 @@ void xics_migrate_irqs_away(void) raw_spin_lock_irqsave(&desc->lock, flags); /* Locate interrupt server */ - server = -1; - ics = irq_desc_get_chip_data(desc); - if (ics) - server = ics->get_server(ics, irq); + server = xics_ics->get_server(xics_ics, irq); if (server < 0) { - printk(KERN_ERR "%s: Can't find server for irq %d\n", - __func__, irq); + pr_err("%s: Can't find server for irq %d/%x\n", + __func__, virq, irq); goto unlock; } @@ -307,13 +302,9 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, static int xics_host_match(struct irq_domain *h, struct device_node *node, enum irq_domain_bus_token bus_token) { - struct ics *ics; - - list_for_each_entry(ics, &ics_list, link) - if (ics->host_match(ics, node)) - return 1; - - return 0; + if (WARN_ON(!xics_ics)) + return 0; + return xics_ics->host_match(xics_ics, node) ? 1 : 0; } /* Dummies */ @@ -330,8 +321,6 @@ static struct irq_chip xics_ipi_chip = { static int xics_host_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { - struct ics *ics; - pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); /* @@ -348,12 +337,14 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq, return 0; } + if (WARN_ON(!xics_ics)) + return -EINVAL; + /* Let the ICS setup the chip data */ - list_for_each_entry(ics, &ics_list, link) - if (ics->map(ics, virq) == 0) - return 0; + if (xics_ics->map(xics_ics, virq)) + return -EINVAL; - return -EINVAL; + return 0; } static int xics_host_xlate(struct irq_domain *h, struct device_node *ct, @@ -427,7 +418,9 @@ static void __init xics_init_host(void) void __init xics_register_ics(struct ics *ics) { - list_add(&ics->link, &ics_list); + if (WARN_ONCE(xics_ics, "XICS: Source Controller is already defined !")) + return; + xics_ics = ics; } static void __init xics_get_server_size(void) -- cgit v1.2.3-70-g09d2 From 248af248a8f45461662fb633eca4adf24ae704ad Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:35 +0200 Subject: powerpc/xics: Rename the map handler in a check handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves the IRQ initialization done under the different ICS backends in the common part of XICS. The 'map' handler becomes a simple 'check' on the HW IRQ at the FW level. As we don't need an ICS anymore in xics_migrate_irqs_away(), the XICS domain does not set a chip data for the IRQ. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-18-clg@kaod.org --- arch/powerpc/include/asm/xics.h | 3 ++- arch/powerpc/sysdev/xics/ics-native.c | 13 +++++-------- arch/powerpc/sysdev/xics/ics-opal.c | 27 ++++++++++----------------- arch/powerpc/sysdev/xics/ics-rtas.c | 28 ++++++++++------------------ arch/powerpc/sysdev/xics/xics-common.c | 15 +++++++++------ 5 files changed, 36 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index d9cf192368ad..0ac9bfddf704 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -89,10 +89,11 @@ static inline int ics_opal_init(void) { return -ENODEV; } /* ICS instance, hooked up to chip_data of an irq */ struct ics { struct list_head link; - int (*map)(struct ics *ics, unsigned int virq); + int (*check)(struct ics *ics, unsigned int hwirq); void (*mask_unknown)(struct ics *ics, unsigned long vec); long (*get_server)(struct ics *ics, unsigned long vec); int (*host_match)(struct ics *ics, struct device_node *node); + struct irq_chip *chip; char data[]; }; diff --git a/arch/powerpc/sysdev/xics/ics-native.c b/arch/powerpc/sysdev/xics/ics-native.c index d450502f4053..dec7d93a8ba1 100644 --- a/arch/powerpc/sysdev/xics/ics-native.c +++ b/arch/powerpc/sysdev/xics/ics-native.c @@ -131,19 +131,15 @@ static struct irq_chip ics_native_irq_chip = { .irq_retrigger = xics_retrigger, }; -static int ics_native_map(struct ics *ics, unsigned int virq) +static int ics_native_check(struct ics *ics, unsigned int hw_irq) { - unsigned int vec = (unsigned int)virq_to_hw(virq); struct ics_native *in = to_ics_native(ics); - pr_devel("%s: vec=0x%x\n", __func__, vec); + pr_devel("%s: hw_irq=0x%x\n", __func__, hw_irq); - if (vec < in->ibase || vec >= (in->ibase + in->icount)) + if (hw_irq < in->ibase || hw_irq >= (in->ibase + in->icount)) return -EINVAL; - irq_set_chip_and_handler(virq, &ics_native_irq_chip, handle_fasteoi_irq); - irq_set_chip_data(virq, ics); - return 0; } @@ -177,10 +173,11 @@ static int ics_native_host_match(struct ics *ics, struct device_node *node) } static struct ics ics_native_template = { - .map = ics_native_map, + .check = ics_native_check, .mask_unknown = ics_native_mask_unknown, .get_server = ics_native_get_server, .host_match = ics_native_host_match, + .chip = &ics_native_irq_chip, }; static int __init ics_native_add_one(struct device_node *np) diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index 823f6c9664cd..8c7ddcc718b6 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -157,26 +157,13 @@ static struct irq_chip ics_opal_irq_chip = { .irq_retrigger = xics_retrigger, }; -static int ics_opal_map(struct ics *ics, unsigned int virq); -static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec); -static long ics_opal_get_server(struct ics *ics, unsigned long vec); - static int ics_opal_host_match(struct ics *ics, struct device_node *node) { return 1; } -/* Only one global & state struct ics */ -static struct ics ics_hal = { - .map = ics_opal_map, - .mask_unknown = ics_opal_mask_unknown, - .get_server = ics_opal_get_server, - .host_match = ics_opal_host_match, -}; - -static int ics_opal_map(struct ics *ics, unsigned int virq) +static int ics_opal_check(struct ics *ics, unsigned int hw_irq) { - unsigned int hw_irq = (unsigned int)virq_to_hw(virq); int64_t rc; __be16 server; int8_t priority; @@ -189,9 +176,6 @@ static int ics_opal_map(struct ics *ics, unsigned int virq) if (rc != OPAL_SUCCESS) return -ENXIO; - irq_set_chip_and_handler(virq, &ics_opal_irq_chip, handle_fasteoi_irq); - irq_set_chip_data(virq, &ics_hal); - return 0; } @@ -222,6 +206,15 @@ static long ics_opal_get_server(struct ics *ics, unsigned long vec) return ics_opal_unmangle_server(be16_to_cpu(server)); } +/* Only one global & state struct ics */ +static struct ics ics_hal = { + .check = ics_opal_check, + .mask_unknown = ics_opal_mask_unknown, + .get_server = ics_opal_get_server, + .host_match = ics_opal_host_match, + .chip = &ics_opal_irq_chip, +}; + int __init ics_opal_init(void) { if (!firmware_has_feature(FW_FEATURE_OPAL)) diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index 4cf18000f07c..6d19d711ed35 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c @@ -24,19 +24,6 @@ static int ibm_set_xive; static int ibm_int_on; static int ibm_int_off; -static int ics_rtas_map(struct ics *ics, unsigned int virq); -static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec); -static long ics_rtas_get_server(struct ics *ics, unsigned long vec); -static int ics_rtas_host_match(struct ics *ics, struct device_node *node); - -/* Only one global & state struct ics */ -static struct ics ics_rtas = { - .map = ics_rtas_map, - .mask_unknown = ics_rtas_mask_unknown, - .get_server = ics_rtas_get_server, - .host_match = ics_rtas_host_match, -}; - static void ics_rtas_unmask_irq(struct irq_data *d) { unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); @@ -169,9 +156,8 @@ static struct irq_chip ics_rtas_irq_chip = { .irq_retrigger = xics_retrigger, }; -static int ics_rtas_map(struct ics *ics, unsigned int virq) +static int ics_rtas_check(struct ics *ics, unsigned int hw_irq) { - unsigned int hw_irq = (unsigned int)virq_to_hw(virq); int status[2]; int rc; @@ -183,9 +169,6 @@ static int ics_rtas_map(struct ics *ics, unsigned int virq) if (rc) return -ENXIO; - irq_set_chip_and_handler(virq, &ics_rtas_irq_chip, handle_fasteoi_irq); - irq_set_chip_data(virq, &ics_rtas); - return 0; } @@ -213,6 +196,15 @@ static int ics_rtas_host_match(struct ics *ics, struct device_node *node) return !of_device_is_compatible(node, "chrp,iic"); } +/* Only one global & state struct ics */ +static struct ics ics_rtas = { + .check = ics_rtas_check, + .mask_unknown = ics_rtas_mask_unknown, + .get_server = ics_rtas_get_server, + .host_match = ics_rtas_host_match, + .chip = &ics_rtas_irq_chip, +}; + __init int ics_rtas_init(void) { ibm_get_xive = rtas_token("ibm,get-xive"); diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 08c25748efb9..ed2bc14f56bd 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -318,10 +318,10 @@ static struct irq_chip xics_ipi_chip = { .irq_unmask = xics_ipi_unmask, }; -static int xics_host_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) +static int xics_host_map(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) { - pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw); + pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hwirq); /* * Mark interrupts as edge sensitive by default so that resend @@ -331,7 +331,7 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq, irq_clear_status_flags(virq, IRQ_LEVEL); /* Don't call into ICS for IPIs */ - if (hw == XICS_IPI) { + if (hwirq == XICS_IPI) { irq_set_chip_and_handler(virq, &xics_ipi_chip, handle_percpu_irq); return 0; @@ -340,10 +340,13 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq, if (WARN_ON(!xics_ics)) return -EINVAL; - /* Let the ICS setup the chip data */ - if (xics_ics->map(xics_ics, virq)) + if (xics_ics->check(xics_ics, hwirq)) return -EINVAL; + /* No chip data for the XICS domain */ + irq_domain_set_info(domain, virq, hwirq, xics_ics->chip, + NULL, handle_fasteoi_irq, NULL, NULL); + return 0; } -- cgit v1.2.3-70-g09d2 From 7d14f6c60b76fa7f3f89d81a95385576ca33b483 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:36 +0200 Subject: powerpc/xics: Give a name to the default XICS IRQ domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and clean up the error path. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-19-clg@kaod.org --- arch/powerpc/sysdev/xics/xics-common.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index ed2bc14f56bd..18d3de2f2249 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -412,11 +412,22 @@ static const struct irq_domain_ops xics_host_ops = { .xlate = xics_host_xlate, }; -static void __init xics_init_host(void) +static int __init xics_allocate_domain(void) { - xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL); - BUG_ON(xics_host == NULL); + struct fwnode_handle *fn; + + fn = irq_domain_alloc_named_fwnode("XICS"); + if (!fn) + return -ENOMEM; + + xics_host = irq_domain_create_tree(fn, &xics_host_ops, NULL); + if (!xics_host) { + irq_domain_free_fwnode(fn); + return -ENOMEM; + } + irq_set_default_host(xics_host); + return 0; } void __init xics_register_ics(struct ics *ics) @@ -480,6 +491,8 @@ void __init xics_init(void) /* Initialize common bits */ xics_get_server_size(); xics_update_irq_servers(); - xics_init_host(); + rc = xics_allocate_domain(); + if (rc < 0) + pr_err("XICS: Failed to create IRQ domain"); xics_setup_cpu(); } -- cgit v1.2.3-70-g09d2 From 53b34e8db73af98fa652641bf490384dc665d0f2 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:37 +0200 Subject: powerpc/xics: Add debug logging to the set_irq_affinity handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It really helps to know how the HW is configured when tweaking the IRQ subsystem. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-20-clg@kaod.org --- arch/powerpc/sysdev/xics/ics-opal.c | 2 +- arch/powerpc/sysdev/xics/ics-rtas.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index 8c7ddcc718b6..bf26cae1b982 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -133,7 +133,7 @@ static int ics_opal_set_affinity(struct irq_data *d, } server = ics_opal_mangle_server(wanted_server); - pr_devel("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n", + pr_debug("ics-hal: set-affinity irq %d [hw 0x%x] server: 0x%x/0x%x\n", d->irq, hw_irq, wanted_server, server); rc = opal_set_xive(hw_irq, server, priority); diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index 6d19d711ed35..b50c6341682e 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c @@ -133,6 +133,9 @@ static int ics_rtas_set_affinity(struct irq_data *d, return -1; } + pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq, + hw_irq, irq_server); + status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq, irq_server, xics_status[1]); -- cgit v1.2.3-70-g09d2 From e4f0aa3b4731430ad73fb4485e97f751c7500668 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:38 +0200 Subject: powerpc/xics: Add support for IRQ domain hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XICS doesn't have any state associated with the IRQ. The support is straightforward and simpler than for XIVE. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-21-clg@kaod.org --- arch/powerpc/sysdev/xics/xics-common.c | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 18d3de2f2249..febab57f060f 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -406,7 +406,48 @@ int xics_retrigger(struct irq_data *data) return 0; } +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY +static int xics_host_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec, + unsigned long *hwirq, unsigned int *type) +{ + return xics_host_xlate(d, to_of_node(fwspec->fwnode), fwspec->param, + fwspec->param_count, hwirq, type); +} + +static int xics_host_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + struct irq_fwspec *fwspec = arg; + irq_hw_number_t hwirq; + unsigned int type = IRQ_TYPE_NONE; + int i, rc; + + rc = xics_host_domain_translate(domain, fwspec, &hwirq, &type); + if (rc) + return rc; + + pr_debug("%s %d/%lx #%d\n", __func__, virq, hwirq, nr_irqs); + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, xics_ics->chip, + xics_ics, handle_fasteoi_irq, NULL, NULL); + + return 0; +} + +static void xics_host_domain_free(struct irq_domain *domain, + unsigned int virq, unsigned int nr_irqs) +{ + pr_debug("%s %d #%d\n", __func__, virq, nr_irqs); +} +#endif + static const struct irq_domain_ops xics_host_ops = { +#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY + .alloc = xics_host_domain_alloc, + .free = xics_host_domain_free, + .translate = xics_host_domain_translate, +#endif .match = xics_host_match, .map = xics_host_map, .xlate = xics_host_xlate, -- cgit v1.2.3-70-g09d2 From bbb25af8fbdba4acaf955e412a84eb2eea48697c Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:39 +0200 Subject: powerpc/powernv/pci: Customize the MSI EOI handler to support PHB3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHB3s need an extra OPAL call to EOI the interrupt. The call takes an OPAL HW IRQ number but it is translated into a vector number in OPAL. Here, we directly use the vector number of the in-the-middle "PNV-MSI" domain instead of grabbing the OPAL HW IRQ number in the XICS parent domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-22-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index e77caa4dbbdf..b498876a976f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2169,12 +2169,33 @@ static void pnv_msi_compose_msg(struct irq_data *d, struct msi_msg *msg) entry->msi_attrib.is_64 ? "64" : "32", d->hwirq, rc); } +/* + * The IRQ data is mapped in the MSI domain in which HW IRQ numbers + * correspond to vector numbers. + */ +static void pnv_msi_eoi(struct irq_data *d) +{ + struct pci_controller *hose = irq_data_get_irq_chip_data(d); + struct pnv_phb *phb = hose->private_data; + + if (phb->model == PNV_PHB_MODEL_PHB3) { + /* + * The EOI OPAL call takes an OPAL HW IRQ number but + * since it is translated into a vector number in + * OPAL, use that directly. + */ + WARN_ON_ONCE(opal_pci_msi_eoi(phb->opal_id, d->hwirq)); + } + + irq_chip_eoi_parent(d); +} + static struct irq_chip pnv_msi_irq_chip = { .name = "PNV-MSI", .irq_shutdown = pnv_msi_shutdown, .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, - .irq_eoi = irq_chip_eoi_parent, + .irq_eoi = pnv_msi_eoi, .irq_set_affinity = irq_chip_set_affinity_parent, .irq_compose_msi_msg = pnv_msi_compose_msg, }; -- cgit v1.2.3-70-g09d2 From 679e30b9536eeb93bc8c9a39c0ddc77dec536f6b Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:40 +0200 Subject: powerpc/pci: Drop XIVE restriction on MSI domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PowerNV and pSeries platforms now have support for both the XICS and XIVE IRQ domains. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-23-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 4 +--- arch/powerpc/platforms/pseries/msi.c | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b498876a976f..e2454439e574 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2332,9 +2332,7 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", count, phb->msi_base); - /* Only supported by the XIVE driver */ - if (xive_enabled()) - pnv_msi_allocate_domains(phb->hose, count); + pnv_msi_allocate_domains(phb->hose, count); } static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe, diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index e2127a3f7ebd..e196cc1b8540 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -720,10 +720,6 @@ int pseries_msi_allocate_domains(struct pci_controller *phb) { int count; - /* Only supported by the XIVE driver */ - if (!xive_enabled()) - return -ENODEV; - if (!__find_pe_total_msi(phb->dn, &count)) { pr_err("PCI: failed to find MSIs for bridge %pOF (domain %d)\n", phb->dn, phb->global_number); -- cgit v1.2.3-70-g09d2 From 1e661f81a522eadfe4bc5bb1ec9fbae27c13f163 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:41 +0200 Subject: powerpc/xics: Drop unmask of MSIs at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That was a workaround in the XICS domain because of the lack of MSI domain. This is now handled. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-24-clg@kaod.org --- arch/powerpc/sysdev/xics/ics-opal.c | 11 ----------- arch/powerpc/sysdev/xics/ics-rtas.c | 9 --------- 2 files changed, 20 deletions(-) diff --git a/arch/powerpc/sysdev/xics/ics-opal.c b/arch/powerpc/sysdev/xics/ics-opal.c index bf26cae1b982..c4d95d8beb6f 100644 --- a/arch/powerpc/sysdev/xics/ics-opal.c +++ b/arch/powerpc/sysdev/xics/ics-opal.c @@ -62,17 +62,6 @@ static void ics_opal_unmask_irq(struct irq_data *d) static unsigned int ics_opal_startup(struct irq_data *d) { -#ifdef CONFIG_PCI_MSI - /* - * The generic MSI code returns with the interrupt disabled on the - * card, using the MSI mask bits. Firmware doesn't appear to unmask - * at that level, so we do it here by hand. - */ - if (irq_data_get_msi_desc(d)) - pci_msi_unmask_irq(d); -#endif - - /* unmask it */ ics_opal_unmask_irq(d); return 0; } diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index b50c6341682e..b9da317b7a2d 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c @@ -57,15 +57,6 @@ static void ics_rtas_unmask_irq(struct irq_data *d) static unsigned int ics_rtas_startup(struct irq_data *d) { -#ifdef CONFIG_PCI_MSI - /* - * The generic MSI code returns with the interrupt disabled on the - * card, using the MSI mask bits. Firmware doesn't appear to unmask - * at that level, so we do it here by hand. - */ - if (irq_data_get_msi_desc(d)) - pci_msi_unmask_irq(d); -#endif /* unmask it */ ics_rtas_unmask_irq(d); return 0; -- cgit v1.2.3-70-g09d2 From 3005123eea0daa18d98602ab64b2ce3ad087d849 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:42 +0200 Subject: powerpc/pseries/pci: Drop unused MSI code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSIs should be fully managed by the PCI and IRQ subsystems now. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-25-clg@kaod.org --- arch/powerpc/platforms/pseries/msi.c | 87 ------------------------------------ 1 file changed, 87 deletions(-) diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index e196cc1b8540..1b305e411862 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -111,21 +111,6 @@ static int rtas_query_irq_number(struct pci_dn *pdn, int offset) return rtas_ret[0]; } -static void rtas_teardown_msi_irqs(struct pci_dev *pdev) -{ - struct msi_desc *entry; - - for_each_pci_msi_entry(entry, pdev) { - if (!entry->irq) - continue; - - irq_set_msi_desc(entry->irq, NULL); - irq_dispose_mapping(entry->irq); - } - - rtas_disable_msi(pdev); -} - static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) { struct device_node *dn; @@ -459,66 +444,6 @@ again: return 0; } -static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) -{ - struct pci_dn *pdn; - int hwirq, virq, i; - int rc; - struct msi_desc *entry; - struct msi_msg msg; - - rc = rtas_prepare_msi_irqs(pdev, nvec_in, type, NULL); - if (rc) - return rc; - - pdn = pci_get_pdn(pdev); - i = 0; - for_each_pci_msi_entry(entry, pdev) { - hwirq = rtas_query_irq_number(pdn, i++); - if (hwirq < 0) { - pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); - return hwirq; - } - - /* - * Depending on the number of online CPUs in the original - * kernel, it is likely for CPU #0 to be offline in a kdump - * kernel. The associated IRQs in the affinity mappings - * provided by irq_create_affinity_masks() are thus not - * started by irq_startup(), as per-design for managed IRQs. - * This can be a problem with multi-queue block devices driven - * by blk-mq : such a non-started IRQ is very likely paired - * with the single queue enforced by blk-mq during kdump (see - * blk_mq_alloc_tag_set()). This causes the device to remain - * silent and likely hangs the guest at some point. - * - * We don't really care for fine-grained affinity when doing - * kdump actually : simply ignore the pre-computed affinity - * masks in this case and let the default mask with all CPUs - * be used when creating the IRQ mappings. - */ - if (is_kdump_kernel()) - virq = irq_create_mapping(NULL, hwirq); - else - virq = irq_create_mapping_affinity(NULL, hwirq, - entry->affinity); - - if (!virq) { - pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); - return -ENOSPC; - } - - dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq); - irq_set_msi_desc(virq, entry); - - /* Read config space back so we can restore after reset */ - __pci_read_msi_msg(entry, &msg); - entry->msg = msg; - } - - return 0; -} - static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev, int nvec, msi_alloc_info_t *arg) { @@ -759,8 +684,6 @@ static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev) static int rtas_msi_init(void) { - struct pci_controller *phb; - query_token = rtas_token("ibm,query-interrupt-source-number"); change_token = rtas_token("ibm,change-msi"); @@ -772,16 +695,6 @@ static int rtas_msi_init(void) pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n"); - WARN_ON(pseries_pci_controller_ops.setup_msi_irqs); - pseries_pci_controller_ops.setup_msi_irqs = rtas_setup_msi_irqs; - pseries_pci_controller_ops.teardown_msi_irqs = rtas_teardown_msi_irqs; - - list_for_each_entry(phb, &hose_list, list_node) { - WARN_ON(phb->controller_ops.setup_msi_irqs); - phb->controller_ops.setup_msi_irqs = rtas_setup_msi_irqs; - phb->controller_ops.teardown_msi_irqs = rtas_teardown_msi_irqs; - } - WARN_ON(ppc_md.pci_irq_fixup); ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup; -- cgit v1.2.3-70-g09d2 From 6d9ba6121b1cf453985d08c141970a1b44cd9cf1 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:43 +0200 Subject: powerpc/powernv/pci: Drop unused MSI code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSIs should be fully managed by the PCI and IRQ subsystems now. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-26-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 27 ------------- arch/powerpc/platforms/powernv/pci.c | 67 ------------------------------- arch/powerpc/platforms/powernv/pci.h | 6 --- 3 files changed, 100 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index e2454439e574..eb38ce1fd434 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2080,29 +2080,6 @@ static int __pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, return 0; } -static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int virq, - unsigned int is_64, struct msi_msg *msg) -{ - struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); - unsigned int xive_num = hwirq - phb->msi_base; - int rc; - - rc = __pnv_pci_ioda_msi_setup(phb, dev, xive_num, is_64, msg); - if (rc) - return rc; - - /* P8 only */ - pnv_set_msi_irq_chip(phb, virq); - - pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," - " address=%x_%08x data=%x PE# %x\n", - pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, - msg->address_hi, msg->address_lo, msg->data, pe->pe_number); - - return 0; -} - /* * The msi_free() op is called before irq_domain_free_irqs_top() when * the handler data is still available. Use that to clear the XIVE @@ -2327,8 +2304,6 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) return; } - phb->msi_setup = pnv_pci_ioda_msi_setup; - phb->msi32_support = 1; pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", count, phb->msi_base); @@ -2936,8 +2911,6 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = { .dma_dev_setup = pnv_pci_ioda_dma_dev_setup, .dma_bus_setup = pnv_pci_ioda_dma_bus_setup, .iommu_bypass_supported = pnv_pci_ioda_iommu_bypass_supported, - .setup_msi_irqs = pnv_setup_msi_irqs, - .teardown_msi_irqs = pnv_teardown_msi_irqs, .enable_device_hook = pnv_pci_enable_device_hook, .release_device = pnv_pci_release_device, .window_alignment = pnv_pci_window_alignment, diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 6bb3c52633fb..9a8391b983d1 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -160,73 +160,6 @@ exit: } EXPORT_SYMBOL_GPL(pnv_pci_set_power_state); -int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) -{ - struct pnv_phb *phb = pci_bus_to_pnvhb(pdev->bus); - struct msi_desc *entry; - struct msi_msg msg; - int hwirq; - unsigned int virq; - int rc; - - if (WARN_ON(!phb) || !phb->msi_bmp.bitmap) - return -ENODEV; - - if (pdev->no_64bit_msi && !phb->msi32_support) - return -ENODEV; - - for_each_pci_msi_entry(entry, pdev) { - if (!entry->msi_attrib.is_64 && !phb->msi32_support) { - pr_warn("%s: Supports only 64-bit MSIs\n", - pci_name(pdev)); - return -ENXIO; - } - hwirq = msi_bitmap_alloc_hwirqs(&phb->msi_bmp, 1); - if (hwirq < 0) { - pr_warn("%s: Failed to find a free MSI\n", - pci_name(pdev)); - return -ENOSPC; - } - virq = irq_create_mapping(NULL, phb->msi_base + hwirq); - if (!virq) { - pr_warn("%s: Failed to map MSI to linux irq\n", - pci_name(pdev)); - msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1); - return -ENOMEM; - } - rc = phb->msi_setup(phb, pdev, phb->msi_base + hwirq, - virq, entry->msi_attrib.is_64, &msg); - if (rc) { - pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); - irq_dispose_mapping(virq); - msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq, 1); - return rc; - } - irq_set_msi_desc(virq, entry); - pci_write_msi_msg(virq, &msg); - } - return 0; -} - -void pnv_teardown_msi_irqs(struct pci_dev *pdev) -{ - struct pnv_phb *phb = pci_bus_to_pnvhb(pdev->bus); - struct msi_desc *entry; - irq_hw_number_t hwirq; - - if (WARN_ON(!phb)) - return; - - for_each_pci_msi_entry(entry, pdev) { - if (!entry->irq) - continue; - hwirq = virq_to_hw(entry->irq); - irq_set_msi_desc(entry->irq, NULL); - irq_dispose_mapping(entry->irq); - msi_bitmap_free_hwirqs(&phb->msi_bmp, hwirq - phb->msi_base, 1); - } -} - /* Nicely print the contents of the PE State Tables (PEST). */ static void pnv_pci_dump_pest(__be64 pestA[], __be64 pestB[], int pest_size) { diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index c8d4f222a86f..966a9eb64339 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -123,11 +123,7 @@ struct pnv_phb { #endif unsigned int msi_base; - unsigned int msi32_support; struct msi_bitmap msi_bmp; - int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int virq, - unsigned int is_64, struct msi_msg *msg); int (*init_m64)(struct pnv_phb *phb); int (*get_pe_state)(struct pnv_phb *phb, int pe_no); void (*freeze_pe)(struct pnv_phb *phb, int pe_no); @@ -289,8 +285,6 @@ extern void pnv_pci_init_npu2_opencapi_phb(struct device_node *np); extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev); extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option); -extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type); -extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); extern struct pnv_ioda_pe *pnv_pci_bdfn_to_pe(struct pnv_phb *phb, u16 bdfn); extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev); extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); -- cgit v1.2.3-70-g09d2 From f1a377f86f51b381cfc30bf2270f8a5f81e35ee9 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:44 +0200 Subject: powerpc/powernv/pci: Adapt is_pnv_opal_msi() to detect passthrough interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pnv_ioda2_msi_eoi() chip handler is not used anymore for MSIs. Simply use the check on the PSI-MSI chip. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-27-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index eb38ce1fd434..6c4b37598bcc 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2015,7 +2015,7 @@ static struct irq_chip pnv_pci_msi_irq_chip; */ bool is_pnv_opal_msi(struct irq_chip *chip) { - return chip->irq_eoi == pnv_ioda2_msi_eoi || chip == &pnv_pci_msi_irq_chip; + return chip == &pnv_pci_msi_irq_chip; } EXPORT_SYMBOL_GPL(is_pnv_opal_msi); -- cgit v1.2.3-70-g09d2 From c80198a21792ac59412871e4e6fad5041c9be8e4 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:45 +0200 Subject: powerpc/xics: Fix IRQ migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit desc->irq_data points to the top level IRQ data descriptor which is not necessarily in the XICS IRQ domain. MSIs are in another domain for instance. Fix that by looking for a mapping on the low level XICS IRQ domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-28-clg@kaod.org --- arch/powerpc/sysdev/xics/xics-common.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index febab57f060f..4a7687caec75 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -183,6 +183,8 @@ void xics_migrate_irqs_away(void) unsigned int irq, virq; struct irq_desc *desc; + pr_debug("%s: CPU %u\n", __func__, cpu); + /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == xics_default_server) xics_update_irq_servers(); @@ -197,6 +199,7 @@ void xics_migrate_irqs_away(void) struct irq_chip *chip; long server; unsigned long flags; + struct irq_data *irqd; /* We can't set affinity on ISA interrupts */ if (virq < NR_IRQS_LEGACY) @@ -204,9 +207,11 @@ void xics_migrate_irqs_away(void) /* We only need to migrate enabled IRQS */ if (!desc->action) continue; - if (desc->irq_data.domain != xics_host) + /* We need a mapping in the XICS IRQ domain */ + irqd = irq_domain_get_irq_data(xics_host, virq); + if (!irqd) continue; - irq = desc->irq_data.hwirq; + irq = irqd_to_hwirq(irqd); /* We need to get IPIs still. */ if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) continue; -- cgit v1.2.3-70-g09d2 From 5cd69651ceeed15e021cf7d19f1b1be0a80c0c7a Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:46 +0200 Subject: powerpc/powernv/pci: Set the IRQ chip data for P8/CXL devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before MSI domains, the default IRQ chip of PHB3 MSIs was patched by pnv_set_msi_irq_chip() with the custom EOI handler pnv_ioda2_msi_eoi() and the owning PHB was deduced from the 'ioda.irq_chip' field. This path has been deprecated by the MSI domains but it is still in use by the P8 CAPI 'cxl' driver. Rewriting this driver to support MSI would be a waste of time. Nevertheless, we can still remove the IRQ chip patch and set the IRQ chip data instead. This is cleaner. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-29-clg@kaod.org --- arch/powerpc/platforms/powernv/pci-ioda.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 6c4b37598bcc..aa97245eedbf 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1971,19 +1971,23 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_chip *chip, unsigned int hw_irq) return opal_pci_msi_eoi(phb->opal_id, hw_irq); } +/* + * The IRQ data is mapped in the XICS domain, with OPAL HW IRQ numbers + */ static void pnv_ioda2_msi_eoi(struct irq_data *d) { int64_t rc; unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); - struct irq_chip *chip = irq_data_get_irq_chip(d); + struct pci_controller *hose = irq_data_get_irq_chip_data(d); + struct pnv_phb *phb = hose->private_data; - rc = pnv_opal_pci_msi_eoi(chip, hw_irq); + rc = opal_pci_msi_eoi(phb->opal_id, hw_irq); WARN_ON_ONCE(rc); icp_native_eoi(d); } - +/* P8/CXL only */ void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq) { struct irq_data *idata; @@ -2005,6 +2009,7 @@ void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq) phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; } irq_set_chip(virq, &phb->ioda.irq_chip); + irq_set_chip_data(virq, phb->hose); } static struct irq_chip pnv_pci_msi_irq_chip; -- cgit v1.2.3-70-g09d2 From c325712b5f85e561ea89bae2ba5d0104e797e42c Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:47 +0200 Subject: powerpc/powernv/pci: Rework pnv_opal_pci_msi_eoi() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pnv_opal_pci_msi_eoi() is called from KVM to EOI passthrough interrupts when in real mode. Adding MSI domain broke the hack using the 'ioda.irq_chip' field to deduce the owning PHB. Fix that by using the IRQ chip data in the MSI domain. The 'ioda.irq_chip' field is now unused and could be removed from the pnv_phb struct. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-30-clg@kaod.org --- arch/powerpc/include/asm/pnv-pci.h | 2 +- arch/powerpc/kvm/book3s_hv_rm_xics.c | 8 ++++---- arch/powerpc/platforms/powernv/pci-ioda.c | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index d0ee0ede5767..b3f480799352 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -33,7 +33,7 @@ int pnv_cxl_alloc_hwirqs(struct pci_dev *dev, int num); void pnv_cxl_release_hwirqs(struct pci_dev *dev, int hwirq, int num); int pnv_cxl_get_irq_count(struct pci_dev *dev); struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev); -int64_t pnv_opal_pci_msi_eoi(struct irq_chip *chip, unsigned int hw_irq); +int64_t pnv_opal_pci_msi_eoi(struct irq_data *d); bool is_pnv_opal_msi(struct irq_chip *chip); #ifdef CONFIG_CXL_BASE diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 0a11ec88a0ae..587c33fc4564 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -706,6 +706,7 @@ static int ics_rm_eoi(struct kvm_vcpu *vcpu, u32 irq) icp->rm_eoied_irq = irq; } + /* Handle passthrough interrupts */ if (state->host_irq) { ++vcpu->stat.pthru_all; if (state->intr_cpu != -1) { @@ -759,12 +760,12 @@ int xics_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr) static unsigned long eoi_rc; -static void icp_eoi(struct irq_chip *c, u32 hwirq, __be32 xirr, bool *again) +static void icp_eoi(struct irq_data *d, u32 hwirq, __be32 xirr, bool *again) { void __iomem *xics_phys; int64_t rc; - rc = pnv_opal_pci_msi_eoi(c, hwirq); + rc = pnv_opal_pci_msi_eoi(d); if (rc) eoi_rc = rc; @@ -872,8 +873,7 @@ long kvmppc_deliver_irq_passthru(struct kvm_vcpu *vcpu, icp_rm_deliver_irq(xics, icp, irq, false); /* EOI the interrupt */ - icp_eoi(irq_desc_get_chip(irq_map->desc), irq_map->r_hwirq, xirr, - again); + icp_eoi(irq_desc_get_irq_data(irq_map->desc), irq_map->r_hwirq, xirr, again); if (check_too_hard(xics, icp) == H_TOO_HARD) return 2; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index aa97245eedbf..2389cd79c3c8 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1963,12 +1963,21 @@ void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, pe->dma_setup_done = true; } -int64_t pnv_opal_pci_msi_eoi(struct irq_chip *chip, unsigned int hw_irq) +/* + * Called from KVM in real mode to EOI passthru interrupts. The ICP + * EOI is handled directly in KVM in kvmppc_deliver_irq_passthru(). + * + * The IRQ data is mapped in the PCI-MSI domain and the EOI OPAL call + * needs an HW IRQ number mapped in the XICS IRQ domain. The HW IRQ + * numbers of the in-the-middle MSI domain are vector numbers and it's + * good enough for OPAL. Use that. + */ +int64_t pnv_opal_pci_msi_eoi(struct irq_data *d) { - struct pnv_phb *phb = container_of(chip, struct pnv_phb, - ioda.irq_chip); + struct pci_controller *hose = irq_data_get_irq_chip_data(d->parent_data); + struct pnv_phb *phb = hose->private_data; - return opal_pci_msi_eoi(phb->opal_id, hw_irq); + return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq); } /* -- cgit v1.2.3-70-g09d2 From 1753081f2d445f9157550692fcc4221cd3ff0958 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:48 +0200 Subject: KVM: PPC: Book3S HV: XICS: Fix mapping of passthrough interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCI MSIs now live in an MSI domain but the underlying calls, which will EOI the interrupt in real mode, need an HW IRQ number mapped in the XICS IRQ domain. Grab it there. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-31-clg@kaod.org --- arch/powerpc/kvm/book3s_hv.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 05b3a3548c18..f28f99805c4c 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -5328,6 +5328,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) struct kvmppc_passthru_irqmap *pimap; struct irq_chip *chip; int i, rc = 0; + struct irq_data *host_data; if (!kvm_irq_bypass) return 1; @@ -5392,7 +5393,14 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) * the KVM real mode handler. */ smp_wmb(); - irq_map->r_hwirq = desc->irq_data.hwirq; + + /* + * The 'host_irq' number is mapped in the PCI-MSI domain but + * the underlying calls, which will EOI the interrupt in real + * mode, need an HW IRQ number mapped in the XICS IRQ domain. + */ + host_data = irq_domain_get_irq_data(irq_get_default_host(), host_irq); + irq_map->r_hwirq = (unsigned int)irqd_to_hwirq(host_data); if (i == pimap->n_mapped) pimap->n_mapped++; @@ -5400,7 +5408,7 @@ static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) if (xics_on_xive()) rc = kvmppc_xive_set_mapped(kvm, guest_gsi, host_irq); else - kvmppc_xics_set_mapped(kvm, guest_gsi, desc->irq_data.hwirq); + kvmppc_xics_set_mapped(kvm, guest_gsi, irq_map->r_hwirq); if (rc) irq_map->r_hwirq = 0; -- cgit v1.2.3-70-g09d2 From 59b2bc18b1492b46d45b6b6828ba098f09b9ba67 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Thu, 1 Jul 2021 15:27:49 +0200 Subject: powerpc/xive: Use XIVE domain under xmon and debugfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default domain of the PCI/MSIs is not the XIVE domain anymore. To list the IRQ mappings under XMON and debugfs, query the IRQ data from the low level XIVE domain. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210701132750.1475580-32-clg@kaod.org --- arch/powerpc/sysdev/xive/common.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 107f442d3411..d0deaebbfeeb 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -312,11 +312,10 @@ void xmon_xive_get_irq_all(void) struct irq_desc *desc; for_each_irq_desc(i, desc) { - struct irq_data *d = irq_desc_get_irq_data(desc); - unsigned int hwirq = (unsigned int)irqd_to_hwirq(d); + struct irq_data *d = irq_domain_get_irq_data(xive_irq_domain, i); - if (d->domain == xive_irq_domain) - xmon_xive_get_irq_config(hwirq, d); + if (d) + xmon_xive_get_irq_config(irqd_to_hwirq(d), d); } } @@ -1757,9 +1756,9 @@ static int xive_core_debug_show(struct seq_file *m, void *private) xive_debug_show_cpu(m, cpu); for_each_irq_desc(i, desc) { - struct irq_data *d = irq_desc_get_irq_data(desc); + struct irq_data *d = irq_domain_get_irq_data(xive_irq_domain, i); - if (d->domain == xive_irq_domain) + if (d) xive_debug_show_irq(m, d); } return 0; -- cgit v1.2.3-70-g09d2 From 17df41fec5b80b16ea4774495f1eb730e2225619 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Mon, 19 Jul 2021 15:06:14 +0200 Subject: powerpc: use IRQF_NO_DEBUG for IPIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no need to use the lockup detector ("noirqdebug") for IPIs. The ipistorm benchmark measures a ~10% improvement on high systems when this flag is set. Signed-off-by: Cédric Le Goater Reviewed-by: Thomas Gleixner Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210719130614.195886-1-clg@kaod.org --- arch/powerpc/sysdev/xics/xics-common.c | 2 +- arch/powerpc/sysdev/xive/common.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 4a7687caec75..5c1a157a83b8 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -132,7 +132,7 @@ static void xics_request_ipi(void) * IPIs are marked IRQF_PERCPU. The handler was set in map. */ BUG_ON(request_irq(ipi, icp_ops->ipi_action, - IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL)); + IRQF_NO_DEBUG | IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL)); } void __init xics_smp_probe(void) diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index d0deaebbfeeb..4018964bbd69 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1149,7 +1149,8 @@ static int __init xive_request_ipi(void) snprintf(xid->name, sizeof(xid->name), "IPI-%d", node); ret = request_irq(xid->irq, xive_muxed_ipi_action, - IRQF_PERCPU | IRQF_NO_THREAD, xid->name, NULL); + IRQF_NO_DEBUG | IRQF_PERCPU | IRQF_NO_THREAD, + xid->name, NULL); WARN(ret < 0, "Failed to request IPI %d: %d\n", xid->irq, ret); } -- cgit v1.2.3-70-g09d2 From b68c6646cce5ee8caefa6333ee743f960222dcea Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Tue, 20 Jul 2021 15:42:08 +0200 Subject: KVM: PPC: Book3S HV: XIVE: Add a 'flags' field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use it to hold platform specific features. P9 DD2 introduced single-escalation support. P10 will add others. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210720134209.256133-2-clg@kaod.org --- arch/powerpc/kvm/book3s_xive.c | 19 ++++++++++--------- arch/powerpc/kvm/book3s_xive.h | 9 ++++++++- arch/powerpc/kvm/book3s_xive_native.c | 12 +++++++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 6878026ee8ec..555cc610e7ab 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -363,9 +363,9 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio) if (!vcpu->arch.xive_vcpu) continue; rc = xive_provision_queue(vcpu, prio); - if (rc == 0 && !xive->single_escalation) + if (rc == 0 && !kvmppc_xive_has_single_escalation(xive)) kvmppc_xive_attach_escalation(vcpu, prio, - xive->single_escalation); + kvmppc_xive_has_single_escalation(xive)); if (rc) return rc; } @@ -1199,7 +1199,7 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu) /* Free escalations */ for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { if (xc->esc_virq[i]) { - if (xc->xive->single_escalation) + if (kvmppc_xive_has_single_escalation(xc->xive)) xive_cleanup_single_escalation(vcpu, xc, xc->esc_virq[i]); free_irq(xc->esc_virq[i], vcpu); @@ -1340,7 +1340,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, * Enable the VP first as the single escalation mode will * affect escalation interrupts numbering */ - r = xive_native_enable_vp(xc->vp_id, xive->single_escalation); + r = xive_native_enable_vp(xc->vp_id, kvmppc_xive_has_single_escalation(xive)); if (r) { pr_err("Failed to enable VP in OPAL, err %d\n", r); goto bail; @@ -1357,15 +1357,15 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, struct xive_q *q = &xc->queues[i]; /* Single escalation, no queue 7 */ - if (i == 7 && xive->single_escalation) + if (i == 7 && kvmppc_xive_has_single_escalation(xive)) break; /* Is queue already enabled ? Provision it */ if (xive->qmap & (1 << i)) { r = xive_provision_queue(vcpu, i); - if (r == 0 && !xive->single_escalation) + if (r == 0 && !kvmppc_xive_has_single_escalation(xive)) kvmppc_xive_attach_escalation( - vcpu, i, xive->single_escalation); + vcpu, i, kvmppc_xive_has_single_escalation(xive)); if (r) goto bail; } else { @@ -1380,7 +1380,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, } /* If not done above, attach priority 0 escalation */ - r = kvmppc_xive_attach_escalation(vcpu, 0, xive->single_escalation); + r = kvmppc_xive_attach_escalation(vcpu, 0, kvmppc_xive_has_single_escalation(xive)); if (r) goto bail; @@ -2135,7 +2135,8 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) */ xive->nr_servers = KVM_MAX_VCPUS; - xive->single_escalation = xive_native_has_single_escalation(); + if (xive_native_has_single_escalation()) + xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION; kvm->arch.xive = xive; return 0; diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index afe9eeac6d56..73c3cd25093c 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -97,6 +97,8 @@ struct kvmppc_xive_ops { int (*reset_mapped)(struct kvm *kvm, unsigned long guest_irq); }; +#define KVMPPC_XIVE_FLAG_SINGLE_ESCALATION 0x1 + struct kvmppc_xive { struct kvm *kvm; struct kvm_device *dev; @@ -133,7 +135,7 @@ struct kvmppc_xive { u32 q_page_order; /* Flags */ - u8 single_escalation; + u8 flags; /* Number of entries in the VP block */ u32 nr_servers; @@ -308,5 +310,10 @@ void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu, int kvmppc_xive_compute_vp_id(struct kvmppc_xive *xive, u32 cpu, u32 *vp); int kvmppc_xive_set_nr_servers(struct kvmppc_xive *xive, u64 addr); +static inline bool kvmppc_xive_has_single_escalation(struct kvmppc_xive *xive) +{ + return xive->flags & KVMPPC_XIVE_FLAG_SINGLE_ESCALATION; +} + #endif /* CONFIG_KVM_XICS */ #endif /* _KVM_PPC_BOOK3S_XICS_H */ diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 573ecaab3597..2abb1358a268 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -93,7 +93,7 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) { /* Free the escalation irq */ if (xc->esc_virq[i]) { - if (xc->xive->single_escalation) + if (kvmppc_xive_has_single_escalation(xc->xive)) xive_cleanup_single_escalation(vcpu, xc, xc->esc_virq[i]); free_irq(xc->esc_virq[i], vcpu); @@ -172,7 +172,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, * Enable the VP first as the single escalation mode will * affect escalation interrupts numbering */ - rc = xive_native_enable_vp(xc->vp_id, xive->single_escalation); + rc = xive_native_enable_vp(xc->vp_id, kvmppc_xive_has_single_escalation(xive)); if (rc) { pr_err("Failed to enable VP in OPAL: %d\n", rc); goto bail; @@ -693,7 +693,7 @@ static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive, } rc = kvmppc_xive_attach_escalation(vcpu, priority, - xive->single_escalation); + kvmppc_xive_has_single_escalation(xive)); error: if (rc) kvmppc_xive_native_cleanup_queue(vcpu, priority); @@ -820,7 +820,7 @@ static int kvmppc_xive_reset(struct kvmppc_xive *xive) for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) { /* Single escalation, no queue 7 */ - if (prio == 7 && xive->single_escalation) + if (prio == 7 && kvmppc_xive_has_single_escalation(xive)) break; if (xc->esc_virq[prio]) { @@ -1111,7 +1111,9 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) */ xive->nr_servers = KVM_MAX_VCPUS; - xive->single_escalation = xive_native_has_single_escalation(); + if (xive_native_has_single_escalation()) + xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION; + xive->ops = &kvmppc_xive_native_ops; kvm->arch.xive = xive; -- cgit v1.2.3-70-g09d2 From f5af0a978776b710f16dc99a85496b1e760bf9e0 Mon Sep 17 00:00:00 2001 From: Cédric Le Goater Date: Tue, 20 Jul 2021 15:42:09 +0200 Subject: KVM: PPC: Book3S HV: XIVE: Add support for automatic save-restore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On P10, the feature doing an automatic "save & restore" of a VCPU interrupt context is set by default in OPAL. When a VP context is pulled out, the state of the interrupt registers are saved by the XIVE interrupt controller under the internal NVP structure representing the VP. This saves a costly store/load in guest entries and exits. If OPAL advertises the "save & restore" feature in the device tree, it should also have set the 'H' bit in the CAM line. Check that when vCPUs are connected to their ICP in KVM before going any further. Signed-off-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210720134209.256133-3-clg@kaod.org --- arch/powerpc/include/asm/xive-regs.h | 3 +++ arch/powerpc/include/asm/xive.h | 1 + arch/powerpc/kvm/book3s_xive.c | 34 ++++++++++++++++++++++++++++++++-- arch/powerpc/kvm/book3s_xive.h | 2 ++ arch/powerpc/kvm/book3s_xive_native.c | 9 +++++++++ arch/powerpc/sysdev/xive/native.c | 10 ++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/xive-regs.h b/arch/powerpc/include/asm/xive-regs.h index 8b211faa0e42..cf8bb6ac4463 100644 --- a/arch/powerpc/include/asm/xive-regs.h +++ b/arch/powerpc/include/asm/xive-regs.h @@ -80,10 +80,13 @@ #define TM_QW0W2_VU PPC_BIT32(0) #define TM_QW0W2_LOGIC_SERV PPC_BITMASK32(1,31) // XX 2,31 ? #define TM_QW1W2_VO PPC_BIT32(0) +#define TM_QW1W2_HO PPC_BIT32(1) /* P10 XIVE2 */ #define TM_QW1W2_OS_CAM PPC_BITMASK32(8,31) #define TM_QW2W2_VP PPC_BIT32(0) +#define TM_QW2W2_HP PPC_BIT32(1) /* P10 XIVE2 */ #define TM_QW2W2_POOL_CAM PPC_BITMASK32(8,31) #define TM_QW3W2_VT PPC_BIT32(0) +#define TM_QW3W2_HT PPC_BIT32(1) /* P10 XIVE2 */ #define TM_QW3W2_LP PPC_BIT32(6) #define TM_QW3W2_LE PPC_BIT32(7) #define TM_QW3W2_T PPC_BIT32(31) diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index 20ae50ab083c..92930b0b5d0e 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -126,6 +126,7 @@ int xive_native_enable_vp(u32 vp_id, bool single_escalation); int xive_native_disable_vp(u32 vp_id); int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id); bool xive_native_has_single_escalation(void); +bool xive_native_has_save_restore(void); int xive_native_get_queue_info(u32 vp_id, uint32_t prio, u64 *out_qpage, diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 555cc610e7ab..912c1e9eef6b 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -59,6 +59,25 @@ */ #define XIVE_Q_GAP 2 +static bool kvmppc_xive_vcpu_has_save_restore(struct kvm_vcpu *vcpu) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + + /* Check enablement at VP level */ + return xc->vp_cam & TM_QW1W2_HO; +} + +bool kvmppc_xive_check_save_restore(struct kvm_vcpu *vcpu) +{ + struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; + struct kvmppc_xive *xive = xc->xive; + + if (xive->flags & KVMPPC_XIVE_FLAG_SAVE_RESTORE) + return kvmppc_xive_vcpu_has_save_restore(vcpu); + + return true; +} + /* * Push a vcpu's context to the XIVE on guest entry. * This assumes we are in virtual mode (MMU on) @@ -77,7 +96,8 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu) return; eieio(); - __raw_writeq(vcpu->arch.xive_saved_state.w01, tima + TM_QW1_OS); + if (!kvmppc_xive_vcpu_has_save_restore(vcpu)) + __raw_writeq(vcpu->arch.xive_saved_state.w01, tima + TM_QW1_OS); __raw_writel(vcpu->arch.xive_cam_word, tima + TM_QW1_OS + TM_WORD2); vcpu->arch.xive_pushed = 1; eieio(); @@ -149,7 +169,8 @@ void kvmppc_xive_pull_vcpu(struct kvm_vcpu *vcpu) /* First load to pull the context, we ignore the value */ __raw_readl(tima + TM_SPC_PULL_OS_CTX); /* Second load to recover the context state (Words 0 and 1) */ - vcpu->arch.xive_saved_state.w01 = __raw_readq(tima + TM_QW1_OS); + if (!kvmppc_xive_vcpu_has_save_restore(vcpu)) + vcpu->arch.xive_saved_state.w01 = __raw_readq(tima + TM_QW1_OS); /* Fixup some of the state for the next load */ vcpu->arch.xive_saved_state.lsmfb = 0; @@ -1319,6 +1340,12 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, if (r) goto bail; + if (!kvmppc_xive_check_save_restore(vcpu)) { + pr_err("inconsistent save-restore setup for VCPU %d\n", cpu); + r = -EIO; + goto bail; + } + /* Configure VCPU fields for use by assembly push/pull */ vcpu->arch.xive_saved_state.w01 = cpu_to_be64(0xff000000); vcpu->arch.xive_cam_word = cpu_to_be32(xc->vp_cam | TM_QW1W2_VO); @@ -2138,6 +2165,9 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) if (xive_native_has_single_escalation()) xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION; + if (xive_native_has_save_restore()) + xive->flags |= KVMPPC_XIVE_FLAG_SAVE_RESTORE; + kvm->arch.xive = xive; return 0; } diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 73c3cd25093c..e6a9651c6f1e 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -98,6 +98,7 @@ struct kvmppc_xive_ops { }; #define KVMPPC_XIVE_FLAG_SINGLE_ESCALATION 0x1 +#define KVMPPC_XIVE_FLAG_SAVE_RESTORE 0x2 struct kvmppc_xive { struct kvm *kvm; @@ -309,6 +310,7 @@ void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu, struct kvmppc_xive_vcpu *xc, int irq); int kvmppc_xive_compute_vp_id(struct kvmppc_xive *xive, u32 cpu, u32 *vp); int kvmppc_xive_set_nr_servers(struct kvmppc_xive *xive, u64 addr); +bool kvmppc_xive_check_save_restore(struct kvm_vcpu *vcpu); static inline bool kvmppc_xive_has_single_escalation(struct kvmppc_xive *xive) { diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 2abb1358a268..af65ea21bde7 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -168,6 +168,12 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, goto bail; } + if (!kvmppc_xive_check_save_restore(vcpu)) { + pr_err("inconsistent save-restore setup for VCPU %d\n", server_num); + rc = -EIO; + goto bail; + } + /* * Enable the VP first as the single escalation mode will * affect escalation interrupts numbering @@ -1114,6 +1120,9 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type) if (xive_native_has_single_escalation()) xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION; + if (xive_native_has_save_restore()) + xive->flags |= KVMPPC_XIVE_FLAG_SAVE_RESTORE; + xive->ops = &kvmppc_xive_native_ops; kvm->arch.xive = xive; diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 57e3f1540435..1aec282cd650 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -41,6 +41,7 @@ static u32 xive_queue_shift; static u32 xive_pool_vps = XIVE_INVALID_VP; static struct kmem_cache *xive_provision_cache; static bool xive_has_single_esc; +static bool xive_has_save_restore; int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) { @@ -588,6 +589,9 @@ bool __init xive_native_init(void) if (of_get_property(np, "single-escalation-support", NULL) != NULL) xive_has_single_esc = true; + if (of_get_property(np, "vp-save-restore", NULL)) + xive_has_save_restore = true; + /* Configure Thread Management areas for KVM */ for_each_possible_cpu(cpu) kvmppc_set_xive_tima(cpu, r.start, tima); @@ -752,6 +756,12 @@ bool xive_native_has_single_escalation(void) } EXPORT_SYMBOL_GPL(xive_native_has_single_escalation); +bool xive_native_has_save_restore(void) +{ + return xive_has_save_restore; +} +EXPORT_SYMBOL_GPL(xive_native_has_save_restore); + int xive_native_get_queue_info(u32 vp_id, u32 prio, u64 *out_qpage, u64 *out_qsize, -- cgit v1.2.3-70-g09d2 From 1bce54250045443d55659b0b23be51e87ed2b919 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 2 Aug 2021 17:26:28 +0100 Subject: powerpc: Bulk conversion to generic_handle_domain_irq() Wherever possible, replace constructs that match either generic_handle_irq(irq_find_mapping()) or generic_handle_irq(irq_linear_revmap()) to a single call to generic_handle_domain_irq(). Signed-off-by: Marc Zyngier Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20210802162630.2219813-13-maz@kernel.org --- arch/powerpc/platforms/4xx/uic.c | 4 +--- arch/powerpc/platforms/512x/mpc5121_ads_cpld.c | 23 ++++++++++------------- arch/powerpc/platforms/52xx/media5200.c | 9 ++++----- arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 7 ++----- arch/powerpc/platforms/82xx/pq2ads-pci-pic.c | 6 ++---- arch/powerpc/platforms/cell/interrupt.c | 8 ++------ arch/powerpc/platforms/cell/spider-pic.c | 11 +++-------- arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 15 +++++++-------- arch/powerpc/platforms/powernv/opal-irqchip.c | 11 ++++------- arch/powerpc/sysdev/fsl_mpic_err.c | 11 ++++------- arch/powerpc/sysdev/fsl_msi.c | 12 ++++-------- 11 files changed, 43 insertions(+), 74 deletions(-) diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/4xx/uic.c index 36fb66ce54cf..89e2587b1a59 100644 --- a/arch/powerpc/platforms/4xx/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -198,7 +198,6 @@ static void uic_irq_cascade(struct irq_desc *desc) struct uic *uic = irq_desc_get_handler_data(desc); u32 msr; int src; - int subvirq; raw_spin_lock(&desc->lock); if (irqd_is_level_type(idata)) @@ -213,8 +212,7 @@ static void uic_irq_cascade(struct irq_desc *desc) src = 32 - ffs(msr); - subvirq = irq_linear_revmap(uic->irqhost, src); - generic_handle_irq(subvirq); + generic_handle_domain_irq(uic->irqhost, src); uic_irq_ret: raw_spin_lock(&desc->lock); diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c index b2981634f1f8..ea46870e5d6e 100644 --- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c @@ -81,11 +81,10 @@ static struct irq_chip cpld_pic = { .irq_unmask = cpld_unmask_irq, }; -static int +static unsigned int cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp, u8 __iomem *maskp) { - int cpld_irq; u8 status = in_8(statusp); u8 mask = in_8(maskp); @@ -93,28 +92,26 @@ cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp, status |= (ignore | mask); if (status == 0xff) - return 0; - - cpld_irq = ffz(status) + offset; + return ~0; - return irq_linear_revmap(cpld_pic_host, cpld_irq); + return ffz(status) + offset; } static void cpld_pic_cascade(struct irq_desc *desc) { - unsigned int irq; + unsigned int hwirq; - irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status, + hwirq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status, &cpld_regs->pci_mask); - if (irq) { - generic_handle_irq(irq); + if (hwirq != ~0) { + generic_handle_domain_irq(cpld_pic_host, hwirq); return; } - irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status, + hwirq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status, &cpld_regs->misc_mask); - if (irq) { - generic_handle_irq(irq); + if (hwirq != ~0) { + generic_handle_domain_irq(cpld_pic_host, hwirq); return; } } diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index efb8bdecbcc7..110c444f4bc7 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -78,7 +78,7 @@ static struct irq_chip media5200_irq_chip = { static void media5200_irq_cascade(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); - int sub_virq, val; + int val; u32 status, enable; /* Mask off the cascaded IRQ */ @@ -92,11 +92,10 @@ static void media5200_irq_cascade(struct irq_desc *desc) enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS); val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT); if (val) { - sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1); - /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n", - * __func__, virq, status, enable, val - 1, sub_virq); + generic_handle_domain_irq(media5200_irq.irqhost, val - 1); + /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i\n", + * __func__, virq, status, enable, val - 1); */ - generic_handle_irq(sub_virq); } /* Processing done; can reenable the cascade now */ diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 3823df235f25..f862b48b4824 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -190,14 +190,11 @@ static struct irq_chip mpc52xx_gpt_irq_chip = { static void mpc52xx_gpt_irq_cascade(struct irq_desc *desc) { struct mpc52xx_gpt_priv *gpt = irq_desc_get_handler_data(desc); - int sub_virq; u32 status; status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK; - if (status) { - sub_virq = irq_linear_revmap(gpt->irqhost, 0); - generic_handle_irq(sub_virq); - } + if (status) + generic_handle_domain_irq(gpt->irqhost, 0); } static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq, diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c index f82f75a6085c..285bfe19b798 100644 --- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c @@ -91,10 +91,8 @@ static void pq2ads_pci_irq_demux(struct irq_desc *desc) break; for (bit = 0; pend != 0; ++bit, pend <<= 1) { - if (pend & 0x80000000) { - int virq = irq_linear_revmap(priv->host, bit); - generic_handle_irq(virq); - } + if (pend & 0x80000000) + generic_handle_domain_irq(priv->host, bit); } } } diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index c0ab62ba6f16..0873a7a20271 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -106,13 +106,9 @@ static void iic_ioexc_cascade(struct irq_desc *desc) out_be64(&node_iic->iic_is, ack); /* handle them */ for (cascade = 63; cascade >= 0; cascade--) - if (bits & (0x8000000000000000UL >> cascade)) { - unsigned int cirq = - irq_linear_revmap(iic_host, + if (bits & (0x8000000000000000UL >> cascade)) + generic_handle_domain_irq(iic_host, base | cascade); - if (cirq) - generic_handle_irq(cirq); - } /* post-ack level interrupts */ ack = bits & ~IIC_ISR_EDGE_MASK; if (ack) diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 210785f59271..8af75867cb42 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -190,16 +190,11 @@ static void spider_irq_cascade(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct spider_pic *pic = irq_desc_get_handler_data(desc); - unsigned int cs, virq; + unsigned int cs; cs = in_be32(pic->regs + TIR_CS) >> 24; - if (cs == SPIDER_IRQ_INVALID) - virq = 0; - else - virq = irq_linear_revmap(pic->host, cs); - - if (virq) - generic_handle_irq(virq); + if (cs != SPIDER_IRQ_INVALID) + generic_handle_domain_irq(pic->host, cs); chip->irq_eoi(&desc->irq_data); } diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index a1b7f79a8a15..15396333a90b 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -108,7 +108,6 @@ static const struct irq_domain_ops hlwd_irq_domain_ops = { static unsigned int __hlwd_pic_get_irq(struct irq_domain *h) { void __iomem *io_base = h->host_data; - int irq; u32 irq_status; irq_status = in_be32(io_base + HW_BROADWAY_ICR) & @@ -116,23 +115,22 @@ static unsigned int __hlwd_pic_get_irq(struct irq_domain *h) if (irq_status == 0) return 0; /* no more IRQs pending */ - irq = __ffs(irq_status); - return irq_linear_revmap(h, irq); + return __ffs(irq_status); } static void hlwd_pic_irq_cascade(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct irq_domain *irq_domain = irq_desc_get_handler_data(desc); - unsigned int virq; + unsigned int hwirq; raw_spin_lock(&desc->lock); chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */ raw_spin_unlock(&desc->lock); - virq = __hlwd_pic_get_irq(irq_domain); - if (virq) - generic_handle_irq(virq); + hwirq = __hlwd_pic_get_irq(irq_domain); + if (hwirq) + generic_handle_domain_irq(irq_domain, hwirq); else pr_err("spurious interrupt!\n"); @@ -190,7 +188,8 @@ static struct irq_domain *hlwd_pic_init(struct device_node *np) unsigned int hlwd_pic_get_irq(void) { - return __hlwd_pic_get_irq(hlwd_irq_host); + unsigned int hwirq = __hlwd_pic_get_irq(hlwd_irq_host); + return hwirq ? irq_linear_revmap(hlwd_irq_host, hwirq) : 0; } /* diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c index c164419e254d..d55652b5f6fa 100644 --- a/arch/powerpc/platforms/powernv/opal-irqchip.c +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -46,18 +46,15 @@ void opal_handle_events(void) e = READ_ONCE(last_outstanding_events) & opal_event_irqchip.mask; again: while (e) { - int virq, hwirq; + int hwirq; hwirq = fls64(e) - 1; e &= ~BIT_ULL(hwirq); local_irq_disable(); - virq = irq_find_mapping(opal_event_irqchip.domain, hwirq); - if (virq) { - irq_enter(); - generic_handle_irq(virq); - irq_exit(); - } + irq_enter(); + generic_handle_domain_irq(opal_event_irqchip.domain, hwirq); + irq_exit(); local_irq_enable(); cond_resched(); diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c index 5fa5fa215541..9a98bb212922 100644 --- a/arch/powerpc/sysdev/fsl_mpic_err.c +++ b/arch/powerpc/sysdev/fsl_mpic_err.c @@ -99,7 +99,6 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data) struct mpic *mpic = (struct mpic *) data; u32 eisr, eimr; int errint; - unsigned int cascade_irq; eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR); eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR); @@ -108,13 +107,11 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data) return IRQ_NONE; while (eisr) { + int ret; errint = __builtin_clz(eisr); - cascade_irq = irq_linear_revmap(mpic->irqhost, - mpic->err_int_vecs[errint]); - WARN_ON(!cascade_irq); - if (cascade_irq) { - generic_handle_irq(cascade_irq); - } else { + ret = generic_handle_domain_irq(mpic->irqhost, + mpic->err_int_vecs[errint]); + if (WARN_ON(ret)) { eimr |= 1 << (31 - errint); mpic_fsl_err_write(mpic->err_regs, eimr); } diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 808e7118abfc..e6b06c3f8197 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -266,7 +266,6 @@ out_free: static irqreturn_t fsl_msi_cascade(int irq, void *data) { - unsigned int cascade_irq; struct fsl_msi *msi_data; int msir_index = -1; u32 msir_value = 0; @@ -279,9 +278,6 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data) msir_index = cascade_data->index; - if (msir_index >= NR_MSI_REG_MAX) - cascade_irq = 0; - switch (msi_data->feature & FSL_PIC_IP_MASK) { case FSL_PIC_IP_MPIC: msir_value = fsl_msi_read(msi_data->msi_regs, @@ -305,15 +301,15 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data) } while (msir_value) { + int err; intr_index = ffs(msir_value) - 1; - cascade_irq = irq_linear_revmap(msi_data->irqhost, + err = generic_handle_domain_irq(msi_data->irqhost, msi_hwirq(msi_data, msir_index, intr_index + have_shift)); - if (cascade_irq) { - generic_handle_irq(cascade_irq); + if (!err) ret = IRQ_HANDLED; - } + have_shift += intr_index + 1; msir_value = msir_value >> (intr_index + 1); } -- cgit v1.2.3-70-g09d2 From afefe67e0893325d75eb7b816dd394eef2eac628 Mon Sep 17 00:00:00 2001 From: Sai Prakash Ranjan Date: Tue, 10 Aug 2021 12:18:08 +0530 Subject: iommu/arm-smmu: Add clk_bulk_{prepare/unprepare} to system pm callbacks Some clocks for SMMU can have parent as XO such as gpu_cc_hub_cx_int_clk of GPU SMMU in QTI SC7280 SoC and in order to enter deep sleep states in such cases, we would need to drop the XO clock vote in unprepare call and this unprepare callback for XO is in RPMh (Resource Power Manager-Hardened) clock driver which controls RPMh managed clock resources for new QTI SoCs. Given we cannot have a sleeping calls such as clk_bulk_prepare() and clk_bulk_unprepare() in arm-smmu runtime pm callbacks since the iommu operations like map and unmap can be in atomic context and are in fast path, add this prepare and unprepare call to drop the XO vote only for system pm callbacks since it is not a fast path and we expect the system to enter deep sleep states with system pm as opposed to runtime pm. This is a similar sequence of clock requests (prepare,enable and disable,unprepare) in arm-smmu probe and remove. Signed-off-by: Sai Prakash Ranjan Co-developed-by: Rajendra Nayak Signed-off-by: Rajendra Nayak Link: https://lore.kernel.org/r/20210810064808.32486-1-saiprakash.ranjan@codeaurora.org Signed-off-by: Will Deacon --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index f22dbeb1e510..fc8b932b47d4 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -2281,18 +2281,38 @@ static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) static int __maybe_unused arm_smmu_pm_resume(struct device *dev) { + int ret; + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + ret = clk_bulk_prepare(smmu->num_clks, smmu->clks); + if (ret) + return ret; + if (pm_runtime_suspended(dev)) return 0; - return arm_smmu_runtime_resume(dev); + ret = arm_smmu_runtime_resume(dev); + if (ret) + clk_bulk_unprepare(smmu->num_clks, smmu->clks); + + return ret; } static int __maybe_unused arm_smmu_pm_suspend(struct device *dev) { + int ret = 0; + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + if (pm_runtime_suspended(dev)) - return 0; + goto clk_unprepare; - return arm_smmu_runtime_suspend(dev); + ret = arm_smmu_runtime_suspend(dev); + if (ret) + return ret; + +clk_unprepare: + clk_bulk_unprepare(smmu->num_clks, smmu->clks); + return ret; } static const struct dev_pm_ops arm_smmu_pm_ops = { -- cgit v1.2.3-70-g09d2 From 5fa9d19b3fb640e3616de2a7615236c0cc45e702 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 22 Jul 2021 20:48:40 -0700 Subject: pinctrl: aspeed: placate kernel-doc warnings Eliminate kernel-doc warnings in drivers/pinctrl/aspeed by using proper kernel-doc notation. Fixes these kernel-doc warnings: drivers/pinctrl/aspeed/pinmux-aspeed.c:61: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Query the enabled or disabled state for a mux function's signal on a pin drivers/pinctrl/aspeed/pinctrl-aspeed.c:135: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * Search for the signal expression needed to enable the pin's signal for the Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Aditya Srivastava Cc: Andrew Jeffery Cc: linux-aspeed@lists.ozlabs.org Cc: openbmc@lists.ozlabs.org Cc: Linus Walleij Cc: linux-gpio@vger.kernel.org Acked-by: Andrew Jeffery Link: https://lore.kernel.org/r/20210723034840.8752-1-rdunlap@infradead.org Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed.c | 4 ++-- drivers/pinctrl/aspeed/pinmux-aspeed.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c index 9bbfe5c14b36..c94e24aadf92 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c @@ -133,8 +133,8 @@ static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx, } /** - * Search for the signal expression needed to enable the pin's signal for the - * requested function. + * aspeed_find_expr_by_name - Search for the signal expression needed to + * enable the pin's signal for the requested function. * * @exprs: List of signal expressions (haystack) * @name: The name of the requested function (needle) diff --git a/drivers/pinctrl/aspeed/pinmux-aspeed.c b/drivers/pinctrl/aspeed/pinmux-aspeed.c index 894e2efd3be7..4aa46383c2c5 100644 --- a/drivers/pinctrl/aspeed/pinmux-aspeed.c +++ b/drivers/pinctrl/aspeed/pinmux-aspeed.c @@ -59,7 +59,8 @@ int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, } /** - * Query the enabled or disabled state for a mux function's signal on a pin + * aspeed_sig_expr_eval - Query the enabled or disabled state for a + * mux function's signal on a pin * * @ctx: The driver context for the pinctrl IP * @expr: An expression controlling the signal for a mux function on a pin -- cgit v1.2.3-70-g09d2 From f2c24ebadd90b4165ce2c49c3c6a100312266f54 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Mon, 9 Aug 2021 15:32:26 +0000 Subject: perf docs: Fix accidental em-dashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit " -- " is an em dash (—) in asciidoc, so all these examples that were supposed to be producing a literal two dashes were being misrendered. Signed-off-by: Alyssa Ross Cc: Alexander Shishkin Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210809153226.332545-1-hi@alyssa.is Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/intel-hybrid.txt | 2 +- tools/perf/Documentation/perf-c2c.txt | 2 +- tools/perf/Documentation/perf-iostat.txt | 4 ++-- tools/perf/Documentation/perf-record.txt | 2 +- tools/perf/Documentation/perf-stat.txt | 14 +++++++------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/perf/Documentation/intel-hybrid.txt b/tools/perf/Documentation/intel-hybrid.txt index 07f0aa3bf682..c9302096dc46 100644 --- a/tools/perf/Documentation/intel-hybrid.txt +++ b/tools/perf/Documentation/intel-hybrid.txt @@ -140,7 +140,7 @@ displayed. The percentage is the event's running time/enabling time. One example, 'triad_loop' runs on cpu16 (atom core), while we can see the scaled value for core cycles is 160,444,092 and the percentage is 0.47%. -perf stat -e cycles -- taskset -c 16 ./triad_loop +perf stat -e cycles \-- taskset -c 16 ./triad_loop As previous, two events are created. diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt index c81d72e3eecf..de6beedb7283 100644 --- a/tools/perf/Documentation/perf-c2c.txt +++ b/tools/perf/Documentation/perf-c2c.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'perf c2c record' [] -'perf c2c record' [] -- [] +'perf c2c record' [] \-- [] 'perf c2c report' [] DESCRIPTION diff --git a/tools/perf/Documentation/perf-iostat.txt b/tools/perf/Documentation/perf-iostat.txt index 165176944031..04d510364384 100644 --- a/tools/perf/Documentation/perf-iostat.txt +++ b/tools/perf/Documentation/perf-iostat.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'perf iostat' list -'perf iostat' -- [] +'perf iostat' \-- [] DESCRIPTION ----------- @@ -85,4 +85,4 @@ EXAMPLES SEE ALSO -------- -linkperf:perf-stat[1] \ No newline at end of file +linkperf:perf-stat[1] diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index d71bac847936..f1079ee7f2ec 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'perf record' [-e | --event=EVENT] [-a] -'perf record' [-e | --event=EVENT] [-a] -- [] +'perf record' [-e | --event=EVENT] [-a] \-- [] DESCRIPTION ----------- diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 45c2467e4eb2..4c9310be6acc 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -9,8 +9,8 @@ SYNOPSIS -------- [verse] 'perf stat' [-e | --event=EVENT] [-a] -'perf stat' [-e | --event=EVENT] [-a] -- [] -'perf stat' [-e | --event=EVENT] [-a] record [-o file] -- [] +'perf stat' [-e | --event=EVENT] [-a] \-- [] +'perf stat' [-e | --event=EVENT] [-a] record [-o file] \-- [] 'perf stat' report [-i file] DESCRIPTION @@ -217,8 +217,8 @@ Append to the output file designated with the -o option. Ignored if -o is not sp Log output to fd, instead of stderr. Complementary to --output, and mutually exclusive with it. --append may be used here. Examples: - 3>results perf stat --log-fd 3 -- $cmd - 3>>results perf stat --log-fd 3 --append -- $cmd + 3>results perf stat --log-fd 3 \-- $cmd + 3>>results perf stat --log-fd 3 --append \-- $cmd --control=fifo:ctl-fifo[,ack-fifo]:: --control=fd:ctl-fd[,ack-fd]:: @@ -245,7 +245,7 @@ disable events during measurements: perf stat -D -1 -e cpu-cycles -a -I 1000 \ --control fd:${ctl_fd},${ctl_fd_ack} \ - -- sleep 30 & + \-- sleep 30 & perf_pid=$! sleep 5 && echo 'enable' >&${ctl_fd} && read -u ${ctl_fd_ack} e1 && echo "enabled(${e1})" @@ -265,7 +265,7 @@ disable events during measurements: --post:: Pre and post measurement hooks, e.g.: -perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- make -s -j64 O=defconfig-build/ bzImage +perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' \-- make -s -j64 O=defconfig-build/ bzImage -I msecs:: --interval-print msecs:: @@ -496,7 +496,7 @@ $ perf config stat.no-csv-summary=true EXAMPLES -------- -$ perf stat -- make +$ perf stat \-- make Performance counter stats for 'make': -- cgit v1.2.3-70-g09d2 From a20d1cebb98bba75f2e34fddc768dd8712c1bded Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 3 May 2021 15:37:33 -0400 Subject: jbd2: fix portability problems caused by unaligned accesses This commit applies the e2fsck/recovery.c portions of commit 1e0c8ca7c08a ("e2fsck: fix portability problems caused by unaligned accesses) from the e2fsprogs git tree. The on-disk format for the ext4 journal can have unaigned 32-bit integers. This can happen when replaying a journal using a obsolete checksum format (which was never popularly used, since the v3 format replaced v2 while the metadata checksum feature was being stablized). Signed-off-by: Theodore Ts'o --- fs/jbd2/recovery.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index d47a0d96bf30..4c4209262437 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -196,7 +196,7 @@ static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf) static int count_tags(journal_t *journal, struct buffer_head *bh) { char * tagp; - journal_block_tag_t * tag; + journal_block_tag_t tag; int nr = 0, size = journal->j_blocksize; int tag_bytes = journal_tag_bytes(journal); @@ -206,14 +206,14 @@ static int count_tags(journal_t *journal, struct buffer_head *bh) tagp = &bh->b_data[sizeof(journal_header_t)]; while ((tagp - bh->b_data + tag_bytes) <= size) { - tag = (journal_block_tag_t *) tagp; + memcpy(&tag, tagp, sizeof(tag)); nr++; tagp += tag_bytes; - if (!(tag->t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID))) + if (!(tag.t_flags & cpu_to_be16(JBD2_FLAG_SAME_UUID))) tagp += 16; - if (tag->t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG)) + if (tag.t_flags & cpu_to_be16(JBD2_FLAG_LAST_TAG)) break; } @@ -433,9 +433,9 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf) } static int jbd2_block_tag_csum_verify(journal_t *j, journal_block_tag_t *tag, + journal_block_tag3_t *tag3, void *buf, __u32 sequence) { - journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; __u32 csum32; __be32 seq; @@ -496,7 +496,7 @@ static int do_one_pass(journal_t *journal, while (1) { int flags; char * tagp; - journal_block_tag_t * tag; + journal_block_tag_t tag; struct buffer_head * obh; struct buffer_head * nbh; @@ -613,8 +613,8 @@ static int do_one_pass(journal_t *journal, <= journal->j_blocksize - descr_csum_size) { unsigned long io_block; - tag = (journal_block_tag_t *) tagp; - flags = be16_to_cpu(tag->t_flags); + memcpy(&tag, tagp, sizeof(tag)); + flags = be16_to_cpu(tag.t_flags); io_block = next_log_block++; wrap(journal, next_log_block); @@ -632,7 +632,7 @@ static int do_one_pass(journal_t *journal, J_ASSERT(obh != NULL); blocknr = read_tag_block(journal, - tag); + &tag); /* If the block has been * revoked, then we're all done @@ -647,8 +647,8 @@ static int do_one_pass(journal_t *journal, /* Look for block corruption */ if (!jbd2_block_tag_csum_verify( - journal, tag, obh->b_data, - be32_to_cpu(tmp->h_sequence))) { + journal, &tag, (journal_block_tag3_t *)tagp, + obh->b_data, be32_to_cpu(tmp->h_sequence))) { brelse(obh); success = -EFSBADCRC; printk(KERN_ERR "JBD2: Invalid " -- cgit v1.2.3-70-g09d2 From 4241eabf59d5b7e9b5b567526f6e319f81dff894 Mon Sep 17 00:00:00 2001 From: Riccardo Mancini Date: Mon, 9 Aug 2021 22:11:02 +0200 Subject: perf bench: Add benchmark for evlist open/close operations This new benchmark finds the total time that is taken to open, mmap, enable, disable, munmap, close an evlist (time taken for new, create_maps, config, delete is not counted in). The evlist can be configured as in perf-record using the -a,-C,-e,-u,--per-thread,-t,-p options. The events can be duplicated in the evlist to quickly test performance with many events using the -n options. Furthermore, also the number of iterations used to calculate the statistics is customizable. Examples: - Open one dummy event system-wide: $ sudo ./perf bench internals evlist-open-close Number of cpus: 4 Number of threads: 1 Number of events: 1 (4 fds) Number of iterations: 100 Average open-close took: 613.870 usec (+- 32.852 usec) - Open the group '{cs,cycles}' on CPU 0 $ sudo ./perf bench internals evlist-open-close -e '{cs,cycles}' -C 0 Number of cpus: 1 Number of threads: 1 Number of events: 2 (2 fds) Number of iterations: 100 Average open-close took: 8503.220 usec (+- 252.652 usec) - Open 10 'cycles' events for user 0, calculate average over 100 runs $ sudo ./perf bench internals evlist-open-close -e cycles -n 10 -u 0 -i 100 Number of cpus: 4 Number of threads: 328 Number of events: 10 (13120 fds) Number of iterations: 100 Average open-close took: 180043.140 usec (+- 2295.889 usec) Committer notes: Replaced a deprecated bzero() call with designated initialized zeroing. Added some missing evlist allocation checks, one noted by Riccardo on the mailing list. Minor cosmetic changes (sent in private). Signed-off-by: Riccardo Mancini Tested-by: Arnaldo Carvalho de Melo Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210809201101.277594-1-rickyman7@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/bench/Build | 1 + tools/perf/bench/bench.h | 1 + tools/perf/bench/evlist-open-close.c | 257 +++++++++++++++++++++++++++++++++++ tools/perf/builtin-bench.c | 1 + 4 files changed, 260 insertions(+) create mode 100644 tools/perf/bench/evlist-open-close.c diff --git a/tools/perf/bench/Build b/tools/perf/bench/Build index e43f46931b41..61d45fcb4057 100644 --- a/tools/perf/bench/Build +++ b/tools/perf/bench/Build @@ -13,6 +13,7 @@ perf-y += synthesize.o perf-y += kallsyms-parse.o perf-y += find-bit-bench.o perf-y += inject-buildid.o +perf-y += evlist-open-close.o perf-$(CONFIG_X86_64) += mem-memcpy-x86-64-asm.o perf-$(CONFIG_X86_64) += mem-memset-x86-64-asm.o diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h index eac36afab2b3..b3480bc33fe8 100644 --- a/tools/perf/bench/bench.h +++ b/tools/perf/bench/bench.h @@ -48,6 +48,7 @@ int bench_epoll_ctl(int argc, const char **argv); int bench_synthesize(int argc, const char **argv); int bench_kallsyms_parse(int argc, const char **argv); int bench_inject_build_id(int argc, const char **argv); +int bench_evlist_open_close(int argc, const char **argv); #define BENCH_FORMAT_DEFAULT_STR "default" #define BENCH_FORMAT_DEFAULT 0 diff --git a/tools/perf/bench/evlist-open-close.c b/tools/perf/bench/evlist-open-close.c new file mode 100644 index 000000000000..674cb14cbaa9 --- /dev/null +++ b/tools/perf/bench/evlist-open-close.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "bench.h" +#include "../util/debug.h" +#include "../util/stat.h" +#include "../util/evlist.h" +#include "../util/evsel.h" +#include "../util/strbuf.h" +#include "../util/record.h" +#include "../util/parse-events.h" +#include "internal/threadmap.h" +#include "internal/cpumap.h" +#include +#include +#include +#include +#include + +#define MMAP_FLUSH_DEFAULT 1 + +static int iterations = 100; +static int nr_events = 1; +static const char *event_string = "dummy"; + +static struct record_opts opts = { + .sample_time = true, + .mmap_pages = UINT_MAX, + .user_freq = UINT_MAX, + .user_interval = ULLONG_MAX, + .freq = 4000, + .target = { + .uses_mmap = true, + .default_per_cpu = true, + }, + .mmap_flush = MMAP_FLUSH_DEFAULT, + .nr_threads_synthesize = 1, + .ctl_fd = -1, + .ctl_fd_ack = -1, +}; + +static const struct option options[] = { + OPT_STRING('e', "event", &event_string, "event", "event selector. use 'perf list' to list available events"), + OPT_INTEGER('n', "nr-events", &nr_events, + "number of dummy events to create (default 1). If used with -e, it clones those events n times (1 = no change)"), + OPT_INTEGER('i', "iterations", &iterations, "Number of iterations used to compute average (default=100)"), + OPT_BOOLEAN('a', "all-cpus", &opts.target.system_wide, "system-wide collection from all CPUs"), + OPT_STRING('C', "cpu", &opts.target.cpu_list, "cpu", "list of cpus where to open events"), + OPT_STRING('p', "pid", &opts.target.pid, "pid", "record events on existing process id"), + OPT_STRING('t', "tid", &opts.target.tid, "tid", "record events on existing thread id"), + OPT_STRING('u', "uid", &opts.target.uid_str, "user", "user to profile"), + OPT_BOOLEAN(0, "per-thread", &opts.target.per_thread, "use per-thread mmaps"), + OPT_END() +}; + +static const char *const bench_usage[] = { + "perf bench internals evlist-open-close ", + NULL +}; + +static int evlist__count_evsel_fds(struct evlist *evlist) +{ + struct evsel *evsel; + int cnt = 0; + + evlist__for_each_entry(evlist, evsel) + cnt += evsel->core.threads->nr * evsel->core.cpus->nr; + + return cnt; +} + +static struct evlist *bench__create_evlist(char *evstr) +{ + struct parse_events_error err = { .idx = 0, }; + struct evlist *evlist = evlist__new(); + int ret; + + if (!evlist) { + pr_err("Not enough memory to create evlist\n"); + return NULL; + } + + ret = parse_events(evlist, evstr, &err); + if (ret) { + parse_events_print_error(&err, evstr); + pr_err("Run 'perf list' for a list of valid events\n"); + ret = 1; + goto out_delete_evlist; + } + + ret = evlist__create_maps(evlist, &opts.target); + if (ret < 0) { + pr_err("Not enough memory to create thread/cpu maps\n"); + goto out_delete_evlist; + } + + evlist__config(evlist, &opts, NULL); + + return evlist; + +out_delete_evlist: + evlist__delete(evlist); + return NULL; +} + +static int bench__do_evlist_open_close(struct evlist *evlist) +{ + char sbuf[STRERR_BUFSIZE]; + int err = evlist__open(evlist); + + if (err < 0) { + pr_err("evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); + return err; + } + + err = evlist__mmap(evlist, opts.mmap_pages); + if (err < 0) { + pr_err("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf))); + return err; + } + + evlist__enable(evlist); + evlist__disable(evlist); + evlist__munmap(evlist); + evlist__close(evlist); + + return 0; +} + +static int bench_evlist_open_close__run(char *evstr) +{ + // used to print statistics only + struct evlist *evlist = bench__create_evlist(evstr); + double time_average, time_stddev; + struct timeval start, end, diff; + struct stats time_stats; + u64 runtime_us; + int i, err; + + if (!evlist) + return -ENOMEM; + + init_stats(&time_stats); + + printf(" Number of cpus:\t%d\n", evlist->core.cpus->nr); + printf(" Number of threads:\t%d\n", evlist->core.threads->nr); + printf(" Number of events:\t%d (%d fds)\n", + evlist->core.nr_entries, evlist__count_evsel_fds(evlist)); + printf(" Number of iterations:\t%d\n", iterations); + + evlist__delete(evlist); + + for (i = 0; i < iterations; i++) { + pr_debug("Started iteration %d\n", i); + evlist = bench__create_evlist(evstr); + if (!evlist) + return -ENOMEM; + + gettimeofday(&start, NULL); + err = bench__do_evlist_open_close(evlist); + if (err) { + evlist__delete(evlist); + return err; + } + + gettimeofday(&end, NULL); + timersub(&end, &start, &diff); + runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec; + update_stats(&time_stats, runtime_us); + + evlist__delete(evlist); + pr_debug("Iteration %d took:\t%ldus\n", i, runtime_us); + } + + time_average = avg_stats(&time_stats); + time_stddev = stddev_stats(&time_stats); + printf(" Average open-close took: %.3f usec (+- %.3f usec)\n", time_average, time_stddev); + + return 0; +} + +static char *bench__repeat_event_string(const char *evstr, int n) +{ + char sbuf[STRERR_BUFSIZE]; + struct strbuf buf; + int i, str_size = strlen(evstr), + final_size = str_size * n + n, + err = strbuf_init(&buf, final_size); + + if (err) { + pr_err("strbuf_init: %s\n", str_error_r(err, sbuf, sizeof(sbuf))); + goto out_error; + } + + for (i = 0; i < n; i++) { + err = strbuf_add(&buf, evstr, str_size); + if (err) { + pr_err("strbuf_add: %s\n", str_error_r(err, sbuf, sizeof(sbuf))); + goto out_error; + } + + err = strbuf_addch(&buf, i == n-1 ? '\0' : ','); + if (err) { + pr_err("strbuf_addch: %s\n", str_error_r(err, sbuf, sizeof(sbuf))); + goto out_error; + } + } + + return strbuf_detach(&buf, NULL); + +out_error: + strbuf_release(&buf); + return NULL; +} + + +int bench_evlist_open_close(int argc, const char **argv) +{ + char *evstr, errbuf[BUFSIZ]; + int err; + + argc = parse_options(argc, argv, options, bench_usage, 0); + if (argc) { + usage_with_options(bench_usage, options); + exit(EXIT_FAILURE); + } + + err = target__validate(&opts.target); + if (err) { + target__strerror(&opts.target, err, errbuf, sizeof(errbuf)); + pr_err("%s\n", errbuf); + goto out; + } + + err = target__parse_uid(&opts.target); + if (err) { + target__strerror(&opts.target, err, errbuf, sizeof(errbuf)); + pr_err("%s", errbuf); + goto out; + } + + /* Enable ignoring missing threads when -u/-p option is defined. */ + opts.ignore_missing_thread = opts.target.uid != UINT_MAX || opts.target.pid; + + evstr = bench__repeat_event_string(event_string, nr_events); + if (!evstr) { + err = -ENOMEM; + goto out; + } + + err = bench_evlist_open_close__run(evstr); + + free(evstr); +out: + return err; +} diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index 62a7b7420a44..d0895162c2ba 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -88,6 +88,7 @@ static struct bench internals_benchmarks[] = { { "synthesize", "Benchmark perf event synthesis", bench_synthesize }, { "kallsyms-parse", "Benchmark kallsyms parsing", bench_kallsyms_parse }, { "inject-build-id", "Benchmark build-id injection", bench_inject_build_id }, + { "evlist-open-close", "Benchmark evlist open and close", bench_evlist_open_close }, { NULL, NULL, NULL } }; -- cgit v1.2.3-70-g09d2 From 517db3b59537a59f6cc251b1926df93e93bb9c87 Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 3 Aug 2021 08:44:09 +0100 Subject: perf jevents: Make build dependency on test JSONs Currently all JSONs and the mapfile for an arch are dependencies for building pmu-events.c The test JSONs are missing as a dependency, so add them. Signed-off-by: John Garry Reported-by: Arnaldo Carvalho de Melo Cc: Alexander Shishkin Cc: Ian Rogers Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: http://lore.kernel.org/lkml/90094733-741c-50e5-ac7d-f5640b5f0bdd@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/Build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index 215ba30b8534..a055dee6a46a 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -6,10 +6,13 @@ pmu-events-y += pmu-events.o JDIR = pmu-events/arch/$(SRCARCH) JSON = $(shell [ -d $(JDIR) ] && \ find $(JDIR) -name '*.json' -o -name 'mapfile.csv') +JDIR_TEST = pmu-events/arch/test +JSON_TEST = $(shell [ -d $(JDIR_TEST) ] && \ + find $(JDIR_TEST) -name '*.json') # # Locate/process JSON files in pmu-events/arch/ # directory and create tables in pmu-events.c. # -$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JEVENTS) +$(OUTPUT)pmu-events/pmu-events.c: $(JSON) $(JSON_TEST) $(JEVENTS) $(Q)$(call echo-cmd,gen)$(JEVENTS) $(SRCARCH) pmu-events/arch $(OUTPUT)pmu-events/pmu-events.c $(V) -- cgit v1.2.3-70-g09d2 From 19ac3df32f883a8341b1ceaad40be33b3ac85f23 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:16 +0800 Subject: perf test: Factor out pmu-events event comparison Factor out event comparison which will be used in multiple places. Also test "pmu" and "compat" fields. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-2-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 119 +++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 53 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index b8aff8fb50d8..c064f08c63c9 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -161,6 +161,71 @@ static struct pmu_events_map *__test_pmu_get_events_map(void) return NULL; } +static int compare_pmu_events(struct pmu_event *e1, const struct pmu_event *e2) +{ + if (!is_same(e1->desc, e2->desc)) { + pr_debug2("testing event e1 %s: mismatched desc, %s vs %s\n", + e1->name, e1->desc, e2->desc); + return -1; + } + + if (!is_same(e1->topic, e2->topic)) { + pr_debug2("testing event e1 %s: mismatched topic, %s vs %s\n", + e1->name, e1->topic, e2->topic); + return -1; + } + + if (!is_same(e1->long_desc, e2->long_desc)) { + pr_debug2("testing event e1 %s: mismatched long_desc, %s vs %s\n", + e1->name, e1->long_desc, e2->long_desc); + return -1; + } + + if (!is_same(e1->unit, e2->unit)) { + pr_debug2("testing event e1 %s: mismatched unit, %s vs %s\n", + e1->name, e1->unit, e2->unit); + return -1; + } + + if (!is_same(e1->perpkg, e2->perpkg)) { + pr_debug2("testing event e1 %s: mismatched perpkg, %s vs %s\n", + e1->name, e1->perpkg, e2->perpkg); + return -1; + } + + if (!is_same(e1->metric_expr, e2->metric_expr)) { + pr_debug2("testing event e1 %s: mismatched metric_expr, %s vs %s\n", + e1->name, e1->metric_expr, e2->metric_expr); + return -1; + } + + if (!is_same(e1->metric_name, e2->metric_name)) { + pr_debug2("testing event e1 %s: mismatched metric_name, %s vs %s\n", + e1->name, e1->metric_name, e2->metric_name); + return -1; + } + + if (!is_same(e1->deprecated, e2->deprecated)) { + pr_debug2("testing event e1 %s: mismatched deprecated, %s vs %s\n", + e1->name, e1->deprecated, e2->deprecated); + return -1; + } + + if (!is_same(e1->pmu, e2->pmu)) { + pr_debug2("testing event e1 %s: mismatched pmu string, %s vs %s\n", + e1->name, e1->pmu, e2->pmu); + return -1; + } + + if (!is_same(e1->compat, e2->compat)) { + pr_debug2("testing event e1 %s: mismatched compat string, %s vs %s\n", + e1->name, e1->compat, e2->compat); + return -1; + } + + return 0; +} + /* Verify generated events from pmu-events.c is as expected */ static int test_pmu_event_table(void) { @@ -193,60 +258,8 @@ static int test_pmu_event_table(void) found = true; map_events++; - if (!is_same(table->desc, te->desc)) { - pr_debug2("testing event table %s: mismatched desc, %s vs %s\n", - table->name, table->desc, te->desc); - return -1; - } - - if (!is_same(table->topic, te->topic)) { - pr_debug2("testing event table %s: mismatched topic, %s vs %s\n", - table->name, table->topic, - te->topic); - return -1; - } - - if (!is_same(table->long_desc, te->long_desc)) { - pr_debug2("testing event table %s: mismatched long_desc, %s vs %s\n", - table->name, table->long_desc, - te->long_desc); - return -1; - } - - if (!is_same(table->unit, te->unit)) { - pr_debug2("testing event table %s: mismatched unit, %s vs %s\n", - table->name, table->unit, - te->unit); - return -1; - } - - if (!is_same(table->perpkg, te->perpkg)) { - pr_debug2("testing event table %s: mismatched perpkg, %s vs %s\n", - table->name, table->perpkg, - te->perpkg); - return -1; - } - - if (!is_same(table->metric_expr, te->metric_expr)) { - pr_debug2("testing event table %s: mismatched metric_expr, %s vs %s\n", - table->name, table->metric_expr, - te->metric_expr); + if (compare_pmu_events(table, te)) return -1; - } - - if (!is_same(table->metric_name, te->metric_name)) { - pr_debug2("testing event table %s: mismatched metric_name, %s vs %s\n", - table->name, table->metric_name, - te->metric_name); - return -1; - } - - if (!is_same(table->deprecated, te->deprecated)) { - pr_debug2("testing event table %s: mismatched deprecated, %s vs %s\n", - table->name, table->deprecated, - te->deprecated); - return -1; - } pr_debug("testing event table %s: pass\n", table->name); } -- cgit v1.2.3-70-g09d2 From 35267cea901456d16fb3841ab44347937bf0b087 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:17 +0800 Subject: perf jevents: Relocate test events to cpu folder In future to add support for sys events, relocate the core and uncore events to a cpu folder. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-3-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/pmu-events/arch/test/test_cpu/branch.json | 12 ---------- .../perf/pmu-events/arch/test/test_cpu/cache.json | 5 ----- .../perf/pmu-events/arch/test/test_cpu/other.json | 26 ---------------------- .../perf/pmu-events/arch/test/test_cpu/uncore.json | 21 ----------------- .../pmu-events/arch/test/test_soc/cpu/branch.json | 12 ++++++++++ .../pmu-events/arch/test/test_soc/cpu/cache.json | 5 +++++ .../pmu-events/arch/test/test_soc/cpu/other.json | 26 ++++++++++++++++++++++ .../pmu-events/arch/test/test_soc/cpu/uncore.json | 21 +++++++++++++++++ tools/perf/pmu-events/jevents.c | 2 +- 9 files changed, 65 insertions(+), 65 deletions(-) delete mode 100644 tools/perf/pmu-events/arch/test/test_cpu/branch.json delete mode 100644 tools/perf/pmu-events/arch/test/test_cpu/cache.json delete mode 100644 tools/perf/pmu-events/arch/test/test_cpu/other.json delete mode 100644 tools/perf/pmu-events/arch/test/test_cpu/uncore.json create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/branch.json create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/cache.json create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/other.json create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json diff --git a/tools/perf/pmu-events/arch/test/test_cpu/branch.json b/tools/perf/pmu-events/arch/test/test_cpu/branch.json deleted file mode 100644 index 93ddfd8053ca..000000000000 --- a/tools/perf/pmu-events/arch/test/test_cpu/branch.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "EventName": "bp_l1_btb_correct", - "EventCode": "0x8a", - "BriefDescription": "L1 BTB Correction." - }, - { - "EventName": "bp_l2_btb_correct", - "EventCode": "0x8b", - "BriefDescription": "L2 BTB Correction." - } -] diff --git a/tools/perf/pmu-events/arch/test/test_cpu/cache.json b/tools/perf/pmu-events/arch/test/test_cpu/cache.json deleted file mode 100644 index 036d0efdb2bb..000000000000 --- a/tools/perf/pmu-events/arch/test/test_cpu/cache.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - { - "ArchStdEvent": "L3_CACHE_RD" - } -] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/test/test_cpu/other.json b/tools/perf/pmu-events/arch/test/test_cpu/other.json deleted file mode 100644 index 7d53d7ecd723..000000000000 --- a/tools/perf/pmu-events/arch/test/test_cpu/other.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "EventCode": "0x6", - "Counter": "0,1", - "UMask": "0x80", - "EventName": "SEGMENT_REG_LOADS.ANY", - "SampleAfterValue": "200000", - "BriefDescription": "Number of segment register loads." - }, - { - "EventCode": "0x9", - "Counter": "0,1", - "UMask": "0x20", - "EventName": "DISPATCH_BLOCKED.ANY", - "SampleAfterValue": "200000", - "BriefDescription": "Memory cluster signals to block micro-op dispatch for any reason" - }, - { - "EventCode": "0x3A", - "Counter": "0,1", - "UMask": "0x0", - "EventName": "EIST_TRANS", - "SampleAfterValue": "200000", - "BriefDescription": "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions" - } -] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/test/test_cpu/uncore.json b/tools/perf/pmu-events/arch/test/test_cpu/uncore.json deleted file mode 100644 index d0a890cc814d..000000000000 --- a/tools/perf/pmu-events/arch/test/test_cpu/uncore.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "EventCode": "0x02", - "EventName": "uncore_hisi_ddrc.flux_wcmd", - "BriefDescription": "DDRC write commands", - "PublicDescription": "DDRC write commands", - "Unit": "hisi_sccl,ddrc" - }, - { - "Unit": "CBO", - "EventCode": "0x22", - "UMask": "0x81", - "EventName": "UNC_CBO_XSNP_RESPONSE.MISS_EVICTION", - "BriefDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.", - "PublicDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.", - "Counter": "0,1", - "CounterMask": "0", - "Invert": "0", - "EdgeDetect": "0" - } -] diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/branch.json b/tools/perf/pmu-events/arch/test/test_soc/cpu/branch.json new file mode 100644 index 000000000000..93ddfd8053ca --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/branch.json @@ -0,0 +1,12 @@ +[ + { + "EventName": "bp_l1_btb_correct", + "EventCode": "0x8a", + "BriefDescription": "L1 BTB Correction." + }, + { + "EventName": "bp_l2_btb_correct", + "EventCode": "0x8b", + "BriefDescription": "L2 BTB Correction." + } +] diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/cache.json b/tools/perf/pmu-events/arch/test/test_soc/cpu/cache.json new file mode 100644 index 000000000000..036d0efdb2bb --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/cache.json @@ -0,0 +1,5 @@ +[ + { + "ArchStdEvent": "L3_CACHE_RD" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/other.json b/tools/perf/pmu-events/arch/test/test_soc/cpu/other.json new file mode 100644 index 000000000000..7d53d7ecd723 --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/other.json @@ -0,0 +1,26 @@ +[ + { + "EventCode": "0x6", + "Counter": "0,1", + "UMask": "0x80", + "EventName": "SEGMENT_REG_LOADS.ANY", + "SampleAfterValue": "200000", + "BriefDescription": "Number of segment register loads." + }, + { + "EventCode": "0x9", + "Counter": "0,1", + "UMask": "0x20", + "EventName": "DISPATCH_BLOCKED.ANY", + "SampleAfterValue": "200000", + "BriefDescription": "Memory cluster signals to block micro-op dispatch for any reason" + }, + { + "EventCode": "0x3A", + "Counter": "0,1", + "UMask": "0x0", + "EventName": "EIST_TRANS", + "SampleAfterValue": "200000", + "BriefDescription": "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json b/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json new file mode 100644 index 000000000000..d0a890cc814d --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json @@ -0,0 +1,21 @@ +[ + { + "EventCode": "0x02", + "EventName": "uncore_hisi_ddrc.flux_wcmd", + "BriefDescription": "DDRC write commands", + "PublicDescription": "DDRC write commands", + "Unit": "hisi_sccl,ddrc" + }, + { + "Unit": "CBO", + "EventCode": "0x22", + "UMask": "0x81", + "EventName": "UNC_CBO_XSNP_RESPONSE.MISS_EVICTION", + "BriefDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.", + "PublicDescription": "A cross-core snoop resulted from L3 Eviction which misses in some processor core.", + "Counter": "0,1", + "CounterMask": "0", + "Invert": "0", + "EdgeDetect": "0" + } +] diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 9604446f8360..405bdd36b9b9 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -814,7 +814,7 @@ static void print_mapping_test_table(FILE *outfp) fprintf(outfp, "\t.cpuid = \"testcpu\",\n"); fprintf(outfp, "\t.version = \"v1\",\n"); fprintf(outfp, "\t.type = \"core\",\n"); - fprintf(outfp, "\t.table = pme_test_cpu,\n"); + fprintf(outfp, "\t.table = pme_test_soc_cpu,\n"); fprintf(outfp, "},\n"); } -- cgit v1.2.3-70-g09d2 From 390add0cc9f4d7fda89cf3db7651717e82cf0afc Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 10 Aug 2021 12:55:51 -0400 Subject: jbd2: fix clang warning in recovery.c Remove unused variable store which was never used. This fix is also in e2fsprogs commit 99a2294f85f0 ("e2fsck: value stored to err is never read"). Signed-off-by: Lukas Czerner Signed-off-by: Theodore Ts'o --- fs/jbd2/recovery.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 4c4209262437..ba979fcf1cd3 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -760,7 +760,6 @@ static int do_one_pass(journal_t *journal, */ jbd_debug(1, "JBD2: Invalid checksum ignored in transaction %u, likely stale data\n", next_commit_ID); - err = 0; brelse(bh); goto done; } -- cgit v1.2.3-70-g09d2 From c81e823ff8667f19d2b6ee0ab0e919e3043abd36 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:18 +0800 Subject: perf test: Declare pmu-events test events separately Currently all test events are put into arrays of test events. Create pointer arrays of test events instead, so the test events may be referenced later for tighter alias verification. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-4-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 244 ++++++++++++++++++++++-------------------- 1 file changed, 126 insertions(+), 118 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index c064f08c63c9..0837f2c9d882 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -30,108 +30,114 @@ struct perf_pmu_test_event { const char *alias_long_desc; }; -static struct perf_pmu_test_event test_cpu_events[] = { - { - .event = { - .name = "bp_l1_btb_correct", - .event = "event=0x8a", - .desc = "L1 BTB Correction", - .topic = "branch", - }, - .alias_str = "event=0x8a", - .alias_long_desc = "L1 BTB Correction", - }, - { - .event = { - .name = "bp_l2_btb_correct", - .event = "event=0x8b", - .desc = "L2 BTB Correction", - .topic = "branch", - }, - .alias_str = "event=0x8b", - .alias_long_desc = "L2 BTB Correction", +static const struct perf_pmu_test_event bp_l1_btb_correct = { + .event = { + .name = "bp_l1_btb_correct", + .event = "event=0x8a", + .desc = "L1 BTB Correction", + .topic = "branch", }, - { - .event = { - .name = "segment_reg_loads.any", - .event = "umask=0x80,period=200000,event=0x6", - .desc = "Number of segment register loads", - .topic = "other", - }, - .alias_str = "umask=0x80,(null)=0x30d40,event=0x6", - .alias_long_desc = "Number of segment register loads", + .alias_str = "event=0x8a", + .alias_long_desc = "L1 BTB Correction", +}; + +static const struct perf_pmu_test_event bp_l2_btb_correct = { + .event = { + .name = "bp_l2_btb_correct", + .event = "event=0x8b", + .desc = "L2 BTB Correction", + .topic = "branch", }, - { - .event = { - .name = "dispatch_blocked.any", - .event = "umask=0x20,period=200000,event=0x9", - .desc = "Memory cluster signals to block micro-op dispatch for any reason", - .topic = "other", - }, - .alias_str = "umask=0x20,(null)=0x30d40,event=0x9", - .alias_long_desc = "Memory cluster signals to block micro-op dispatch for any reason", + .alias_str = "event=0x8b", + .alias_long_desc = "L2 BTB Correction", +}; + +static const struct perf_pmu_test_event segment_reg_loads_any = { + .event = { + .name = "segment_reg_loads.any", + .event = "umask=0x80,period=200000,event=0x6", + .desc = "Number of segment register loads", + .topic = "other", }, - { - .event = { - .name = "eist_trans", - .event = "umask=0x0,period=200000,event=0x3a", - .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", - .topic = "other", - }, - .alias_str = "umask=0,(null)=0x30d40,event=0x3a", - .alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", + .alias_str = "umask=0x80,(null)=0x30d40,event=0x6", + .alias_long_desc = "Number of segment register loads", +}; + +static const struct perf_pmu_test_event dispatch_blocked_any = { + .event = { + .name = "dispatch_blocked.any", + .event = "umask=0x20,period=200000,event=0x9", + .desc = "Memory cluster signals to block micro-op dispatch for any reason", + .topic = "other", }, - { - .event = { - .name = "l3_cache_rd", - .event = "event=0x40", - .desc = "L3 cache access, read", - .long_desc = "Attributable Level 3 cache access, read", - .topic = "cache", - }, - .alias_str = "event=0x40", - .alias_long_desc = "Attributable Level 3 cache access, read", + .alias_str = "umask=0x20,(null)=0x30d40,event=0x9", + .alias_long_desc = "Memory cluster signals to block micro-op dispatch for any reason", +}; + +static const struct perf_pmu_test_event eist_trans = { + .event = { + .name = "eist_trans", + .event = "umask=0x0,period=200000,event=0x3a", + .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", + .topic = "other", }, - { /* sentinel */ - .event = { - .name = NULL, - }, + .alias_str = "umask=0,(null)=0x30d40,event=0x3a", + .alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", +}; + +static const struct perf_pmu_test_event l3_cache_rd = { + .event = { + .name = "l3_cache_rd", + .event = "event=0x40", + .desc = "L3 cache access, read", + .long_desc = "Attributable Level 3 cache access, read", + .topic = "cache", }, + .alias_str = "event=0x40", + .alias_long_desc = "Attributable Level 3 cache access, read", }; -static struct perf_pmu_test_event test_uncore_events[] = { - { - .event = { - .name = "uncore_hisi_ddrc.flux_wcmd", - .event = "event=0x2", - .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", - .topic = "uncore", - .long_desc = "DDRC write commands", - .pmu = "hisi_sccl,ddrc", - }, - .alias_str = "event=0x2", - .alias_long_desc = "DDRC write commands", +static const struct perf_pmu_test_event *core_events[] = { + &bp_l1_btb_correct, + &bp_l2_btb_correct, + &segment_reg_loads_any, + &dispatch_blocked_any, + &eist_trans, + &l3_cache_rd, + NULL +}; + +static const struct perf_pmu_test_event uncore_hisi_ddrc_flux_wcmd = { + .event = { + .name = "uncore_hisi_ddrc.flux_wcmd", + .event = "event=0x2", + .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", + .topic = "uncore", + .long_desc = "DDRC write commands", + .pmu = "hisi_sccl,ddrc", }, - { - .event = { - .name = "unc_cbo_xsnp_response.miss_eviction", - .event = "umask=0x81,event=0x22", - .desc = "Unit: uncore_cbox A cross-core snoop resulted from L3 Eviction which misses in some processor core", - .topic = "uncore", - .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", - .pmu = "uncore_cbox", - }, - .alias_str = "umask=0x81,event=0x22", - .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .alias_str = "event=0x2", + .alias_long_desc = "DDRC write commands", +}; + +static const struct perf_pmu_test_event unc_cbo_xsnp_response_miss_eviction = { + .event = { + .name = "unc_cbo_xsnp_response.miss_eviction", + .event = "umask=0x81,event=0x22", + .desc = "Unit: uncore_cbox A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .topic = "uncore", + .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .pmu = "uncore_cbox", }, - { /* sentinel */ - .event = { - .name = NULL, - }, - } + .alias_str = "umask=0x81,event=0x22", + .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", }; -const int total_test_events_size = ARRAY_SIZE(test_uncore_events); +static const struct perf_pmu_test_event *uncore_events[] = { + &uncore_hisi_ddrc_flux_wcmd, + &unc_cbo_xsnp_response_miss_eviction, + NULL +}; static bool is_same(const char *reference, const char *test) { @@ -226,7 +232,7 @@ static int compare_pmu_events(struct pmu_event *e1, const struct pmu_event *e2) return 0; } -/* Verify generated events from pmu-events.c is as expected */ +/* Verify generated events from pmu-events.c are as expected */ static int test_pmu_event_table(void) { struct pmu_events_map *map = __test_pmu_get_events_map(); @@ -234,31 +240,31 @@ static int test_pmu_event_table(void) int map_events = 0, expected_events; /* ignore 2x sentinels */ - expected_events = ARRAY_SIZE(test_cpu_events) + - ARRAY_SIZE(test_uncore_events) - 2; + expected_events = ARRAY_SIZE(core_events) + + ARRAY_SIZE(uncore_events) - 2; if (!map) return -1; for (table = map->table; table->name; table++) { - struct perf_pmu_test_event *test; - struct pmu_event *te; + struct perf_pmu_test_event const **test_event_table; bool found = false; if (table->pmu) - test = &test_uncore_events[0]; + test_event_table = &uncore_events[0]; else - test = &test_cpu_events[0]; + test_event_table = &core_events[0]; - te = &test->event; + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; - for (; te->name; test++, te = &test->event) { - if (strcmp(table->name, te->name)) + if (strcmp(table->name, event->name)) continue; found = true; map_events++; - if (compare_pmu_events(table, te)) + if (compare_pmu_events(table, event)) return -1; pr_debug("testing event table %s: pass\n", table->name); @@ -294,8 +300,7 @@ static struct perf_pmu_alias *find_alias(const char *test_event, struct list_hea /* Verify aliases are as expected */ static int __test__pmu_event_aliases(char *pmu_name, int *count) { - struct perf_pmu_test_event *test; - struct pmu_event *te; + struct perf_pmu_test_event const **test_event_table; struct perf_pmu *pmu; LIST_HEAD(aliases); int res = 0; @@ -307,10 +312,10 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) return -1; if (is_pmu_core(pmu_name)) { - test = &test_cpu_events[0]; + test_event_table = &core_events[0]; use_uncore_table = false; } else { - test = &test_uncore_events[0]; + test_event_table = &uncore_events[0]; use_uncore_table = true; } @@ -322,50 +327,53 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) pmu_add_cpu_aliases_map(&aliases, pmu, map); - for (te = &test->event; te->name; test++, te = &test->event) { - struct perf_pmu_alias *alias = find_alias(te->name, &aliases); + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; + + struct perf_pmu_alias *alias = find_alias(event->name, &aliases); if (!alias) { bool uncore_match = pmu_uncore_alias_match(pmu_name, - te->pmu); + event->pmu); if (use_uncore_table && !uncore_match) { pr_debug3("testing aliases PMU %s: skip matching alias %s\n", - pmu_name, te->name); + pmu_name, event->name); continue; } pr_debug2("testing aliases PMU %s: no alias, alias_table->name=%s\n", - pmu_name, te->name); + pmu_name, event->name); res = -1; break; } - if (!is_same(alias->desc, te->desc)) { + if (!is_same(alias->desc, event->desc)) { pr_debug2("testing aliases PMU %s: mismatched desc, %s vs %s\n", - pmu_name, alias->desc, te->desc); + pmu_name, alias->desc, event->desc); res = -1; break; } - if (!is_same(alias->long_desc, test->alias_long_desc)) { + if (!is_same(alias->long_desc, test_event->alias_long_desc)) { pr_debug2("testing aliases PMU %s: mismatched long_desc, %s vs %s\n", pmu_name, alias->long_desc, - test->alias_long_desc); + test_event->alias_long_desc); res = -1; break; } - if (!is_same(alias->str, test->alias_str)) { + if (!is_same(alias->str, test_event->alias_str)) { pr_debug2("testing aliases PMU %s: mismatched str, %s vs %s\n", - pmu_name, alias->str, test->alias_str); + pmu_name, alias->str, test_event->alias_str); res = -1; break; } - if (!is_same(alias->topic, te->topic)) { + if (!is_same(alias->topic, event->topic)) { pr_debug2("testing aliases PMU %s: mismatched topic, %s vs %s\n", - pmu_name, alias->topic, te->topic); + pmu_name, alias->topic, event->topic); res = -1; break; } -- cgit v1.2.3-70-g09d2 From e386acd79017952ba032aad60e8307befc5aa378 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:19 +0800 Subject: perf test: Factor out pmu-events alias comparison Factor out alias test which will be used in multiple places. Also test missing fields. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-5-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 80 +++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 0837f2c9d882..8fb5df6ee500 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -232,6 +232,60 @@ static int compare_pmu_events(struct pmu_event *e1, const struct pmu_event *e2) return 0; } +static int compare_alias_to_test_event(struct perf_pmu_alias *alias, + struct perf_pmu_test_event const *test_event, + char const *pmu_name) +{ + struct pmu_event const *event = &test_event->event; + + /* An alias was found, ensure everything is in order */ + if (!is_same(alias->name, event->name)) { + pr_debug("testing aliases PMU %s: mismatched name, %s vs %s\n", + pmu_name, alias->name, event->name); + return -1; + } + + if (!is_same(alias->desc, event->desc)) { + pr_debug("testing aliases PMU %s: mismatched desc, %s vs %s\n", + pmu_name, alias->desc, event->desc); + return -1; + } + + if (!is_same(alias->long_desc, test_event->alias_long_desc)) { + pr_debug("testing aliases PMU %s: mismatched long_desc, %s vs %s\n", + pmu_name, alias->long_desc, + test_event->alias_long_desc); + return -1; + } + + if (!is_same(alias->topic, event->topic)) { + pr_debug("testing aliases PMU %s: mismatched topic, %s vs %s\n", + pmu_name, alias->topic, event->topic); + return -1; + } + + if (!is_same(alias->str, test_event->alias_str)) { + pr_debug("testing aliases PMU %s: mismatched str, %s vs %s\n", + pmu_name, alias->str, test_event->alias_str); + return -1; + } + + if (!is_same(alias->long_desc, test_event->alias_long_desc)) { + pr_debug("testing aliases PMU %s: mismatched long desc, %s vs %s\n", + pmu_name, alias->str, test_event->alias_long_desc); + return -1; + } + + + if (!is_same(alias->pmu_name, test_event->event.pmu)) { + pr_debug("testing aliases PMU %s: mismatched pmu_name, %s vs %s\n", + pmu_name, alias->pmu_name, test_event->event.pmu); + return -1; + } + + return 0; +} + /* Verify generated events from pmu-events.c are as expected */ static int test_pmu_event_table(void) { @@ -349,31 +403,7 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) break; } - if (!is_same(alias->desc, event->desc)) { - pr_debug2("testing aliases PMU %s: mismatched desc, %s vs %s\n", - pmu_name, alias->desc, event->desc); - res = -1; - break; - } - - if (!is_same(alias->long_desc, test_event->alias_long_desc)) { - pr_debug2("testing aliases PMU %s: mismatched long_desc, %s vs %s\n", - pmu_name, alias->long_desc, - test_event->alias_long_desc); - res = -1; - break; - } - - if (!is_same(alias->str, test_event->alias_str)) { - pr_debug2("testing aliases PMU %s: mismatched str, %s vs %s\n", - pmu_name, alias->str, test_event->alias_str); - res = -1; - break; - } - - if (!is_same(alias->topic, event->topic)) { - pr_debug2("testing aliases PMU %s: mismatched topic, %s vs %s\n", - pmu_name, alias->topic, event->topic); + if (compare_alias_to_test_event(alias, test_event, pmu_name)) { res = -1; break; } -- cgit v1.2.3-70-g09d2 From 3bc4526b30f14b70280ec2a7a02fbfdab2ebdb0a Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:20 +0800 Subject: perf test: Test pmu-events core aliases separately The current method to test uncore event aliasing is limited, as it relies on the uncore PMU being present in the host system to test. As such, breakages of uncore PMU aliases goes unnoticed. To make this more robust, a new method of testing uncore PMUs with fake PMUs will be used in future. This will be separate to testing core PMU aliases. So make the current test function core PMU only. Uncore PMU alias support will be re-added later. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-6-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 45 +++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 8fb5df6ee500..9537bbdd09f0 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -352,26 +352,19 @@ static struct perf_pmu_alias *find_alias(const char *test_event, struct list_hea } /* Verify aliases are as expected */ -static int __test__pmu_event_aliases(char *pmu_name, int *count) +static int __test_core_pmu_event_aliases(char *pmu_name, int *count) { struct perf_pmu_test_event const **test_event_table; struct perf_pmu *pmu; LIST_HEAD(aliases); int res = 0; - bool use_uncore_table; struct pmu_events_map *map = __test_pmu_get_events_map(); struct perf_pmu_alias *a, *tmp; if (!map) return -1; - if (is_pmu_core(pmu_name)) { - test_event_table = &core_events[0]; - use_uncore_table = false; - } else { - test_event_table = &uncore_events[0]; - use_uncore_table = true; - } + test_event_table = &core_events[0]; pmu = zalloc(sizeof(*pmu)); if (!pmu) @@ -384,20 +377,10 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) for (; *test_event_table; test_event_table++) { struct perf_pmu_test_event const *test_event = *test_event_table; struct pmu_event const *event = &test_event->event; - struct perf_pmu_alias *alias = find_alias(event->name, &aliases); if (!alias) { - bool uncore_match = pmu_uncore_alias_match(pmu_name, - event->pmu); - - if (use_uncore_table && !uncore_match) { - pr_debug3("testing aliases PMU %s: skip matching alias %s\n", - pmu_name, event->name); - continue; - } - - pr_debug2("testing aliases PMU %s: no alias, alias_table->name=%s\n", + pr_debug("testing aliases core PMU %s: no alias, alias_table->name=%s\n", pmu_name, event->name); res = -1; break; @@ -409,7 +392,7 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) } (*count)++; - pr_debug2("testing aliases PMU %s: matched event %s\n", + pr_debug2("testing aliases core PMU %s: matched event %s\n", pmu_name, alias->name); } @@ -421,7 +404,6 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) return res; } - /* Test that aliases generated are as expected */ static int test_aliases(void) { @@ -430,21 +412,26 @@ static int test_aliases(void) while ((pmu = perf_pmu__scan(pmu)) != NULL) { int count = 0; + if (!is_pmu_core(pmu->name)) + continue; + if (list_empty(&pmu->format)) { - pr_debug2("skipping testing PMU %s\n", pmu->name); + pr_debug2("skipping testing core PMU %s\n", pmu->name); continue; } - if (__test__pmu_event_aliases(pmu->name, &count)) { - pr_debug("testing PMU %s aliases: failed\n", pmu->name); + if (__test_core_pmu_event_aliases(pmu->name, &count)) { + pr_debug("testing core PMU %s aliases: failed\n", pmu->name); return -1; } - if (count == 0) - pr_debug3("testing PMU %s aliases: no events to match\n", + if (count == 0) { + pr_debug("testing core PMU %s aliases: no events to match\n", pmu->name); - else - pr_debug("testing PMU %s aliases: pass\n", pmu->name); + return -1; + } + + pr_debug("testing core PMU %s aliases: pass\n", pmu->name); } return 0; -- cgit v1.2.3-70-g09d2 From 5806099a2e2ab36fa7a7705faaf3d7296b701e67 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:21 +0800 Subject: perf pmu: Check .is_uncore field in pmu_add_cpu_aliases_map() Calling pmu_is_uncore() for fake PMUs does not work, as it checks sysfs for the PMU details (which won't exist). Check .is_uncore field instead, which makes sense anyway. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-7-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index fc683bc41715..b1fc82073443 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -843,8 +843,7 @@ void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, break; } - if (pmu_is_uncore(name) && - pmu_uncore_alias_match(pname, name)) + if (pmu->is_uncore && pmu_uncore_alias_match(pname, name)) goto new_alias; if (strcmp(pname, name)) -- cgit v1.2.3-70-g09d2 From 5a65c0c8f6fd5e0708e52131940f2306a3be4e55 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:22 +0800 Subject: perf test: Re-add pmu-event uncore PMU alias test Add support to match aliases for uncore PMUs. Since we cannot rely on the PMUs being present on the host system, use fake PMUs. The following conditions in the test are ensures: - Expected count of aliases created - All aliases can be matched to an expected alias in perf_pmu_test_pmu.aliases This will catch the condition fixed in commit c47a5599eda3 ("perf tools: Fix pattern matching for same substring in different PMU type"), where excess events were created for a PMU. It will also fix the scenario inadvertently broken there, where no aliases were created for aliases with multiple tokens. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-8-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/pmu-events.c | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 9537bbdd09f0..74c7dfe0a97f 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -28,6 +28,14 @@ struct perf_pmu_test_event { * be set in the alias. */ const char *alias_long_desc; + + /* PMU which we should match against */ + const char *matching_pmu; +}; + +struct perf_pmu_test_pmu { + struct perf_pmu pmu; + struct perf_pmu_test_event const *aliases[10]; }; static const struct perf_pmu_test_event bp_l1_btb_correct = { @@ -118,6 +126,7 @@ static const struct perf_pmu_test_event uncore_hisi_ddrc_flux_wcmd = { }, .alias_str = "event=0x2", .alias_long_desc = "DDRC write commands", + .matching_pmu = "hisi_sccl1_ddrc2", }; static const struct perf_pmu_test_event unc_cbo_xsnp_response_miss_eviction = { @@ -131,6 +140,7 @@ static const struct perf_pmu_test_event unc_cbo_xsnp_response_miss_eviction = { }, .alias_str = "umask=0x81,event=0x22", .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .matching_pmu = "uncore_cbox_0", }; static const struct perf_pmu_test_event *uncore_events[] = { @@ -404,10 +414,103 @@ static int __test_core_pmu_event_aliases(char *pmu_name, int *count) return res; } +static int __test_uncore_pmu_event_aliases(struct perf_pmu_test_pmu *test_pmu) +{ + int alias_count = 0, to_match_count = 0, matched_count = 0; + struct perf_pmu_test_event const **table; + struct perf_pmu *pmu = &test_pmu->pmu; + const char *pmu_name = pmu->name; + struct perf_pmu_alias *a, *tmp, *alias; + struct pmu_events_map *map; + LIST_HEAD(aliases); + int res = 0; + + map = __test_pmu_get_events_map(); + if (!map) + return -1; + pmu_add_cpu_aliases_map(&aliases, pmu, map); + + /* Count how many aliases we generated */ + list_for_each_entry(alias, &aliases, list) + alias_count++; + + /* Count how many aliases we expect from the known table */ + for (table = &test_pmu->aliases[0]; *table; table++) + to_match_count++; + + if (alias_count != to_match_count) { + pr_debug("testing aliases uncore PMU %s: mismatch expected aliases (%d) vs found (%d)\n", + pmu_name, to_match_count, alias_count); + res = -1; + goto out; + } + + list_for_each_entry(alias, &aliases, list) { + bool matched = false; + + for (table = &test_pmu->aliases[0]; *table; table++) { + struct perf_pmu_test_event const *test_event = *table; + struct pmu_event const *event = &test_event->event; + + if (!strcmp(event->name, alias->name)) { + if (compare_alias_to_test_event(alias, + test_event, + pmu_name)) { + continue; + } + matched = true; + matched_count++; + } + } + + if (matched == false) { + pr_debug("testing aliases uncore PMU %s: could not match alias %s\n", + pmu_name, alias->name); + res = -1; + goto out; + } + } + + if (alias_count != matched_count) { + pr_debug("testing aliases uncore PMU %s: mismatch found aliases (%d) vs matched (%d)\n", + pmu_name, matched_count, alias_count); + res = -1; + } + +out: + list_for_each_entry_safe(a, tmp, &aliases, list) { + list_del(&a->list); + perf_pmu_free_alias(a); + } + return res; +} + +static struct perf_pmu_test_pmu test_pmus[] = { + { + .pmu = { + .name = (char *)"hisi_sccl1_ddrc2", + .is_uncore = 1, + }, + .aliases = { + &uncore_hisi_ddrc_flux_wcmd, + }, + }, + { + .pmu = { + .name = (char *)"uncore_cbox_0", + .is_uncore = 1, + }, + .aliases = { + &unc_cbo_xsnp_response_miss_eviction, + }, + }, +}; + /* Test that aliases generated are as expected */ static int test_aliases(void) { struct perf_pmu *pmu = NULL; + unsigned long i; while ((pmu = perf_pmu__scan(pmu)) != NULL) { int count = 0; @@ -434,6 +537,13 @@ static int test_aliases(void) pr_debug("testing core PMU %s aliases: pass\n", pmu->name); } + for (i = 0; i < ARRAY_SIZE(test_pmus); i++) { + int res = __test_uncore_pmu_event_aliases(&test_pmus[i]); + + if (res) + return res; + } + return 0; } -- cgit v1.2.3-70-g09d2 From 6a86657fbc245119190f3f6a477f2331e882af0c Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:23 +0800 Subject: perf test: Add more pmu-events uncore aliases Add more events to cover the scenarios fixed and also inadvertently broken by commit c47a5599eda324ba ("perf tools: Fix pattern matching for same substring in different PMU type") Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-9-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/test/test_soc/cpu/uncore.json | 23 ++++++- tools/perf/tests/pmu-events.c | 72 ++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json b/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json index d0a890cc814d..788766f45dbc 100644 --- a/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json +++ b/tools/perf/pmu-events/arch/test/test_soc/cpu/uncore.json @@ -17,5 +17,26 @@ "CounterMask": "0", "Invert": "0", "EdgeDetect": "0" - } + }, + { + "EventCode": "0x7", + "EventName": "uncore_hisi_l3c.rd_hit_cpipe", + "BriefDescription": "Total read hits", + "PublicDescription": "Total read hits", + "Unit": "hisi_sccl,l3c" + }, + { + "EventCode": "0x12", + "EventName": "uncore_imc_free_running.cache_miss", + "BriefDescription": "Total cache misses", + "PublicDescription": "Total cache misses", + "Unit": "imc_free_running" + }, + { + "EventCode": "0x34", + "EventName": "uncore_imc.cache_hits", + "BriefDescription": "Total cache hits", + "PublicDescription": "Total cache hits", + "Unit": "imc" + }, ] diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 74c7dfe0a97f..0fcdeeda00ec 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -143,9 +143,54 @@ static const struct perf_pmu_test_event unc_cbo_xsnp_response_miss_eviction = { .matching_pmu = "uncore_cbox_0", }; +static const struct perf_pmu_test_event uncore_hisi_l3c_rd_hit_cpipe = { + .event = { + .name = "uncore_hisi_l3c.rd_hit_cpipe", + .event = "event=0x2", + .desc = "Total read hits. Unit: hisi_sccl,l3c ", + .topic = "uncore", + .long_desc = "Total read hits", + .pmu = "hisi_sccl,l3c", + }, + .alias_str = "event=0x7", + .alias_long_desc = "Total read hits", + .matching_pmu = "hisi_sccl3_l3c7", +}; + +static const struct perf_pmu_test_event uncore_imc_free_running_cache_miss = { + .event = { + .name = "uncore_imc_free_running.cache_miss", + .event = "event=0x12", + .desc = "Total cache misses. Unit: uncore_imc_free_running ", + .topic = "uncore", + .long_desc = "Total cache misses", + .pmu = "uncore_imc_free_running", + }, + .alias_str = "event=0x12", + .alias_long_desc = "Total cache misses", + .matching_pmu = "uncore_imc_free_running_0", +}; + +static const struct perf_pmu_test_event uncore_imc_cache_hits = { + .event = { + .name = "uncore_imc.cache_hits", + .event = "event=0x34", + .desc = "Total cache hits. Unit: uncore_imc ", + .topic = "uncore", + .long_desc = "Total cache hits", + .pmu = "uncore_imc", + }, + .alias_str = "event=0x34", + .alias_long_desc = "Total cache hits", + .matching_pmu = "uncore_imc_0", +}; + static const struct perf_pmu_test_event *uncore_events[] = { &uncore_hisi_ddrc_flux_wcmd, &unc_cbo_xsnp_response_miss_eviction, + &uncore_hisi_l3c_rd_hit_cpipe, + &uncore_imc_free_running_cache_miss, + &uncore_imc_cache_hits, NULL }; @@ -504,6 +549,33 @@ static struct perf_pmu_test_pmu test_pmus[] = { &unc_cbo_xsnp_response_miss_eviction, }, }, + { + .pmu = { + .name = (char *)"hisi_sccl3_l3c7", + .is_uncore = 1, + }, + .aliases = { + &uncore_hisi_l3c_rd_hit_cpipe, + }, + }, + { + .pmu = { + .name = (char *)"uncore_imc_free_running_0", + .is_uncore = 1, + }, + .aliases = { + &uncore_imc_free_running_cache_miss, + }, + }, + { + .pmu = { + .name = (char *)"uncore_imc_0", + .is_uncore = 1, + }, + .aliases = { + &uncore_imc_cache_hits, + }, + }, }; /* Test that aliases generated are as expected */ -- cgit v1.2.3-70-g09d2 From e199f47f159d72f12b91d2b33cee78f95ff8ff59 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:24 +0800 Subject: perf pmu: Make pmu_add_sys_aliases() public Function pmu_add_sys_aliases() will be required for the PMU events test for system events aliases, so make it public. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-10-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 2 +- tools/perf/util/pmu.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index b1fc82073443..6cdbee8a12e7 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -926,7 +926,7 @@ static int pmu_add_sys_aliases_iter_fn(struct pmu_event *pe, void *data) return 0; } -static void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu) +void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu) { struct pmu_sys_event_iter_data idata = { .head = head, diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 926da483a141..033e8211c025 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -81,6 +81,7 @@ struct perf_pmu_alias { struct perf_pmu *perf_pmu__find(const char *name); struct perf_pmu *perf_pmu__find_by_type(unsigned int type); +void pmu_add_sys_aliases(struct list_head *head, struct perf_pmu *pmu); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms, struct parse_events_error *error); -- cgit v1.2.3-70-g09d2 From 5abd3988b0382d31a35600732a46fa7f90740658 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:25 +0800 Subject: perf jevents: Print SoC name per system event table Print the SoC name per system event table, which will allow the test SoC be identified by the pmu-events test. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-11-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/pmu-events/jevents.c | 3 ++- tools/perf/pmu-events/pmu-events.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 405bdd36b9b9..6731b3cf0c2f 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -836,7 +836,8 @@ static int process_system_event_tables(FILE *outfp) print_system_event_mapping_table_prefix(outfp); list_for_each_entry(sys_event_table, &sys_event_tables, list) { - fprintf(outfp, "\n\t{\n\t\t.table = %s,\n\t},", + fprintf(outfp, "\n\t{\n\t\t.table = %s,\n\t\t.name = \"%s\",\n\t},", + sys_event_table->soc_id, sys_event_table->soc_id); } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index d1172f6aebf1..5c2bf7275c1c 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -45,6 +45,7 @@ struct pmu_events_map { }; struct pmu_sys_events { + const char *name; struct pmu_event *table; }; -- cgit v1.2.3-70-g09d2 From 8ee465a181d0100533c6039bbbcea5517a049aec Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 29 Jul 2021 21:56:26 +0800 Subject: perf test: Add pmu-events sys event support Add support for system events, along with core and uncore events. Support for a sample PMU is also added. Signed-off-by: John Garry Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jin Yao Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: linuxarm@huawei.com Link: https //lore.kernel.org/r/1627566986-30605-12-git-send-email-john.garry@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/test/test_soc/sys/uncore.json | 9 +++ tools/perf/tests/pmu-events.c | 77 +++++++++++++++++++++- 2 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 tools/perf/pmu-events/arch/test/test_soc/sys/uncore.json diff --git a/tools/perf/pmu-events/arch/test/test_soc/sys/uncore.json b/tools/perf/pmu-events/arch/test/test_soc/sys/uncore.json new file mode 100644 index 000000000000..0f681a6e10ea --- /dev/null +++ b/tools/perf/pmu-events/arch/test/test_soc/sys/uncore.json @@ -0,0 +1,9 @@ +[ + { + "BriefDescription": "ddr write-cycles event", + "EventCode": "0x2b", + "EventName": "sys_ddr_pmu.write_cycles", + "Unit": "sys_ddr_pmu", + "Compat": "v8" + }, +] diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index 0fcdeeda00ec..43743cf719ef 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -194,6 +194,25 @@ static const struct perf_pmu_test_event *uncore_events[] = { NULL }; +static const struct perf_pmu_test_event sys_ddr_pmu_write_cycles = { + .event = { + .name = "sys_ddr_pmu.write_cycles", + .event = "event=0x2b", + .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .topic = "uncore", + .pmu = "uncore_sys_ddr_pmu", + .compat = "v8", + }, + .alias_str = "event=0x2b", + .alias_long_desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .matching_pmu = "uncore_sys_ddr_pmu", +}; + +static const struct perf_pmu_test_event *sys_events[] = { + &sys_ddr_pmu_write_cycles, + NULL +}; + static bool is_same(const char *reference, const char *test) { if (!reference && !test) @@ -222,6 +241,18 @@ static struct pmu_events_map *__test_pmu_get_events_map(void) return NULL; } +static struct pmu_event *__test_pmu_get_sys_events_table(void) +{ + struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; + + for ( ; tables->name; tables++) { + if (!strcmp("pme_test_soc_sys", tables->name)) + return tables->table; + } + + return NULL; +} + static int compare_pmu_events(struct pmu_event *e1, const struct pmu_event *e2) { if (!is_same(e1->desc, e2->desc)) { @@ -344,15 +375,17 @@ static int compare_alias_to_test_event(struct perf_pmu_alias *alias, /* Verify generated events from pmu-events.c are as expected */ static int test_pmu_event_table(void) { + struct pmu_event *sys_event_tables = __test_pmu_get_sys_events_table(); struct pmu_events_map *map = __test_pmu_get_events_map(); struct pmu_event *table; int map_events = 0, expected_events; - /* ignore 2x sentinels */ + /* ignore 3x sentinels */ expected_events = ARRAY_SIZE(core_events) + - ARRAY_SIZE(uncore_events) - 2; + ARRAY_SIZE(uncore_events) + + ARRAY_SIZE(sys_events) - 3; - if (!map) + if (!map || !sys_event_tables) return -1; for (table = map->table; table->name; table++) { @@ -386,6 +419,33 @@ static int test_pmu_event_table(void) } } + for (table = sys_event_tables; table->name; table++) { + struct perf_pmu_test_event const **test_event_table; + bool found = false; + + test_event_table = &sys_events[0]; + + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; + + if (strcmp(table->name, event->name)) + continue; + found = true; + map_events++; + + if (compare_pmu_events(table, event)) + return -1; + + pr_debug("testing sys event table %s: pass\n", table->name); + } + if (!found) { + pr_debug("testing event table: could not find event %s\n", + table->name); + return -1; + } + } + if (map_events != expected_events) { pr_err("testing event table: found %d, but expected %d\n", map_events, expected_events); @@ -474,6 +534,7 @@ static int __test_uncore_pmu_event_aliases(struct perf_pmu_test_pmu *test_pmu) if (!map) return -1; pmu_add_cpu_aliases_map(&aliases, pmu, map); + pmu_add_sys_aliases(&aliases, pmu); /* Count how many aliases we generated */ list_for_each_entry(alias, &aliases, list) @@ -576,6 +637,16 @@ static struct perf_pmu_test_pmu test_pmus[] = { &uncore_imc_cache_hits, }, }, + { + .pmu = { + .name = (char *)"uncore_sys_ddr_pmu0", + .is_uncore = 1, + .id = (char *)"v8", + }, + .aliases = { + &sys_ddr_pmu_write_cycles, + }, + }, }; /* Test that aliases generated are as expected */ -- cgit v1.2.3-70-g09d2 From e0ddfd8d5018f4cb203a7c41906c16e841a124a8 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 09:25:02 +0800 Subject: perf vendor events intel: Update core event list for CascadeLake Server Update JSON core events for CascadeLake Server. Based on JSON list v1.11: https://download.01.org/perfmon/CLX/ Signed-off-by: Jin Yao Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-2-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../pmu-events/arch/x86/cascadelakex/cache.json | 5468 ++++++++++---------- .../arch/x86/cascadelakex/floating-point.json | 48 +- .../pmu-events/arch/x86/cascadelakex/frontend.json | 550 +- .../pmu-events/arch/x86/cascadelakex/memory.json | 5444 +++++++++---------- .../pmu-events/arch/x86/cascadelakex/other.json | 4146 +++++++-------- .../pmu-events/arch/x86/cascadelakex/pipeline.json | 1046 ++-- .../arch/x86/cascadelakex/virtual-memory.json | 256 +- 7 files changed, 8484 insertions(+), 8474 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/cache.json b/tools/perf/pmu-events/arch/x86/cascadelakex/cache.json index 3c0f5837480f..ffafb9f284d2 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/cache.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/cache.json @@ -1,9976 +1,9976 @@ [ { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "L1D data line replacements", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x51", + "EventName": "L1D.REPLACEMENT", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.FB_FULL", + "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "L1D miss outstandings duration in cycles", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING", + "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles with L1D load Misses outstanding.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "AnyThread": "1", + "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "L2 cache lines filling L2", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF1", + "EventName": "L2_LINES_IN.ALL", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", + "SampleAfterValue": "100003", + "UMask": "0x1f" + }, + { + "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.NON_SILENT", + "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.SILENT", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.USELESS_HWPF", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event L2_LINES_OUT.USELESS_HWPF", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Deprecated": "1", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.USELESS_PREF", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "L2 code requests", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "PublicDescription": "Counts the total number of L2 code requests.", + "SampleAfterValue": "200003", + "UMask": "0xe4" + }, + { + "BriefDescription": "Demand Data Read requests", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", + "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "UMask": "0xe1" + }, + { + "BriefDescription": "Demand requests that miss L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_MISS", + "PublicDescription": "Demand requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x27" + }, + { + "BriefDescription": "Demand requests to L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", + "PublicDescription": "Demand requests to L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xe7" + }, + { + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_PF", + "PublicDescription": "Counts the total number of requests from the L2 hardware prefetchers.", + "SampleAfterValue": "200003", + "UMask": "0xf8" + }, + { + "BriefDescription": "RFO requests to L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_RFO", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "SampleAfterValue": "200003", + "UMask": "0xe2" + }, + { + "BriefDescription": "L2 cache hits when fetching instructions, code reads.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "SampleAfterValue": "200003", + "UMask": "0xc4" + }, + { + "BriefDescription": "L2 cache misses when fetching instructions", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "SampleAfterValue": "200003", + "UMask": "0x24" + }, + { + "BriefDescription": "Demand Data Read requests that hit L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", + "PublicDescription": "Counts the number of demand Data Read requests, initiated by load instructions, that hit L2 cache", + "SampleAfterValue": "200003", + "UMask": "0xc1" + }, + { + "BriefDescription": "Demand Data Read miss L2, no rejects", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", + "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", + "SampleAfterValue": "200003", + "UMask": "0x21" + }, + { + "BriefDescription": "All requests that miss L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.MISS", + "PublicDescription": "All requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x3f" + }, + { + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.PF_HIT", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xd8" + }, + { + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.PF_MISS", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x38" + }, + { + "BriefDescription": "All L2 requests", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.REFERENCES", + "PublicDescription": "All L2 requests.", + "SampleAfterValue": "200003", + "UMask": "0xff" + }, + { + "BriefDescription": "RFO requests that hit L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_HIT", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xc2" + }, + { + "BriefDescription": "RFO requests that miss L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_MISS", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x22" + }, + { + "BriefDescription": "L2 writebacks that access L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF0", + "EventName": "L2_TRANS.L2_WB", + "PublicDescription": "Counts L2 writebacks that access L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x40" + }, + { + "BriefDescription": "Core-originated cacheable demand requests missed L3", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Errata": "SKL057", + "EventCode": "0x2E", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x41" + }, + { + "BriefDescription": "Core-originated cacheable demand requests that refer to L3", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Errata": "SKL057", + "EventCode": "0x2E", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x4f" + }, + { + "BriefDescription": "All retired load instructions.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x81" + }, + { + "BriefDescription": "All retired store instructions.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x82" + }, + { + "BriefDescription": "Retired load instructions with locked access.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x21" + }, + { + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x41" + }, + { + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400028000", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x42" + }, + { + "BriefDescription": "Retired load instructions that miss the STLB.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "PEBS": "1", + "SampleAfterValue": "100003", + "UMask": "0x11" + }, + { + "BriefDescription": "Retired store instructions that miss the STLB.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "SampleAfterValue": "100003", + "UMask": "0x12" + }, + { + "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", + "SampleAfterValue": "20011", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", + "SampleAfterValue": "20011", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "PEBS": "1", + "SampleAfterValue": "20011", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", + "SampleAfterValue": "100007", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions whose data sources was forwarded from a remote cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_FWD", + "PublicDescription": "Retired load instructions whose data sources was forwarded from a remote cache.", + "SampleAfterValue": "100007", + "UMask": "0x8" + }, + { + "BriefDescription": "Retired load instructions whose data sources was remote HITM", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", + "PEBS": "1", + "PublicDescription": "Retired load instructions whose data sources was remote HITM.", + "SampleAfterValue": "100007", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions with remote Intel Optane DC persistent memory as the data source where the data request missed all caches. Precise event.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "ELLC": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_PMM", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with remote Intel Optane DC persistent memory as the data source and the data request missed L3 (AppDirect or Memory Mode) and DRAM cache(Memory Mode). Precise event", + "SampleAfterValue": "100007", + "UMask": "0x10" + }, + { + "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD4", + "EventName": "MEM_LOAD_MISC_RETIRED.UC", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", + "SampleAfterValue": "100007", + "UMask": "0x40" + }, + { + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PEBS": "1", + "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PEBS": "1", + "PublicDescription": "Retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "50021", + "UMask": "0x10" + }, + { + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", + "SampleAfterValue": "50021", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", + "SampleAfterValue": "100007", + "UMask": "0x20" + }, + { + "BriefDescription": "Retired load instructions with local Intel Optane DC persistent memory as the data source where the data request missed all caches. Precise event.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "ELLC": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.LOCAL_PMM", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with local Intel Optane DC persistent memory as the data source and the data request missed L3 (AppDirect or Memory Mode) and DRAM cache(Memory Mode). Precise event", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Demand and prefetch data reads", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0x8" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Any memory transaction that reached the SQ.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400002", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0x80" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "Cacheable and noncachaeble code read requests", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0004", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", + "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Demand Data Read requests sent to uncore", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand requests that miss L2 cache", + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_MISS", - "PublicDescription": "Demand requests that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x27" + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "SampleAfterValue": "100003", + "UMask": "0x4" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB2", + "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", + "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040010", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", + "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L3_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", - "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", "UMask": "0x4" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400001", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Offcore outstanding Demand Data Read transactions in uncore queue.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding Demand Data Read transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor. See the corresponding Umask under OFFCORE_REQUESTS.Note: A prefetch promoted to Demand is counted from the promotion point.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "L2 writebacks that access L2 cache", + "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF0", - "EventName": "L2_TRANS.L2_WB", - "PublicDescription": "Counts L2 writebacks that access L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x40" + "CounterMask": "6", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "L2 cache lines filling L2", + "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF1", - "EventName": "L2_LINES_IN.ALL", - "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", - "SampleAfterValue": "100003", - "UMask": "0x1f" + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x4" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200002", - "Offcore": "1", + "EventName": "OFFCORE_RESPONSE", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0010", + "MSRValue": "0x0000010491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020004", + "MSRValue": "0x3F803C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040080", + "MSRValue": "0x10003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000807F7", + "MSRValue": "0x08003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.SILENT", - "SampleAfterValue": "200003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080080", + "MSRValue": "0x04003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100020", + "MSRValue": "0x01003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080004", + "MSRValue": "0x08007C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0080", + "MSRValue": "0x02003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200001", + "MSRValue": "0x00803C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020491", + "MSRValue": "0x3F80080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100001", + "MSRValue": "0x1000080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200004", + "MSRValue": "0x0800080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0100", + "MSRValue": "0x0400080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100080", + "MSRValue": "0x0100080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200020", + "MSRValue": "0x0200080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200100", + "MSRValue": "0x0080080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040020", + "MSRValue": "0x3F80200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020490", + "MSRValue": "0x1000200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200490", + "MSRValue": "0x0800200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80028000", + "MSRValue": "0x0400200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F804007F7", + "MSRValue": "0x0100200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100400", + "MSRValue": "0x0200200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020400", + "MSRValue": "0x0080200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040400", + "MSRValue": "0x3F80040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "All requests that miss L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.MISS", - "PublicDescription": "All requests that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x3f" - }, - { - "BriefDescription": "Retired load instructions whose data sources was forwarded from a remote cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_FWD", - "PublicDescription": "Retired load instructions whose data sources was forwarded from a remote cache.", - "SampleAfterValue": "100007", - "UMask": "0x8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400490", + "MSRValue": "0x1000040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0400", + "MSRValue": "0x0800040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400490", + "MSRValue": "0x0400040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020491", + "MSRValue": "0x0100040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", - "SampleAfterValue": "20011", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040001", + "MSRValue": "0x0200040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100122", + "MSRValue": "0x0080040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0080", + "MSRValue": "0x3F80100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions missed L1 cache as data sources", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L1_MISS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", - "SampleAfterValue": "100003", - "UMask": "0x8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800108000", + "MSRValue": "0x1000100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020122", + "MSRValue": "0x0800100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020080", + "MSRValue": "0x0400100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200010", + "MSRValue": "0x0100100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100002", + "MSRValue": "0x0200100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100020", + "MSRValue": "0x0080100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400002", + "MSRValue": "0x3F80400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200048000", + "MSRValue": "0x0080400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080400", + "MSRValue": "0x0100400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200122", + "MSRValue": "0x3F80020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040001", + "MSRValue": "0x1000020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080122", + "MSRValue": "0x0800020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020122", + "MSRValue": "0x0400020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200122", + "MSRValue": "0x0100020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400208000", + "MSRValue": "0x0200020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100010", + "MSRValue": "0x0080020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020080", + "MSRValue": "0x0000010490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100491", + "MSRValue": "0x3F803C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200020", + "MSRValue": "0x10003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Any memory transaction that reached the SQ.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", - "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", - "SampleAfterValue": "100003", - "UMask": "0x80" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200010", + "MSRValue": "0x08003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200120", + "MSRValue": "0x04003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040120", + "MSRValue": "0x01003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100048000", + "MSRValue": "0x08007C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000028000", + "MSRValue": "0x02003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200400", + "MSRValue": "0x00803C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0010", + "MSRValue": "0x3F80080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD4", - "EventName": "MEM_LOAD_MISC_RETIRED.UC", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x4" - }, - { - "BriefDescription": "Retired load instructions with remote Intel\u00ae Optane\u2122 DC persistent memory as the data source where the data request missed all caches. Precise event.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "ELLC": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_PMM", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with remote Intel\u00ae Optane\u2122 DC persistent memory as the data source and the data request missed L3 (AppDirect or Memory Mode) and DRAM cache(Memory Mode). Precise event", - "SampleAfterValue": "100007", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080122", + "MSRValue": "0x1000080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080400", + "MSRValue": "0x0800080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000807F7", + "MSRValue": "0x0400080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0490", + "MSRValue": "0x0100080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080002", + "MSRValue": "0x0200080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080010", + "MSRValue": "0x0080080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400001", + "MSRValue": "0x3F80200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010490", + "MSRValue": "0x1000200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0800200490", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400122", + "MSRValue": "0x0400200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", - "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", - "SampleAfterValue": "200003", - "UMask": "0xe1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200020", + "MSRValue": "0x0100200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040491", + "MSRValue": "0x0200200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040010", + "MSRValue": "0x0080200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0001", + "MSRValue": "0x3F80040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200028000", + "MSRValue": "0x1000040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", - "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100001", + "MSRValue": "0x0800040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of cache line split locks sent to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF4", - "EventName": "SQ_MISC.SPLIT_LOCK", - "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", - "SampleAfterValue": "100003", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200100", + "MSRValue": "0x0400040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100002", + "MSRValue": "0x0100040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L2 cache hits when fetching instructions, code reads.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.CODE_RD_HIT", - "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", - "SampleAfterValue": "200003", - "UMask": "0xc4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200120", + "MSRValue": "0x0200040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020010", + "MSRValue": "0x0080040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10001007F7", + "MSRValue": "0x3F80100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040122", + "MSRValue": "0x1000100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100010", + "MSRValue": "0x0800100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02001007F7", + "MSRValue": "0x0400100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020120", + "MSRValue": "0x0100100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040120", + "MSRValue": "0x0200100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040020", + "MSRValue": "0x0080100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08001007F7", + "MSRValue": "0x3F80400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C07F7", + "MSRValue": "0x0080400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0004", + "MSRValue": "0x0100400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", - "SampleAfterValue": "20011", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200020", + "MSRValue": "0x3F80020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200080", + "MSRValue": "0x1000020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400048000", + "MSRValue": "0x0800020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.SPLIT_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", - "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0400020490", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x42" + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010122", + "MSRValue": "0x0100020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100120", + "MSRValue": "0x0200020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010002", + "MSRValue": "0x0080020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020491", + "MSRValue": "0x0000010120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100120", + "MSRValue": "0x3F803C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010001", + "MSRValue": "0x10003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080400", + "MSRValue": "0x08003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400080", + "MSRValue": "0x04003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0122", + "MSRValue": "0x01003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400080", + "MSRValue": "0x08007C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080120", + "MSRValue": "0x02003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080001", + "MSRValue": "0x00803C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100491", + "MSRValue": "0x3F80080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100002", + "MSRValue": "0x1000080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400100", + "MSRValue": "0x0800080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080001", + "MSRValue": "0x0400080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010004", + "MSRValue": "0x0100080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100490", + "MSRValue": "0x0200080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040004", + "MSRValue": "0x0080080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400020", + "MSRValue": "0x3F80200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C8000", + "MSRValue": "0x1000200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020100", + "MSRValue": "0x0800200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200020", + "MSRValue": "0x0400200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200400", + "MSRValue": "0x0100200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040120", + "MSRValue": "0x0200200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0400", + "MSRValue": "0x0080200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040020", + "MSRValue": "0x3F80040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100120", + "MSRValue": "0x1000040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400002", + "MSRValue": "0x0800040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040491", + "MSRValue": "0x0400040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.FB_FULL", - "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0100040120", + "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020020", + "MSRValue": "0x0200040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0120", + "MSRValue": "0x0080040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020010", + "MSRValue": "0x3F80100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200490", + "MSRValue": "0x1000100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0100", + "MSRValue": "0x0800100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040001", + "MSRValue": "0x0400100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB2", - "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", - "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200020", + "MSRValue": "0x0100100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200490", + "MSRValue": "0x0200100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0100", + "MSRValue": "0x0080100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400491", + "MSRValue": "0x3F80400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000207F7", + "MSRValue": "0x0080400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080120", + "MSRValue": "0x0100400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions missed L2 cache as data sources", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L2_MISS", - "PEBS": "1", - "PublicDescription": "Retired load instructions missed L2 cache as data sources.", - "SampleAfterValue": "50021", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0122", + "MSRValue": "0x3F80020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200400", + "MSRValue": "0x1000020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400004", + "MSRValue": "0x0800020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020120", + "MSRValue": "0x0400020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200100", + "MSRValue": "0x0100020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040080", + "MSRValue": "0x0200020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200088000", + "MSRValue": "0x0080020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C8000", + "MSRValue": "0x00000107F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200001", + "MSRValue": "0x3F803C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080020", + "MSRValue": "0x10003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400490", + "MSRValue": "0x08003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400400", + "MSRValue": "0x04003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400020", + "MSRValue": "0x01003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.PF_MISS", - "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x38" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000407F7", + "MSRValue": "0x08007C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200100", + "MSRValue": "0x02003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080004", + "MSRValue": "0x00803C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040400", + "MSRValue": "0x3F800807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100004", + "MSRValue": "0x10000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080080", + "MSRValue": "0x08000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000407F7", + "MSRValue": "0x04000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800207F7", + "MSRValue": "0x01000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0491", + "MSRValue": "0x02000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010080", + "MSRValue": "0x00800807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020122", + "MSRValue": "0x3F802007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0122", + "MSRValue": "0x10002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080001", + "MSRValue": "0x08002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020491", + "MSRValue": "0x04002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040001", + "MSRValue": "0x01002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400122", + "MSRValue": "0x02002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010020", + "MSRValue": "0x00802007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0490", + "MSRValue": "0x3F800407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020020", + "MSRValue": "0x10000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100122", + "MSRValue": "0x08000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200001", + "MSRValue": "0x04000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020080", + "MSRValue": "0x01000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040010", + "MSRValue": "0x02000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080100", + "MSRValue": "0x00800407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020490", + "MSRValue": "0x3F801007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000207F7", + "MSRValue": "0x10001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions missed L3 cache as data sources", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L3_MISS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", - "SampleAfterValue": "100007", - "UMask": "0x20" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200100", + "MSRValue": "0x08001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020002", + "MSRValue": "0x04001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080028000", + "MSRValue": "0x01001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020491", + "MSRValue": "0x02001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080120", + "MSRValue": "0x00801007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0120", + "MSRValue": "0x3F804007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0010", + "MSRValue": "0x00804007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020020", + "MSRValue": "0x01004007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020100", + "MSRValue": "0x3F800207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x1" - }, - { - "BriefDescription": "Core-originated cacheable demand requests missed L3", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL057", - "EventCode": "0x2E", - "EventName": "LONGEST_LAT_CACHE.MISS", - "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", - "SampleAfterValue": "100003", - "UMask": "0x41" + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200490", + "MSRValue": "0x10000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200080", + "MSRValue": "0x08000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080120", + "MSRValue": "0x04000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020010", + "MSRValue": "0x01000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0120", + "MSRValue": "0x02000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020400", + "MSRValue": "0x00800207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100400", + "MSRValue": "0x0000010122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C8000", + "MSRValue": "0x3F803C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0400", + "MSRValue": "0x10003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040120", + "MSRValue": "0x08003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0100", + "MSRValue": "0x04003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200002", + "MSRValue": "0x01003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0490", + "MSRValue": "0x08007C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200100", + "MSRValue": "0x02003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01004007F7", + "MSRValue": "0x00803C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080120", + "MSRValue": "0x3F80080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", - "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0491", + "MSRValue": "0x1000080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100100", + "MSRValue": "0x0800080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020100", + "MSRValue": "0x0400080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080010", + "MSRValue": "0x0100080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400010", + "MSRValue": "0x0200080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.NON_SILENT", - "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", - "SampleAfterValue": "200003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040010", + "MSRValue": "0x0080080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00804007F7", + "MSRValue": "0x3F80200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0020", + "MSRValue": "0x1000200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100100", + "MSRValue": "0x0800200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "RFO requests that hit L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.RFO_HIT", - "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xc2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100080", + "MSRValue": "0x0400200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200001", + "MSRValue": "0x0100200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020100", + "MSRValue": "0x0200200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", - "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x8" + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.SNOOP_NONE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0080200122", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400108000", + "MSRValue": "0x3F80040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00000107F7", + "MSRValue": "0x1000040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800807F7", + "MSRValue": "0x0800040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040004", + "MSRValue": "0x0400040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020001", + "MSRValue": "0x0100040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100122", + "MSRValue": "0x0200040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100122", + "MSRValue": "0x0080040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0001", + "MSRValue": "0x3F80100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080002", + "MSRValue": "0x1000100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040010", + "MSRValue": "0x0800100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200010", + "MSRValue": "0x0400100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100100", + "MSRValue": "0x0100100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200001", + "MSRValue": "0x0200100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080408000", + "MSRValue": "0x0080100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040400", + "MSRValue": "0x3F80400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040400", + "MSRValue": "0x0080400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080491", + "MSRValue": "0x0100400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0491", + "MSRValue": "0x3F80020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200080", + "MSRValue": "0x1000020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040122", + "MSRValue": "0x0800020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080088000", + "MSRValue": "0x0400020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040490", + "MSRValue": "0x0100020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0080", + "MSRValue": "0x0200020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100122", + "MSRValue": "0x0080020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020004", + "MSRValue": "0x0000010004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100080", + "MSRValue": "0x3F803C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200080", + "MSRValue": "0x10003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0002", + "MSRValue": "0x08003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080100", + "MSRValue": "0x04003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F801007F7", + "MSRValue": "0x01003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100400", + "MSRValue": "0x08007C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020400", + "MSRValue": "0x02003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040490", + "MSRValue": "0x00803C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100002", + "MSRValue": "0x3F80080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0002", + "MSRValue": "0x1000080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080048000", + "MSRValue": "0x0800080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L1D data line replacements", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x51", - "EventName": "L1D.REPLACEMENT", - "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020010", + "MSRValue": "0x0400080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0010", + "MSRValue": "0x0100080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200010", + "MSRValue": "0x0200080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080122", + "MSRValue": "0x0080080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200010", + "MSRValue": "0x3F80200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200122", + "MSRValue": "0x1000200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040490", + "MSRValue": "0x0800200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100002", + "MSRValue": "0x0400200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080491", + "MSRValue": "0x0100200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests that hit L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", - "PublicDescription": "Counts the number of demand Data Read requests, initiated by load instructions, that hit L2 cache", - "SampleAfterValue": "200003", - "UMask": "0xc1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C07F7", + "MSRValue": "0x0200200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100010", + "MSRValue": "0x0080200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "All retired load instructions.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.ALL_LOADS", - "PEBS": "1", - "SampleAfterValue": "2000003", - "UMask": "0x81" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200400", + "MSRValue": "0x3F80040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0080", + "MSRValue": "0x1000040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000108000", + "MSRValue": "0x0800040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020010", + "MSRValue": "0x0400040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080010", + "MSRValue": "0x0100040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040491", + "MSRValue": "0x0200040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800208000", + "MSRValue": "0x0080040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010010", + "MSRValue": "0x3F80100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020080", + "MSRValue": "0x1000100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080208000", + "MSRValue": "0x0800100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100002", + "MSRValue": "0x0400100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100020", + "MSRValue": "0x0100100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100020", + "MSRValue": "0x0200100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080100", + "MSRValue": "0x0080100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200002", + "MSRValue": "0x3F80400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100120", + "MSRValue": "0x0080400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200490", + "MSRValue": "0x0100400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0100", + "MSRValue": "0x3F80020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080491", + "MSRValue": "0x1000020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100122", + "MSRValue": "0x0800020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040004", + "MSRValue": "0x0400020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040100", + "MSRValue": "0x0100020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080020", + "MSRValue": "0x0200020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0001", + "MSRValue": "0x0080020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020080", + "MSRValue": "0x0000010001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080100", + "MSRValue": "0x3F803C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200010", + "MSRValue": "0x10003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80108000", + "MSRValue": "0x08003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0490", + "MSRValue": "0x04003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080490", + "MSRValue": "0x01003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000807F7", + "MSRValue": "0x08007C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020004", + "MSRValue": "0x02003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020002", + "MSRValue": "0x00803C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040400", + "MSRValue": "0x3F80080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", - "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080020", + "MSRValue": "0x1000080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0002", + "MSRValue": "0x0800080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0400", + "MSRValue": "0x0400080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200001", + "MSRValue": "0x0100080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200010", + "MSRValue": "0x0200080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010400", + "MSRValue": "0x0080080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000088000", + "MSRValue": "0x3F80200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0004", + "MSRValue": "0x1000200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", - "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200020", + "MSRValue": "0x0800200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080490", + "MSRValue": "0x0400200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080122", + "MSRValue": "0x0100200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400010", + "MSRValue": "0x0200200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040490", + "MSRValue": "0x0080200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040120", + "MSRValue": "0x3F80040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions that split across a cacheline boundary.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", - "SampleAfterValue": "100003", - "UMask": "0x41" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040080", + "MSRValue": "0x1000040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100491", + "MSRValue": "0x0800040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040100", + "MSRValue": "0x0400040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0122", + "MSRValue": "0x0100040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired store instructions that miss the STLB.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", - "SampleAfterValue": "100003", - "UMask": "0x12" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400001", + "MSRValue": "0x0200040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "RFO requests to L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_RFO", - "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", - "SampleAfterValue": "200003", - "UMask": "0xe2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400120", + "MSRValue": "0x0080040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C07F7", + "MSRValue": "0x3F80100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0004", + "MSRValue": "0x1000100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100010", + "MSRValue": "0x0800100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080122", + "MSRValue": "0x0400100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040080", + "MSRValue": "0x0100100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0020", + "MSRValue": "0x0200100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0004", + "MSRValue": "0x0080100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040491", + "MSRValue": "0x3F80400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0080", + "MSRValue": "0x0080400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100120", + "MSRValue": "0x0100400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0020", + "MSRValue": "0x3F80020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100490", + "MSRValue": "0x1000020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C07F7", + "MSRValue": "0x0800020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040020", + "MSRValue": "0x0400020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01001007F7", + "MSRValue": "0x0100020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040122", + "MSRValue": "0x0200020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100028000", + "MSRValue": "0x0080020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000407F7", + "MSRValue": "0x0000010002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020122", + "MSRValue": "0x3F803C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080490", + "MSRValue": "0x10003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080400", + "MSRValue": "0x08003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080004", + "MSRValue": "0x04003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0001", + "MSRValue": "0x01003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100004", + "MSRValue": "0x08007C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400491", + "MSRValue": "0x02003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080004", + "MSRValue": "0x00803C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020001", + "MSRValue": "0x3F80080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200004", + "MSRValue": "0x1000080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400088000", + "MSRValue": "0x0800080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040010", + "MSRValue": "0x0400080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100400", + "MSRValue": "0x0100080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020400", + "MSRValue": "0x0200080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040100", + "MSRValue": "0x0080080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100088000", + "MSRValue": "0x3F80200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100491", + "MSRValue": "0x1000200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200080", + "MSRValue": "0x0800200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020020", + "MSRValue": "0x0400200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_PF", - "PublicDescription": "Counts the total number of requests from the L2 hardware prefetchers.", - "SampleAfterValue": "200003", - "UMask": "0xf8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200122", + "MSRValue": "0x0100200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100004", + "MSRValue": "0x0200200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080001", + "MSRValue": "0x0080200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200400", + "MSRValue": "0x3F80040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080491", + "MSRValue": "0x1000040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080490", + "MSRValue": "0x0800040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040002", + "MSRValue": "0x0400040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080080", + "MSRValue": "0x0100040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200400", + "MSRValue": "0x0200040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L2 code requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_CODE_RD", - "PublicDescription": "Counts the total number of L2 code requests.", - "SampleAfterValue": "200003", - "UMask": "0xe4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100010", + "MSRValue": "0x0080040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020001", + "MSRValue": "0x3F80100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080100", + "MSRValue": "0x1000100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0491", + "MSRValue": "0x0800100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040002", + "MSRValue": "0x0400100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand requests to L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", - "PublicDescription": "Demand requests to L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xe7" - }, - { - "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800207F7", + "MSRValue": "0x0100100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000407F7", + "MSRValue": "0x0200100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080490", + "MSRValue": "0x0080100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100100", + "MSRValue": "0x3F80400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L2 cache misses when fetching instructions", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.CODE_RD_MISS", - "PublicDescription": "Counts L2 cache misses when fetching instructions.", - "SampleAfterValue": "200003", - "UMask": "0x24" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100080", + "MSRValue": "0x0080400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080120", + "MSRValue": "0x0100400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040100", + "MSRValue": "0x3F80020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080491", + "MSRValue": "0x1000020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding Demand Data Read transactions in uncore queue.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", - "PublicDescription": "Counts the number of offcore outstanding Demand Data Read transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor. See the corresponding Umask under OFFCORE_REQUESTS.Note: A prefetch promoted to Demand is counted from the promotion point.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0122", + "MSRValue": "0x0800020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200004", + "MSRValue": "0x0400020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000407F7", + "MSRValue": "0x0100020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100020", + "MSRValue": "0x0200020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", - "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000207F7", + "MSRValue": "0x0080020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020122", + "MSRValue": "0x0000018000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040002", + "MSRValue": "0x3F803C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0100", + "MSRValue": "0x10003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040080", + "MSRValue": "0x08003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020490", + "MSRValue": "0x04003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100001", + "MSRValue": "0x01003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040100", + "MSRValue": "0x08007C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100490", + "MSRValue": "0x02003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100004", + "MSRValue": "0x00803C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core-originated cacheable demand requests that refer to L3", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL057", - "EventCode": "0x2E", - "EventName": "LONGEST_LAT_CACHE.REFERENCE", - "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", - "SampleAfterValue": "100003", - "UMask": "0x4f" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040002", + "MSRValue": "0x3F80088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0002", + "MSRValue": "0x1000088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080020", + "MSRValue": "0x0800088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020001", + "MSRValue": "0x0400088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000208000", + "MSRValue": "0x0100088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080020", + "MSRValue": "0x0200088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0122", + "MSRValue": "0x0080088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200002", + "MSRValue": "0x3F80208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400100", + "MSRValue": "0x1000208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040491", + "MSRValue": "0x0800208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions that miss the STLB.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", - "PEBS": "1", - "SampleAfterValue": "100003", - "UMask": "0x11" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020100", + "MSRValue": "0x0400208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200122", + "MSRValue": "0x0100208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400010", + "MSRValue": "0x0200208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400080", + "MSRValue": "0x0080208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0010", + "MSRValue": "0x3F80048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200004", + "MSRValue": "0x1000048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with local Intel\u00ae Optane\u2122 DC persistent memory as the data source where the data request missed all caches. Precise event.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "ELLC": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.LOCAL_PMM", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with local Intel\u00ae Optane\u2122 DC persistent memory as the data source and the data request missed L3 (AppDirect or Memory Mode) and DRAM cache(Memory Mode). Precise event", - "SampleAfterValue": "100003", - "UMask": "0x80" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0002", + "MSRValue": "0x0800048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040010", + "MSRValue": "0x0400048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010491", + "MSRValue": "0x0100048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0400", + "MSRValue": "0x0200048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200120", + "MSRValue": "0x0080048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100490", + "MSRValue": "0x3F80108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event L2_LINES_OUT.USELESS_HWPF", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Deprecated": "1", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.USELESS_PREF", - "SampleAfterValue": "200003", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0122", + "MSRValue": "0x1000108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100491", + "MSRValue": "0x0800108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read miss L2, no rejects", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", - "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", - "SampleAfterValue": "200003", - "UMask": "0x21" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080001", + "MSRValue": "0x0400108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020002", + "MSRValue": "0x0100108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", - "PEBS": "1", - "SampleAfterValue": "20011", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.SNOOP_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0200108000", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800028000", + "MSRValue": "0x0080108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0080", + "MSRValue": "0x3F80408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0400", + "MSRValue": "0x0080408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "All L2 requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.REFERENCES", - "PublicDescription": "All L2 requests.", - "SampleAfterValue": "200003", - "UMask": "0xff" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100400", + "MSRValue": "0x0100408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020400", + "MSRValue": "0x3F80028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with L1D load Misses outstanding.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING_CYCLES", - "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100020", + "MSRValue": "0x1000028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080108000", + "MSRValue": "0x0800028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080080", + "MSRValue": "0x0400028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100120", + "MSRValue": "0x0100028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0001", + "MSRValue": "0x0200028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040490", + "MSRValue": "0x0080028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020002", + "MSRValue": "0x0000010400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0120", + "MSRValue": "0x3F803C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080100", + "MSRValue": "0x10003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020120", + "MSRValue": "0x08003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040122", + "MSRValue": "0x04003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0491", + "MSRValue": "0x01003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C8000", + "MSRValue": "0x08007C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100491", + "MSRValue": "0x02003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0100", + "MSRValue": "0x00803C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02002007F7", + "MSRValue": "0x3F80080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200080", + "MSRValue": "0x1000080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400400", + "MSRValue": "0x0800080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020020", + "MSRValue": "0x0400080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020004", + "MSRValue": "0x0100080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00801007F7", + "MSRValue": "0x0200080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100100", + "MSRValue": "0x0080080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0010", + "MSRValue": "0x3F80200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0120", + "MSRValue": "0x1000200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020120", + "MSRValue": "0x0800200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100002", + "MSRValue": "0x0400200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200108000", + "MSRValue": "0x0100200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0080", + "MSRValue": "0x0200200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040120", + "MSRValue": "0x0080200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200491", + "MSRValue": "0x3F80040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080080", + "MSRValue": "0x1000040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020002", + "MSRValue": "0x0800040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200491", + "MSRValue": "0x0400040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400122", + "MSRValue": "0x0100040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800088000", + "MSRValue": "0x0200040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040122", + "MSRValue": "0x0080040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0490", + "MSRValue": "0x3F80100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01002007F7", + "MSRValue": "0x1000100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0400", + "MSRValue": "0x0800100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0491", + "MSRValue": "0x0400100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040002", + "MSRValue": "0x0100100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080002", + "MSRValue": "0x0200100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with locked access.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.LOCK_LOADS", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x21" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0002", + "MSRValue": "0x0080100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0001", + "MSRValue": "0x3F80400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080100", + "MSRValue": "0x0080400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040020", + "MSRValue": "0x0100400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200400", + "MSRValue": "0x3F80020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "All retired store instructions.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.ALL_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", - "SampleAfterValue": "2000003", - "UMask": "0x82" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080400", + "MSRValue": "0x1000020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0001", + "MSRValue": "0x0800020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080004", + "MSRValue": "0x0400020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100120", + "MSRValue": "0x0100020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", - "SampleAfterValue": "100007", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0200020400", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020491", + "MSRValue": "0x0080020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040004", + "MSRValue": "0x0000010010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100080", + "MSRValue": "0x3F803C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400120", + "MSRValue": "0x10003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040004", + "MSRValue": "0x08003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000207F7", + "MSRValue": "0x04003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020490", + "MSRValue": "0x01003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040490", + "MSRValue": "0x08007C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080002", + "MSRValue": "0x02003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100108000", + "MSRValue": "0x00803C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040400", + "MSRValue": "0x3F80080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200002", + "MSRValue": "0x1000080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040001", + "MSRValue": "0x0800080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080020", + "MSRValue": "0x0400080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0020", + "MSRValue": "0x0100080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080122", + "MSRValue": "0x0200080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040002", + "MSRValue": "0x0080080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000048000", + "MSRValue": "0x3F80200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000807F7", + "MSRValue": "0x1000200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020004", + "MSRValue": "0x0800200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020001", + "MSRValue": "0x0400200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", - "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0100200010", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x4" + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040491", + "MSRValue": "0x0200200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020010", + "MSRValue": "0x0080200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200100", + "MSRValue": "0x3F80040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100080", + "MSRValue": "0x1000040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040004", + "MSRValue": "0x0800040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040080", + "MSRValue": "0x0400040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040001", + "MSRValue": "0x0100040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020120", + "MSRValue": "0x0200040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000207F7", + "MSRValue": "0x0080040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100001", + "MSRValue": "0x3F80100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080400", + "MSRValue": "0x1000100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests sent to uncore", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", - "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0800100010", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04001007F7", + "MSRValue": "0x0400100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0010", + "MSRValue": "0x0100100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200004", + "MSRValue": "0x0200100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040001", + "MSRValue": "0x0080100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0100", + "MSRValue": "0x3F80400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100100", + "MSRValue": "0x0080400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0010", + "MSRValue": "0x0100400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020490", + "MSRValue": "0x3F80020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040004", + "MSRValue": "0x1000020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200080", + "MSRValue": "0x0800020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200120", + "MSRValue": "0x0400020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions whose data sources was remote HITM", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", - "PEBS": "1", - "PublicDescription": "Retired load instructions whose data sources was remote HITM.", - "SampleAfterValue": "100007", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080010", + "MSRValue": "0x0100020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020100", + "MSRValue": "0x0200020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040100", + "MSRValue": "0x0080020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000018000", + "MSRValue": "0x0000010020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020020", + "MSRValue": "0x3F803C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200491", + "MSRValue": "0x10003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "RFO requests that miss L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.RFO_MISS", - "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x22" - }, - { - "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.USELESS_HWPF", - "SampleAfterValue": "200003", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100010", + "MSRValue": "0x08003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080010", + "MSRValue": "0x04003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.PF_HIT", - "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xd8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0080", + "MSRValue": "0x01003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100020", + "MSRValue": "0x08007C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020002", + "MSRValue": "0x02003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0020", + "MSRValue": "0x00803C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020004", + "MSRValue": "0x3F80080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100490", + "MSRValue": "0x1000080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020001", + "MSRValue": "0x0800080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cacheable and noncachaeble code read requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", - "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400120", + "MSRValue": "0x0400080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100010", + "MSRValue": "0x0100080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040122", + "MSRValue": "0x0200080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020122", + "MSRValue": "0x0080080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100408000", + "MSRValue": "0x3F80200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0122", + "MSRValue": "0x1000200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200004", + "MSRValue": "0x0800200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80088000", + "MSRValue": "0x0400200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080004", + "MSRValue": "0x0100200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100001", + "MSRValue": "0x0200200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08002007F7", + "MSRValue": "0x0080200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100100", + "MSRValue": "0x3F80040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020001", + "MSRValue": "0x1000040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080080", + "MSRValue": "0x0800040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020002", + "MSRValue": "0x0400040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0120", + "MSRValue": "0x0100040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020004", + "MSRValue": "0x0200040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400100", + "MSRValue": "0x0080040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0020", + "MSRValue": "0x3F80100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040020", + "MSRValue": "0x1000100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020122", + "MSRValue": "0x0800100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040080", + "MSRValue": "0x0400100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080010", + "MSRValue": "0x0100100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040002", + "MSRValue": "0x0200100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80408000", + "MSRValue": "0x0080100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040120", + "MSRValue": "0x3F80400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200122", + "MSRValue": "0x0080400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200001", + "MSRValue": "0x0100400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100001", + "MSRValue": "0x3F80020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C07F7", + "MSRValue": "0x1000020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C07F7", + "MSRValue": "0x0800020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0002", + "MSRValue": "0x0400020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040490", + "MSRValue": "0x0100020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100004", + "MSRValue": "0x0200020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080001", + "MSRValue": "0x0080020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010120", + "MSRValue": "0x0000010080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800407F7", + "MSRValue": "0x3F803C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080001", + "MSRValue": "0x10003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C07F7", + "MSRValue": "0x08003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020400", + "MSRValue": "0x04003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800807F7", + "MSRValue": "0x01003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020491", + "MSRValue": "0x08007C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100004", + "MSRValue": "0x02003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100400", + "MSRValue": "0x00803C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.FB_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", - "SampleAfterValue": "100007", - "UMask": "0x40" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200120", + "MSRValue": "0x3F80080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080010", + "MSRValue": "0x1000080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080002", + "MSRValue": "0x0800080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080490", + "MSRValue": "0x0400080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100004", + "MSRValue": "0x0100080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080120", + "MSRValue": "0x0200080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020100", + "MSRValue": "0x0080080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800407F7", + "MSRValue": "0x3F80200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040400", + "MSRValue": "0x1000200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080020", + "MSRValue": "0x0800200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200208000", + "MSRValue": "0x0400200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020490", + "MSRValue": "0x0100200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200122", + "MSRValue": "0x0200200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080002", + "MSRValue": "0x0080200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0001", + "MSRValue": "0x3F80040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200491", + "MSRValue": "0x1000040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080490", + "MSRValue": "0x0800040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80048000", + "MSRValue": "0x0400040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020080", + "MSRValue": "0x0100040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0490", + "MSRValue": "0x0200040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L2 cache hits as data sources", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L2_HIT", - "PEBS": "1", - "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0020", + "MSRValue": "0x0080040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200490", + "MSRValue": "0x3F80100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400020", + "MSRValue": "0x1000100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00802007F7", + "MSRValue": "0x0800100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L1D miss outstandings duration in cycles", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING", - "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080002", + "MSRValue": "0x0400100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200004", + "MSRValue": "0x0100100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0004", + "MSRValue": "0x0200100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0002", + "MSRValue": "0x0080100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0120", + "MSRValue": "0x3F80400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100490", + "MSRValue": "0x0080400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200490", + "MSRValue": "0x0100400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200120", + "MSRValue": "0x3F80020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080400", + "MSRValue": "0x1000020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0120", + "MSRValue": "0x0800020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400400", + "MSRValue": "0x0400020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200120", + "MSRValue": "0x0100020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020120", + "MSRValue": "0x0200020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200002", + "MSRValue": "0x0080020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.ANY_RESPONSE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0490", + "MSRValue": "0x0000010100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0491", + "MSRValue": "0x3F803C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080491", + "MSRValue": "0x10003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0020", + "MSRValue": "0x08003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0490", + "MSRValue": "0x04003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0004", + "MSRValue": "0x01003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C07F7", + "MSRValue": "0x08007C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020010", + "MSRValue": "0x02003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100491", + "MSRValue": "0x00803C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80208000", + "MSRValue": "0x3F80080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000807F7", + "MSRValue": "0x1000080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0004", + "MSRValue": "0x0800080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C8000", + "MSRValue": "0x0400080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400004", + "MSRValue": "0x0100080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100080", + "MSRValue": "0x0200080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020020", + "MSRValue": "0x0080080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020120", + "MSRValue": "0x3F80200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400004", + "MSRValue": "0x1000200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400491", + "MSRValue": "0x0800200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10002007F7", + "MSRValue": "0x0400200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C8000", + "MSRValue": "0x0100200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080080", + "MSRValue": "0x0200200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020490", + "MSRValue": "0x0080200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100400", + "MSRValue": "0x3F80040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020400", + "MSRValue": "0x1000040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040020", + "MSRValue": "0x0800040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080122", + "MSRValue": "0x0400040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L1_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Demand and prefetch data reads", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", - "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0100040100", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800048000", + "MSRValue": "0x0200040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100208000", + "MSRValue": "0x0080040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020080", + "MSRValue": "0x3F80100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0400", + "MSRValue": "0x1000100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200491", + "MSRValue": "0x0800100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C8000", + "MSRValue": "0x0400100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200002", + "MSRValue": "0x0100100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040122", + "MSRValue": "0x0200100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080491", + "MSRValue": "0x0080100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", - "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200491", + "MSRValue": "0x3F80400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100490", + "MSRValue": "0x0080400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040100", + "MSRValue": "0x0100400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C8000", + "MSRValue": "0x3F80020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F802007F7", + "MSRValue": "0x1000020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100001", + "MSRValue": "0x0800020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100122", + "MSRValue": "0x0400020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04002007F7", + "MSRValue": "0x0100020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.ANY_RESPONSE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010100", + "MSRValue": "0x0200020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080004", + "MSRValue": "0x0080020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" + }, + { + "BriefDescription": "Number of cache line split locks sent to uncore.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF4", + "EventName": "SQ_MISC.SPLIT_LOCK", + "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", + "SampleAfterValue": "100003", + "UMask": "0x10" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/floating-point.json b/tools/perf/pmu-events/arch/x86/cascadelakex/floating-point.json index 3c0b95fd60ad..ade925d7a68c 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/floating-point.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/floating-point.json @@ -1,12 +1,12 @@ [ { - "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT14 RCP14 DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x4" }, { "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", @@ -18,13 +18,13 @@ "UMask": "0x8" }, { - "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", "SampleAfterValue": "2000003", - "UMask": "0x40" + "UMask": "0x10" }, { "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", @@ -36,13 +36,13 @@ "UMask": "0x20" }, { - "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x40" }, { "BriefDescription": "Number of SSE/AVX computational 512-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", @@ -54,32 +54,32 @@ "UMask": "0x80" }, { - "BriefDescription": "Cycles with any input/output SSE or FP assist", + "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xCA", - "EventName": "FP_ASSIST.ANY", - "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", - "SampleAfterValue": "100003", - "UMask": "0x1e" + "EventCode": "0xC7", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 2 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB HADD HSUB SUBADD MUL DIV MIN MAX SQRT RSQRT14 RCP14 DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x2" }, { - "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Cycles with any input/output SSE or FP assist", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterMask": "1", + "EventCode": "0xCA", + "EventName": "FP_ASSIST.ANY", + "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", + "SampleAfterValue": "100003", + "UMask": "0x1e" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/frontend.json b/tools/perf/pmu-events/arch/x86/cascadelakex/frontend.json index 0716b2e3ff75..078706a50091 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/frontend.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/frontend.json @@ -1,210 +1,125 @@ [ { - "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", - "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", - "SampleAfterValue": "2000003", + "EventCode": "0xE6", + "EventName": "BACLEARS.ANY", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switches", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.L2_MISS", - "MSRIndex": "0x3F7", - "MSRValue": "0x13", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xAB", + "EventName": "DSB2MITE_SWITCHES.COUNT", + "PublicDescription": "This event counts the number of the Decode Stream Buffer (DSB)-to-MITE switches including all misses because of missing Decode Stream Buffer (DSB) cache and u-arch forced misses.\nNote: Invoking MITE requires two or three cycles delay.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.MS_MITE_UOPS", - "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "EventCode": "0xAB", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 02 cycles.", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x2" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", + "EventName": "FRONTEND_RETIRED.DSB_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x200206", + "MSRValue": "0x11", "PEBS": "1", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x300206", + "MSRValue": "0x14", "PEBS": "1", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "EventName": "FRONTEND_RETIRED.L1I_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x100206", + "MSRValue": "0x12", "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts cycles FE delivered 4 uops or Resource Allocation Table (RAT) was stalling FE.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", - "Invert": "1", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.MS_UOPS", - "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", - "SampleAfterValue": "2000003", - "UMask": "0x30" - }, - { - "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.L1I_MISS", + "EventName": "FRONTEND_RETIRED.L2_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x12", + "MSRValue": "0x13", "PEBS": "1", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", + "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", - "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x400106", + "PEBS": "2", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.DSB_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.DSB_MISS", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", "MSRIndex": "0x3F7", - "MSRValue": "0x11", + "MSRValue": "0x408006", "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.MITE_UOPS", - "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.MS_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", - "SampleAfterValue": "2000003", - "UMask": "0x30" - }, - { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.MITE_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", - "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding 4 x when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAB", - "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", - "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 02 cycles.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", "MSRIndex": "0x3F7", - "MSRValue": "0x400806", + "MSRValue": "0x401006", "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" @@ -223,93 +138,96 @@ "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", "MSRIndex": "0x3F7", - "MSRValue": "0x400406", + "MSRValue": "0x410006", "PEBS": "1", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.MS_DSB_CYCLES", - "PublicDescription": "Counts cycles during which uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x100206", + "PEBS": "1", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switches", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAB", - "EventName": "DSB2MITE_SWITCHES.COUNT", - "PublicDescription": "This event counts the number of the Decode Stream Buffer (DSB)-to-MITE switches including all misses because of missing Decode Stream Buffer (DSB) cache and u-arch forced misses.\nNote: Invoking MITE requires two or three cycles delay.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", + "MSRIndex": "0x3F7", + "MSRValue": "0x200206", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", - "Counter": "0,1,2,3,4,5,6,7", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xc6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", "MSRIndex": "0x3F7", - "MSRValue": "0x400106", - "PEBS": "2", - "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", + "MSRValue": "0x300206", + "PEBS": "1", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x83", - "EventName": "ICACHE_64B.IFTAG_MISS", - "SampleAfterValue": "200003", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "MSRValue": "0x402006", + "PEBS": "1", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", "MSRIndex": "0x3F7", - "MSRValue": "0x408006", + "MSRValue": "0x400406", "PEBS": "1", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", - "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x83", - "EventName": "ICACHE_64B.IFTAG_HIT", - "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "MSRValue": "0x420006", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { @@ -326,38 +244,29 @@ "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.STLB_MISS", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", "MSRIndex": "0x3F7", - "MSRValue": "0x15", + "MSRValue": "0x400806", "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.DSB_UOPS", - "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "EventName": "FRONTEND_RETIRED.STLB_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x410006", + "MSRValue": "0x15", "PEBS": "1", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" @@ -372,6 +281,66 @@ "SampleAfterValue": "2000003", "UMask": "0x4" }, + { + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_HIT", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_MISS", + "SampleAfterValue": "200003", + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_STALL", + "SampleAfterValue": "200003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0x79", + "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x18" + }, + { + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.ALL_DSB_CYCLES_ANY_UOPS", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x18" + }, + { + "BriefDescription": "Cycles MITE is delivering 4 Uops", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0x79", + "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x24" + }, { "BriefDescription": "Cycles MITE is delivering any Uop", "Counter": "0,1,2,3", @@ -384,53 +353,78 @@ "UMask": "0x24" }, { - "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xE6", - "EventName": "BACLEARS.ANY", - "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.DSB_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", - "MSRIndex": "0x3F7", - "MSRValue": "0x401006", - "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x79", + "EventName": "IDQ.DSB_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", - "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MITE_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x4" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", - "MSRIndex": "0x3F7", - "MSRValue": "0x402006", - "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x79", + "EventName": "IDQ.MITE_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MS_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", + "SampleAfterValue": "2000003", + "UMask": "0x30" + }, + { + "BriefDescription": "Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MS_DSB_CYCLES", + "PublicDescription": "Counts cycles during which uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x79", + "EventName": "IDQ.MS_MITE_UOPS", + "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x20" }, { "BriefDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer", @@ -445,72 +439,78 @@ "UMask": "0x30" }, { - "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.ITLB_MISS", - "MSRIndex": "0x3F7", - "MSRValue": "0x14", - "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x79", + "EventName": "IDQ.MS_UOPS", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "SampleAfterValue": "2000003", + "UMask": "0x30" + }, + { + "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding 4 x when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.ALL_DSB_CYCLES_ANY_UOPS", - "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "CounterMask": "4", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", "SampleAfterValue": "2000003", - "UMask": "0x18" + "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Counts cycles FE delivered 4 uops or Resource Allocation Table (RAT) was stalling FE.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", - "MSRIndex": "0x3F7", - "MSRValue": "0x420006", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", + "Invert": "1", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles MITE is delivering 4 Uops", + "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0x79", - "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", - "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "CounterMask": "3", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", + "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", "SampleAfterValue": "2000003", - "UMask": "0x24" + "UMask": "0x1" }, { - "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", + "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0x79", - "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", - "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "CounterMask": "2", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", + "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", "SampleAfterValue": "2000003", - "UMask": "0x18" + "UMask": "0x1" }, { - "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x83", - "EventName": "ICACHE_64B.IFTAG_STALL", - "SampleAfterValue": "200003", - "UMask": "0x4" + "CounterMask": "1", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", + "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "UMask": "0x1" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/memory.json b/tools/perf/pmu-events/arch/x86/cascadelakex/memory.json index 0c07cb4fbf58..7c2adadca87e 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/memory.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/memory.json @@ -1,1338 +1,1358 @@ [ { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x06040007F7", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "6", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x6" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED", + "PEBS": "1", + "PublicDescription": "Number of times HLE abort was triggered.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times an HLE execution successfully committed", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.COMMIT", + "PublicDescription": "Number of times HLE commit succeeded.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an HLE execution started.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.START", + "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Errata": "SKL089", + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "MSRValue": "0x80", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "1009", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "MSRValue": "0x10", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "20011", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000100", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "MSRValue": "0x100", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "503", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "MSRValue": "0x20", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000020", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "MSRValue": "0x4", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "100003", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "MSRValue": "0x200", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "101", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "MSRValue": "0x40", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "2003", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "MSRValue": "0x8", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "50021", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000100", + "MSRValue": "0x3FBC000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000400", + "MSRValue": "0x103C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000490", + "MSRValue": "0x083C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000010", + "MSRValue": "0x043C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00490", + "MSRValue": "0x013C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000120", + "MSRValue": "0x103FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000100", + "MSRValue": "0x083FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000100", + "MSRValue": "0x023C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000100", + "MSRValue": "0x00BC000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804008000", + "MSRValue": "0x3F84000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x06040007F7", + "MSRValue": "0x1004000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000491", + "MSRValue": "0x0804000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000010", + "MSRValue": "0x0404000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000080", + "MSRValue": "0x0104000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000010", + "MSRValue": "0x0204000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01040007F7", + "MSRValue": "0x0604000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000400", + "MSRValue": "0x0084000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000004", + "MSRValue": "0x063B800491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000010", + "MSRValue": "0x3F90000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000491", + "MSRValue": "0x1010000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_MEM", - "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000010", + "MSRValue": "0x0810000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10040007F7", + "MSRValue": "0x0410000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000002", + "MSRValue": "0x0110000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000004", + "MSRValue": "0x0210000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000400", + "MSRValue": "0x0090000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000120", + "MSRValue": "0x3FBC000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08100007F7", + "MSRValue": "0x103C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000100", + "MSRValue": "0x083C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000120", + "MSRValue": "0x043C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000020", + "MSRValue": "0x013C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000020", + "MSRValue": "0x103FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000400", + "MSRValue": "0x083FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000120", + "MSRValue": "0x023C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000002", + "MSRValue": "0x00BC000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000020", + "MSRValue": "0x3F84000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410008000", + "MSRValue": "0x1004000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000002", + "MSRValue": "0x0804000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800002", + "MSRValue": "0x0404000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F840007F7", + "MSRValue": "0x0104000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000491", + "MSRValue": "0x0204000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000400", + "MSRValue": "0x0604000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000004", + "MSRValue": "0x0084000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000100", + "MSRValue": "0x063B800490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000490", + "MSRValue": "0x3F90000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000004", + "MSRValue": "0x1010000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000010", + "MSRValue": "0x0810000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000100", + "MSRValue": "0x0410000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", - "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000004", + "MSRValue": "0x0110000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000020", + "MSRValue": "0x0210000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_CONFLICT", - "PublicDescription": "Number of times a TSX line had a cache conflict.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000400", + "MSRValue": "0x0090000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000120", + "MSRValue": "0x3FBC000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000002", + "MSRValue": "0x103C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000004", + "MSRValue": "0x083C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800100", + "MSRValue": "0x043C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000120", + "MSRValue": "0x013C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000122", + "MSRValue": "0x103FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000122", + "MSRValue": "0x083FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104008000", + "MSRValue": "0x023C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC5", - "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC4", - "PublicDescription": "RTM region detected inside HLE.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC3", - "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC2", - "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC1", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000122", + "MSRValue": "0x00BC000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000002", + "MSRValue": "0x3F84000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00490", + "MSRValue": "0x1004000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800010", + "MSRValue": "0x0804000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000400", + "MSRValue": "0x0404000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000400", + "MSRValue": "0x0104000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000001", + "MSRValue": "0x0204000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000010", + "MSRValue": "0x0604000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00490", + "MSRValue": "0x0084000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800122", + "MSRValue": "0x063B800120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000400", + "MSRValue": "0x3F90000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000020", + "MSRValue": "0x1010000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000400", + "MSRValue": "0x0810000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B8007F7", + "MSRValue": "0x0410000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000491", + "MSRValue": "0x0110000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000001", + "MSRValue": "0x0210000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000002", + "MSRValue": "0x0090000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_MISS.ANY_SNOOP OCR.ALL_READS.L3_MISS.ANY_SNOOP OCR.ALL_READS.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00840007F7", + "MSRValue": "0x3FBC0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000490", + "MSRValue": "0x103C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000100", + "MSRValue": "0x083C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10100007F7", + "MSRValue": "0x043C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000004", + "MSRValue": "0x013C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_TIMER", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS.REMOTE_HITM OCR.ALL_READS.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_READS.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000002", + "MSRValue": "0x103FC007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00004", + "MSRValue": "0x083FC007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS.SNOOP_MISS OCR.ALL_READS.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000002", + "MSRValue": "0x023C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_MISS.SNOOP_NONE OCR.ALL_READS.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F900007F7", + "MSRValue": "0x00BC0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000100", + "MSRValue": "0x3F840007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000010", + "MSRValue": "0x10040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000001", + "MSRValue": "0x08040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -1352,360 +1372,338 @@ "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000010", + "MSRValue": "0x01040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000004", + "MSRValue": "0x02040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000010", + "MSRValue": "0x06040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000002", + "MSRValue": "0x00840007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000080", + "MSRValue": "0x063B8007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00490", + "MSRValue": "0x3F900007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000004", + "MSRValue": "0x10100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000004", + "MSRValue": "0x08100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000080", + "MSRValue": "0x04100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000400", + "MSRValue": "0x01100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000080", + "MSRValue": "0x02100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000010", + "MSRValue": "0x00900007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.ANY_SNOOP OCR.ALL_RFO.L3_MISS.ANY_SNOOP OCR.ALL_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000400", + "MSRValue": "0x3FBC000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000004", + "MSRValue": "0x103C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00400", + "MSRValue": "0x083C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000100", + "MSRValue": "0x043C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution successfully committed", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.COMMIT", - "PublicDescription": "Number of times HLE commit succeeded.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000122", + "MSRValue": "0x013C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.REMOTE_HITM OCR.ALL_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000002", + "MSRValue": "0x103FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000002", + "MSRValue": "0x083FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.SNOOP_MISS OCR.ALL_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000491", + "MSRValue": "0x023C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS.SNOOP_NONE OCR.ALL_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000010", + "MSRValue": "0x00BC000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000491", + "MSRValue": "0x3F84000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000001", + "MSRValue": "0x1004000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000010", + "MSRValue": "0x0804000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00100", + "MSRValue": "0x0404000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000490", + "MSRValue": "0x0104000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -1725,389 +1723,375 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000002", + "MSRValue": "0x0604000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000080", + "MSRValue": "0x0084000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000100", + "MSRValue": "0x063B800122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.SNOOP_MISS OCR.ALL_READS.L3_MISS.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C0007F7", + "MSRValue": "0x3F90000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000004", + "MSRValue": "0x1010000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00122", + "MSRValue": "0x0810000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C0007F7", + "MSRValue": "0x0410000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000120", + "MSRValue": "0x0110000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00020", + "MSRValue": "0x0210000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84008000", + "MSRValue": "0x0090000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000002", + "MSRValue": "0x3FBC000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000004", + "MSRValue": "0x103C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000120", + "MSRValue": "0x083C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000122", + "MSRValue": "0x043C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000080", + "MSRValue": "0x013C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000004", + "MSRValue": "0x103FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000010", + "MSRValue": "0x083FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800490", + "MSRValue": "0x023C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000490", + "MSRValue": "0x00BC000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110008000", + "MSRValue": "0x3F84000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800100", + "MSRValue": "0x1004000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC008000", + "MSRValue": "0x0804000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000122", + "MSRValue": "0x0404000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00080", + "MSRValue": "0x0104000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00002", + "MSRValue": "0x0204000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000020", + "MSRValue": "0x0604000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000120", + "MSRValue": "0x0084000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F840007F7", + "MSRValue": "0x063B800004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x3F90000004", "Offcore": "1", @@ -2116,1002 +2100,949 @@ "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.SNOOP_MISS", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C0007F7", + "MSRValue": "0x1010000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000122", + "MSRValue": "0x0810000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000490", + "MSRValue": "0x0410000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000001", + "MSRValue": "0x0110000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00491", + "MSRValue": "0x0210000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10040007F7", + "MSRValue": "0x0090000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C0007F7", + "MSRValue": "0x3FBC000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000002", + "MSRValue": "0x103C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004008000", + "MSRValue": "0x083C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", - "MSRIndex": "0x3F6", - "MSRValue": "0x80", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "1009", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x043C000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C0007F7", + "MSRValue": "0x013C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", - "PublicDescription": "Number of times we could not allocate Lock Buffer.", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204008000", + "MSRValue": "0x103FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000010", + "MSRValue": "0x083FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000491", + "MSRValue": "0x023C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000020", + "MSRValue": "0x00BC000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000122", + "MSRValue": "0x3F84000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000400", + "MSRValue": "0x1004000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000122", + "MSRValue": "0x0804000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000491", + "MSRValue": "0x0404000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000120", + "MSRValue": "0x0104000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000490", + "MSRValue": "0x0204000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000490", + "MSRValue": "0x0604000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000490", + "MSRValue": "0x0084000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000002", + "MSRValue": "0x063B800001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000491", + "MSRValue": "0x3F90000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000080", + "MSRValue": "0x1010000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000491", + "MSRValue": "0x0810000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000100", + "MSRValue": "0x0410000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000120", + "MSRValue": "0x0110000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000120", + "MSRValue": "0x0210000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC008000", + "MSRValue": "0x0090000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000100", + "MSRValue": "0x3FBC000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000002", + "MSRValue": "0x103C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090008000", + "MSRValue": "0x083C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000122", + "MSRValue": "0x043C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000490", + "MSRValue": "0x013C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000122", + "MSRValue": "0x103FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000080", + "MSRValue": "0x083FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000490", + "MSRValue": "0x023C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000120", + "MSRValue": "0x00BC000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000490", + "MSRValue": "0x3F84000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000001", + "MSRValue": "0x1004000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000120", + "MSRValue": "0x0804000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000001", + "MSRValue": "0x0404000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", - "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000120", + "MSRValue": "0x0104000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000490", + "MSRValue": "0x0204000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00010", + "MSRValue": "0x0604000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000122", + "MSRValue": "0x0084000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00900007F7", + "MSRValue": "0x063B800002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000010", + "MSRValue": "0x3F90000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000400", + "MSRValue": "0x1010000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02040007F7", + "MSRValue": "0x0810000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000122", + "MSRValue": "0x0410000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000001", + "MSRValue": "0x0110000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000080", + "MSRValue": "0x0210000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00122", + "MSRValue": "0x0090000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.ANY_SNOOP OCR.OTHER.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000010", + "MSRValue": "0x3FBC008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HITM_OTHER_CORE OCR.OTHER.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B8007F7", + "MSRValue": "0x103C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000122", + "MSRValue": "0x083C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000010", + "MSRValue": "0x043C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000020", + "MSRValue": "0x013C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000002", + "MSRValue": "0x103FC08000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000004", + "MSRValue": "0x083FC08000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.OTHER.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000490", + "MSRValue": "0x023C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800080", + "MSRValue": "0x00BC008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000122", + "MSRValue": "0x3F84008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000100", + "MSRValue": "0x1004008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404008000", + "MSRValue": "0x0804008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000100", + "MSRValue": "0x0404008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000490", + "MSRValue": "0x0104008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000001", + "MSRValue": "0x0204008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000400", + "MSRValue": "0x0604008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000100", + "MSRValue": "0x0084008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -3131,1426 +3062,1326 @@ "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", - "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", - "SampleAfterValue": "2000003", - "UMask": "0x8" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F90008000", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084008000", + "MSRValue": "0x1010008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000001", + "MSRValue": "0x0810008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000100", + "MSRValue": "0x0410008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000002", + "MSRValue": "0x0110008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000491", + "MSRValue": "0x0210008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000120", + "MSRValue": "0x0090008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000490", + "MSRValue": "0x3FBC000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000001", + "MSRValue": "0x103C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000004", + "MSRValue": "0x083C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000491", + "MSRValue": "0x043C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000490", + "MSRValue": "0x013C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000010", + "MSRValue": "0x103FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC007F7", + "MSRValue": "0x083FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604008000", + "MSRValue": "0x023C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000010", + "MSRValue": "0x00BC000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000002", + "MSRValue": "0x3F84000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.REMOTE_HITM", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.REMOTE_HITM", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC007F7", + "MSRValue": "0x1004000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000001", + "MSRValue": "0x0804000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000122", + "MSRValue": "0x0404000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000080", + "MSRValue": "0x0104000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000100", + "MSRValue": "0x0204000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000004", + "MSRValue": "0x0604000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000491", + "MSRValue": "0x0084000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000002", + "MSRValue": "0x063B800400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B808000", + "MSRValue": "0x3F90000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000002", + "MSRValue": "0x1010000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000002", + "MSRValue": "0x0810000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000010", + "MSRValue": "0x0410000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000490", + "MSRValue": "0x0110000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC08000", + "MSRValue": "0x0210000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800002", + "MSRValue": "0x0090000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000020", + "MSRValue": "0x3FBC000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000001", + "MSRValue": "0x103C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000002", + "MSRValue": "0x083C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000120", + "MSRValue": "0x043C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10100007F7", + "MSRValue": "0x013C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000400", + "MSRValue": "0x103FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000100", + "MSRValue": "0x083FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000002", + "MSRValue": "0x023C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000002", + "MSRValue": "0x00BC000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00080", + "MSRValue": "0x3F84000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08040007F7", + "MSRValue": "0x1004000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000100", + "MSRValue": "0x0804000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000400", + "MSRValue": "0x0404000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000020", + "MSRValue": "0x0104000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90008000", + "MSRValue": "0x0204000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00491", + "MSRValue": "0x0604000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000004", + "MSRValue": "0x0084000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410008000", + "MSRValue": "0x063B800010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000004", + "MSRValue": "0x3F90000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000120", + "MSRValue": "0x1010000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000001", + "MSRValue": "0x0810000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01100007F7", + "MSRValue": "0x0410000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000001", + "MSRValue": "0x0110000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000010", + "MSRValue": "0x0210000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000080", + "MSRValue": "0x0090000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804008000", + "MSRValue": "0x3FBC000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000001", + "MSRValue": "0x103C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000020", + "MSRValue": "0x083C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000080", + "MSRValue": "0x043C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000490", + "MSRValue": "0x013C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000020", + "MSRValue": "0x103FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000100", + "MSRValue": "0x083FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000001", + "MSRValue": "0x023C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000100", + "MSRValue": "0x00BC000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000100", + "MSRValue": "0x3F84000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", - "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", - "SampleAfterValue": "2000003", - "UMask": "0x20" - }, - { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000120", + "MSRValue": "0x1004000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000020", + "MSRValue": "0x0804000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000080", + "MSRValue": "0x0404000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000080", + "MSRValue": "0x0104000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000002", + "MSRValue": "0x0204000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000080", + "MSRValue": "0x0604000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000490", + "MSRValue": "0x0084000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000120", + "MSRValue": "0x063B800020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000004", + "MSRValue": "0x3F90000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.ANY_SNOOP OCR.ALL_READS.L3_MISS.ANY_SNOOP OCR.ALL_READS.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC0007F7", + "MSRValue": "0x1010000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000490", + "MSRValue": "0x0810000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00400", + "MSRValue": "0x0410000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000020", + "MSRValue": "0x0110000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000002", + "MSRValue": "0x0210000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED", - "PEBS": "1", - "PublicDescription": "Number of times RTM abort was triggered.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000020", + "MSRValue": "0x0090000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000490", + "MSRValue": "0x3FBC000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000020", + "MSRValue": "0x103C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000020", + "MSRValue": "0x083C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000100", + "MSRValue": "0x043C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010008000", + "MSRValue": "0x013C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000491", + "MSRValue": "0x103FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800490", + "MSRValue": "0x083FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000100", + "MSRValue": "0x023C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000080", + "MSRValue": "0x00BC000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000020", + "MSRValue": "0x3F84000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000001", + "MSRValue": "0x1004000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000490", + "MSRValue": "0x0804000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000010", + "MSRValue": "0x0404000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL089", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", - "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", - "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000010", + "MSRValue": "0x0104000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000020", + "MSRValue": "0x0204000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000002", + "MSRValue": "0x0604000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000080", + "MSRValue": "0x0084000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000010", + "MSRValue": "0x063B800080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000122", + "MSRValue": "0x3F90000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000122", + "MSRValue": "0x1010000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -4570,52 +4401,50 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000001", + "MSRValue": "0x0410000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810008000", + "MSRValue": "0x0110000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00122", + "MSRValue": "0x0210000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x0090000080", "Offcore": "1", @@ -4624,526 +4453,544 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000020", + "MSRValue": "0x3FBC000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000002", + "MSRValue": "0x103C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C0007F7", + "MSRValue": "0x083C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000001", + "MSRValue": "0x043C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_EVENTS", - "PublicDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", - "SampleAfterValue": "2000003", - "UMask": "0x80" - }, - { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04100007F7", + "MSRValue": "0x013C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000120", + "MSRValue": "0x103FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000001", + "MSRValue": "0x083FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.SNOOP_MISS OCR.ALL_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000122", + "MSRValue": "0x023C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110008000", + "MSRValue": "0x00BC000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010008000", + "MSRValue": "0x3F84000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000400", + "MSRValue": "0x1004000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x6" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000122", + "MSRValue": "0x0804000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000400", + "MSRValue": "0x0404000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000100", + "MSRValue": "0x0104000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000001", + "MSRValue": "0x0204000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00400", + "MSRValue": "0x0604000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000400", + "MSRValue": "0x0084000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204008000", + "MSRValue": "0x063B800100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090008000", + "MSRValue": "0x3F90000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08100007F7", + "MSRValue": "0x1010000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000004", + "MSRValue": "0x0810000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000491", + "MSRValue": "0x0410000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00002", + "MSRValue": "0x0110000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000004", + "MSRValue": "0x0210000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800122", + "MSRValue": "0x0090000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "Demand Data Read requests who miss L3 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "6", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC007F7", + "MSRValue": "0x3FBC000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000122", + "MSRValue": "0x103C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000100", + "MSRValue": "0x083C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000004", + "MSRValue": "0x043C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000120", + "MSRValue": "0x013C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02100007F7", + "MSRValue": "0x103FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.REMOTE_HITM OCR.ALL_READS.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC007F7", + "MSRValue": "0x083FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000490", + "MSRValue": "0x023C000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000100", + "MSRValue": "0x00BC000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000004", + "MSRValue": "0x3F84000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000490", + "MSRValue": "0x1004000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000491", + "MSRValue": "0x0804000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x0404000491", "Offcore": "1", @@ -5152,2455 +4999,2406 @@ "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00002", + "MSRValue": "0x0104000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_TIMER", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.REMOTE_HITM OCR.ALL_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00122", + "MSRValue": "0x0204000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000491", + "MSRValue": "0x0604000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00080", + "MSRValue": "0x0084000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800004", + "MSRValue": "0x063B800491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000490", + "MSRValue": "0x3F90000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90008000", + "MSRValue": "0x1010000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000490", + "MSRValue": "0x0810000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000010", + "MSRValue": "0x0410000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000020", + "MSRValue": "0x0110000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000001", + "MSRValue": "0x0210000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000100", + "MSRValue": "0x0090000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C008000", + "MSRValue": "0x3FBC000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000400", + "MSRValue": "0x103C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800491", + "MSRValue": "0x083C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000020", + "MSRValue": "0x043C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604008000", + "MSRValue": "0x013C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000100", + "MSRValue": "0x103FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", - "MSRIndex": "0x3F6", - "MSRValue": "0x20", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000080", + "MSRValue": "0x083FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000122", + "MSRValue": "0x023C000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000020", + "MSRValue": "0x00BC000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00080", + "MSRValue": "0x3F84000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000004", + "MSRValue": "0x1004000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000080", + "MSRValue": "0x0804000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000122", + "MSRValue": "0x0404000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000100", + "MSRValue": "0x0104000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000002", + "MSRValue": "0x0204000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000001", + "MSRValue": "0x0604000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_MEM", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000080", + "MSRValue": "0x0084000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.SNOOP_NONE OCR.ALL_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000122", + "MSRValue": "0x063B800490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800120", + "MSRValue": "0x3F90000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC08000", + "MSRValue": "0x1010000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000490", + "MSRValue": "0x0810000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000004", + "MSRValue": "0x0410000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000002", + "MSRValue": "0x0110000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000010", + "MSRValue": "0x0210000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000491", + "MSRValue": "0x0090000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000010", + "MSRValue": "0x3FBC000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C008000", + "MSRValue": "0x103C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210008000", + "MSRValue": "0x083C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000080", + "MSRValue": "0x043C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00001", + "MSRValue": "0x013C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.SNOOP_NONE OCR.ALL_READS.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC0007F7", + "MSRValue": "0x103FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000491", + "MSRValue": "0x083FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC0007F7", + "MSRValue": "0x023C000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000491", + "MSRValue": "0x00BC000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00001", + "MSRValue": "0x3F84000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000020", + "MSRValue": "0x1004000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000001", + "MSRValue": "0x0804000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000491", + "MSRValue": "0x0404000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000010", + "MSRValue": "0x0104000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000491", + "MSRValue": "0x0204000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084008000", + "MSRValue": "0x0604000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000020", + "MSRValue": "0x0084000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000020", + "MSRValue": "0x063B800120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000120", + "MSRValue": "0x3F90000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000120", + "MSRValue": "0x1010000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00100", + "MSRValue": "0x0810000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000491", + "MSRValue": "0x0410000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800020", + "MSRValue": "0x0110000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000490", + "MSRValue": "0x0210000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000004", + "MSRValue": "0x0090000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000001", + "MSRValue": "0x3FBC0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000080", + "MSRValue": "0x103C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000122", + "MSRValue": "0x083C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000020", + "MSRValue": "0x043C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000001", + "MSRValue": "0x013C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000122", + "MSRValue": "0x103FC007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC008000", + "MSRValue": "0x083FC007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000491", + "MSRValue": "0x023C0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000120", + "MSRValue": "0x00BC0007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000020", + "MSRValue": "0x3F840007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000080", + "MSRValue": "0x10040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000120", + "MSRValue": "0x08040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000120", + "MSRValue": "0x04040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000400", + "MSRValue": "0x01040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000001", + "MSRValue": "0x02040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000020", + "MSRValue": "0x06040007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC0007F7", + "MSRValue": "0x00840007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000020", + "MSRValue": "0x063B8007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000001", + "MSRValue": "0x3F900007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000100", + "MSRValue": "0x10100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000001", + "MSRValue": "0x08100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000080", + "MSRValue": "0x04100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000004", + "MSRValue": "0x01100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000001", + "MSRValue": "0x02100007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000491", + "MSRValue": "0x00900007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000122", + "MSRValue": "0x3FBC000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000020", + "MSRValue": "0x103C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000400", + "MSRValue": "0x083C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000002", + "MSRValue": "0x043C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000020", + "MSRValue": "0x013C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000120", + "MSRValue": "0x103FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HITM_OTHER_CORE OCR.OTHER.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C008000", + "MSRValue": "0x083FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000004", + "MSRValue": "0x023C000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104008000", + "MSRValue": "0x00BC000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", - "MSRIndex": "0x3F6", - "MSRValue": "0x100", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "503", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000004", + "MSRValue": "0x3F84000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000100", + "MSRValue": "0x1004000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000100", + "MSRValue": "0x0804000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000002", + "MSRValue": "0x0404000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800004", + "MSRValue": "0x0104000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000080", + "MSRValue": "0x0204000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", - "MSRIndex": "0x3F6", - "MSRValue": "0x10", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "20011", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000400", + "MSRValue": "0x0604000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000020", + "MSRValue": "0x0084000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", - "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", - "SampleAfterValue": "2000003", - "UMask": "0x20" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000080", + "MSRValue": "0x063B800122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000491", + "MSRValue": "0x3F90000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000400", + "MSRValue": "0x1010000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000001", + "MSRValue": "0x0810000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000010", + "MSRValue": "0x0410000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000002", + "MSRValue": "0x0110000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800400", + "MSRValue": "0x0210000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_CAPACITY", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", - "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "Number of times an RTM execution started.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.START", - "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000122", + "MSRValue": "0x0090000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000490", + "MSRValue": "0x3FBC000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404008000", + "MSRValue": "0x103C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000100", + "MSRValue": "0x083C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000001", + "MSRValue": "0x043C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000490", + "MSRValue": "0x013C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000490", + "MSRValue": "0x103FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000080", + "MSRValue": "0x083FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", - "MSRIndex": "0x3F6", - "MSRValue": "0x200", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "101", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", - "SampleAfterValue": "2000003", - "UMask": "0x20" - }, - { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000010", + "MSRValue": "0x023C000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000020", + "MSRValue": "0x00BC000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000080", + "MSRValue": "0x3F84000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000120", + "MSRValue": "0x1004000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000490", + "MSRValue": "0x0804000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000010", + "MSRValue": "0x0404000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02100007F7", + "MSRValue": "0x0104000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C0007F7", + "MSRValue": "0x0204000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000020", + "MSRValue": "0x0604000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000004", + "MSRValue": "0x0084000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000400", + "MSRValue": "0x063B800004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000002", + "MSRValue": "0x3F90000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000122", + "MSRValue": "0x1010000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00001", + "MSRValue": "0x0810000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000001", + "MSRValue": "0x0410000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800020", + "MSRValue": "0x0110000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04100007F7", + "MSRValue": "0x0210000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000080", + "MSRValue": "0x0090000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.ANY_SNOOP OCR.ALL_RFO.L3_MISS.ANY_SNOOP OCR.ALL_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000122", + "MSRValue": "0x3FBC000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000490", + "MSRValue": "0x103C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000490", + "MSRValue": "0x083C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000004", + "MSRValue": "0x043C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00120", + "MSRValue": "0x013C000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000004", + "MSRValue": "0x103FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00010", + "MSRValue": "0x083FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", - "MSRIndex": "0x3F6", - "MSRValue": "0x40", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "2003", - "TakenAlone": "1", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x023C000001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000122", + "MSRValue": "0x00BC000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000002", + "MSRValue": "0x3F84000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000010", + "MSRValue": "0x1004000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000490", + "MSRValue": "0x0804000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00120", + "MSRValue": "0x0404000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000122", + "MSRValue": "0x0104000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C008000", + "MSRValue": "0x0204000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000120", + "MSRValue": "0x0604000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800010", + "MSRValue": "0x0084000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000491", + "MSRValue": "0x063B800001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00020", + "MSRValue": "0x3F90000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800400", + "MSRValue": "0x1010000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.ANY_SNOOP OCR.OTHER.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC008000", + "MSRValue": "0x0810000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000004", + "MSRValue": "0x0410000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000122", + "MSRValue": "0x0110000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000122", + "MSRValue": "0x0210000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000080", + "MSRValue": "0x0090000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000490", + "MSRValue": "0x3FBC000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000080", + "MSRValue": "0x103C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00020", + "MSRValue": "0x083C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00120", + "MSRValue": "0x043C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000080", + "MSRValue": "0x013C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000120", + "MSRValue": "0x103FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84008000", + "MSRValue": "0x083FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000100", + "MSRValue": "0x023C000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C008000", + "MSRValue": "0x00BC000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x3F84000002", "Offcore": "1", @@ -7609,183 +7407,180 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000002", + "MSRValue": "0x1004000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00400", + "MSRValue": "0x0804000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000120", + "MSRValue": "0x0404000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000491", + "MSRValue": "0x0104000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC08000", + "MSRValue": "0x0204000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000122", + "MSRValue": "0x0604000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800001", + "MSRValue": "0x0084000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C008000", + "MSRValue": "0x063B800002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000080", + "MSRValue": "0x3F90000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000122", + "MSRValue": "0x1010000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000120", + "MSRValue": "0x0810000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C0007F7", + "MSRValue": "0x0410000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x0110000002", "Offcore": "1", @@ -7794,160 +7589,168 @@ "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000491", + "MSRValue": "0x0210000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000491", + "MSRValue": "0x0090000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000122", + "MSRValue": "0x3FBC008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000490", + "MSRValue": "0x103C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000001", + "MSRValue": "0x083C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC08000", + "MSRValue": "0x043C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000120", + "MSRValue": "0x013C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000491", + "MSRValue": "0x103FC08000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000020", + "MSRValue": "0x083FC08000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000080", + "MSRValue": "0x023C008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000001", + "MSRValue": "0x00BC008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000491", + "MSRValue": "0x3F84008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -7968,1043 +7771,1062 @@ "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000010", + "MSRValue": "0x0804008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000010", + "MSRValue": "0x0404008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution successfully committed", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.COMMIT", - "PublicDescription": "Number of times RTM commit succeeded.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000400", + "MSRValue": "0x0104008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000491", + "MSRValue": "0x0204008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_EVENTS", - "SampleAfterValue": "2000003", - "UMask": "0x80" - }, - { - "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0604008000", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000002", + "MSRValue": "0x0084008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000490", + "MSRValue": "0x063B808000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04040007F7", + "MSRValue": "0x3F90008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000080", + "MSRValue": "0x1010008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000001", + "MSRValue": "0x0810008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F900007F7", + "MSRValue": "0x0410008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000004", + "MSRValue": "0x0110008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000120", + "MSRValue": "0x0210008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000010", + "MSRValue": "0x0090008000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C008000", + "MSRValue": "0x3FBC000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000020", + "MSRValue": "0x103C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00004", + "MSRValue": "0x083C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01040007F7", + "MSRValue": "0x043C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000004", + "MSRValue": "0x013C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800080", + "MSRValue": "0x103FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000400", + "MSRValue": "0x083FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000120", + "MSRValue": "0x023C000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000020", + "MSRValue": "0x00BC000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000080", + "MSRValue": "0x3F84000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000010", + "MSRValue": "0x1004000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00491", + "MSRValue": "0x0804000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000122", + "MSRValue": "0x0404000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000001", + "MSRValue": "0x0104000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000400", + "MSRValue": "0x0204000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00001", + "MSRValue": "0x0604000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000120", + "MSRValue": "0x0084000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00004", + "MSRValue": "0x063B800400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000491", + "MSRValue": "0x3F90000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00002", + "MSRValue": "0x1010000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000120", + "MSRValue": "0x0810000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000490", + "MSRValue": "0x0410000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00100", + "MSRValue": "0x0110000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000002", + "MSRValue": "0x0210000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00100", + "MSRValue": "0x0090000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800001", + "MSRValue": "0x3FBC000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000002", + "MSRValue": "0x103C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000080", + "MSRValue": "0x083C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000122", + "MSRValue": "0x043C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000002", + "MSRValue": "0x013C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000080", + "MSRValue": "0x103FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000400", + "MSRValue": "0x083FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000080", + "MSRValue": "0x023C000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000010", + "MSRValue": "0x00BC000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000400", + "MSRValue": "0x3F84000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C008000", + "MSRValue": "0x1004000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000004", + "MSRValue": "0x0804000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000001", + "MSRValue": "0x0404000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000400", + "MSRValue": "0x0104000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000080", + "MSRValue": "0x0204000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210008000", + "MSRValue": "0x0604000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000100", + "MSRValue": "0x0084000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00491", + "MSRValue": "0x063B800010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000491", + "MSRValue": "0x3F90000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests who miss L3 cache", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", - "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x1010000010", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x10" + "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01100007F7", + "MSRValue": "0x0810000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000010", + "MSRValue": "0x0410000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000400", + "MSRValue": "0x0110000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02040007F7", + "MSRValue": "0x0210000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000120", + "MSRValue": "0x0090000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000400", + "MSRValue": "0x3FBC000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_READS.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00900007F7", + "MSRValue": "0x103C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000120", + "MSRValue": "0x083C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000100", + "MSRValue": "0x043C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00BC000122", + "MSRValue": "0x013C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000490", + "MSRValue": "0x103FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000080", + "MSRValue": "0x083FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000400", + "MSRValue": "0x023C000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000004", + "MSRValue": "0x00BC000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000491", + "MSRValue": "0x3F84000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000400", + "MSRValue": "0x1004000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", "MSRValue": "0x0804000020", "Offcore": "1", @@ -9013,905 +8835,1083 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000020", + "MSRValue": "0x0404000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000491", + "MSRValue": "0x0104000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08040007F7", + "MSRValue": "0x0204000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000100", + "MSRValue": "0x0604000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000004", + "MSRValue": "0x0084000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000122", + "MSRValue": "0x063B800020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00010", + "MSRValue": "0x3F90000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000002", + "MSRValue": "0x1010000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0084000004", + "MSRValue": "0x0810000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000120", + "MSRValue": "0x0410000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000001", + "MSRValue": "0x0110000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one).", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED", - "PEBS": "1", - "PublicDescription": "Number of times HLE abort was triggered.", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0210000020", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C008000", + "MSRValue": "0x0090000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x013C000010", + "MSRValue": "0x3FBC000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000120", + "MSRValue": "0x103C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000020", + "MSRValue": "0x083C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000010", + "MSRValue": "0x043C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000004", + "MSRValue": "0x013C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000491", + "MSRValue": "0x103FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000491", + "MSRValue": "0x083FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000400", + "MSRValue": "0x023C000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800120", + "MSRValue": "0x00BC000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000490", + "MSRValue": "0x3F84000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F84000491", + "MSRValue": "0x1004000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000400", + "MSRValue": "0x0804000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000010", + "MSRValue": "0x0404000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000122", + "MSRValue": "0x0104000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000004", + "MSRValue": "0x0204000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000004", + "MSRValue": "0x0604000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000400", + "MSRValue": "0x0084000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000080", + "MSRValue": "0x063B800080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000491", + "MSRValue": "0x3F90000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000001", + "MSRValue": "0x1010000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0104000001", + "MSRValue": "0x0810000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00010", + "MSRValue": "0x0410000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C000491", + "MSRValue": "0x0110000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_MISS.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x043C000010", + "MSRValue": "0x0210000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000100", + "MSRValue": "0x0090000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0804000400", + "MSRValue": "0x3FBC000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000020", + "MSRValue": "0x103C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0210000122", + "MSRValue": "0x083C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810000001", + "MSRValue": "0x043C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F90000400", + "MSRValue": "0x013C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.REMOTE_HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0090000490", + "MSRValue": "0x103FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000400", + "MSRValue": "0x083FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000120", + "MSRValue": "0x023C000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00020", + "MSRValue": "0x00BC000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution started.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.START", - "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1004000020", + "MSRValue": "0x3F84000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000400", + "MSRValue": "0x1004000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00004", + "MSRValue": "0x0804000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000491", + "MSRValue": "0x0404000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C000120", + "MSRValue": "0x0104000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0410000400", + "MSRValue": "0x0204000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103C0007F7", + "MSRValue": "0x0604000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0404000100", + "MSRValue": "0x0084000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1010000100", + "MSRValue": "0x063B800100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_MISS.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C008000", + "MSRValue": "0x3F90000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.OTHER.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0810008000", + "MSRValue": "0x1010000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00120", + "MSRValue": "0x0810000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0204000010", + "MSRValue": "0x0410000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", + "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS_LOCAL_DRAM.SNOOP_NONE", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00840007F7", + "MSRValue": "0x0110000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", - "MSRIndex": "0x3F6", - "MSRValue": "0x4", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", + "Deprecated": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_MISS", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0210000100", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS.SNOOP_MISS", + "BriefDescription": "This event is deprecated. Refer to new event OCR.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "Deprecated": "1", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_HOP1_DRAM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x023C000100", + "MSRValue": "0x0090000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one).", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", - "MSRIndex": "0x3F6", - "MSRValue": "0x8", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "50021", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED", + "PEBS": "1", + "PublicDescription": "Number of times RTM abort was triggered.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_EVENTS", + "PublicDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times an RTM execution successfully committed", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.COMMIT", + "PublicDescription": "Number of times RTM commit succeeded.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an RTM execution started.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.START", + "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_MISS.HIT_OTHER_CORE_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083C0007F7", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC1", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "This event is deprecated. Refer to new event OCR.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", + "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Deprecated": "1", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_HOP1_DRAM.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0110000001", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC2", + "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC3", + "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC4", + "PublicDescription": "RTM region detected inside HLE.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC5", + "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CAPACITY", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CONFLICT", + "PublicDescription": "Number of times a TSX line had a cache conflict.", + "SampleAfterValue": "2000003", "UMask": "0x1" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", + "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", + "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", + "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", + "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", + "PublicDescription": "Number of times we could not allocate Lock Buffer.", + "SampleAfterValue": "2000003", + "UMask": "0x40" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/other.json b/tools/perf/pmu-events/arch/x86/cascadelakex/other.json index f77d78e90954..2f111a22d81f 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/other.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/other.json @@ -1,1335 +1,1382 @@ [ { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100010", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", + "SampleAfterValue": "200003", + "UMask": "0x7" + }, + { + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "UMask": "0x18" + }, + { + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x28", + "EventName": "CORE_POWER.THROTTLE", + "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", + "SampleAfterValue": "200003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of hardware interrupts received by the processor.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xCB", + "EventName": "HW_INTERRUPTS.RECEIVED", + "PublicDescription": "Counts the number of hardware interruptions received by the processor.", + "SampleAfterValue": "203", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xFE", + "EventName": "IDI_MISC.WB_DOWNGRADE", + "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xFE", + "EventName": "IDI_MISC.WB_UPGRADE", + "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "OCR.ALL_DATA_RD.ANY_RESPONSE have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100120", + "MSRValue": "0x0000010491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01002007F7", + "MSRValue": "0x3F803C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0491", + "MSRValue": "0x10003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020122", + "MSRValue": "0x08003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000407F7", + "MSRValue": "0x04003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100004", + "MSRValue": "0x01003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080088000", + "MSRValue": "0x08007C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100001", + "MSRValue": "0x02003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100122", + "MSRValue": "0x00803C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000028000", + "MSRValue": "0x3F80080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040002", + "MSRValue": "0x1000080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200020", + "MSRValue": "0x0800080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100120", + "MSRValue": "0x0400080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080004", + "MSRValue": "0x0100080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0120", + "MSRValue": "0x0200080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100491", + "MSRValue": "0x0080080491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100120", + "MSRValue": "0x3F80200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100001", + "MSRValue": "0x1000200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0001", + "MSRValue": "0x0800200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000048000", + "MSRValue": "0x0400200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020020", + "MSRValue": "0x0100200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100002", + "MSRValue": "0x0200200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080080", + "MSRValue": "0x0080200491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200080", + "MSRValue": "0x3F80040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000407F7", + "MSRValue": "0x1000040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80088000", + "MSRValue": "0x0800040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0020", + "MSRValue": "0x0400040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080120", + "MSRValue": "0x0100040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0490", + "MSRValue": "0x0200040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020122", + "MSRValue": "0x0080040491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200491", + "MSRValue": "0x3F80100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80408000", + "MSRValue": "0x1000100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020490", + "MSRValue": "0x0800100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F804007F7", + "MSRValue": "0x0400100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xFE", - "EventName": "IDI_MISC.WB_DOWNGRADE", - "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", - "SampleAfterValue": "100003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080002", + "MSRValue": "0x0100100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0004", + "MSRValue": "0x0200100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080120", + "MSRValue": "0x0080100491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200001", + "MSRValue": "0x3F80400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040004", + "MSRValue": "0x0080400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80108000", + "MSRValue": "0x0100400491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C8000", + "MSRValue": "0x3F80020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400491", + "MSRValue": "0x1000020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0010", + "MSRValue": "0x0800020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100108000", + "MSRValue": "0x0400020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02002007F7", + "MSRValue": "0x0100020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0400", + "MSRValue": "0x0200020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040490", + "MSRValue": "0x0080020491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.ANY_RESPONSE have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080020", + "MSRValue": "0x0000010490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020004", + "MSRValue": "0x3F803C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080120", + "MSRValue": "0x10003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100122", + "MSRValue": "0x08003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0100", + "MSRValue": "0x04003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100490", + "MSRValue": "0x01003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C8000", + "MSRValue": "0x08007C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080400", + "MSRValue": "0x02003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100001", + "MSRValue": "0x00803C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_MISS OCR.ALL_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0122", + "MSRValue": "0x3F80080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040002", + "MSRValue": "0x1000080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100080", + "MSRValue": "0x0800080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200122", + "MSRValue": "0x0400080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800088000", + "MSRValue": "0x0100080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020491", + "MSRValue": "0x0200080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080010", + "MSRValue": "0x0080080490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0400", + "MSRValue": "0x3F80200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080002", + "MSRValue": "0x1000200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040122", + "MSRValue": "0x0800200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0122", + "MSRValue": "0x0400200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0080", + "MSRValue": "0x0100200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080001", + "MSRValue": "0x0200200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040400", + "MSRValue": "0x0080200490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs have any response type.", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.ANY_RESPONSE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010020", + "MSRValue": "0x3F80040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020002", + "MSRValue": "0x1000040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200004", + "MSRValue": "0x0800040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200028000", + "MSRValue": "0x0400040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080100", + "MSRValue": "0x0100040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400080", + "MSRValue": "0x0200040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000807F7", + "MSRValue": "0x0080040490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200122", + "MSRValue": "0x3F80100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040020", + "MSRValue": "0x1000100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200001", + "MSRValue": "0x0800100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040001", + "MSRValue": "0x0400100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400400", + "MSRValue": "0x0100100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0100", + "MSRValue": "0x0200100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040010", + "MSRValue": "0x0080100490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800048000", + "MSRValue": "0x3F80400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080001", + "MSRValue": "0x0080400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080491", + "MSRValue": "0x0100400490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100020", + "MSRValue": "0x3F80020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080020", + "MSRValue": "0x1000020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0002", + "MSRValue": "0x0800020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020491", + "MSRValue": "0x0400020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020010", + "MSRValue": "0x0100020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020490", + "MSRValue": "0x0200020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0122", + "MSRValue": "0x0080020490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.ANY_RESPONSE have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020001", + "MSRValue": "0x0000010120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0001", + "MSRValue": "0x3F803C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020100", + "MSRValue": "0x10003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200010", + "MSRValue": "0x08003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100490", + "MSRValue": "0x04003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.ANY_RESPONSE have any response type.", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.ANY_RESPONSE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010490", + "MSRValue": "0x01003C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800108000", + "MSRValue": "0x08007C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -1349,2756 +1396,2717 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040400", + "MSRValue": "0x00803C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020010", + "MSRValue": "0x3F80080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200048000", + "MSRValue": "0x1000080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100491", + "MSRValue": "0x0800080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040122", + "MSRValue": "0x0400080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200002", + "MSRValue": "0x0100080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020100", + "MSRValue": "0x0200080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.ANY_SNOOP OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800807F7", + "MSRValue": "0x0080080120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080400", + "MSRValue": "0x3F80200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020100", + "MSRValue": "0x1000200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200490", + "MSRValue": "0x0800200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08000207F7", + "MSRValue": "0x0400200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000207F7", + "MSRValue": "0x0100200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080490", + "MSRValue": "0x0200200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200491", + "MSRValue": "0x0080200120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080120", + "MSRValue": "0x3F80040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080122", + "MSRValue": "0x1000040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200491", + "MSRValue": "0x0800040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0100", + "MSRValue": "0x0400040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080001", + "MSRValue": "0x0100040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080001", + "MSRValue": "0x0200040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400088000", + "MSRValue": "0x0080040120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040122", + "MSRValue": "0x3F80100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040001", + "MSRValue": "0x1000100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.ANY_RESPONSE have any response type.", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.ANY_RESPONSE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010122", + "MSRValue": "0x0800100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads have any response type.", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.ANY_RESPONSE", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010004", + "MSRValue": "0x0400100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080004", + "MSRValue": "0x0100100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040100", + "MSRValue": "0x0200100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0002", + "MSRValue": "0x0080100120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400400", + "MSRValue": "0x3F80400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0001", + "MSRValue": "0x0080400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0020", + "MSRValue": "0x0100400120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080020", + "MSRValue": "0x3F80020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400020", + "MSRValue": "0x1000020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200020", + "MSRValue": "0x0800020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020080", + "MSRValue": "0x0400020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_MISS OCR.ALL_READS.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C07F7", + "MSRValue": "0x0100020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020490", + "MSRValue": "0x0200020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200001", + "MSRValue": "0x0080020120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.ANY_RESPONSE have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_READS.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400010", + "MSRValue": "0x00000107F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "OCR.ALL_READS.L3_HIT.ANY_SNOOP OCR.ALL_READS.L3_HIT.ANY_SNOOP OCR.ALL_READS.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080100", + "MSRValue": "0x3F803C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200002", + "MSRValue": "0x10003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020020", + "MSRValue": "0x08003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100088000", + "MSRValue": "0x04003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200100", + "MSRValue": "0x01003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200490", + "MSRValue": "0x08007C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_MISS OCR.ALL_READS.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040120", + "MSRValue": "0x02003C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_NONE OCR.ALL_READS.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800207F7", + "MSRValue": "0x00803C07F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.ANY_SNOOP OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200080", + "MSRValue": "0x3F800807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0010", + "MSRValue": "0x10000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100491", + "MSRValue": "0x08000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020120", + "MSRValue": "0x04000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040122", + "MSRValue": "0x01000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800207F7", + "MSRValue": "0x02000807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100491", + "MSRValue": "0x00800807F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.ANY_SNOOP OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020400", + "MSRValue": "0x3F802007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400122", + "MSRValue": "0x10002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020490", + "MSRValue": "0x08002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000807F7", + "MSRValue": "0x04002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.ALL_READS.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400100", + "MSRValue": "0x01002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040491", + "MSRValue": "0x02002007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400122", + "MSRValue": "0x00802007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.ANY_SNOOP OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040122", + "MSRValue": "0x3F800407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040004", + "MSRValue": "0x10000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200010", + "MSRValue": "0x08000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040010", + "MSRValue": "0x04000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0001", + "MSRValue": "0x01000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0120", + "MSRValue": "0x02000407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200100", + "MSRValue": "0x00800407F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.ANY_SNOOP OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100080", + "MSRValue": "0x3F801007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080001", + "MSRValue": "0x10001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200400", + "MSRValue": "0x08001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100010", + "MSRValue": "0x04001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200001", + "MSRValue": "0x01001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080004", + "MSRValue": "0x02001007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020010", + "MSRValue": "0x00801007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200490", + "MSRValue": "0x3F804007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040490", + "MSRValue": "0x00804007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020004", + "MSRValue": "0x01004007F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0004", + "MSRValue": "0x3F800207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020004", + "MSRValue": "0x10000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100020", + "MSRValue": "0x08000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040002", + "MSRValue": "0x04000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200122", + "MSRValue": "0x01000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080122", + "MSRValue": "0x02000207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020002", + "MSRValue": "0x00800207F7", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", - "PublicDescription": "Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", - "SampleAfterValue": "200003", - "UMask": "0x7" - }, - { - "BriefDescription": "Counts any other requests", + "BriefDescription": "OCR.ALL_RFO.ANY_RESPONSE have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080028000", + "MSRValue": "0x0000010122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.ANY_SNOOP OCR.ALL_RFO.L3_HIT.ANY_SNOOP OCR.ALL_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400490", + "MSRValue": "0x3F803C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040002", + "MSRValue": "0x10003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200002", + "MSRValue": "0x08003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020122", + "MSRValue": "0x04003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400020", + "MSRValue": "0x01003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080004", + "MSRValue": "0x08007C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_MISS OCR.ALL_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100491", + "MSRValue": "0x02003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_NONE OCR.ALL_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08002007F7", + "MSRValue": "0x00803C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200491", + "MSRValue": "0x3F80080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020120", + "MSRValue": "0x1000080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.ANY_RESPONSE have any response type.", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.ANY_RESPONSE", + "EventName": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010120", + "MSRValue": "0x0800080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0122", + "MSRValue": "0x0400080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040100", + "MSRValue": "0x0100080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200004", + "MSRValue": "0x0200080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080010", + "MSRValue": "0x0080080122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000407F7", + "MSRValue": "0x3F80200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0020", + "MSRValue": "0x1000200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040080", + "MSRValue": "0x0800200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0002", + "MSRValue": "0x0400200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.THROTTLE", - "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", - "SampleAfterValue": "200003", - "UMask": "0x40" - }, - { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0002", + "MSRValue": "0x0100200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200020", + "MSRValue": "0x0200200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080004", + "MSRValue": "0x0080200122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020004", + "MSRValue": "0x3F80040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040400", + "MSRValue": "0x1000040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040120", + "MSRValue": "0x0800040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100001", + "MSRValue": "0x0400040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040002", + "MSRValue": "0x0100040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0001", + "MSRValue": "0x0200040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040400", + "MSRValue": "0x0080040122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100010", + "MSRValue": "0x3F80100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020122", + "MSRValue": "0x1000100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests have any response type.", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.ANY_RESPONSE", + "EventName": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000018000", + "MSRValue": "0x0800100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100004", + "MSRValue": "0x0400100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.ALL_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020004", + "MSRValue": "0x0100100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080020", + "MSRValue": "0x0200100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020010", + "MSRValue": "0x0080100122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020002", + "MSRValue": "0x3F80400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080010", + "MSRValue": "0x0080400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0120", + "MSRValue": "0x0100400122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads have any response type.", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010001", + "MSRValue": "0x3F80020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0004", + "MSRValue": "0x1000020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080208000", + "MSRValue": "0x0800020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020020", + "MSRValue": "0x0400020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100080", + "MSRValue": "0x0100020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400002", + "MSRValue": "0x0200020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100002", + "MSRValue": "0x0080020122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040120", + "MSRValue": "0x0000010004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080120", + "MSRValue": "0x3F803C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020001", + "MSRValue": "0x10003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.ANY_RESPONSE have any response type.", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.ANY_RESPONSE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010491", + "MSRValue": "0x08003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080100", + "MSRValue": "0x04003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100122", + "MSRValue": "0x01003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080020", + "MSRValue": "0x08007C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200004", + "MSRValue": "0x02003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400120", + "MSRValue": "0x00803C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020080", + "MSRValue": "0x3F80080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040002", + "MSRValue": "0x1000080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200120", + "MSRValue": "0x0800080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200100", + "MSRValue": "0x0400080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080120", + "MSRValue": "0x0100080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C8000", + "MSRValue": "0x0200080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040100", + "MSRValue": "0x0080080004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040490", + "MSRValue": "0x3F80200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020100", + "MSRValue": "0x1000200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080490", + "MSRValue": "0x0800200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200020", + "MSRValue": "0x0400200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020400", + "MSRValue": "0x0100200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040100", + "MSRValue": "0x0200200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200100", + "MSRValue": "0x0080200004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020100", + "MSRValue": "0x3F80040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100100", + "MSRValue": "0x1000040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0491", + "MSRValue": "0x0800040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C07F7", + "MSRValue": "0x0400040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0004", + "MSRValue": "0x0100040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400491", + "MSRValue": "0x0200040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020491", + "MSRValue": "0x0080040004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400002", + "MSRValue": "0x3F80100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0490", + "MSRValue": "0x1000100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0491", + "MSRValue": "0x0800100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040400", + "MSRValue": "0x0400100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040001", + "MSRValue": "0x0100100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200400", + "MSRValue": "0x0200100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0491", + "MSRValue": "0x0080100004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", + "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0100", + "MSRValue": "0x3F80400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100010", + "MSRValue": "0x0080400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100100", + "MSRValue": "0x0100400004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080491", + "MSRValue": "0x3F80020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400100", + "MSRValue": "0x1000020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10002007F7", + "MSRValue": "0x0800020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0400", + "MSRValue": "0x0400020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0120", + "MSRValue": "0x0100020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200108000", + "MSRValue": "0x0200020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand code reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0100", + "MSRValue": "0x0080020004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts demand data reads have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020400", + "MSRValue": "0x0000010001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads have any response type.", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.ANY_RESPONSE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010010", + "MSRValue": "0x3F803C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100002", + "MSRValue": "0x10003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040491", + "MSRValue": "0x08003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xFE", - "EventName": "IDI_MISC.WB_UPGRADE", - "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200010", + "MSRValue": "0x04003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0004", + "MSRValue": "0x01003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100048000", + "MSRValue": "0x08007C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0490", + "MSRValue": "0x02003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040490", + "MSRValue": "0x00803C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200400", + "MSRValue": "0x3F80080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200491", + "MSRValue": "0x1000080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100010", + "MSRValue": "0x0800080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200120", + "MSRValue": "0x0400080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100004", + "MSRValue": "0x0100080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040010", + "MSRValue": "0x0200080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0020", + "MSRValue": "0x0080080001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0010", + "MSRValue": "0x3F80200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400400", + "MSRValue": "0x1000200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400020", + "MSRValue": "0x0800200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C07F7", + "MSRValue": "0x0400200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100400", + "MSRValue": "0x0100200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040004", + "MSRValue": "0x0200200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C07F7", + "MSRValue": "0x0080200001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200490", + "MSRValue": "0x3F80040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100028000", + "MSRValue": "0x1000040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080080", + "MSRValue": "0x0800040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080408000", + "MSRValue": "0x0400040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08001007F7", + "MSRValue": "0x0100040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.T1_T2", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400010", + "MSRValue": "0x0200040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -4109,945 +4117,945 @@ "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020001", + "MSRValue": "0x0080040001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040020", + "MSRValue": "0x3F80100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020020", + "MSRValue": "0x1000100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040491", + "MSRValue": "0x0800100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200020", + "MSRValue": "0x0400100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200122", + "MSRValue": "0x0100100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200020", + "MSRValue": "0x0200100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020400", + "MSRValue": "0x0080100001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0120", + "MSRValue": "0x3F80400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads have any response type.", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.ANY_RESPONSE", + "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010080", + "MSRValue": "0x0080400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020490", + "MSRValue": "0x0100400001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040100", + "MSRValue": "0x3F80020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020122", + "MSRValue": "0x1000020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0010", + "MSRValue": "0x0800020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200122", + "MSRValue": "0x0400020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100490", + "MSRValue": "0x0100020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100122", + "MSRValue": "0x0200020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts demand data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100408000", + "MSRValue": "0x0080020001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs) have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0020", + "MSRValue": "0x0000010002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0002", + "MSRValue": "0x3F803C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04001007F7", + "MSRValue": "0x10003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80048000", + "MSRValue": "0x08003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100490", + "MSRValue": "0x04003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200002", + "MSRValue": "0x01003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080491", + "MSRValue": "0x08007C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000807F7", + "MSRValue": "0x02003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100400", + "MSRValue": "0x00803C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200002", + "MSRValue": "0x3F80080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100004", + "MSRValue": "0x1000080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests have any response type.", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.ANY_RESPONSE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010400", + "MSRValue": "0x0800080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200001", + "MSRValue": "0x0400080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C8000", + "MSRValue": "0x0100080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100120", + "MSRValue": "0x0200080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040010", + "MSRValue": "0x0080080002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100080", + "MSRValue": "0x3F80200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020122", + "MSRValue": "0x1000200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000088000", + "MSRValue": "0x0800200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.ANY_SNOOP OCR.ALL_READS.L3_HIT.ANY_SNOOP OCR.ALL_READS.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C07F7", + "MSRValue": "0x0400200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00804007F7", + "MSRValue": "0x0100200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400028000", + "MSRValue": "0x0200200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0490", + "MSRValue": "0x0080200002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400004", + "MSRValue": "0x3F80040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0001", + "MSRValue": "0x1000040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020002", + "MSRValue": "0x0800040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C07F7", + "MSRValue": "0x0400040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400004", + "MSRValue": "0x0100040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100001", + "MSRValue": "0x0200040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.SNOOP_NONE OCR.ALL_READS.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.SNOOP_NONE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C07F7", + "MSRValue": "0x0080040002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080080", + "MSRValue": "0x3F80100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020490", + "MSRValue": "0x1000100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80028000", + "MSRValue": "0x0800100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0490", + "MSRValue": "0x0400100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200020", + "MSRValue": "0x0100100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01001007F7", + "MSRValue": "0x0200100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100122", + "MSRValue": "0x0080100002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0122", + "MSRValue": "0x3F80400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.ANY_SNOOP OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F800407F7", + "MSRValue": "0x0080400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C07F7", + "MSRValue": "0x0100400002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.ANY_RESPONSE have any response type.", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.ANY_RESPONSE", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00000107F7", + "MSRValue": "0x3F80020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0491", + "MSRValue": "0x1000020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040491", + "MSRValue": "0x0800020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020080", + "MSRValue": "0x0400020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000208000", + "MSRValue": "0x0100020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0491", + "MSRValue": "0x0200020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all demand data writes (RFOs)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040400", + "MSRValue": "0x0080020002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080010", + "MSRValue": "0x0000018000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.ANY_SNOOP OCR.OTHER.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400100", + "MSRValue": "0x3F803C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HITM_OTHER_CORE OCR.OTHER.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100080", + "MSRValue": "0x10003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080100", + "MSRValue": "0x08003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080010", + "MSRValue": "0x04003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400120", + "MSRValue": "0x01003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080400", + "MSRValue": "0x08007C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0490", + "MSRValue": "0x02003C8000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -5067,2440 +5075,2405 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800028000", + "MSRValue": "0x3F80088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080491", + "MSRValue": "0x1000088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100002", + "MSRValue": "0x0800088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10001007F7", + "MSRValue": "0x0400088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.ANY_SNOOP OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F802007F7", + "MSRValue": "0x0100088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000407F7", + "MSRValue": "0x0200088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00801007F7", + "MSRValue": "0x0080088000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0080", + "MSRValue": "0x3F80208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080490", + "MSRValue": "0x1000208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020400", + "MSRValue": "0x0800208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100400", + "MSRValue": "0x0400208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04000807F7", + "MSRValue": "0x0100208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100004", + "MSRValue": "0x0200208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100491", + "MSRValue": "0x0080208000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020002", + "MSRValue": "0x3F80048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.OTHER.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0080", + "MSRValue": "0x1000048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.SNOOP_NONE OCR.ALL_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0122", + "MSRValue": "0x0800048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040490", + "MSRValue": "0x0400048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0002", + "MSRValue": "0x0100048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020100", + "MSRValue": "0x0200048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040120", + "MSRValue": "0x0080048000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.OTHER.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800807F7", + "MSRValue": "0x3F80108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020001", + "MSRValue": "0x1000108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02000207F7", + "MSRValue": "0x0800108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200080", + "MSRValue": "0x0400108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of PREFETCHT0 instructions executed.", + "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.T0", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OCR.OTHER.L3_HIT_S.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0100108000", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0122", + "MSRValue": "0x0200108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.OTHER.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200001", + "MSRValue": "0x0080108000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100491", + "MSRValue": "0x3F80408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00800407F7", + "MSRValue": "0x0080408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts any other requests OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.OTHER.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100020", + "MSRValue": "0x0100408000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", - "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", - "SampleAfterValue": "200003", - "UMask": "0x20" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0400", + "MSRValue": "0x3F80028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.OTHER.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0020", + "MSRValue": "0x1000028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080400", + "MSRValue": "0x0800028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.OTHER.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200120", + "MSRValue": "0x0400028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts any other requests OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.OTHER.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400080", + "MSRValue": "0x0100028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.OTHER.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020004", + "MSRValue": "0x0200028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts any other requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.OTHER.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100400", + "MSRValue": "0x0080028000", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080002", + "MSRValue": "0x0000010400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200120", + "MSRValue": "0x3F803C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0004", + "MSRValue": "0x10003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200490", + "MSRValue": "0x08003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80208000", + "MSRValue": "0x04003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100400", + "MSRValue": "0x01003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01000207F7", + "MSRValue": "0x08007C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200490", + "MSRValue": "0x02003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100002", + "MSRValue": "0x00803C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00802007F7", + "MSRValue": "0x3F80080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0400", + "MSRValue": "0x1000080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0080", + "MSRValue": "0x0800080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100100", + "MSRValue": "0x0400080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200010", + "MSRValue": "0x0100080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040120", + "MSRValue": "0x0200080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200004", + "MSRValue": "0x0080080400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0002", + "MSRValue": "0x3F80200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200080", + "MSRValue": "0x1000200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040080", + "MSRValue": "0x0800200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400490", + "MSRValue": "0x0400200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020400", + "MSRValue": "0x0100200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0491", + "MSRValue": "0x0200200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100002", + "MSRValue": "0x0080200400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100122", + "MSRValue": "0x3F80040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080490", + "MSRValue": "0x1000040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080080", + "MSRValue": "0x0800040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040020", + "MSRValue": "0x0400040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0100", + "MSRValue": "0x0100040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040491", + "MSRValue": "0x0200040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040080", + "MSRValue": "0x0080040400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0100", + "MSRValue": "0x3F80100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400080", + "MSRValue": "0x1000100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200120", + "MSRValue": "0x0800100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080120", + "MSRValue": "0x0400100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080002", + "MSRValue": "0x0100100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040490", + "MSRValue": "0x0200100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080002", + "MSRValue": "0x0080100400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020020", + "MSRValue": "0x3F80400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080048000", + "MSRValue": "0x0080400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080002", + "MSRValue": "0x0100400400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080001", + "MSRValue": "0x3F80020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200122", + "MSRValue": "0x1000020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080490", + "MSRValue": "0x0800020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040004", + "MSRValue": "0x0400020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040002", + "MSRValue": "0x0100020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040001", + "MSRValue": "0x0200020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200400", + "MSRValue": "0x0080020400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100400", + "MSRValue": "0x0000010010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400001", + "MSRValue": "0x3F803C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040122", + "MSRValue": "0x10003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400001", + "MSRValue": "0x08003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200491", + "MSRValue": "0x04003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400002", + "MSRValue": "0x01003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400010", + "MSRValue": "0x08007C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.ANY_SNOOP OCR.OTHER.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C8000", + "MSRValue": "0x02003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200080", + "MSRValue": "0x00803C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100120", + "MSRValue": "0x3F80080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0010", + "MSRValue": "0x1000080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000807F7", + "MSRValue": "0x0800080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100010", + "MSRValue": "0x0400080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80400004", + "MSRValue": "0x0100080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080491", + "MSRValue": "0x0200080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020001", + "MSRValue": "0x0080080010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800208000", + "MSRValue": "0x3F80200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020100", + "MSRValue": "0x1000200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0001", + "MSRValue": "0x0800200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040080", + "MSRValue": "0x0400200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0400", + "MSRValue": "0x0100200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0120", + "MSRValue": "0x0200200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020120", + "MSRValue": "0x0080200010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400108000", + "MSRValue": "0x3F80040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0490", + "MSRValue": "0x1000040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080108000", + "MSRValue": "0x0800040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020080", + "MSRValue": "0x0400040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01004007F7", + "MSRValue": "0x0100040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040010", + "MSRValue": "0x0200040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200010", + "MSRValue": "0x0080040010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0004", + "MSRValue": "0x3F80100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200100", + "MSRValue": "0x1000100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200080", + "MSRValue": "0x0800100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040020", + "MSRValue": "0x0400100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020080", + "MSRValue": "0x0100100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000407F7", + "MSRValue": "0x0200100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100080", + "MSRValue": "0x0080100010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10000207F7", + "MSRValue": "0x3F80400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040491", + "MSRValue": "0x0080400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080122", + "MSRValue": "0x0100400010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200400", + "MSRValue": "0x3F80020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200100", + "MSRValue": "0x1000020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040010", + "MSRValue": "0x0800020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080080", + "MSRValue": "0x0400020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200004", + "MSRValue": "0x0100020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C8000", + "MSRValue": "0x0200020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200120", + "MSRValue": "0x0080020010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100100", + "MSRValue": "0x0000010020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0001", + "MSRValue": "0x3F803C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT.ANY_SNOOP OCR.ALL_RFO.L3_HIT.ANY_SNOOP OCR.ALL_RFO.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0122", + "MSRValue": "0x10003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0100", + "MSRValue": "0x08003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080010", + "MSRValue": "0x04003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200088000", + "MSRValue": "0x01003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080400", + "MSRValue": "0x08007C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020491", + "MSRValue": "0x02003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040122", + "MSRValue": "0x00803C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020020", + "MSRValue": "0x3F80080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400490", + "MSRValue": "0x1000080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020002", + "MSRValue": "0x0800080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100002", + "MSRValue": "0x0400080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020122", + "MSRValue": "0x0100080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020080", + "MSRValue": "0x0200080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020001", + "MSRValue": "0x0080080020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040490", + "MSRValue": "0x3F80200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of PREFETCHW instructions executed.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100490", + "MSRValue": "0x1000200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100020", + "MSRValue": "0x0800200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080491", + "MSRValue": "0x0400200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040120", + "MSRValue": "0x0100200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_M.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200040120", + "MSRValue": "0x0200200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020010", + "MSRValue": "0x0080200020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020490", + "MSRValue": "0x3F80040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0004", + "MSRValue": "0x1000040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200490", + "MSRValue": "0x0800040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080122", + "MSRValue": "0x0400040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040001", + "MSRValue": "0x0100040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0010", + "MSRValue": "0x0200040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100100", + "MSRValue": "0x0080040020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0080", + "MSRValue": "0x3F80100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040080", + "MSRValue": "0x1000100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080010", + "MSRValue": "0x0800100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020120", + "MSRValue": "0x0400100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100122", + "MSRValue": "0x0100100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020120", + "MSRValue": "0x0200100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", - "PublicDescription": "Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", - "SampleAfterValue": "200003", - "UMask": "0x18" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L2_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040020", + "MSRValue": "0x0080100020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200004", + "MSRValue": "0x3F80400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020080", + "MSRValue": "0x0080400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L2_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040020", + "MSRValue": "0x0100400020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080400001", + "MSRValue": "0x3F80020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080004", + "MSRValue": "0x1000020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080100", + "MSRValue": "0x0800020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100490", + "MSRValue": "0x0400020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100020", + "MSRValue": "0x0100020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.ANY_SNOOP", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80080122", + "MSRValue": "0x0200020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400100120", + "MSRValue": "0x0080020020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400491", + "MSRValue": "0x0000010080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100080080", + "MSRValue": "0x3F803C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200002", + "MSRValue": "0x10003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0120", + "MSRValue": "0x08003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of hardware interrupts received by the processor.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xCB", - "EventName": "HW_INTERRUPTS.RECEIVED", - "PublicDescription": "Counts the number of hardware interruptions received by the processor.", - "SampleAfterValue": "203", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200080", + "MSRValue": "0x04003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020020", + "MSRValue": "0x01003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -7520,1143 +7493,1170 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0020", + "MSRValue": "0x02003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000108000", + "MSRValue": "0x00803C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100080", + "MSRValue": "0x3F80080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040001", + "MSRValue": "0x1000080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0002", + "MSRValue": "0x0800080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040491", + "MSRValue": "0x0400080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020120", + "MSRValue": "0x0100080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100490", + "MSRValue": "0x0200080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) have any response type.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.ANY_RESPONSE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010002", + "MSRValue": "0x0080080080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040004", + "MSRValue": "0x3F80200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020004", + "MSRValue": "0x1000200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100001", + "MSRValue": "0x0800200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400020002", + "MSRValue": "0x0400200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100004", + "MSRValue": "0x0100200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400208000", + "MSRValue": "0x0200200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs have any response type.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.ANY_RESPONSE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010100", + "MSRValue": "0x0080200080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080491", + "MSRValue": "0x3F80040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080490", + "MSRValue": "0x1000040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040100", + "MSRValue": "0x0800040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100001", + "MSRValue": "0x0400040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02003C0491", + "MSRValue": "0x0100040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400048000", + "MSRValue": "0x0200040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0010", + "MSRValue": "0x0080040080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200208000", + "MSRValue": "0x3F80100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x00803C0490", + "MSRValue": "0x1000100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.SUPPLIER_NONE.ANY_SNOOP", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80020120", + "MSRValue": "0x0800100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0010", + "MSRValue": "0x0400100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200400", + "MSRValue": "0x0100100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080020", + "MSRValue": "0x0200100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800200491", + "MSRValue": "0x0080100080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_S.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000100400", + "MSRValue": "0x3F80400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020010", + "MSRValue": "0x0080400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.SNOOP_NONE", + "EventName": "OCR.PF_L3_DATA_RD.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080040004", + "MSRValue": "0x0100400080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080004", + "MSRValue": "0x3F80020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080100", + "MSRValue": "0x1000020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_M.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000040010", + "MSRValue": "0x0800020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200020001", + "MSRValue": "0x0400020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080001", + "MSRValue": "0x0100020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04002007F7", + "MSRValue": "0x0200020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_DATA_RD.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000080122", + "MSRValue": "0x0080020080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OCR.PF_L3_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08007C0020", + "MSRValue": "0x0000010100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200002", + "MSRValue": "0x3F803C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080020", + "MSRValue": "0x10003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.SUPPLIER_NONE.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080020400", + "MSRValue": "0x08003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100020491", + "MSRValue": "0x04003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100100", + "MSRValue": "0x01003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_F.ANY_SNOOP", + "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80200120", + "MSRValue": "0x08007C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0400", + "MSRValue": "0x02003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400040080", + "MSRValue": "0x00803C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200010", + "MSRValue": "0x3F80080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040020", + "MSRValue": "0x1000080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT.HITM_OTHER_CORE OCR.OTHER.L3_HIT.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C8000", + "MSRValue": "0x0800080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040100", + "MSRValue": "0x0400080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200100100", + "MSRValue": "0x0100080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400080400", + "MSRValue": "0x0200080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_F.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_E.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000200001", + "MSRValue": "0x0080080100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of PREFETCHNTA instructions executed.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.NTA", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100200004", + "MSRValue": "0x3F80200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_M.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800040004", + "MSRValue": "0x1000200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100120", + "MSRValue": "0x0800200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_CODE_RD.L3_HIT_S.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080100004", + "MSRValue": "0x0400200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040400", + "MSRValue": "0x0100200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0400", + "MSRValue": "0x0200200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_F.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200200400", + "MSRValue": "0x0080200100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_E.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080080122", + "MSRValue": "0x3F80040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80100020", + "MSRValue": "0x1000040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_RFO.L3_HIT_S.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100100020", + "MSRValue": "0x0800040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200122", + "MSRValue": "0x0400040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0080", + "MSRValue": "0x0100040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_DATA_RD.L3_HIT_M.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100040001", + "MSRValue": "0x0200040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_S.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_M.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800100010", + "MSRValue": "0x0080040100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HITM_OTHER_CORE", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x1000020491", + "MSRValue": "0x3F80100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080490", + "MSRValue": "0x1000100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts any other requests OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.OTHER.L3_HIT_F.NO_SNOOP_NEEDED", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100208000", + "MSRValue": "0x0800100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.ANY_SNOOP OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.ANY_SNOOP", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F801007F7", + "MSRValue": "0x0400100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs)", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.DEMAND_RFO.L3_HIT_E.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0200080002", + "MSRValue": "0x0100100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020010", + "MSRValue": "0x0200100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.L3_HIT_S.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0080", + "MSRValue": "0x0080100100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_F.SNOOP_NONE", + "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0080200100", + "MSRValue": "0x3F80400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080080", + "MSRValue": "0x0080400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L3_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400122", + "MSRValue": "0x0100400100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_RFO.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080100", + "MSRValue": "0x3F80020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L3_DATA_RD.L3_HIT_M.ANY_SNOOP", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F80040080", + "MSRValue": "0x1000020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_PF_RFO.PMM_HIT_LOCAL_PMM.SNOOP_NOT_NEEDED", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0100400120", + "MSRValue": "0x0800020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_DATA_RD.SUPPLIER_NONE.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800020491", + "MSRValue": "0x0400020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L1D_AND_SW.L3_HIT_E.HIT_OTHER_CORE_FWD", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0800080400", + "MSRValue": "0x0100020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.PF_L2_DATA_RD.L3_HIT_F.HIT_OTHER_CORE_NO_FWD", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_MISS", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0400200010", + "MSRValue": "0x0200020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OCR.ALL_READS.L3_HIT_S.SNOOP_MISS", + "EventName": "OCR.PF_L3_RFO.SUPPLIER_NONE.SNOOP_NONE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x02001007F7", + "MSRValue": "0x0080020100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" + }, + { + "BriefDescription": "Number of PREFETCHNTA instructions executed.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.NTA", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of PREFETCHW instructions executed.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of PREFETCHT0 instructions executed.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T0", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T1_T2", + "SampleAfterValue": "2000003", + "UMask": "0x4" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/pipeline.json b/tools/perf/pmu-events/arch/x86/cascadelakex/pipeline.json index 023f31c72a42..ca5748120666 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/pipeline.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/pipeline.json @@ -1,148 +1,158 @@ [ { - "BriefDescription": "Far branch instructions retired.", + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x14", + "EventName": "ARITH.DIVIDER_ACTIVE", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "All (macro) branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "Errata": "SKL091", "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.FAR_BRANCH", - "PEBS": "1", - "PublicDescription": "This event counts far branch instructions retired.", - "SampleAfterValue": "100007", - "UMask": "0x40" + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009" }, { - "BriefDescription": "Total execution stalls.", + "BriefDescription": "All (macro) branch instructions retired.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", + "PEBS": "2", + "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", "UMask": "0x4" }, { - "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", + "BriefDescription": "Conditional branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.SLOW_LEA", - "SampleAfterValue": "2000003", - "UMask": "0x20" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.CONDITIONAL", + "PEBS": "1", + "PublicDescription": "This event counts conditional branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x1" }, { - "BriefDescription": "Cycles with less than 10 actually retired uops.", + "BriefDescription": "Not taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "10", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.TOTAL_CYCLES", - "Invert": "1", - "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "Errata": "SKL091", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_NTAKEN", + "PublicDescription": "This event counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x10" }, { - "BriefDescription": "Thread cycles when thread is not in halt state", + "BriefDescription": "Far branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.THREAD_P", - "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", - "SampleAfterValue": "2000003" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "PEBS": "1", + "PublicDescription": "This event counts far branch instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x40" }, { - "BriefDescription": "Cycles without actually retired uops.", + "BriefDescription": "Direct and indirect near call instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "This event counts cycles without actually retired uops.", - "SampleAfterValue": "2000003", + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "PEBS": "1", + "PublicDescription": "This event counts both direct and indirect near call instructions retired.", + "SampleAfterValue": "100007", "UMask": "0x2" }, { - "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", + "BriefDescription": "Return instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", - "Invert": "1", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "PEBS": "1", + "PublicDescription": "This event counts return instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x8" }, { - "AnyThread": "1", - "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", + "BriefDescription": "Taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x1" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", + "PEBS": "1", + "PublicDescription": "This event counts taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x20" }, { - "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", + "BriefDescription": "Not taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xA8", - "EventName": "LSD.CYCLES_4_UOPS", - "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Core cycles when the thread is not in halt state", - "Counter": "Fixed counter 1", - "CounterHTOff": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.THREAD", - "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NOT_TAKEN", + "PublicDescription": "This event counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x10" }, { - "AnyThread": "1", - "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "BriefDescription": "All mispredicted macro branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", - "SampleAfterValue": "25003", - "UMask": "0x1" + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "SampleAfterValue": "400009" }, { - "BriefDescription": "Direct and indirect near call instructions retired.", + "BriefDescription": "Mispredicted macro branch instructions retired.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_CALL", - "PEBS": "1", - "PublicDescription": "This event counts both direct and indirect near call instructions retired.", - "SampleAfterValue": "100007", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", + "PEBS": "2", + "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x4" }, { - "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "BriefDescription": "Mispredicted conditional branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x14", - "EventName": "ARITH.DIVIDER_ACTIVE", - "SampleAfterValue": "2000003", + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.CONDITIONAL", + "PEBS": "1", + "PublicDescription": "This event counts mispredicted conditional branch instructions retired.", + "SampleAfterValue": "400009", "UMask": "0x1" }, { - "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", - "SampleAfterValue": "25003", + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.NEAR_CALL", + "PEBS": "1", + "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", + "SampleAfterValue": "400009", "UMask": "0x2" }, { @@ -156,217 +166,206 @@ "UMask": "0x20" }, { - "BriefDescription": "Increments whenever there is an update to the LBR array.", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xCC", - "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", - "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", - "SampleAfterValue": "2000003", - "UMask": "0x20" + "EventCode": "0x3C", + "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "25003", + "UMask": "0x2" }, { - "BriefDescription": "Instructions retired from execution.", - "Counter": "Fixed counter 0", - "CounterHTOff": "Fixed counter 0", - "EventName": "INST_RETIRED.ANY", - "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", - "SampleAfterValue": "2000003", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x3C", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", + "SampleAfterValue": "25003", "UMask": "0x1" }, { - "BriefDescription": "Conditional branch instructions retired.", + "AnyThread": "1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.CONDITIONAL", - "PEBS": "1", - "PublicDescription": "This event counts conditional branch instructions retired.", - "SampleAfterValue": "400009", + "EventCode": "0x3C", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", + "SampleAfterValue": "25003", "UMask": "0x1" }, { - "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", - "SampleAfterValue": "2000003", - "UMask": "0x80" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "25003", + "UMask": "0x2" }, { - "BriefDescription": "Cycles where at least 1 uop was executed per-thread", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", - "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "BriefDescription": "Reference cycles when the core is not in halt state.", + "Counter": "Fixed counter 2", + "CounterHTOff": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x3" }, { - "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", - "SampleAfterValue": "2000003", + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "SampleAfterValue": "25003", "UMask": "0x1" }, { - "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", + "AnyThread": "1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", - "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", + "SampleAfterValue": "25003", + "UMask": "0x1" }, { - "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "5", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x5" + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", + "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", + "SampleAfterValue": "100007" }, { - "BriefDescription": "Mispredicted macro branch instructions retired.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", - "PEBS": "2", - "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x4" + "BriefDescription": "Core cycles when the thread is not in halt state", + "Counter": "Fixed counter 1", + "CounterHTOff": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Cycles where at least 2 uops were executed per-thread", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", - "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "AnyThread": "1", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "Fixed counter 1", + "CounterHTOff": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "BriefDescription": "Thread cycles when thread is not in halt state", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", - "SampleAfterValue": "25003", - "UMask": "0x1" + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "AnyThread": "1", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", - "SampleAfterValue": "25003", - "UMask": "0x2" + "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "All (macro) branch instructions retired.", + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.ALL_BRANCHES", - "PublicDescription": "Counts all (macro) branch instructions retired.", - "SampleAfterValue": "400009" + "CounterMask": "8", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 0", + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_0", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "CounterMask": "1", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 1", + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_1", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "CounterMask": "16", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x10" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 2", + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_2", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", + "CounterMask": "12", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0xc" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 3", + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_3", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", + "CounterMask": "5", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x5" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 4", + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_4", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", + "CounterHTOff": "0,1,2,3", + "CounterMask": "20", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", "SampleAfterValue": "2000003", - "UMask": "0x10" + "UMask": "0x14" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 5", + "BriefDescription": "Total execution stalls.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_5", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "CounterMask": "4", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x4" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 6", + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_6", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "UMask": "0x40" + "UMask": "0x2" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 7", + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_7", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "UMask": "0x80" + "UMask": "0x4" }, { "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", @@ -379,37 +378,31 @@ "UMask": "0x8" }, { - "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", + "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0x5E", - "EventName": "RS_EVENTS.EMPTY_END", - "Invert": "1", - "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x10" }, { - "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", + "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x40" }, { - "BriefDescription": "Number of Uops delivered by the LSD.", + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA8", - "EventName": "LSD.UOPS", - "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", "UMask": "0x1" }, @@ -424,117 +417,108 @@ "UMask": "0x1" }, { - "BriefDescription": "Taken branch instructions retired.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_TAKEN", - "PEBS": "1", - "PublicDescription": "This event counts taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x20" - }, - { - "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.ANY", - "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "BriefDescription": "Instructions retired from execution.", + "Counter": "Fixed counter 0", + "CounterHTOff": "Fixed counter 0", + "EventName": "INST_RETIRED.ANY", + "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Resource-related stall cycles", + "BriefDescription": "Number of instructions retired. General Counter - architectural event", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xa2", - "EventName": "RESOURCE_STALLS.ANY", - "PublicDescription": "Counts resource-related stall cycles.", - "SampleAfterValue": "2000003", - "UMask": "0x1" + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.ANY_P", + "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "CounterMask": "20", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", + "Counter": "1", + "CounterHTOff": "1", + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.PREC_DIST", + "PEBS": "2", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", "SampleAfterValue": "2000003", - "UMask": "0x14" + "UMask": "0x1" }, { - "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", - "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", + "Counter": "0,2,3", + "CounterHTOff": "0,2,3", + "CounterMask": "10", + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", + "Invert": "1", + "PEBS": "2", + "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", + "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA2", - "EventName": "RESOURCE_STALLS.SB", - "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "EventCode": "0x0D", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x80" }, { - "BriefDescription": "Not taken branch instructions retired.", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NOT_TAKEN", - "PublicDescription": "This event counts not taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x10" + "EventCode": "0x0D", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "AnyThread": "1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "12", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "EventCode": "0x0D", + "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", "SampleAfterValue": "2000003", - "UMask": "0xc" + "UMask": "0x1" }, { - "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", - "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "EventCode": "0x03", + "EventName": "LD_BLOCKS.NO_SR", + "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "SampleAfterValue": "100003", + "UMask": "0x8" }, { - "BriefDescription": "Number of instructions retired. General Counter - architectural event", + "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.ANY_P", - "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", - "SampleAfterValue": "2000003" + "EventCode": "0x03", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", + "SampleAfterValue": "100003", + "UMask": "0x2" }, { - "BriefDescription": "Counts the number of x87 uops dispatched.", + "BriefDescription": "False dependencies in MOB due to partial compare on address.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.X87", - "PublicDescription": "Counts the number of x87 uops executed.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "EventCode": "0x07", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { "BriefDescription": "Demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", @@ -547,219 +531,238 @@ "UMask": "0x1" }, { - "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", + "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.NEAR_CALL", - "PEBS": "1", - "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", - "SampleAfterValue": "400009", - "UMask": "0x2" + "CounterMask": "4", + "EventCode": "0xA8", + "EventName": "LSD.CYCLES_4_UOPS", + "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.THREAD", - "PublicDescription": "Number of uops to be executed per-thread each cycle.", + "CounterMask": "1", + "EventCode": "0xA8", + "EventName": "LSD.CYCLES_ACTIVE", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "BriefDescription": "Number of Uops delivered by the LSD.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", - "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "EventCode": "0xA8", + "EventName": "LSD.UOPS", + "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "BriefDescription": "Number of machine clears (nukes) of any type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EventCode": "0xA8", - "EventName": "LSD.CYCLES_ACTIVE", - "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", - "SampleAfterValue": "2000003", + "EdgeDetect": "1", + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.COUNT", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", + "BriefDescription": "Self-modifying code (SMC) detected.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.RECOVERY_CYCLES", - "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.SMC", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC1", + "EventName": "OTHER_ASSISTS.ANY", + "SampleAfterValue": "100003", + "UMask": "0x3f" + }, + { + "BriefDescription": "Cycles where the pipeline is stalled due to serializing operations.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x59", + "EventName": "PARTIAL_RAT_STALLS.SCOREBOARD", + "PublicDescription": "This event counts cycles during which the microcode scoreboard stalls happen.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "BriefDescription": "Resource-related stall cycles", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.REF_XCLK", - "SampleAfterValue": "25003", + "EventCode": "0xa2", + "EventName": "RESOURCE_STALLS.ANY", + "PublicDescription": "Counts resource-related stall cycles.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "8", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "EventCode": "0xA2", + "EventName": "RESOURCE_STALLS.SB", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", "SampleAfterValue": "2000003", "UMask": "0x8" }, { - "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", - "Counter": "1", - "CounterHTOff": "1", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.PREC_DIST", - "PEBS": "2", - "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", + "BriefDescription": "Increments whenever there is an update to the LBR array.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xCC", + "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x20" }, { - "BriefDescription": "Not taken branch instructions retired.", + "BriefDescription": "Number of retired PAUSE instructions (that do not end up with a VMExit to the VMM; TSX aborted Instructions may be counted). This event is not supported on first SKL and KBL products.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.COND_NTAKEN", - "PublicDescription": "This event counts not taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x10" + "EventCode": "0xCC", + "EventName": "ROB_MISC_EVENTS.PAUSE_INST", + "SampleAfterValue": "2000003", + "UMask": "0x40" }, { - "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "EventCode": "0x5E", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "EdgeDetect": "1", + "EventCode": "0x5E", + "EventName": "RS_EVENTS.EMPTY_END", + "Invert": "1", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "BriefDescription": "Cycles per thread when uops are executed in port 0", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_0", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", + "BriefDescription": "Cycles per thread when uops are executed in port 1", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC1", - "EventName": "OTHER_ASSISTS.ANY", - "SampleAfterValue": "100003", - "UMask": "0x3f" + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_1", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", + "BriefDescription": "Cycles per thread when uops are executed in port 2", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", "SampleAfterValue": "2000003", - "UMask": "0x40" + "UMask": "0x4" }, { - "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "BriefDescription": "Cycles per thread when uops are executed in port 3", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "16", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_3", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", "SampleAfterValue": "2000003", - "UMask": "0x10" + "UMask": "0x8" }, { - "BriefDescription": "Number of retired PAUSE instructions (that do not end up with a VMExit to the VMM; TSX aborted Instructions may be counted). This event is not supported on first SKL and KBL products.", + "BriefDescription": "Cycles per thread when uops are executed in port 4", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xCC", - "EventName": "ROB_MISC_EVENTS.PAUSE_INST", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_4", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", "SampleAfterValue": "2000003", - "UMask": "0x40" + "UMask": "0x10" }, { - "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "BriefDescription": "Cycles per thread when uops are executed in port 5", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", - "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_5", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x20" }, { - "BriefDescription": "Cycles where the pipeline is stalled due to serializing operations.", + "BriefDescription": "Cycles per thread when uops are executed in port 6", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x59", - "EventName": "PARTIAL_RAT_STALLS.SCOREBOARD", - "PublicDescription": "This event counts cycles during which the microcode scoreboard stalls happen.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_6", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x40" }, { - "BriefDescription": "Retirement slots used.", + "BriefDescription": "Cycles per thread when uops are executed in port 7", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.RETIRE_SLOTS", - "PublicDescription": "Counts the retirement slots used.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x80" }, { - "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", + "BriefDescription": "Number of uops executed on the core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", - "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to Mixing Intel AVX and Intel SSE Code section of the Optimization Guide.", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE", + "PublicDescription": "Number of uops executed from any thread.", "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Return instructions retired.", + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_RETURN", - "PEBS": "1", - "PublicDescription": "This event counts return instructions retired.", - "SampleAfterValue": "100007", - "UMask": "0x8" + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", @@ -772,188 +775,195 @@ "UMask": "0x2" }, { - "BriefDescription": "Mispredicted conditional branch instructions retired.", + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.CONDITIONAL", - "PEBS": "1", - "PublicDescription": "This event counts mispredicted conditional branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x1" + "CounterMask": "3", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", - "Counter": "0,2,3", - "CounterHTOff": "0,2,3", - "CounterMask": "10", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", - "Invert": "1", - "PEBS": "2", - "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "False dependencies in MOB due to partial compare on address.", + "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x07", - "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", - "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", + "Invert": "1", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Number of machine clears (nukes) of any type.", + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.COUNT", - "SampleAfterValue": "100003", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", - "Counter": "Fixed counter 1", - "CounterHTOff": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.STORE_FORWARD", - "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", - "SampleAfterValue": "100003", - "UMask": "0x2" + "CounterMask": "3", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", - "SampleAfterValue": "25003", + "CounterMask": "4", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Reference cycles when the core is not in halt state.", - "Counter": "Fixed counter 2", - "CounterHTOff": "Fixed counter 2", - "EventName": "CPU_CLK_UNHALTED.REF_TSC", - "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", "SampleAfterValue": "2000003", - "UMask": "0x3" + "UMask": "0x1" }, { - "BriefDescription": "All mispredicted macro branch instructions retired.", + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", - "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", - "SampleAfterValue": "400009" + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.THREAD", + "PublicDescription": "Number of uops to be executed per-thread each cycle.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", + "BriefDescription": "Counts the number of x87 uops dispatched.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.NO_SR", - "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", - "SampleAfterValue": "100003", - "UMask": "0x8" + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.X87", + "PublicDescription": "Counts the number of x87 uops executed.", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Self-modifying code (SMC) detected.", + "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.SMC", - "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", - "SampleAfterValue": "100003", - "UMask": "0x4" + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.ANY", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", - "SampleAfterValue": "2000003" + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.SLOW_LEA", + "SampleAfterValue": "2000003", + "UMask": "0x20" }, { - "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", + "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5E", - "EventName": "RS_EVENTS.EMPTY_CYCLES", - "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", + "CounterMask": "1", + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", + "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", - "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", - "SampleAfterValue": "100007" + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", + "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to Mixing Intel AVX and Intel SSE Code section of the Optimization Guide.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "All (macro) branch instructions retired.", + "BriefDescription": "Number of macro-fused uops retired. (non precise)", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", - "PEBS": "2", - "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", - "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.MACRO_FUSED", + "PublicDescription": "Counts the number of macro-fused uops retired. (non precise)", + "SampleAfterValue": "2000003", "UMask": "0x4" }, { - "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", + "BriefDescription": "Retirement slots used.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", - "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.RETIRE_SLOTS", + "PublicDescription": "Counts the retirement slots used.", "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Number of uops executed on the core.", + "BriefDescription": "Cycles without actually retired uops.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE", - "PublicDescription": "Number of uops executed from any thread.", + "CounterMask": "1", + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "This event counts cycles without actually retired uops.", "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "BriefDescription": "Cycles with less than 10 actually retired uops.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "CounterMask": "10", + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "Invert": "1", + "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/virtual-memory.json b/tools/perf/pmu-events/arch/x86/cascadelakex/virtual-memory.json index d13b4111eb52..792ca39f013a 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/virtual-memory.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/virtual-memory.json @@ -1,34 +1,4 @@ [ - { - "BriefDescription": "Page walk completed due to a demand data store to a 2M/4M page", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "100003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_PENDING", - "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture.", - "SampleAfterValue": "100003", - "UMask": "0x10" - }, - { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts completed page walks (2M and 4M page sizes) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", - "SampleAfterValue": "100003", - "UMask": "0xe" - }, { "BriefDescription": "Load misses in all DTLB levels that cause page walks", "Counter": "0,1,2,3", @@ -40,13 +10,13 @@ "UMask": "0x1" }, { - "BriefDescription": "STLB flush attempts", + "BriefDescription": "Loads that miss the DTLB and hit the STLB.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xBD", - "EventName": "TLB_FLUSH.STLB_ANY", - "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", - "SampleAfterValue": "100007", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "SampleAfterValue": "2000003", "UMask": "0x20" }, { @@ -61,44 +31,34 @@ "UMask": "0x10" }, { - "BriefDescription": "Page walk completed due to a demand data store to a 1G page", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 1G pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "100003", - "UMask": "0x8" - }, - { - "BriefDescription": "Store misses in all DTLB levels that cause page walks", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", - "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data loads. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0xe" }, { - "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", + "BriefDescription": "Page walk completed due to a demand data load to a 1G page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAE", - "EventName": "ITLB.ITLB_FLUSH", - "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", - "SampleAfterValue": "100007", - "UMask": "0x1" + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Page walk completed due to a demand data load to a 2M/4M page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_PENDING", - "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "2000003", - "UMask": "0x10" + "UMask": "0x4" }, { "BriefDescription": "Page walk completed due to a demand data load to a 4K page", @@ -106,20 +66,10 @@ "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x08", "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "2000003", "UMask": "0x2" }, - { - "BriefDescription": "Page walk completed due to a demand data load to a 2M/4M page", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, { "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", @@ -131,14 +81,24 @@ "UMask": "0x10" }, { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", + "BriefDescription": "Store misses in all DTLB levels that cause page walks", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x4F", - "EventName": "EPT.WALK_PENDING", - "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Stores that miss the DTLB and hit the STLB.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.STLB_HIT", + "PublicDescription": "Stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "SampleAfterValue": "100003", + "UMask": "0x20" }, { "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", @@ -152,34 +112,34 @@ "UMask": "0x10" }, { - "BriefDescription": "Misses at all ITLB levels that cause page walks", + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", - "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data stores. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0xe" }, { - "BriefDescription": "Stores that miss the DTLB and hit the STLB.", + "BriefDescription": "Page walk completed due to a demand data store to a 1G page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.STLB_HIT", - "PublicDescription": "Stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x20" + "UMask": "0x8" }, { - "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", + "BriefDescription": "Page walk completed due to a demand data store to a 2M/4M page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts demand data loads that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0xe" + "UMask": "0x4" }, { "BriefDescription": "Page walk completed due to a demand data store to a 4K page", @@ -187,29 +147,49 @@ "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x49", "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", "UMask": "0x2" }, { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts completed page walks (4K page size) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", - "SampleAfterValue": "100003", - "UMask": "0x2" + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture.", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x4f", + "EventName": "EPT.WALK_PENDING", + "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xAE", + "EventName": "ITLB.ITLB_FLUSH", + "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", + "SampleAfterValue": "100007", + "UMask": "0x1" + }, + { + "BriefDescription": "Misses at all ITLB levels that cause page walks", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x1" }, { "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", @@ -221,13 +201,34 @@ "UMask": "0x20" }, { - "BriefDescription": "Page walk completed due to a demand data load to a 1G page", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "2000003", + "CounterMask": "1", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0xe" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", "UMask": "0x8" }, { @@ -236,41 +237,30 @@ "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x85", "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts code misses in all ITLB levels that caused a completed page walk (2M and 4M page sizes). The page walk can end with or without a fault.", + "PublicDescription": "Counts completed page walks (2M/4M page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", "UMask": "0x4" }, { - "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts demand data stores that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0xe" + "UMask": "0x2" }, { - "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_ACTIVE", - "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture.", "SampleAfterValue": "100003", "UMask": "0x10" }, - { - "BriefDescription": "Loads that miss the DTLB and hit the STLB.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.STLB_HIT", - "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", - "SampleAfterValue": "2000003", - "UMask": "0x20" - }, { "BriefDescription": "DTLB flush attempts of the thread-specific entries", "Counter": "0,1,2,3", @@ -280,5 +270,15 @@ "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", "SampleAfterValue": "100007", "UMask": "0x1" + }, + { + "BriefDescription": "STLB flush attempts", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xBD", + "EventName": "TLB_FLUSH.STLB_ANY", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "SampleAfterValue": "100007", + "UMask": "0x20" } ] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 96fe584f9967287f8833c85a7d952af7df6d6d07 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 09:36:12 +0800 Subject: perf vendor events intel: Update uncore event list for CascadeLake Server Update JSON uncore events for CascadeLake Server. Based on JSON list v1.11: https://download.01.org/perfmon/CLX/ Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-3-yao.jin@linux.intel.com Signed-off-by: Jin Yao --- .../arch/x86/cascadelakex/uncore-memory.json | 21 +-- .../arch/x86/cascadelakex/uncore-other.json | 161 +++++++++++++++++++-- 2 files changed, 157 insertions(+), 25 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-memory.json b/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-memory.json index 4ba9e6d9f25e..2600fd8d7a54 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-memory.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-memory.json @@ -64,15 +64,6 @@ "UMask": "0x4", "Unit": "iMC" }, - { - "BriefDescription": "Pre-charge for writes", - "Counter": "0,1,2,3", - "EventCode": "0x2", - "EventName": "UNC_M_PRE_COUNT.WR", - "PerPkg": "1", - "UMask": "0x8", - "Unit": "iMC" - }, { "BriefDescription": "Write requests allocated in the PMM Write Pending Queue for Intel Optane DC persistent memory", "Counter": "0,1,2,3", @@ -90,32 +81,32 @@ "Unit": "iMC" }, { - "BriefDescription": "Intel Optane DC persistent memory bandwidth read (MB). Derived from unc_m_pmm_rpq_inserts", + "BriefDescription": "Intel Optane DC persistent memory bandwidth read (MB/sec). Derived from unc_m_pmm_rpq_inserts", "Counter": "0,1,2,3", "EventCode": "0xE3", "EventName": "UNC_M_PMM_BANDWIDTH.READ", "PerPkg": "1", - "ScaleUnit": "6.103515625E-5MB", + "ScaleUnit": "6.103515625E-5MB/sec", "Unit": "iMC" }, { - "BriefDescription": "Intel Optane DC persistent memory bandwidth write (MB). Derived from unc_m_pmm_wpq_inserts", + "BriefDescription": "Intel Optane DC persistent memory bandwidth write (MB/sec). Derived from unc_m_pmm_wpq_inserts", "Counter": "0,1,2,3", "EventCode": "0xE7", "EventName": "UNC_M_PMM_BANDWIDTH.WRITE", "PerPkg": "1", - "ScaleUnit": "6.103515625E-5MB", + "ScaleUnit": "6.103515625E-5MB/sec", "Unit": "iMC" }, { - "BriefDescription": "Intel Optane DC persistent memory bandwidth total (MB). Derived from unc_m_pmm_rpq_inserts", + "BriefDescription": "Intel Optane DC persistent memory bandwidth total (MB/sec). Derived from unc_m_pmm_rpq_inserts", "Counter": "0,1,2,3", "EventCode": "0xE3", "EventName": "UNC_M_PMM_BANDWIDTH.TOTAL", "MetricExpr": "UNC_M_PMM_RPQ_INSERTS + UNC_M_PMM_WPQ_INSERTS", "MetricName": "UNC_M_PMM_BANDWIDTH.TOTAL", "PerPkg": "1", - "ScaleUnit": "6.103515625E-5MB", + "ScaleUnit": "6.103515625E-5MB/sec", "Unit": "iMC" }, { diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-other.json b/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-other.json index 0cd083839e75..3be09986ce8b 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-other.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/uncore-other.json @@ -103,15 +103,6 @@ "UMask": "0x04", "Unit": "CHA" }, - { - "BriefDescription": "write requests from remote home agent", - "Counter": "0,1,2,3", - "EventCode": "0x50", - "EventName": "UNC_CHA_REQUESTS.WRITES_REMOTE", - "PerPkg": "1", - "UMask": "0x08", - "Unit": "CHA" - }, { "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", "Counter": "0,1,2,3", @@ -544,7 +535,7 @@ "EventName": "UNC_CHA_TOR_INSERTS.IA_MISS_DRD", "Filter": "config1=0x40433", "PerPkg": "1", - "PublicDescription": "TOR Inserts : DRds issued by iA Cores that Missed the LLC : Counts the number of entries successfully inserted into the TOR that match qualifications specified by the subevent. Does not include addressless requests such as locks and interrupts.", + "PublicDescription": "TOR Inserts : DRds issued by iA Cores that Missed the LLC : Counts the number of entries successfuly inserted into the TOR that match qualifications specified by the subevent. Does not include addressless requests such as locks and interrupts.", "UMask": "0x21", "Unit": "CHA" }, @@ -567,6 +558,98 @@ "PublicDescription": "Counts clockticks of the 1GHz trafiic controller clock in the IIO unit.", "Unit": "IIO" }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 0", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART0", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 0", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 1", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART1", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 1", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 2", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART2", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 2", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 3", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART3", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 3", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 0", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART0", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 0", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 1", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART1", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 1", + "UMask": "0x02", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 2", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART2", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 2", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 3", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART3", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 3", + "UMask": "0x08", + "Unit": "IIO" + }, { "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part0", "Counter": "2,3", @@ -1239,6 +1322,64 @@ "UMask": "0x02", "Unit": "IIO" }, + { + "BriefDescription": "Total IRP occupancy of inbound read and write requests.", + "Counter": "0,1", + "EventCode": "0xF", + "EventName": "UNC_I_CACHE_TOTAL_OCCUPANCY.MEM", + "PerPkg": "1", + "PublicDescription": "Total IRP occupancy of inbound read and write requests. This is effectively the sum of read occupancy and write occupancy.", + "UMask": "0x4", + "Unit": "IRP" + }, + { + "BriefDescription": "PCIITOM request issued by the IRP unit to the mesh with the intention of writing a full cacheline.", + "Counter": "0,1", + "EventCode": "0x10", + "EventName": "UNC_I_COHERENT_OPS.PCITOM", + "PerPkg": "1", + "PublicDescription": "PCIITOM request issued by the IRP unit to the mesh with the intention of writing a full cacheline to coherent memory, without a RFO. PCIITOM is a speculative Invalidate to Modified command that requests ownership of the cacheline and does not move data from the mesh to IRP cache.", + "UMask": "0x10", + "Unit": "IRP" + }, + { + "BriefDescription": "RFO request issued by the IRP unit to the mesh with the intention of writing a partial cacheline.", + "Counter": "0,1", + "EventCode": "0x10", + "EventName": "UNC_I_COHERENT_OPS.RFO", + "PerPkg": "1", + "PublicDescription": "RFO request issued by the IRP unit to the mesh with the intention of writing a partial cacheline to coherent memory. RFO is a Read For Ownership command that requests ownership of the cacheline and moves data from the mesh to IRP cache.", + "UMask": "0x8", + "Unit": "IRP" + }, + { + "BriefDescription": "Inbound read requests received by the IRP and inserted into the FAF queue.", + "Counter": "0,1", + "EventCode": "0x18", + "EventName": "UNC_I_FAF_INSERTS", + "PerPkg": "1", + "PublicDescription": "Inbound read requests to coherent memory, received by the IRP and inserted into the Fire and Forget queue (FAF), a queue used for processing inbound reads in the IRP.", + "Unit": "IRP" + }, + { + "BriefDescription": "Occupancy of the IRP FAF queue.", + "Counter": "0,1", + "EventCode": "0x19", + "EventName": "UNC_I_FAF_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Occupancy of the IRP Fire and Forget (FAF) queue, a queue used for processing inbound reads in the IRP.", + "Unit": "IRP" + }, + { + "BriefDescription": "Inbound write (fast path) requests received by the IRP.", + "Counter": "0,1", + "EventCode": "0x11", + "EventName": "UNC_I_TRANSACTIONS.WR_PREF", + "PerPkg": "1", + "PublicDescription": "Inbound write (fast path) requests to coherent memory, received by the IRP resulting in write ownership requests issued by IRP to the mesh.", + "UMask": "0x8", + "Unit": "IRP" + }, { "BriefDescription": "Traffic in which the M2M to iMC Bypass was not taken", "Counter": "0,1,2,3", -- cgit v1.2.3-70-g09d2 From 4009cc7ad6b5f8a260e46cdaabb3763f2e6ca2e0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 10 Aug 2021 14:02:33 -0400 Subject: jbd2: clean up two gcc -Wall warnings in recovery.c Fix a signed vs unsigned and a void * pointer arithmetic warning. This cleanup is also in e2fsprogs commit aec460db9a93 ("e2fsck: clean up two gcc -Wall warnings in recovery.c"). Signed-off-by: Theodore Ts'o --- fs/jbd2/recovery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index ba979fcf1cd3..8ca3527189f8 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -179,8 +179,8 @@ static int jbd2_descriptor_block_csum_verify(journal_t *j, void *buf) if (!jbd2_journal_has_csum_v2or3(j)) return 1; - tail = (struct jbd2_journal_block_tail *)(buf + j->j_blocksize - - sizeof(struct jbd2_journal_block_tail)); + tail = (struct jbd2_journal_block_tail *)((char *)buf + + j->j_blocksize - sizeof(struct jbd2_journal_block_tail)); provided = tail->t_checksum; tail->t_checksum = 0; calculated = jbd2_chksum(j, j->j_csum_seed, buf, j->j_blocksize); @@ -896,7 +896,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, { jbd2_journal_revoke_header_t *header; int offset, max; - int csum_size = 0; + unsigned csum_size = 0; __u32 rcount; int record_len = 4; -- cgit v1.2.3-70-g09d2 From 438623a06bacd69c40c4af633bb09a3bbb9dfc78 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:06 -0400 Subject: SUNRPC: Add svc_rqst::rq_auth_stat I'd like to take commit 4532608d71c8 ("SUNRPC: Clean up generic dispatcher code") even further by using only private local SVC dispatchers for all kernel RPC services. This change would enable the removal of the logic that switches between svc_generic_dispatch() and a service's private dispatcher, and simplify the invocation of the service's pc_release method so that humans can visually verify that it is always invoked properly. All that will come later. First, let's provide a better way to return authentication errors from SVC dispatcher functions. Instead of overloading the dispatch method's *statp argument, add a field to struct svc_rqst that can hold an error value. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- include/linux/sunrpc/svc.h | 1 + include/linux/sunrpc/svcauth.h | 4 ++-- include/trace/events/sunrpc.h | 6 +++--- net/sunrpc/auth_gss/svcauth_gss.c | 43 +++++++++++++++++++-------------------- net/sunrpc/svc.c | 17 ++++++++-------- net/sunrpc/svcauth.c | 8 ++++---- net/sunrpc/svcauth_unix.c | 12 +++++------ 7 files changed, 46 insertions(+), 45 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index e91d51ea028b..35f12963e1ff 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -282,6 +282,7 @@ struct svc_rqst { void * rq_argp; /* decoded arguments */ void * rq_resp; /* xdr'd results */ void * rq_auth_data; /* flavor-specific data */ + __be32 rq_auth_stat; /* authentication status */ int rq_auth_slack; /* extra space xdr code * should leave in head * for krb5i, krb5p. diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index b0003866a249..6d9cc9080aca 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -127,7 +127,7 @@ struct auth_ops { char * name; struct module *owner; int flavour; - int (*accept)(struct svc_rqst *rq, __be32 *authp); + int (*accept)(struct svc_rqst *rq); int (*release)(struct svc_rqst *rq); void (*domain_release)(struct auth_domain *); int (*set_client)(struct svc_rqst *rq); @@ -149,7 +149,7 @@ struct auth_ops { struct svc_xprt; -extern int svc_authenticate(struct svc_rqst *rqstp, __be32 *authp); +extern int svc_authenticate(struct svc_rqst *rqstp); extern int svc_authorise(struct svc_rqst *rqstp); extern int svc_set_client(struct svc_rqst *rqstp); extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops); diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index 18d552a17c19..c7d9e6c7a979 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1582,9 +1582,9 @@ TRACE_DEFINE_ENUM(SVC_COMPLETE); { SVC_COMPLETE, "SVC_COMPLETE" }) TRACE_EVENT(svc_authenticate, - TP_PROTO(const struct svc_rqst *rqst, int auth_res, __be32 auth_stat), + TP_PROTO(const struct svc_rqst *rqst, int auth_res), - TP_ARGS(rqst, auth_res, auth_stat), + TP_ARGS(rqst, auth_res), TP_STRUCT__entry( __field(u32, xid) @@ -1595,7 +1595,7 @@ TRACE_EVENT(svc_authenticate, TP_fast_assign( __entry->xid = be32_to_cpu(rqst->rq_xid); __entry->svc_status = auth_res; - __entry->auth_stat = be32_to_cpu(auth_stat); + __entry->auth_stat = be32_to_cpu(rqst->rq_auth_stat); ), TP_printk("xid=0x%08x auth_res=%s auth_stat=%s", diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index a81be45f40d9..635449ed7af6 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -707,11 +707,11 @@ svc_safe_putnetobj(struct kvec *resv, struct xdr_netobj *o) /* * Verify the checksum on the header and return SVC_OK on success. * Otherwise, return SVC_DROP (in the case of a bad sequence number) - * or return SVC_DENIED and indicate error in authp. + * or return SVC_DENIED and indicate error in rqstp->rq_auth_stat. */ static int gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci, - __be32 *rpcstart, struct rpc_gss_wire_cred *gc, __be32 *authp) + __be32 *rpcstart, struct rpc_gss_wire_cred *gc) { struct gss_ctx *ctx_id = rsci->mechctx; struct xdr_buf rpchdr; @@ -725,7 +725,7 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci, iov.iov_len = (u8 *)argv->iov_base - (u8 *)rpcstart; xdr_buf_from_iov(&iov, &rpchdr); - *authp = rpc_autherr_badverf; + rqstp->rq_auth_stat = rpc_autherr_badverf; if (argv->iov_len < 4) return SVC_DENIED; flavor = svc_getnl(argv); @@ -737,13 +737,13 @@ gss_verify_header(struct svc_rqst *rqstp, struct rsc *rsci, if (rqstp->rq_deferred) /* skip verification of revisited request */ return SVC_OK; if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) { - *authp = rpcsec_gsserr_credproblem; + rqstp->rq_auth_stat = rpcsec_gsserr_credproblem; return SVC_DENIED; } if (gc->gc_seq > MAXSEQ) { trace_rpcgss_svc_seqno_large(rqstp, gc->gc_seq); - *authp = rpcsec_gsserr_ctxproblem; + rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem; return SVC_DENIED; } if (!gss_check_seq_num(rqstp, rsci, gc->gc_seq)) @@ -1142,7 +1142,7 @@ static void gss_free_in_token_pages(struct gssp_in_token *in_token) } static int gss_read_proxy_verf(struct svc_rqst *rqstp, - struct rpc_gss_wire_cred *gc, __be32 *authp, + struct rpc_gss_wire_cred *gc, struct xdr_netobj *in_handle, struct gssp_in_token *in_token) { @@ -1151,7 +1151,7 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp, int pages, i, res, pgto, pgfrom; size_t inlen, to_offs, from_offs; - res = gss_read_common_verf(gc, argv, authp, in_handle); + res = gss_read_common_verf(gc, argv, &rqstp->rq_auth_stat, in_handle); if (res) return res; @@ -1227,7 +1227,7 @@ gss_write_resv(struct kvec *resv, size_t size_limit, * Otherwise, drop the request pending an answer to the upcall. */ static int svcauth_gss_legacy_init(struct svc_rqst *rqstp, - struct rpc_gss_wire_cred *gc, __be32 *authp) + struct rpc_gss_wire_cred *gc) { struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; @@ -1236,7 +1236,7 @@ static int svcauth_gss_legacy_init(struct svc_rqst *rqstp, struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); memset(&rsikey, 0, sizeof(rsikey)); - ret = gss_read_verf(gc, argv, authp, + ret = gss_read_verf(gc, argv, &rqstp->rq_auth_stat, &rsikey.in_handle, &rsikey.in_token); if (ret) return ret; @@ -1339,7 +1339,7 @@ out: } static int svcauth_gss_proxy_init(struct svc_rqst *rqstp, - struct rpc_gss_wire_cred *gc, __be32 *authp) + struct rpc_gss_wire_cred *gc) { struct kvec *resv = &rqstp->rq_res.head[0]; struct xdr_netobj cli_handle; @@ -1351,8 +1351,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp, struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); memset(&ud, 0, sizeof(ud)); - ret = gss_read_proxy_verf(rqstp, gc, authp, - &ud.in_handle, &ud.in_token); + ret = gss_read_proxy_verf(rqstp, gc, &ud.in_handle, &ud.in_token); if (ret) return ret; @@ -1525,7 +1524,7 @@ static void destroy_use_gss_proxy_proc_entry(struct net *net) {} * response here and return SVC_COMPLETE. */ static int -svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) +svcauth_gss_accept(struct svc_rqst *rqstp) { struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; @@ -1538,7 +1537,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) int ret; struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); - *authp = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; if (!svcdata) svcdata = kmalloc(sizeof(*svcdata), GFP_KERNEL); if (!svcdata) @@ -1575,22 +1574,22 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) if ((gc->gc_proc != RPC_GSS_PROC_DATA) && (rqstp->rq_proc != 0)) goto auth_err; - *authp = rpc_autherr_badverf; + rqstp->rq_auth_stat = rpc_autherr_badverf; switch (gc->gc_proc) { case RPC_GSS_PROC_INIT: case RPC_GSS_PROC_CONTINUE_INIT: if (use_gss_proxy(SVC_NET(rqstp))) - return svcauth_gss_proxy_init(rqstp, gc, authp); + return svcauth_gss_proxy_init(rqstp, gc); else - return svcauth_gss_legacy_init(rqstp, gc, authp); + return svcauth_gss_legacy_init(rqstp, gc); case RPC_GSS_PROC_DATA: case RPC_GSS_PROC_DESTROY: /* Look up the context, and check the verifier: */ - *authp = rpcsec_gsserr_credproblem; + rqstp->rq_auth_stat = rpcsec_gsserr_credproblem; rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx); if (!rsci) goto auth_err; - switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) { + switch (gss_verify_header(rqstp, rsci, rpcstart, gc)) { case SVC_OK: break; case SVC_DENIED: @@ -1600,7 +1599,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) } break; default: - *authp = rpc_autherr_rejectedcred; + rqstp->rq_auth_stat = rpc_autherr_rejectedcred; goto auth_err; } @@ -1616,13 +1615,13 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) svc_putnl(resv, RPC_SUCCESS); goto complete; case RPC_GSS_PROC_DATA: - *authp = rpcsec_gsserr_ctxproblem; + rqstp->rq_auth_stat = rpcsec_gsserr_ctxproblem; svcdata->verf_start = resv->iov_base + resv->iov_len; if (gss_write_verf(rqstp, rsci->mechctx, gc->gc_seq)) goto auth_err; rqstp->rq_cred = rsci->cred; get_group_info(rsci->cred.cr_group_info); - *authp = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; switch (gc->gc_svc) { case RPC_GSS_SVC_NONE: break; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 0de918cb3d90..360dab62b6b4 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1283,7 +1283,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) struct svc_process_info process; __be32 *statp; u32 prog, vers; - __be32 auth_stat, rpc_stat; + __be32 rpc_stat; int auth_res; __be32 *reply_statp; @@ -1326,14 +1326,14 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) * We do this before anything else in order to get a decent * auth verifier. */ - auth_res = svc_authenticate(rqstp, &auth_stat); + auth_res = svc_authenticate(rqstp); /* Also give the program a chance to reject this call: */ if (auth_res == SVC_OK && progp) { - auth_stat = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; auth_res = progp->pg_authenticate(rqstp); } if (auth_res != SVC_OK) - trace_svc_authenticate(rqstp, auth_res, auth_stat); + trace_svc_authenticate(rqstp, auth_res); switch (auth_res) { case SVC_OK: break; @@ -1392,8 +1392,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) goto release_dropit; if (*statp == rpc_garbage_args) goto err_garbage; - auth_stat = svc_get_autherr(rqstp, statp); - if (auth_stat != rpc_auth_ok) + rqstp->rq_auth_stat = svc_get_autherr(rqstp, statp); + if (rqstp->rq_auth_stat != rpc_auth_ok) goto err_release_bad_auth; } else { dprintk("svc: calling dispatcher\n"); @@ -1450,13 +1450,14 @@ err_release_bad_auth: if (procp->pc_release) procp->pc_release(rqstp); err_bad_auth: - dprintk("svc: authentication failed (%d)\n", ntohl(auth_stat)); + dprintk("svc: authentication failed (%d)\n", + be32_to_cpu(rqstp->rq_auth_stat)); serv->sv_stats->rpcbadauth++; /* Restore write pointer to location of accept status: */ xdr_ressize_check(rqstp, reply_statp); svc_putnl(resv, 1); /* REJECT */ svc_putnl(resv, 1); /* AUTH_ERROR */ - svc_putnl(resv, ntohl(auth_stat)); /* status */ + svc_putu32(resv, rqstp->rq_auth_stat); /* status */ goto sendit; err_bad_prog: diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 998b196b6176..5a8b8e03fdd4 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c @@ -59,12 +59,12 @@ svc_put_auth_ops(struct auth_ops *aops) } int -svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) +svc_authenticate(struct svc_rqst *rqstp) { rpc_authflavor_t flavor; struct auth_ops *aops; - *authp = rpc_auth_ok; + rqstp->rq_auth_stat = rpc_auth_ok; flavor = svc_getnl(&rqstp->rq_arg.head[0]); @@ -72,7 +72,7 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) aops = svc_get_auth_ops(flavor); if (aops == NULL) { - *authp = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; return SVC_DENIED; } @@ -80,7 +80,7 @@ svc_authenticate(struct svc_rqst *rqstp, __be32 *authp) init_svc_cred(&rqstp->rq_cred); rqstp->rq_authop = aops; - return aops->accept(rqstp, authp); + return aops->accept(rqstp); } EXPORT_SYMBOL_GPL(svc_authenticate); diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 35b7966ac3b3..eacfebf326dd 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -725,7 +725,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) EXPORT_SYMBOL_GPL(svcauth_unix_set_client); static int -svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) +svcauth_null_accept(struct svc_rqst *rqstp) { struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; @@ -736,12 +736,12 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) if (svc_getu32(argv) != 0) { dprintk("svc: bad null cred\n"); - *authp = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; return SVC_DENIED; } if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { dprintk("svc: bad null verf\n"); - *authp = rpc_autherr_badverf; + rqstp->rq_auth_stat = rpc_autherr_badverf; return SVC_DENIED; } @@ -785,7 +785,7 @@ struct auth_ops svcauth_null = { static int -svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) +svcauth_unix_accept(struct svc_rqst *rqstp) { struct kvec *argv = &rqstp->rq_arg.head[0]; struct kvec *resv = &rqstp->rq_res.head[0]; @@ -827,7 +827,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) } groups_sort(cred->cr_group_info); if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { - *authp = rpc_autherr_badverf; + rqstp->rq_auth_stat = rpc_autherr_badverf; return SVC_DENIED; } @@ -839,7 +839,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) return SVC_OK; badcred: - *authp = rpc_autherr_badcred; + rqstp->rq_auth_stat = rpc_autherr_badcred; return SVC_DENIED; } -- cgit v1.2.3-70-g09d2 From 5c2465dfd457f3015eebcc3ace50570e1d896aeb Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:12 -0400 Subject: SUNRPC: Set rq_auth_stat in the pg_authenticate() callout In a few moments, rq_auth_stat will need to be explicitly set to rpc_auth_ok before execution gets to the dispatcher. svc_authenticate() already sets it, but it often gets reset to rpc_autherr_badcred right after that call, even when authentication is successful. Let's ensure that the pg_authenticate callout and svc_set_client() set it properly in every case. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/lockd/svc.c | 2 ++ fs/nfs/callback.c | 4 ++++ net/sunrpc/auth_gss/svcauth_gss.c | 4 ++++ net/sunrpc/svc.c | 4 +--- net/sunrpc/svcauth_unix.c | 6 +++++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 2de048f80eb8..8e936999216c 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -649,6 +649,7 @@ static int lockd_authenticate(struct svc_rqst *rqstp) switch (rqstp->rq_authop->flavour) { case RPC_AUTH_NULL: case RPC_AUTH_UNIX: + rqstp->rq_auth_stat = rpc_auth_ok; if (rqstp->rq_proc == 0) return SVC_OK; if (is_callback(rqstp->rq_proc)) { @@ -659,6 +660,7 @@ static int lockd_authenticate(struct svc_rqst *rqstp) } return svc_set_client(rqstp); } + rqstp->rq_auth_stat = rpc_autherr_badcred; return SVC_DENIED; } diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 7817ad94a6ba..86d856de1389 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -429,6 +429,8 @@ check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) */ static int nfs_callback_authenticate(struct svc_rqst *rqstp) { + rqstp->rq_auth_stat = rpc_autherr_badcred; + switch (rqstp->rq_authop->flavour) { case RPC_AUTH_NULL: if (rqstp->rq_proc != CB_NULL) @@ -439,6 +441,8 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp) if (svc_is_backchannel(rqstp)) return SVC_DENIED; } + + rqstp->rq_auth_stat = rpc_auth_ok; return SVC_OK; } diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 635449ed7af6..f89075070fb0 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -1038,6 +1038,8 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) struct rpc_gss_wire_cred *gc = &svcdata->clcred; int stat; + rqstp->rq_auth_stat = rpc_autherr_badcred; + /* * A gss export can be specified either by: * export *(sec=krb5,rw) @@ -1053,6 +1055,8 @@ svcauth_gss_set_client(struct svc_rqst *rqstp) stat = svcauth_unix_set_client(rqstp); if (stat == SVC_DROP || stat == SVC_CLOSE) return stat; + + rqstp->rq_auth_stat = rpc_auth_ok; return SVC_OK; } diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 360dab62b6b4..2019d1203641 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1328,10 +1328,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) */ auth_res = svc_authenticate(rqstp); /* Also give the program a chance to reject this call: */ - if (auth_res == SVC_OK && progp) { - rqstp->rq_auth_stat = rpc_autherr_badcred; + if (auth_res == SVC_OK && progp) auth_res = progp->pg_authenticate(rqstp); - } if (auth_res != SVC_OK) trace_svc_authenticate(rqstp, auth_res); switch (auth_res) { diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index eacfebf326dd..d7ed7d49115a 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -681,8 +681,9 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) rqstp->rq_client = NULL; if (rqstp->rq_proc == 0) - return SVC_OK; + goto out; + rqstp->rq_auth_stat = rpc_autherr_badcred; ipm = ip_map_cached_get(xprt); if (ipm == NULL) ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class, @@ -719,6 +720,9 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) put_group_info(cred->cr_group_info); cred->cr_group_info = gi; } + +out: + rqstp->rq_auth_stat = rpc_auth_ok; return SVC_OK; } -- cgit v1.2.3-70-g09d2 From 9082e1d914f8b27114352b1940bbcc7522f682e7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:19 -0400 Subject: SUNRPC: Eliminate the RQ_AUTHERR flag Now that there is an alternate method for returning an auth_stat value, replace the RQ_AUTHERR flag with use of that new method. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/callback_xdr.c | 3 ++- include/linux/sunrpc/svc.h | 2 -- include/trace/events/sunrpc.h | 3 +-- net/sunrpc/svc.c | 24 ++++-------------------- 4 files changed, 7 insertions(+), 25 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c5348ba81129..7ff99155b023 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -988,7 +988,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) out_invalidcred: pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n"); - return svc_return_autherr(rqstp, rpc_autherr_badcred); + rqstp->rq_auth_stat = rpc_autherr_badcred; + return rpc_success; } /* diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 35f12963e1ff..63c9210cae06 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -275,7 +275,6 @@ struct svc_rqst { #define RQ_VICTIM (5) /* about to be shut down */ #define RQ_BUSY (6) /* request is busy */ #define RQ_DATA (7) /* request has data */ -#define RQ_AUTHERR (8) /* Request status is auth error */ unsigned long rq_flags; /* flags field */ ktime_t rq_qtime; /* enqueue time */ @@ -533,7 +532,6 @@ unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first, void *p, size_t total); -__be32 svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err); __be32 svc_generic_init_request(struct svc_rqst *rqstp, const struct svc_program *progp, struct svc_process_info *procinfo); diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h index c7d9e6c7a979..169b93e4dbc1 100644 --- a/include/trace/events/sunrpc.h +++ b/include/trace/events/sunrpc.h @@ -1539,8 +1539,7 @@ DEFINE_SVCXDRBUF_EVENT(sendto); svc_rqst_flag(SPLICE_OK) \ svc_rqst_flag(VICTIM) \ svc_rqst_flag(BUSY) \ - svc_rqst_flag(DATA) \ - svc_rqst_flag_end(AUTHERR) + svc_rqst_flag_end(DATA) #undef svc_rqst_flag #undef svc_rqst_flag_end diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2019d1203641..95836bf514b5 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1163,22 +1163,6 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {} #endif -__be32 -svc_return_autherr(struct svc_rqst *rqstp, __be32 auth_err) -{ - set_bit(RQ_AUTHERR, &rqstp->rq_flags); - return auth_err; -} -EXPORT_SYMBOL_GPL(svc_return_autherr); - -static __be32 -svc_get_autherr(struct svc_rqst *rqstp, __be32 *statp) -{ - if (test_and_clear_bit(RQ_AUTHERR, &rqstp->rq_flags)) - return *statp; - return rpc_auth_ok; -} - static int svc_generic_dispatch(struct svc_rqst *rqstp, __be32 *statp) { @@ -1202,7 +1186,7 @@ svc_generic_dispatch(struct svc_rqst *rqstp, __be32 *statp) test_bit(RQ_DROPME, &rqstp->rq_flags)) return 0; - if (test_bit(RQ_AUTHERR, &rqstp->rq_flags)) + if (rqstp->rq_auth_stat != rpc_auth_ok) return 1; if (*statp != rpc_success) @@ -1390,15 +1374,15 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) goto release_dropit; if (*statp == rpc_garbage_args) goto err_garbage; - rqstp->rq_auth_stat = svc_get_autherr(rqstp, statp); - if (rqstp->rq_auth_stat != rpc_auth_ok) - goto err_release_bad_auth; } else { dprintk("svc: calling dispatcher\n"); if (!process.dispatch(rqstp, statp)) goto release_dropit; /* Release reply info */ } + if (rqstp->rq_auth_stat != rpc_auth_ok) + goto err_release_bad_auth; + /* Check RPC status result */ if (*statp != rpc_success) resv->iov_len = ((void*)statp) - resv->iov_base + 4; -- cgit v1.2.3-70-g09d2 From 7d34c96217cf3c2d37ca0a56ca0bc3c3bef1e189 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:25 -0400 Subject: NFS: Add a private local dispatcher for NFSv4 callback operations The client's NFSv4 callback service is the only remaining user of svc_generic_dispatch(). Note that the NFSv4 callback service doesn't use the .pc_encode and .pc_decode callouts in any substantial way, so they are removed. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/callback_xdr.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 7ff99155b023..e30374e363a6 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -992,6 +992,15 @@ out_invalidcred: return rpc_success; } +static int +nfs_callback_dispatch(struct svc_rqst *rqstp, __be32 *statp) +{ + const struct svc_procedure *procp = rqstp->rq_procinfo; + + *statp = procp->pc_func(rqstp); + return 1; +} + /* * Define NFS4 callback COMPOUND ops. */ @@ -1080,7 +1089,7 @@ const struct svc_version nfs4_callback_version1 = { .vs_proc = nfs4_callback_procedures1, .vs_count = nfs4_callback_count1, .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, - .vs_dispatch = NULL, + .vs_dispatch = nfs_callback_dispatch, .vs_hidden = true, .vs_need_cong_ctrl = true, }; @@ -1092,7 +1101,7 @@ const struct svc_version nfs4_callback_version4 = { .vs_proc = nfs4_callback_procedures1, .vs_count = nfs4_callback_count4, .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, - .vs_dispatch = NULL, + .vs_dispatch = nfs_callback_dispatch, .vs_hidden = true, .vs_need_cong_ctrl = true, }; -- cgit v1.2.3-70-g09d2 From c35a810ce59524971c4a3b45faed4d0121e5a305 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:31 -0400 Subject: NFS: Remove unused callback void decoder Clean up: The callback RPC dispatcher no longer invokes these call outs, although svc_process_common() relies on seeing a .pc_encode function. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/callback_xdr.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index e30374e363a6..c1d08ab1fe22 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -63,11 +63,10 @@ static __be32 nfs4_callback_null(struct svc_rqst *rqstp) return htonl(NFS4_OK); } -static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p) -{ - return xdr_argsize_check(rqstp, p); -} - +/* + * svc_process_common() looks for an XDR encoder to know when + * not to drop a Reply. + */ static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); @@ -1067,7 +1066,6 @@ static struct callback_op callback_ops[] = { static const struct svc_procedure nfs4_callback_procedures1[] = { [CB_NULL] = { .pc_func = nfs4_callback_null, - .pc_decode = nfs4_decode_void, .pc_encode = nfs4_encode_void, .pc_xdrressize = 1, .pc_name = "NULL", -- cgit v1.2.3-70-g09d2 From 89ef17b6636f2ae3e4e4041f53be7c0118b4b6c1 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:37 -0400 Subject: NFS: Extract the xdr_init_encode/decode() calls from decode_compound Clean up: Move the xdr_init_encode() and xdr_init_decode() calls into the dispatcher, just like the NFSD and lockd dispatchers. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/callback_xdr.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c1d08ab1fe22..bf0efec93da8 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -925,22 +925,15 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) { struct cb_compound_hdr_arg hdr_arg = { 0 }; struct cb_compound_hdr_res hdr_res = { NULL }; - struct xdr_stream xdr_in, xdr_out; - __be32 *p, status; struct cb_process_state cps = { .drc_status = 0, .clp = NULL, .net = SVC_NET(rqstp), }; unsigned int nops = 0; + __be32 status; - xdr_init_decode(&xdr_in, &rqstp->rq_arg, - rqstp->rq_arg.head[0].iov_base, NULL); - - p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len); - xdr_init_encode(&xdr_out, &rqstp->rq_res, p, NULL); - - status = decode_compound_hdr_arg(&xdr_in, &hdr_arg); + status = decode_compound_hdr_arg(&rqstp->rq_arg_stream, &hdr_arg); if (status == htonl(NFS4ERR_RESOURCE)) return rpc_garbage_args; @@ -960,15 +953,15 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) cps.minorversion = hdr_arg.minorversion; hdr_res.taglen = hdr_arg.taglen; hdr_res.tag = hdr_arg.tag; - if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0) { + if (encode_compound_hdr_res(&rqstp->rq_res_stream, &hdr_res) != 0) { if (cps.clp) nfs_put_client(cps.clp); return rpc_system_err; } while (status == 0 && nops != hdr_arg.nops) { - status = process_op(nops, rqstp, &xdr_in, - rqstp->rq_argp, &xdr_out, rqstp->rq_resp, - &cps); + status = process_op(nops, rqstp, &rqstp->rq_arg_stream, + rqstp->rq_argp, &rqstp->rq_res_stream, + rqstp->rq_resp, &cps); nops++; } @@ -996,6 +989,9 @@ nfs_callback_dispatch(struct svc_rqst *rqstp, __be32 *statp) { const struct svc_procedure *procp = rqstp->rq_procinfo; + svcxdr_init_decode(rqstp); + svcxdr_init_encode(rqstp); + *statp = procp->pc_func(rqstp); return 1; } -- cgit v1.2.3-70-g09d2 From 9eff97abef057c02a13bb3aa0e4821cd60fd80df Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 15 Jul 2021 15:52:43 -0400 Subject: NFS: Clean up the synopsis of callback process_op() The xdr_stream and rq_arg and rq_res are already accessible via the @rqstp parameter. Signed-off-by: Chuck Lever Signed-off-by: Anna Schumaker --- fs/nfs/callback_xdr.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index bf0efec93da8..4c48d85f6517 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -863,17 +863,16 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) } static __be32 process_op(int nop, struct svc_rqst *rqstp, - struct xdr_stream *xdr_in, void *argp, - struct xdr_stream *xdr_out, void *resp, - struct cb_process_state *cps) + struct cb_process_state *cps) { + struct xdr_stream *xdr_out = &rqstp->rq_res_stream; struct callback_op *op = &callback_ops[0]; unsigned int op_nr; __be32 status; long maxlen; __be32 res; - status = decode_op_hdr(xdr_in, &op_nr); + status = decode_op_hdr(&rqstp->rq_arg_stream, &op_nr); if (unlikely(status)) return status; @@ -903,9 +902,11 @@ static __be32 process_op(int nop, struct svc_rqst *rqstp, maxlen = xdr_out->end - xdr_out->p; if (maxlen > 0 && maxlen < PAGE_SIZE) { - status = op->decode_args(rqstp, xdr_in, argp); + status = op->decode_args(rqstp, &rqstp->rq_arg_stream, + rqstp->rq_argp); if (likely(status == 0)) - status = op->process_op(argp, resp, cps); + status = op->process_op(rqstp->rq_argp, rqstp->rq_resp, + cps); } else status = htonl(NFS4ERR_RESOURCE); @@ -914,7 +915,7 @@ encode_hdr: if (unlikely(res)) return res; if (op->encode_res != NULL && status == 0) - status = op->encode_res(rqstp, xdr_out, resp); + status = op->encode_res(rqstp, xdr_out, rqstp->rq_resp); return status; } @@ -959,9 +960,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) return rpc_system_err; } while (status == 0 && nops != hdr_arg.nops) { - status = process_op(nops, rqstp, &rqstp->rq_arg_stream, - rqstp->rq_argp, &rqstp->rq_res_stream, - rqstp->rq_resp, &cps); + status = process_op(nops, rqstp, &cps); nops++; } -- cgit v1.2.3-70-g09d2 From ca7d1d1a0b975d3d8aaaeab008a07bb3d3c5ec7e Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Fri, 21 May 2021 15:09:38 -0400 Subject: NFSv4.2: remove restriction of copy size for inter-server copy. Currently inter-server copy is allowed only if the copy size is larger than (rsize*14) which is the over-head of the mount operation of the source export. This patch, relying on the delayed unmount feature, removes this restriction since the mount and unmount overhead is now not applicable for every inter-server copy. Signed-off-by: Dai Ngo Signed-off-by: Anna Schumaker --- fs/nfs/nfs4file.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index c820de58a661..c91565227ea2 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -158,13 +158,11 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, sync = true; retry: if (!nfs42_files_from_same_server(file_in, file_out)) { - /* for inter copy, if copy size if smaller than 12 RPC - * payloads, fallback to traditional copy. There are - * 14 RPCs during an NFSv4.x mount between source/dest - * servers. + /* + * for inter copy, if copy size is too small + * then fallback to generic copy. */ - if (sync || - count <= 14 * NFS_SERVER(file_inode(file_in))->rsize) + if (sync) return -EOPNOTSUPP; cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), GFP_NOFS); -- cgit v1.2.3-70-g09d2 From ed97cc6cbb1f440a0a3ab1483c93aff67ebe6f1d Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 13:15:43 +0800 Subject: perf vendor events: Update metrics for CascadeLake Server Update JSON metrics for CascadeLake Server. Based on TMA metrics 4.21 at 01.org. https://download.01.org/perfmon/ Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-4-yao.jin@linux.intel.com Signed-off-by: Jin Yao --- .../arch/x86/cascadelakex/clx-metrics.json | 253 +++++++-------------- 1 file changed, 86 insertions(+), 167 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json b/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json index 00f4fcffa815..5d6b2e6fcb7b 100644 --- a/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json +++ b/tools/perf/pmu-events/arch/x86/cascadelakex/clx-metrics.json @@ -1,61 +1,4 @@ [ - { - "BriefDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend", - "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Frontend_Bound", - "PublicDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. Frontend denotes the first part of the processor core responsible to fetch operations that are executed later on by the Backend part. Within the Frontend; a branch predictor predicts the next address to fetch; cache-lines are fetched from the memory subsystem; parsed into instructions; and lastly decoded into micro-operations (uops). Ideally the Frontend can issue Machine_Width uops every cycle to the Backend. Frontend Bound denotes unutilized issue-slots when there is no Backend stall; i.e. bubbles where Frontend delivered no uops while Backend could have accepted them. For example; stalls due to instruction-cache misses would be categorized under Frontend Bound." - }, - { - "BriefDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Frontend_Bound_SMT", - "PublicDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. Frontend denotes the first part of the processor core responsible to fetch operations that are executed later on by the Backend part. Within the Frontend; a branch predictor predicts the next address to fetch; cache-lines are fetched from the memory subsystem; parsed into instructions; and lastly decoded into micro-operations (uops). Ideally the Frontend can issue Machine_Width uops every cycle to the Backend. Frontend Bound denotes unutilized issue-slots when there is no Backend stall; i.e. bubbles where Frontend delivered no uops while Backend could have accepted them. For example; stalls due to instruction-cache misses would be categorized under Frontend Bound. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots wasted due to incorrect speculations", - "MetricExpr": "( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Bad_Speculation", - "PublicDescription": "This category represents fraction of slots wasted due to incorrect speculations. This include slots used to issue uops that do not eventually get retired and slots for which the issue-pipeline was blocked due to recovery from earlier incorrect speculation. For example; wasted work due to miss-predicted branches are categorized under Bad Speculation category. Incorrect data speculation followed by Memory Ordering Nukes is another example." - }, - { - "BriefDescription": "This category represents fraction of slots wasted due to incorrect speculations. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Bad_Speculation_SMT", - "PublicDescription": "This category represents fraction of slots wasted due to incorrect speculations. This include slots used to issue uops that do not eventually get retired and slots for which the issue-pipeline was blocked due to recovery from earlier incorrect speculation. For example; wasted work due to miss-predicted branches are categorized under Bad Speculation category. Incorrect data speculation followed by Memory Ordering Nukes is another example. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend", - "MetricConstraint": "NO_NMI_WATCHDOG", - "MetricExpr": "1 - ( (IDQ_UOPS_NOT_DELIVERED.CORE / (4 * cycles)) + (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles)) + (UOPS_RETIRED.RETIRE_SLOTS / (4 * cycles)) )", - "MetricGroup": "TopdownL1", - "MetricName": "Backend_Bound", - "PublicDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. Backend is the portion of the processor core where the out-of-order scheduler dispatches ready uops into their respective execution units; and once completed these uops get retired according to program order. For example; stalls due to data-cache misses or stalls due to the divider unit being overloaded are both categorized under Backend Bound. Backend Bound is further divided into two main categories: Memory Bound and Core Bound." - }, - { - "BriefDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "1 - ( (IDQ_UOPS_NOT_DELIVERED.CORE / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) + (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) + (UOPS_RETIRED.RETIRE_SLOTS / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) )", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Backend_Bound_SMT", - "PublicDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. Backend is the portion of the processor core where the out-of-order scheduler dispatches ready uops into their respective execution units; and once completed these uops get retired according to program order. For example; stalls due to data-cache misses or stalls due to the divider unit being overloaded are both categorized under Backend Bound. Backend Bound is further divided into two main categories: Memory Bound and Core Bound. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired", - "MetricExpr": "UOPS_RETIRED.RETIRE_SLOTS / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Retiring", - "PublicDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. Ideally; all pipeline slots would be attributed to the Retiring category. Retiring of 100% would indicate the maximum 4 uops retired per cycle has been achieved. Maximizing Retiring typically increases the Instruction-Per-Cycle metric. Note that a high Retiring value does not necessary mean there is no room for more performance. For example; Microcode assists are categorized under Retiring. They hurt performance and can often be avoided. " - }, - { - "BriefDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "UOPS_RETIRED.RETIRE_SLOTS / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Retiring_SMT", - "PublicDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. Ideally; all pipeline slots would be attributed to the Retiring category. Retiring of 100% would indicate the maximum 4 uops retired per cycle has been achieved. Maximizing Retiring typically increases the Instruction-Per-Cycle metric. Note that a high Retiring value does not necessary mean there is no room for more performance. For example; Microcode assists are categorized under Retiring. They hurt performance and can often be avoided. SMT version; use when SMT is enabled and measuring per logical CPU." - }, { "BriefDescription": "Instructions Per Cycle (per Logical Processor)", "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", @@ -71,49 +14,79 @@ { "BriefDescription": "Instruction per taken branch", "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_TAKEN", - "MetricGroup": "Branches;Fetch_BW;PGO", + "MetricGroup": "Branches;FetchBW;PGO", "MetricName": "IpTB" }, { "BriefDescription": "Cycles Per Instruction (per Logical Processor)", - "MetricExpr": "1 / (INST_RETIRED.ANY / cycles)", - "MetricGroup": "Pipeline;Summary", + "MetricExpr": "1 / (INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD)", + "MetricGroup": "Pipeline", "MetricName": "CPI" }, { "BriefDescription": "Per-Logical Processor actual clocks when the Logical Processor is active.", "MetricExpr": "CPU_CLK_UNHALTED.THREAD", - "MetricGroup": "Summary", + "MetricGroup": "Pipeline", "MetricName": "CLKS" }, { - "BriefDescription": "Total issue-pipeline slots (per-Physical Core till ICL; per-Logical Processor ICL onward)", - "MetricExpr": "4 * cycles", - "MetricGroup": "TopDownL1", - "MetricName": "SLOTS" + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC" }, { - "BriefDescription": "Total issue-pipeline slots (per-Physical Core till ICL; per-Logical Processor ICL onward)", - "MetricExpr": "4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "TopDownL1_SMT", - "MetricName": "SLOTS_SMT" + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC_SMT" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Flops", + "MetricName": "FLOPc" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", + "MetricGroup": "Flops_SMT", + "MetricName": "FLOPc_SMT" + }, + { + "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", + "MetricExpr": "UOPS_EXECUTED.THREAD / (( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 ) if #SMT_on else UOPS_EXECUTED.CORE_CYCLES_GE_1)", + "MetricGroup": "Pipeline;PortsUtil", + "MetricName": "ILP" + }, + { + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "MetricGroup": "BrMispredicts", + "MetricName": "IpMispredict" + }, + { + "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", + "MetricExpr": "( CPU_CLK_UNHALTED.THREAD_ANY / 2 ) if #SMT_on else CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "SMT", + "MetricName": "CORE_CLKS" }, { "BriefDescription": "Instructions per Load (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_LOADS", - "MetricGroup": "Instruction_Type", + "MetricGroup": "InsType", "MetricName": "IpLoad" }, { "BriefDescription": "Instructions per Store (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_STORES", - "MetricGroup": "Instruction_Type", + "MetricGroup": "InsType", "MetricName": "IpStore" }, { "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", - "MetricGroup": "Branches;Instruction_Type", + "MetricGroup": "Branches;InsType", "MetricName": "IpBranch" }, { @@ -131,13 +104,13 @@ { "BriefDescription": "Instructions per Floating Point (FP) Operation (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE )", - "MetricGroup": "FLOPS;FP_Arith;Instruction_Type", + "MetricGroup": "Flops;FpArith;InsType", "MetricName": "IpFLOP" }, { - "BriefDescription": "Total number of retired Instructions", + "BriefDescription": "Total number of retired Instructions, Sample with: INST_RETIRED.PREC_DIST", "MetricExpr": "INST_RETIRED.ANY", - "MetricGroup": "Summary;TopDownL1", + "MetricGroup": "Summary;TmaL1", "MetricName": "Instructions" }, { @@ -149,164 +122,110 @@ { "BriefDescription": "Fraction of Uops delivered by the DSB (aka Decoded ICache; or Uop Cache)", "MetricExpr": "IDQ.DSB_UOPS / (IDQ.DSB_UOPS + LSD.UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", - "MetricGroup": "DSB;Fetch_BW", + "MetricGroup": "DSB;FetchBW", "MetricName": "DSB_Coverage" }, - { - "BriefDescription": "Instructions Per Cycle (per physical core)", - "MetricExpr": "INST_RETIRED.ANY / cycles", - "MetricGroup": "SMT;TopDownL1", - "MetricName": "CoreIPC" - }, - { - "BriefDescription": "Instructions Per Cycle (per physical core)", - "MetricExpr": "INST_RETIRED.ANY / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "SMT;TopDownL1", - "MetricName": "CoreIPC_SMT" - }, - { - "BriefDescription": "Floating Point Operations Per Cycle", - "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / cycles", - "MetricGroup": "FLOPS", - "MetricName": "FLOPc" - }, - { - "BriefDescription": "Floating Point Operations Per Cycle", - "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "FLOPS_SMT", - "MetricName": "FLOPc_SMT" - }, - { - "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", - "MetricExpr": "UOPS_EXECUTED.THREAD / ( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 )", - "MetricGroup": "Pipeline;Ports_Utilization", - "MetricName": "ILP" - }, - { - "BriefDescription": "Branch Misprediction Cost: Fraction of TopDown slots wasted per non-speculative branch misprediction (jeclear)", - "MetricExpr": "( ((BR_MISP_RETIRED.ALL_BRANCHES / ( BR_MISP_RETIRED.ALL_BRANCHES + MACHINE_CLEARS.COUNT )) * (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles))) + (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * cycles)) * (( INT_MISC.CLEAR_RESTEER_CYCLES + 9 * BACLEARS.ANY ) / cycles) / (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * cycles)) ) * (4 * cycles) / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts", - "MetricName": "Branch_Misprediction_Cost" - }, - { - "BriefDescription": "Branch Misprediction Cost: Fraction of TopDown slots wasted per non-speculative branch misprediction (jeclear)", - "MetricExpr": "( ((BR_MISP_RETIRED.ALL_BRANCHES / ( BR_MISP_RETIRED.ALL_BRANCHES + MACHINE_CLEARS.COUNT )) * (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )))) + (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) * (( INT_MISC.CLEAR_RESTEER_CYCLES + 9 * BACLEARS.ANY ) / cycles) / (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) ) * (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )) / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts_SMT", - "MetricName": "Branch_Misprediction_Cost_SMT" - }, - { - "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", - "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts", - "MetricName": "IpMispredict" - }, - { - "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", - "MetricExpr": "( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "SMT", - "MetricName": "CORE_CLKS" - }, { "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads (in core cycles)", "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", - "MetricGroup": "Memory_Bound;Memory_Lat", + "MetricGroup": "MemoryBound;MemoryLat", "MetricName": "Load_Miss_Real_Latency" }, { "BriefDescription": "Memory-Level-Parallelism (average number of L1 miss demand load when there is at least one such miss. Per-Logical Processor)", "MetricExpr": "L1D_PEND_MISS.PENDING / L1D_PEND_MISS.PENDING_CYCLES", - "MetricGroup": "Memory_Bound;Memory_BW", + "MetricGroup": "MemoryBound;MemoryBW", "MetricName": "MLP" }, { "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", "MetricConstraint": "NO_NMI_WATCHDOG", - "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * cycles )", - "MetricGroup": "TLB", + "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * CORE_CLKS )", + "MetricGroup": "MemoryTLB", "MetricName": "Page_Walks_Utilization" }, - { - "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", - "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ) )", - "MetricGroup": "TLB_SMT", - "MetricName": "Page_Walks_Utilization_SMT" - }, { "BriefDescription": "Average data fill bandwidth to the L1 data cache [GB / sec]", "MetricExpr": "64 * L1D.REPLACEMENT / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L1D_Cache_Fill_BW" }, { "BriefDescription": "Average data fill bandwidth to the L2 cache [GB / sec]", "MetricExpr": "64 * L2_LINES_IN.ALL / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L2_Cache_Fill_BW" }, { "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", "MetricExpr": "64 * LONGEST_LAT_CACHE.MISS / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L3_Cache_Fill_BW" }, { - "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", + "BriefDescription": "Average per-core data access bandwidth to the L3 cache [GB / sec]", "MetricExpr": "64 * OFFCORE_REQUESTS.ALL_REQUESTS / 1000000000 / duration_time", - "MetricGroup": "Memory_BW;Offcore", + "MetricGroup": "MemoryBW;Offcore", "MetricName": "L3_Cache_Access_BW" }, { "BriefDescription": "L1 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L1_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L1MPKI" }, { "BriefDescription": "L2 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L2_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L2MPKI" }, { "BriefDescription": "L2 cache misses per kilo instruction for all request types (including speculative)", "MetricExpr": "1000 * L2_RQSTS.MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses;Offcore", + "MetricGroup": "CacheMisses;Offcore", "MetricName": "L2MPKI_All" }, { "BriefDescription": "L2 cache hits per kilo instruction for all request types (including speculative)", "MetricExpr": "1000 * ( L2_RQSTS.REFERENCES - L2_RQSTS.MISS ) / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L2HPKI_All" }, { "BriefDescription": "L3 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L3_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L3MPKI" }, { "BriefDescription": "Rate of silent evictions from the L2 cache per Kilo instruction where the evicted lines are dropped (no writeback to L3 or memory)", "MetricExpr": "1000 * L2_LINES_OUT.SILENT / INST_RETIRED.ANY", - "MetricGroup": "", + "MetricGroup": "L2Evicts;Server", "MetricName": "L2_Evictions_Silent_PKI" }, { "BriefDescription": "Rate of non silent evictions from the L2 cache per Kilo instruction", "MetricExpr": "1000 * L2_LINES_OUT.NON_SILENT / INST_RETIRED.ANY", - "MetricGroup": "", + "MetricGroup": "L2Evicts;Server", "MetricName": "L2_Evictions_NonSilent_PKI" }, { "BriefDescription": "Average CPU Utilization", "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", - "MetricGroup": "Summary", + "MetricGroup": "HPC;Summary", "MetricName": "CPU_Utilization" }, + { + "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", + "MetricExpr": "(CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC) * msr@tsc@ / 1000000000 / duration_time", + "MetricGroup": "Summary;Power", + "MetricName": "Average_Frequency" + }, { "BriefDescription": "Giga Floating Point Operations Per Second", "MetricExpr": "( ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / 1000000000 ) / duration_time", - "MetricGroup": "FLOPS;Summary", + "MetricGroup": "Flops;HPC", "MetricName": "GFLOPs" }, { @@ -317,62 +236,62 @@ }, { "BriefDescription": "Fraction of cycles where both hardware Logical Processors were active", - "MetricExpr": "1 - CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE / ( CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY / 2 )", - "MetricGroup": "SMT;Summary", + "MetricExpr": "1 - CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / ( CPU_CLK_UNHALTED.REF_XCLK_ANY / 2 ) if #SMT_on else 0", + "MetricGroup": "SMT", "MetricName": "SMT_2T_Utilization" }, { "BriefDescription": "Fraction of cycles spent in the Operating System (OS) Kernel mode", - "MetricExpr": "CPU_CLK_UNHALTED.THREAD:k / CPU_CLK_UNHALTED.THREAD", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD_P:k / CPU_CLK_UNHALTED.THREAD", "MetricGroup": "OS", "MetricName": "Kernel_Utilization" }, { "BriefDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]", - "MetricExpr": "( ( ( uncore_imc@cas_count_read@ + uncore_imc@cas_count_write@ ) * 1048576 ) / 1000000000 ) / duration_time", - "MetricGroup": "Memory_BW;SoC", + "MetricExpr": "( 64 * ( uncore_imc@cas_count_read@ + uncore_imc@cas_count_write@ ) / 1000000000 ) / duration_time", + "MetricGroup": "HPC;MemoryBW;SoC", "MetricName": "DRAM_BW_Use" }, { "BriefDescription": "Average latency of data read request to external memory (in nanoseconds). Accounts for demand loads and L1/L2 prefetches", "MetricExpr": "1000000000 * ( cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433@ / cha@event\\=0x35\\,umask\\=0x21\\,config\\=0x40433@ ) / ( cha_0@event\\=0x0@ / duration_time )", - "MetricGroup": "Memory_Lat;SoC", + "MetricGroup": "MemoryLat;SoC", "MetricName": "MEM_Read_Latency" }, { "BriefDescription": "Average number of parallel data read requests to external memory. Accounts for demand loads and L1/L2 prefetches", "MetricExpr": "cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433@ / cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433\\,thresh\\=1@", - "MetricGroup": "Memory_BW;SoC", + "MetricGroup": "MemoryBW;SoC", "MetricName": "MEM_Parallel_Reads" }, { "BriefDescription": "Average latency of data read request to external 3D X-Point memory [in nanoseconds]. Accounts for demand loads and L1/L2 data-read prefetches", "MetricExpr": "( 1000000000 * ( imc@event\\=0xe0\\,umask\\=0x1@ / imc@event\\=0xe3@ ) / imc_0@event\\=0x0@ )", - "MetricGroup": "Memory_Lat;SoC;Server", + "MetricGroup": "MemoryLat;SoC;Server", "MetricName": "MEM_PMM_Read_Latency" }, { "BriefDescription": "Average 3DXP Memory Bandwidth Use for reads [GB / sec]", "MetricExpr": "( ( 64 * imc@event\\=0xe3@ / 1000000000 ) / duration_time )", - "MetricGroup": "Memory_BW;SoC;Server", + "MetricGroup": "MemoryBW;SoC;Server", "MetricName": "PMM_Read_BW" }, { "BriefDescription": "Average 3DXP Memory Bandwidth Use for Writes [GB / sec]", "MetricExpr": "( ( 64 * imc@event\\=0xe7@ / 1000000000 ) / duration_time )", - "MetricGroup": "Memory_BW;SoC;Server", + "MetricGroup": "MemoryBW;SoC;Server", "MetricName": "PMM_Write_BW" }, { "BriefDescription": "Average IO (network or disk) Bandwidth Use for Writes [GB / sec]", "MetricExpr": "( UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3 ) * 4 / 1000000000 / duration_time", - "MetricGroup": "IO_BW;SoC;Server", + "MetricGroup": "IoBW;SoC;Server", "MetricName": "IO_Write_BW" }, { "BriefDescription": "Average IO (network or disk) Bandwidth Use for Reads [GB / sec]", "MetricExpr": "( UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3 ) * 4 / 1000000000 / duration_time", - "MetricGroup": "IO_BW;SoC;Server", + "MetricGroup": "IoBW;SoC;Server", "MetricName": "IO_Read_BW" }, { @@ -383,7 +302,7 @@ }, { "BriefDescription": "Instructions per Far Branch ( Far Branches apply upon transition from application to operating system, handling interrupts, exceptions) [lower number means higher occurrence rate]", - "MetricExpr": "INST_RETIRED.ANY / ( BR_INST_RETIRED.FAR_BRANCH / 2 )", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.FAR_BRANCH:u", "MetricGroup": "Branches;OS", "MetricName": "IpFarBranch" }, -- cgit v1.2.3-70-g09d2 From 2c72404e950a9e0cf39cedcee9bb34a29b19baf0 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 10:53:48 +0800 Subject: perf vendor events intel: Update core event list for SkyLake Server Update JSON core events for SkyLake Server. Based on JSON list v1.24: https://download.01.org/perfmon/SKX/ Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-5-yao.jin@linux.intel.com Signed-off-by: Jin Yao --- tools/perf/pmu-events/arch/x86/skylakex/cache.json | 1724 ++++++++++---------- .../arch/x86/skylakex/floating-point.json | 56 +- .../pmu-events/arch/x86/skylakex/frontend.json | 580 +++---- .../perf/pmu-events/arch/x86/skylakex/memory.json | 1300 +++++++-------- tools/perf/pmu-events/arch/x86/skylakex/other.json | 104 +- .../pmu-events/arch/x86/skylakex/pipeline.json | 1068 ++++++------ .../arch/x86/skylakex/virtual-memory.json | 288 ++-- 7 files changed, 2565 insertions(+), 2555 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/skylakex/cache.json b/tools/perf/pmu-events/arch/x86/skylakex/cache.json index e750a21976f1..9ff67206ade4 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/cache.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/cache.json @@ -1,94 +1,55 @@ [ { - "BriefDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0004", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" - }, - { - "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", + "BriefDescription": "L1D data line replacements", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", - "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", - "SampleAfterValue": "100003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts all demand code reads that have any response type.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010004", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "EventCode": "0x51", + "EventName": "L1D.REPLACEMENT", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", + "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.PF_MISS", - "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x38" + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.FB_FULL", + "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Demand requests that miss L2 cache", + "BriefDescription": "L1D miss outstandings duration in cycles", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_MISS", - "PublicDescription": "Demand requests that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x27" - }, - { - "BriefDescription": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0002", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING", + "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "BriefDescription": "Cycles with L1D load Misses outstanding.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L3_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", - "SampleAfterValue": "50021", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "L2 writebacks that access L2 cache", + "AnyThread": "1", + "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF0", - "EventName": "L2_TRANS.L2_WB", - "PublicDescription": "Counts L2 writebacks that access L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x40" + "CounterMask": "1", + "EventCode": "0x48", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { "BriefDescription": "L2 cache lines filling L2", @@ -101,123 +62,82 @@ "UMask": "0x1f" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0400", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0001", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.", + "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0100", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.NON_SILENT", + "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", + "SampleAfterValue": "200003", + "UMask": "0x2" }, { - "BriefDescription": "Demand Data Read requests sent to uncore", + "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", - "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", - "SampleAfterValue": "100003", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.SILENT", + "SampleAfterValue": "200003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L3_MISS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", - "SampleAfterValue": "100007", - "UMask": "0x20" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.USELESS_HWPF", + "SampleAfterValue": "200003", + "UMask": "0x4" }, { - "BriefDescription": "All retired store instructions.", + "BriefDescription": "This event is deprecated. Refer to new event L2_LINES_OUT.USELESS_HWPF", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.ALL_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", - "SampleAfterValue": "2000003", - "UMask": "0x82" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Deprecated": "1", + "EventCode": "0xF2", + "EventName": "L2_LINES_OUT.USELESS_PREF", + "SampleAfterValue": "200003", + "UMask": "0x4" }, { - "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", + "BriefDescription": "L2 code requests", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.SILENT", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "PublicDescription": "Counts the total number of L2 code requests.", "SampleAfterValue": "200003", - "UMask": "0x1" + "UMask": "0xe4" }, { - "BriefDescription": "Counts all prefetch data reads that hit in the L3.", + "BriefDescription": "Demand Data Read requests", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", + "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "UMask": "0xe1" }, { - "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Demand requests that miss L2 cache", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_MISS", + "PublicDescription": "Demand requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x27" }, { - "BriefDescription": "Core-originated cacheable demand requests missed L3", + "BriefDescription": "Demand requests to L2 cache", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL057", - "EventCode": "0x2E", - "EventName": "LONGEST_LAT_CACHE.MISS", - "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", - "SampleAfterValue": "100003", - "UMask": "0x41" + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", + "PublicDescription": "Demand requests to L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xe7" }, { "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches", @@ -230,78 +150,104 @@ "UMask": "0xf8" }, { - "BriefDescription": "Retired load instructions whose data sources was remote HITM", + "BriefDescription": "RFO requests to L2 cache", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", - "PEBS": "1", - "PublicDescription": "Retired load instructions whose data sources was remote HITM.", - "SampleAfterValue": "100007", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.ALL_RFO", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "SampleAfterValue": "200003", + "UMask": "0xe2" }, { - "BriefDescription": "Counts all prefetch data reads that have any response type.", + "BriefDescription": "L2 cache hits when fetching instructions, code reads.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "SampleAfterValue": "200003", + "UMask": "0xc4" }, { - "BriefDescription": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "L2 cache misses when fetching instructions", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0122", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "SampleAfterValue": "200003", + "UMask": "0x24" }, { - "BriefDescription": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Demand Data Read requests that hit L2 cache", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0100", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", + "PublicDescription": "Counts the number of demand Data Read requests, initiated by load instructions, that hit L2 cache", + "SampleAfterValue": "200003", + "UMask": "0xc1" }, { - "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", + "BriefDescription": "Demand Data Read miss L2, no rejects", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", - "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "EventCode": "0x24", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", + "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", + "SampleAfterValue": "200003", + "UMask": "0x21" }, { - "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "All requests that miss L2 cache", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.MISS", + "PublicDescription": "All requests that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x3f" + }, + { + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.PF_HIT", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xd8" + }, + { + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.PF_MISS", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0x38" + }, + { + "BriefDescription": "All L2 requests", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.REFERENCES", + "PublicDescription": "All L2 requests.", + "SampleAfterValue": "200003", + "UMask": "0xff" + }, + { + "BriefDescription": "RFO requests that hit L2 cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x24", + "EventName": "L2_RQSTS.RFO_HIT", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "UMask": "0xc2" }, { "BriefDescription": "RFO requests that miss L2 cache", @@ -314,56 +260,188 @@ "UMask": "0x22" }, { - "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped", + "BriefDescription": "L2 writebacks that access L2 cache", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.NON_SILENT", - "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", + "EventCode": "0xF0", + "EventName": "L2_TRANS.L2_WB", + "PublicDescription": "Counts L2 writebacks that access L2 cache.", "SampleAfterValue": "200003", - "UMask": "0x2" + "UMask": "0x40" }, { - "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "BriefDescription": "Core-originated cacheable demand requests missed L3", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.USELESS_HWPF", - "SampleAfterValue": "200003", - "UMask": "0x4" + "Errata": "SKL057", + "EventCode": "0x2E", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x41" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that have any response type.", + "BriefDescription": "Core-originated cacheable demand requests that refer to L3", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Errata": "SKL057", + "EventCode": "0x2E", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", + "SampleAfterValue": "100003", + "UMask": "0x4f" + }, + { + "BriefDescription": "All retired load instructions.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010002", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x81" + }, + { + "BriefDescription": "All retired store instructions.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "SampleAfterValue": "2000003", + "UMask": "0x82" + }, + { + "BriefDescription": "Retired load instructions with locked access.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x21" + }, + { + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x41" + }, + { + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "UMask": "0x42" + }, + { + "BriefDescription": "Retired load instructions that miss the STLB.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "PEBS": "1", + "SampleAfterValue": "100003", + "UMask": "0x11" + }, + { + "BriefDescription": "Retired store instructions that miss the STLB.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD0", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "L1_Hit_Indication": "1", + "PEBS": "1", "SampleAfterValue": "100003", + "UMask": "0x12" + }, + { + "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", + "SampleAfterValue": "20011", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", + "SampleAfterValue": "20011", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "PEBS": "1", + "SampleAfterValue": "20011", "UMask": "0x1" }, { - "BriefDescription": "All requests that miss L2 cache", + "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.MISS", - "PublicDescription": "All requests that miss L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0x3f" + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD2", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "UMask": "0x8" }, { - "BriefDescription": "L2 code requests", + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_CODE_RD", - "PublicDescription": "Counts the total number of L2 code requests.", - "SampleAfterValue": "200003", - "UMask": "0xe4" + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", + "PEBS": "1", + "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", + "SampleAfterValue": "100007", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x2" }, { "BriefDescription": "Retired load instructions whose data sources was forwarded from a remote cache", @@ -378,127 +456,235 @@ "UMask": "0x8" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Retired load instructions whose data sources was remote HITM", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0020", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "Data_LA": "1", + "EventCode": "0xD3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", + "PEBS": "1", + "PublicDescription": "Retired load instructions whose data sources was remote HITM.", + "SampleAfterValue": "100007", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD4", + "EventName": "MEM_LOAD_MISC_RETIRED.UC", + "PEBS": "1", + "SampleAfterValue": "100007", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", + "SampleAfterValue": "100007", + "UMask": "0x40" + }, + { + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PEBS": "1", + "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PEBS": "1", + "PublicDescription": "Retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "50021", + "UMask": "0x10" + }, + { + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache.", + "SampleAfterValue": "50021", + "UMask": "0x4" + }, + { + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xD1", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PEBS": "1", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache.", + "SampleAfterValue": "100007", + "UMask": "0x20" + }, + { + "BriefDescription": "Demand and prefetch data reads", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "SampleAfterValue": "100003", + "UMask": "0x8" + }, + { + "BriefDescription": "Any memory transaction that reached the SQ.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", + "SampleAfterValue": "100003", + "UMask": "0x80" + }, + { + "BriefDescription": "Cacheable and noncachaeble code read requests", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", + "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", "SampleAfterValue": "100003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Counts all demand & prefetch data reads that have any response type.", + "BriefDescription": "Demand Data Read requests sent to uncore", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", - "SampleAfterValue": "20011", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "SampleAfterValue": "100003", + "UMask": "0x4" }, { - "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", + "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xB2", + "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", + "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0122", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L1_MISS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", "UMask": "0x8" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0020", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0400", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", + "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "L2 cache misses when fetching instructions", + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.CODE_RD_MISS", - "PublicDescription": "Counts L2 cache misses when fetching instructions.", - "SampleAfterValue": "200003", - "UMask": "0x24" + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x4" }, { - "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { "BriefDescription": "Offcore outstanding Demand Data Read transactions in uncore queue.", @@ -511,73 +697,56 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that hit in the L3.", + "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0001", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "6", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0120", - "Offcore": "1", + "EventName": "OFFCORE_RESPONSE", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all demand & prefetch data reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0120", + "MSRValue": "0x0000010491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", - "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Demand requests to L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", - "PublicDescription": "Demand requests to L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xe7" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0080", + "MSRValue": "0x3F803C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -588,187 +757,157 @@ "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0491", + "MSRValue": "0x10003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010020", + "MSRValue": "0x04003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3.", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0122", + "MSRValue": "0x01003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0001", + "MSRValue": "0x08003C0491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all prefetch data reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0080", + "MSRValue": "0x0000010490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts all prefetch data reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0490", + "MSRValue": "0x3F803C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Core-originated cacheable demand requests that refer to L3", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL057", - "EventCode": "0x2E", - "EventName": "LONGEST_LAT_CACHE.REFERENCE", - "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", - "SampleAfterValue": "100003", - "UMask": "0x4f" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010080", + "MSRValue": "0x10003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0120", + "MSRValue": "0x04003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3.", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0491", + "MSRValue": "0x01003C0490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions that miss the STLB.", + "BriefDescription": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", - "PEBS": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x08003C0490", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x11" + "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that have any response type.", + "BriefDescription": "Counts prefetch RFOs that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010001", + "MSRValue": "0x0000010120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.", + "BriefDescription": "Counts prefetch RFOs that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0020", + "MSRValue": "0x3F803C0120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, - { - "BriefDescription": "L1D data line replacements", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x51", - "EventName": "L1D.REPLACEMENT", - "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, { "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", @@ -783,47 +922,43 @@ "UMask": "0x1" }, { - "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD4", - "EventName": "MEM_LOAD_MISC_RETIRED.UC", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x4" + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x04003C0120", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.FB_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready.", - "SampleAfterValue": "100007", - "UMask": "0x40" - }, - { - "BriefDescription": "This event is deprecated. Refer to new event L2_LINES_OUT.USELESS_HWPF", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Deprecated": "1", - "EventCode": "0xF2", - "EventName": "L2_LINES_OUT.USELESS_PREF", - "SampleAfterValue": "200003", - "UMask": "0x4" + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x01003C0120", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", + "BriefDescription": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.PF_HIT", - "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xd8" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x08003C0120", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { "BriefDescription": "Counts all demand & prefetch RFOs that have any response type.", @@ -839,14 +974,17 @@ "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read miss L2, no rejects", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", - "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", - "SampleAfterValue": "200003", - "UMask": "0x21" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0122", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", @@ -862,293 +1000,247 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010100", + "MSRValue": "0x04003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x01003C0122", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0080", + "MSRValue": "0x08003C0122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts all demand code reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0491", + "MSRValue": "0x0000010004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "All retired load instructions.", + "BriefDescription": "Counts all demand code reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.ALL_LOADS", - "PEBS": "1", - "SampleAfterValue": "2000003", - "UMask": "0x81" + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0004", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", - "PEBS": "1", - "SampleAfterValue": "20011", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0004", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", - "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", - "SampleAfterValue": "200003", - "UMask": "0xe1" - }, - { - "BriefDescription": "All L2 requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.REFERENCES", - "PublicDescription": "All L2 requests.", - "SampleAfterValue": "200003", - "UMask": "0xff" - }, - { - "BriefDescription": "Cycles with L1D load Misses outstanding.", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING_CYCLES", - "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x04003C0004", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", - "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0100", + "MSRValue": "0x01003C0004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of cache line split locks sent to uncore.", + "BriefDescription": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xF4", - "EventName": "SQ_MISC.SPLIT_LOCK", - "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x08003C0004", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x10" + "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3.", + "BriefDescription": "Counts demand data reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0002", + "MSRValue": "0x0000010001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts demand data reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0100", + "MSRValue": "0x3F803C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L2 cache hits when fetching instructions, code reads.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.CODE_RD_HIT", - "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", - "SampleAfterValue": "200003", - "UMask": "0xc4" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0400", + "MSRValue": "0x10003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010010", + "MSRValue": "0x04003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "BriefDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L2_HIT", - "PEBS": "1", - "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x01003C0001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "RFO requests that hit L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.RFO_HIT", - "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", - "SampleAfterValue": "200003", - "UMask": "0xc2" + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0080", + "MSRValue": "0x08003C0001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "L1D miss outstandings duration in cycles", + "BriefDescription": "Counts all demand data writes (RFOs) that have any response type.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.PENDING", - "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0000010002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0491", + "MSRValue": "0x3F803C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests that hit L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", - "PublicDescription": "Counts the number of demand Data Read requests, initiated by load instructions, that hit L2 cache", - "SampleAfterValue": "200003", - "UMask": "0xc1" - }, - { - "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD2", - "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", - "SampleAfterValue": "20011", - "UMask": "0x4" + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0001", + "MSRValue": "0x04003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -1168,508 +1260,416 @@ "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0080", + "MSRValue": "0x08003C0002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0010", + "MSRValue": "0x0000010400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.SPLIT_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", - "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0400", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x42" + "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0010", + "MSRValue": "0x10003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Any memory transaction that reached the SQ.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", - "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", - "SampleAfterValue": "100003", - "UMask": "0x80" - }, - { - "BriefDescription": "Cacheable and noncachaeble code read requests", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", - "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0100", + "MSRValue": "0x04003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0004", + "MSRValue": "0x01003C0400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", + "BriefDescription": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", - "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x08003C0400", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010400", + "MSRValue": "0x0000010010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0004", + "MSRValue": "0x3F803C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0004", + "MSRValue": "0x10003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x48", - "EventName": "L1D_PEND_MISS.FB_FULL", - "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0020", + "MSRValue": "0x04003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that hit in the L3.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0004", + "MSRValue": "0x01003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that hit in the L3.", + "BriefDescription": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0120", + "MSRValue": "0x08003C0010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0020", + "MSRValue": "0x0000010020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0400", + "MSRValue": "0x3F803C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L1_HIT", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", - "SampleAfterValue": "2000003", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x10003C0020", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", - "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0490", + "MSRValue": "0x04003C0020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions with locked access.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.LOCK_LOADS", - "PEBS": "1", - "SampleAfterValue": "100007", - "UMask": "0x21" - }, - { - "BriefDescription": "Demand and prefetch data reads", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", - "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x01003C0020", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x8" - }, - { - "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD3", - "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", - "PEBS": "1", - "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", - "SampleAfterValue": "100007", "UMask": "0x1" }, { - "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", + "BriefDescription": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x08003C0020", + "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0400", + "MSRValue": "0x0000010080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", - "PEBS": "1", - "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3F803C0080", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x41" - }, - { - "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB2", - "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", - "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", - "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", - "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0002", + "MSRValue": "0x10003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3F803C0010", + "MSRValue": "0x04003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that have any response type.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0000010120", + "MSRValue": "0x01003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x10003C0002", + "MSRValue": "0x08003C0080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired store instructions that miss the STLB.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD0", - "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", - "L1_Hit_Indication": "1", - "PEBS": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x0000010100", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x12" - }, - { - "BriefDescription": "RFO requests to L2 cache", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x24", - "EventName": "L2_RQSTS.ALL_RFO", - "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", - "SampleAfterValue": "200003", - "UMask": "0xe2" + "UMask": "0x1" }, { - "BriefDescription": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x08003C0010", + "MSRValue": "0x3F803C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0010", + "MSRValue": "0x10003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xD1", - "EventName": "MEM_LOAD_RETIRED.L2_MISS", - "PEBS": "1", - "PublicDescription": "Retired load instructions missed L2 cache as data sources.", - "SampleAfterValue": "50021", - "UMask": "0x10" + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x04003C0100", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x01003C0001", + "MSRValue": "0x01003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", - "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "BriefDescription": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x04003C0122", + "MSRValue": "0x08003C0100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" + }, + { + "BriefDescription": "Number of cache line split locks sent to uncore.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xF4", + "EventName": "SQ_MISC.SPLIT_LOCK", + "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", + "SampleAfterValue": "100003", + "UMask": "0x10" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json index e197cde15047..503737ed3a83 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json @@ -9,22 +9,13 @@ "UMask": "0x4" }, { - "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 8 calculations per element.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x8" }, { "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", @@ -36,33 +27,31 @@ "UMask": "0x10" }, { - "BriefDescription": "Number of SSE/AVX computational 512-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 16 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", "SampleAfterValue": "2000003", - "UMask": "0x80" + "UMask": "0x20" }, { - "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational 512-bit packed double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 8 computation operations, one for each element. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 8 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x40" }, { - "BriefDescription": "Cycles with any input/output SSE or FP assist", + "BriefDescription": "Number of SSE/AVX computational 512-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 16 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 16 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xCA", - "EventName": "FP_ASSIST.ANY", - "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", - "SampleAfterValue": "100003", - "UMask": "0x1e" + "EventCode": "0xC7", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "UMask": "0x80" }, { "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", @@ -74,12 +63,23 @@ "UMask": "0x1" }, { - "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 4 computation operations, one for each element. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", + "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired; some instructions will count twice as noted below. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP14 RSQRT14 SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform 2 calculations per element.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0xC7", - "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x2" + }, + { + "BriefDescription": "Cycles with any input/output SSE or FP assist", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0xCA", + "EventName": "FP_ASSIST.ANY", + "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", + "SampleAfterValue": "100003", + "UMask": "0x1e" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/frontend.json b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json index cdf95bd2a73d..078706a50091 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/frontend.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json @@ -1,109 +1,115 @@ [ { - "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x80", - "EventName": "ICACHE_16B.IFDATA_STALL", - "PublicDescription": "Cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", + "EventCode": "0xE6", + "EventName": "BACLEARS.ANY", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "SampleAfterValue": "100003", + "UMask": "0x1" + }, + { + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switches", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xAB", + "EventName": "DSB2MITE_SWITCHES.COUNT", + "PublicDescription": "This event counts the number of the Decode Stream Buffer (DSB)-to-MITE switches including all misses because of missing Decode Stream Buffer (DSB) cache and u-arch forced misses.\nNote: Invoking MITE requires two or three cycles delay.", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xAB", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 02 cycles.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.ITLB_MISS", + "EventName": "FRONTEND_RETIRED.DSB_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x14", + "MSRValue": "0x11", "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", "MSRIndex": "0x3F7", - "MSRValue": "0x408006", + "MSRValue": "0x14", "PEBS": "1", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", - "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.L1I_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x12", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.DSB_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", - "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.L2_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x13", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", + "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xE6", - "EventName": "BACLEARS.ANY", - "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xc6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x400106", + "PEBS": "2", + "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.DSB_MISS", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", "MSRIndex": "0x3F7", - "MSRValue": "0x11", + "MSRValue": "0x408006", "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss.", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, - { - "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", - "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", @@ -119,92 +125,110 @@ "UMask": "0x1" }, { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.MITE_UOPS", - "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", + "MSRIndex": "0x3F7", + "MSRValue": "0x400206", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", - "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "MSRIndex": "0x3F7", + "MSRValue": "0x410006", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.MS_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", - "SampleAfterValue": "2000003", - "UMask": "0x30" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "MSRValue": "0x100206", + "PEBS": "1", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Cycles MITE is delivering any Uop", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.ALL_MITE_CYCLES_ANY_UOPS", - "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", - "SampleAfterValue": "2000003", - "UMask": "0x24" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", + "MSRIndex": "0x3F7", + "MSRValue": "0x200206", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x83", - "EventName": "ICACHE_64B.IFTAG_HIT", - "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", + "MSRIndex": "0x3F7", + "MSRValue": "0x300206", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0x79", - "EventName": "IDQ.MS_SWITCHES", - "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", - "SampleAfterValue": "2000003", - "UMask": "0x30" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "MSRValue": "0x402006", + "PEBS": "1", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.L2_MISS", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", "MSRIndex": "0x3F7", - "MSRValue": "0x13", + "MSRValue": "0x400406", "PEBS": "1", "SampleAfterValue": "100007", "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x79", - "EventName": "IDQ.MITE_CYCLES", - "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "MSRValue": "0x420006", + "PEBS": "1", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" }, { "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", @@ -220,24 +244,60 @@ "UMask": "0x1" }, { - "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x9C", - "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", - "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding 4 x when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", - "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "MSRIndex": "0x3F7", + "MSRValue": "0x400806", + "PEBS": "1", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC6", + "EventName": "FRONTEND_RETIRED.STLB_MISS", + "MSRIndex": "0x3F7", + "MSRValue": "0x15", + "PEBS": "1", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", + "SampleAfterValue": "100007", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x79", - "EventName": "IDQ.MS_MITE_UOPS", - "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "EventCode": "0x80", + "EventName": "ICACHE_16B.IFDATA_STALL", + "PublicDescription": "Cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x4" + }, + { + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_HIT", + "SampleAfterValue": "200003", + "UMask": "0x1" + }, + { + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x83", + "EventName": "ICACHE_64B.IFTAG_MISS", + "SampleAfterValue": "200003", + "UMask": "0x2" }, { "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", @@ -249,14 +309,15 @@ "UMask": "0x4" }, { - "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAB", - "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", - "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 02 cycles.", + "CounterMask": "4", + "EventCode": "0x79", + "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x18" }, { "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", @@ -270,106 +331,79 @@ "UMask": "0x18" }, { - "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "BriefDescription": "Cycles MITE is delivering 4 Uops", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.STLB_MISS", - "MSRIndex": "0x3F7", - "MSRValue": "0x15", - "PEBS": "1", - "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0x79", + "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x24" }, { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", + "BriefDescription": "Cycles MITE is delivering any Uop", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", "EventCode": "0x79", - "EventName": "IDQ.DSB_UOPS", - "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "EventName": "IDQ.ALL_MITE_CYCLES_ANY_UOPS", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x24" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", - "MSRIndex": "0x3F7", - "MSRValue": "0x420006", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.DSB_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", - "MSRIndex": "0x3F7", - "MSRValue": "0x400806", - "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "Retired instructions after front-end starvation of at least 1 cycle", - "Counter": "0,1,2,3,4,5,6,7", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xc6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_1", - "MSRIndex": "0x3F7", - "MSRValue": "0x400106", - "PEBS": "2", - "PublicDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of at least 1 cycle which was not interrupted by a back-end stall.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "EventCode": "0x79", + "EventName": "IDQ.DSB_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", - "MSRIndex": "0x3F7", - "MSRValue": "0x400206", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x79", + "EventName": "IDQ.MITE_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "UMask": "0x4" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", - "MSRIndex": "0x3F7", - "MSRValue": "0x400406", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x79", + "EventName": "IDQ.MITE_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "UMask": "0x4" }, { - "BriefDescription": "Cycles MITE is delivering 4 Uops", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", + "CounterMask": "1", "EventCode": "0x79", - "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", - "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "EventName": "IDQ.MS_CYCLES", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", "SampleAfterValue": "2000003", - "UMask": "0x24" + "UMask": "0x30" }, { "BriefDescription": "Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", @@ -383,101 +417,56 @@ "UMask": "0x10" }, { - "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x79", - "EventName": "IDQ.MS_UOPS", - "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "EventName": "IDQ.MS_MITE_UOPS", + "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", "SampleAfterValue": "2000003", - "UMask": "0x30" - }, - { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", - "MSRIndex": "0x3F7", - "MSRValue": "0x410006", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", - "MSRIndex": "0x3F7", - "MSRValue": "0x200206", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" - }, - { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", - "MSRIndex": "0x3F7", - "MSRValue": "0x300206", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "UMask": "0x20" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", - "MSRIndex": "0x3F7", - "MSRValue": "0x100206", - "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", - "SampleAfterValue": "100007", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x79", + "EventName": "IDQ.MS_SWITCHES", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", + "SampleAfterValue": "2000003", + "UMask": "0x30" }, { - "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", "EventCode": "0x79", - "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", - "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "EventName": "IDQ.MS_UOPS", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", "SampleAfterValue": "2000003", - "UMask": "0x18" + "UMask": "0x30" }, { - "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switches", + "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAB", - "EventName": "DSB2MITE_SWITCHES.COUNT", - "PublicDescription": "This event counts the number of the Decode Stream Buffer (DSB)-to-MITE switches including all misses because of missing Decode Stream Buffer (DSB) cache and u-arch forced misses.\nNote: Invoking MITE requires two or three cycles delay.", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding 4 x when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", - "MSRIndex": "0x3F7", - "MSRValue": "0x402006", - "PEBS": "1", - "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { @@ -492,25 +481,36 @@ "UMask": "0x1" }, { - "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x83", - "EventName": "ICACHE_64B.IFTAG_MISS", - "SampleAfterValue": "200003", - "UMask": "0x2" + "CounterMask": "3", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", + "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC6", - "EventName": "FRONTEND_RETIRED.L1I_MISS", - "MSRIndex": "0x3F7", - "MSRValue": "0x12", - "PEBS": "1", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", + "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x9C", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", + "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", + "SampleAfterValue": "2000003", "UMask": "0x1" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/memory.json b/tools/perf/pmu-events/arch/x86/skylakex/memory.json index 6c3fd89d204d..6f29b02fa320 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/memory.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/memory.json @@ -1,658 +1,721 @@ [ { - "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800122", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "2", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "6", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "SampleAfterValue": "2000003", + "UMask": "0x6" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED", + "PEBS": "1", + "PublicDescription": "Number of times HLE abort was triggered.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "UMask": "0x80" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "UMask": "0x40" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times an HLE execution successfully committed", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.COMMIT", + "PublicDescription": "Number of times HLE commit succeeded.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an HLE execution started.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC8", + "EventName": "HLE_RETIRED.START", + "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "Errata": "SKL089", + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "MSRValue": "0x80", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "1009", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that miss in the L3.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000122", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "MSRValue": "0x10", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "20011", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "MSRValue": "0x100", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "503", + "TakenAlone": "1", + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800020", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "MSRValue": "0x20", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "100007", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000100", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "MSRValue": "0x4", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", "SampleAfterValue": "100003", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00002", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "MSRValue": "0x200", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "101", + "TakenAlone": "1", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "MSRValue": "0x40", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "2003", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Data_LA": "1", + "EventCode": "0xcd", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "MSRValue": "0x8", + "PEBS": "2", + "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "SampleAfterValue": "50021", + "TakenAlone": "1", + "UMask": "0x1" + }, + { + "BriefDescription": "Demand Data Read requests who miss L3 cache", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_TIMER", + "EventCode": "0xB0", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", "SampleAfterValue": "2000003", "UMask": "0x10" }, { - "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800490", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", + "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_MEM", - "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "CounterMask": "6", + "EventCode": "0x60", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x10" }, { - "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all demand & prefetch data reads that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800004", + "MSRValue": "0x3FBC000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", - "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "Counts all demand data writes (RFOs) that miss in the L3.", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000002", + "MSRValue": "0x103FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00120", + "MSRValue": "0x083FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch data reads that miss in the L3.", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000490", + "MSRValue": "0x063FC00491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000120", + "MSRValue": "0x0604000491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000490", + "MSRValue": "0x063B800491", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all prefetch data reads that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000491", + "MSRValue": "0x3FBC000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00004", + "MSRValue": "0x103FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00004", + "MSRValue": "0x083FC00490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles.", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", - "MSRIndex": "0x3F6", - "MSRValue": "0x20", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "100007", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x063FC00490", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00020", + "MSRValue": "0x0604000490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00490", + "MSRValue": "0x063B800490", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3.", + "BriefDescription": "Counts prefetch RFOs that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000020", + "MSRValue": "0x3FBC000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", - "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_CONFLICT", - "PublicDescription": "Number of times a TSX line had a cache conflict.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3.", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000400", + "MSRValue": "0x103FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles.", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", - "MSRIndex": "0x3F6", - "MSRValue": "0x40", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "2003", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x083FC00120", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00002", + "MSRValue": "0x063FC00120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_MEM", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", - "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00080", + "MSRValue": "0x0604000120", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC5", - "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC4", - "PublicDescription": "RTM region detected inside HLE.", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, - { - "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC3", - "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC2", - "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5d", - "EventName": "TX_EXEC.MISC1", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Number of times an RTM execution successfully committed", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.COMMIT", - "PublicDescription": "Number of times RTM commit succeeded.", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x063B800120", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that miss in the L3.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000120", + "MSRValue": "0x3FBC000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x103FC00122", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800491", + "MSRValue": "0x083FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800080", + "MSRValue": "0x063FC00122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00490", + "MSRValue": "0x0604000122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000010", + "MSRValue": "0x063B800122", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", + "BriefDescription": "Counts all demand code reads that miss in the L3.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_TIMER", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3FBC000004", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00020", + "MSRValue": "0x103FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00002", + "MSRValue": "0x083FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00490", + "MSRValue": "0x063FC00004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800100", + "MSRValue": "0x0604000004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00010", + "MSRValue": "0x063B800004", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts demand data reads that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00010", + "MSRValue": "0x3FBC000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "BriefDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", - "SampleAfterValue": "2000003", - "UMask": "0x20" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x103FC00001", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800400", + "MSRValue": "0x083FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00122", + "MSRValue": "0x063FC00001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00122", + "MSRValue": "0x0604000001", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -672,541 +735,442 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000001", + "MSRValue": "0x3FBC000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution successfully committed", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.COMMIT", - "PublicDescription": "Number of times HLE commit succeeded.", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", - "PublicDescription": "Number of times we could not allocate Lock Buffer.", - "SampleAfterValue": "2000003", - "UMask": "0x40" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x103FC00002", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00100", + "MSRValue": "0x083FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00001", + "MSRValue": "0x063FC00002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000020", + "MSRValue": "0x0604000002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00080", + "MSRValue": "0x063B800002", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Demand Data Read requests who miss L3 cache", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB0", - "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", - "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x3FBC000400", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", - "UMask": "0x10" + "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00080", + "MSRValue": "0x103FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that miss in the L3.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000001", + "MSRValue": "0x083FC00400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", - "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", - "SampleAfterValue": "2000003", - "UMask": "0x20" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x063FC00400", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00010", + "MSRValue": "0x0604000400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00120", + "MSRValue": "0x063B800400", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00004", + "MSRValue": "0x3FBC000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00100", + "MSRValue": "0x103FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", - "MSRIndex": "0x3F6", - "MSRValue": "0x100", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "503", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x083FC00010", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00122", + "MSRValue": "0x063FC00010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00001", + "MSRValue": "0x0604000010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00020", + "MSRValue": "0x063B800010", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800002", + "MSRValue": "0x3FBC000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00491", + "MSRValue": "0x103FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.ABORTED", - "PEBS": "1", - "PublicDescription": "Number of times RTM abort was triggered.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00400", + "MSRValue": "0x083FC00020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one).", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED", - "PEBS": "1", - "PublicDescription": "Number of times HLE abort was triggered.", - "SampleAfterValue": "2000003", - "UMask": "0x4" - }, - { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", - "MSRIndex": "0x3F6", - "MSRValue": "0x10", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "20011", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x063FC00020", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", - "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", - "SampleAfterValue": "2000003", - "UMask": "0x20" - }, - { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00400", + "MSRValue": "0x0604000020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800010", + "MSRValue": "0x063B800020", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x60", - "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000002", + "MSRValue": "0x3FBC000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", - "MSRIndex": "0x3F6", - "MSRValue": "0x200", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "101", - "TakenAlone": "1", + "EventCode": "0xB7, 0xBB", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "MSRValue": "0x103FC00080", + "Offcore": "1", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00400", + "MSRValue": "0x083FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000010", + "MSRValue": "0x063FC00080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000004", + "MSRValue": "0x0604000080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_CAPACITY", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063B800120", + "MSRValue": "0x063B800080", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", - "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", - "SampleAfterValue": "2000003", - "UMask": "0x40" - }, - { - "BriefDescription": "Number of times an RTM execution started.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC9", - "EventName": "RTM_RETIRED.START", - "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL089", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", - "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x54", - "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", - "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", - "SampleAfterValue": "2000003", - "UMask": "0x10" - }, - { - "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00491", + "MSRValue": "0x3FBC000100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all demand & prefetch data reads that miss in the L3.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000491", + "MSRValue": "0x103FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00001", + "MSRValue": "0x083FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000080", + "MSRValue": "0x063FC00100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", @@ -1226,18 +1190,29 @@ "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3", "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000080", + "MSRValue": "0x063B800100", "Offcore": "1", "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", "SampleAfterValue": "100003", "UMask": "0x1" }, + { + "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one).", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED", + "PEBS": "1", + "PublicDescription": "Number of times RTM abort was triggered.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, { "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", "Counter": "0,1,2,3", @@ -1249,155 +1224,180 @@ "UMask": "0x80" }, { - "BriefDescription": "Number of times an HLE execution started.", + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.START", - "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x8" }, { - "BriefDescription": "Counts all demand code reads that miss in the L3.", + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x3FBC000004", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "UMask": "0x40" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles.", + "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", - "MSRIndex": "0x3F6", - "MSRValue": "0x80", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "1009", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x083FC00491", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "SampleAfterValue": "2000003", + "UMask": "0x20" }, { - "BriefDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "BriefDescription": "Number of times an RTM execution successfully committed", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x103FC00120", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.COMMIT", + "PublicDescription": "Number of times RTM commit succeeded.", + "SampleAfterValue": "2000003", + "UMask": "0x2" + }, + { + "BriefDescription": "Number of times an RTM execution started.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xC9", + "EventName": "RTM_RETIRED.START", + "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram.", + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x063FC00100", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC1", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "6", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC2", + "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", "SampleAfterValue": "2000003", - "UMask": "0x6" + "UMask": "0x2" }, { - "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC8", - "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC3", + "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", "SampleAfterValue": "2000003", - "UMask": "0x80" + "UMask": "0x4" }, { - "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000122", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC4", + "PublicDescription": "RTM region detected inside HLE.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles.", + "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", - "MSRIndex": "0x3F6", - "MSRValue": "0x4", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "100003", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x5d", + "EventName": "TX_EXEC.MISC5", + "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles.", + "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Data_LA": "1", - "EventCode": "0xcd", - "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", - "MSRIndex": "0x3F6", - "MSRValue": "0x8", - "PEBS": "2", - "PublicDescription": "Counts randomly selected loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", - "SampleAfterValue": "50021", - "TakenAlone": "1", - "UMask": "0x1" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CAPACITY", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram.", + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xB7, 0xBB", - "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", - "MSRIndex": "0x1a6,0x1a7", - "MSRValue": "0x0604000400", - "Offcore": "1", - "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", - "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_CONFLICT", + "PublicDescription": "Number of times a TSX line had a cache conflict.", + "SampleAfterValue": "2000003", "UMask": "0x1" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", + "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", + "SampleAfterValue": "2000003", + "UMask": "0x10" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", + "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x8" + }, + { + "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", + "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", + "SampleAfterValue": "2000003", + "UMask": "0x20" + }, + { + "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", + "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", + "SampleAfterValue": "2000003", + "UMask": "0x4" + }, + { + "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x54", + "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", + "PublicDescription": "Number of times we could not allocate Lock Buffer.", + "SampleAfterValue": "2000003", + "UMask": "0x40" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/other.json b/tools/perf/pmu-events/arch/x86/skylakex/other.json index f6b147ba8ef6..8b344259176f 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/other.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/other.json @@ -1,33 +1,4 @@ [ - { - "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.THROTTLE", - "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", - "SampleAfterValue": "200003", - "UMask": "0x40" - }, - { - "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xFE", - "EventName": "IDI_MISC.WB_DOWNGRADE", - "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", - "SampleAfterValue": "100003", - "UMask": "0x4" - }, - { - "BriefDescription": "Number of PREFETCHW instructions executed.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", - "SampleAfterValue": "2000003", - "UMask": "0x8" - }, { "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", "Counter": "0,1,2,3", @@ -49,13 +20,24 @@ "UMask": "0x18" }, { - "BriefDescription": "Number of PREFETCHT0 instructions executed.", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.T0", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "EventCode": "0x28", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "UMask": "0x20" + }, + { + "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x28", + "EventName": "CORE_POWER.THROTTLE", + "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", + "SampleAfterValue": "200003", + "UMask": "0x40" }, { "BriefDescription": "Number of hardware interrupts received by the processor.", @@ -68,14 +50,32 @@ "UMask": "0x1" }, { - "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", + "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x28", - "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", - "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", - "SampleAfterValue": "200003", - "UMask": "0x20" + "EventCode": "0xFE", + "EventName": "IDI_MISC.WB_DOWNGRADE", + "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", + "SampleAfterValue": "100003", + "UMask": "0x4" + }, + { + "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xFE", + "EventName": "IDI_MISC.WB_UPGRADE", + "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", + "SampleAfterValue": "100003", + "UMask": "0x2" + }, + { + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x09", + "EventName": "MEMORY_DISAMBIGUATION.HISTORY_RESET", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { "BriefDescription": "Number of PREFETCHNTA instructions executed.", @@ -87,30 +87,30 @@ "UMask": "0x1" }, { - "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", + "BriefDescription": "Number of PREFETCHW instructions executed.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x32", - "EventName": "SW_PREFETCH_ACCESS.T1_T2", + "EventName": "SW_PREFETCH_ACCESS.PREFETCHW", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x8" }, { + "BriefDescription": "Number of PREFETCHT0 instructions executed.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x09", - "EventName": "MEMORY_DISAMBIGUATION.HISTORY_RESET", + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T0", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", + "BriefDescription": "Number of PREFETCHT1 or PREFETCHT2 instructions executed.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xFE", - "EventName": "IDI_MISC.WB_UPGRADE", - "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", - "SampleAfterValue": "100003", - "UMask": "0x2" + "EventCode": "0x32", + "EventName": "SW_PREFETCH_ACCESS.T1_T2", + "SampleAfterValue": "2000003", + "UMask": "0x4" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json index 3bfc6943ddf9..ca5748120666 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json @@ -1,55 +1,58 @@ [ { - "BriefDescription": "Number of instructions retired. General Counter - architectural event", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.ANY_P", - "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", - "SampleAfterValue": "2000003" - }, - { - "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", + "EventCode": "0x14", + "EventName": "ARITH.DIVIDER_ACTIVE", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", + "BriefDescription": "All (macro) branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", - "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009" }, { - "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "BriefDescription": "All (macro) branch instructions retired.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3", + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", + "PEBS": "2", + "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x4" + }, + { + "BriefDescription": "Conditional branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x14", - "EventName": "ARITH.DIVIDER_ACTIVE", - "SampleAfterValue": "2000003", + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.CONDITIONAL", + "PEBS": "1", + "PublicDescription": "This event counts conditional branch instructions retired.", + "SampleAfterValue": "400009", "UMask": "0x1" }, { - "BriefDescription": "False dependencies in MOB due to partial compare on address.", + "BriefDescription": "Not taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x07", - "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", - "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "Errata": "SKL091", + "EventCode": "0xc4", + "EventName": "BR_INST_RETIRED.COND_NTAKEN", + "PublicDescription": "This event counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x10" }, { "BriefDescription": "Far branch instructions retired.", @@ -64,319 +67,305 @@ "UMask": "0x40" }, { - "BriefDescription": "Counts the number of x87 uops dispatched.", + "BriefDescription": "Direct and indirect near call instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.X87", - "PublicDescription": "Counts the number of x87 uops executed.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "PEBS": "1", + "PublicDescription": "This event counts both direct and indirect near call instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x2" }, { - "BriefDescription": "Demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", + "BriefDescription": "Return instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x4C", - "EventName": "LOAD_HIT_PRE.SW_PF", - "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", - "SampleAfterValue": "100003", - "UMask": "0x1" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "PEBS": "1", + "PublicDescription": "This event counts return instructions retired.", + "SampleAfterValue": "100007", + "UMask": "0x8" }, { - "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", + "BriefDescription": "Taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.NEAR_CALL", + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", "PEBS": "1", - "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", + "PublicDescription": "This event counts taken branch instructions retired.", "SampleAfterValue": "400009", - "UMask": "0x2" + "UMask": "0x20" }, { - "BriefDescription": "Total execution stalls.", + "BriefDescription": "Not taken branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", - "SampleAfterValue": "2000003", - "UMask": "0x4" + "Errata": "SKL091", + "EventCode": "0xC4", + "EventName": "BR_INST_RETIRED.NOT_TAKEN", + "PublicDescription": "This event counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x10" }, { - "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "BriefDescription": "All mispredicted macro branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "5", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x5" + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "SampleAfterValue": "400009" }, { - "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", + "BriefDescription": "Mispredicted macro branch instructions retired.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.SLOW_LEA", - "SampleAfterValue": "2000003", - "UMask": "0x20" + "CounterHTOff": "0,1,2,3", + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", + "PEBS": "2", + "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x4" }, { - "BriefDescription": "Cycles with less than 10 actually retired uops.", + "BriefDescription": "Mispredicted conditional branch instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "10", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.TOTAL_CYCLES", - "Invert": "1", - "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.CONDITIONAL", + "PEBS": "1", + "PublicDescription": "This event counts mispredicted conditional branch instructions retired.", + "SampleAfterValue": "400009", + "UMask": "0x1" }, { - "BriefDescription": "Thread cycles when thread is not in halt state", + "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.THREAD_P", - "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", - "SampleAfterValue": "2000003" + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.NEAR_CALL", + "PEBS": "1", + "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", + "SampleAfterValue": "400009", + "UMask": "0x2" }, { - "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", - "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", - "SampleAfterValue": "2000003", - "UMask": "0x1" + "EventCode": "0xC5", + "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", + "PEBS": "1", + "SampleAfterValue": "400009", + "UMask": "0x20" }, { - "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", + "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", "SampleAfterValue": "25003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Number of machine clears (nukes) of any type.", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.COUNT", - "SampleAfterValue": "100003", + "EventCode": "0x3C", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", + "SampleAfterValue": "25003", "UMask": "0x1" }, { "AnyThread": "1", - "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", - "Counter": "Fixed counter 1", - "CounterHTOff": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x2" - }, - { - "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.THREAD", - "PublicDescription": "Number of uops to be executed per-thread each cycle.", - "SampleAfterValue": "2000003", + "EventCode": "0x3C", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", + "SampleAfterValue": "25003", "UMask": "0x1" }, { - "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", - "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", - "SampleAfterValue": "2000003", - "UMask": "0x1" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "25003", + "UMask": "0x2" }, { - "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", - "Invert": "1", + "BriefDescription": "Reference cycles when the core is not in halt state.", + "Counter": "Fixed counter 2", + "CounterHTOff": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x3" }, { - "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", - "SampleAfterValue": "2000003", - "UMask": "0x40" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "SampleAfterValue": "25003", + "UMask": "0x1" }, { - "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "AnyThread": "1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "8", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", - "SampleAfterValue": "2000003", - "UMask": "0x8" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", + "SampleAfterValue": "25003", + "UMask": "0x1" }, { - "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EventCode": "0xA8", - "EventName": "LSD.CYCLES_ACTIVE", - "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "EdgeDetect": "1", + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", + "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", + "SampleAfterValue": "100007" + }, + { + "BriefDescription": "Core cycles when the thread is not in halt state", + "Counter": "Fixed counter 1", + "CounterHTOff": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.RECOVERY_CYCLES", - "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "AnyThread": "1", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "Fixed counter 1", + "CounterHTOff": "Fixed counter 1", + "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "BriefDescription": "Thread cycles when thread is not in halt state", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.REF_XCLK", - "SampleAfterValue": "25003", - "UMask": "0x1" + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 0", + "AnyThread": "1", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_0", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", - "SampleAfterValue": "2000003", - "UMask": "0x1" + "EventCode": "0x3C", + "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 1", + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_1", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "CounterMask": "8", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x8" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 2", + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_2", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", + "CounterMask": "1", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x1" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 3", + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_3", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", + "CounterMask": "16", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x10" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 4", + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_4", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", + "CounterMask": "12", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", "SampleAfterValue": "2000003", - "UMask": "0x10" + "UMask": "0xc" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 5", + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_5", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "CounterMask": "5", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x5" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 6", + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_6", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "CounterHTOff": "0,1,2,3", + "CounterMask": "20", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", "SampleAfterValue": "2000003", - "UMask": "0x40" + "UMask": "0x14" }, { - "BriefDescription": "Cycles per thread when uops are executed in port 7", + "BriefDescription": "Total execution stalls.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA1", - "EventName": "UOPS_DISPATCHED_PORT.PORT_7", - "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", + "CounterMask": "4", + "EventCode": "0xA3", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", "SampleAfterValue": "2000003", - "UMask": "0x80" + "UMask": "0x4" }, { - "AnyThread": "1", - "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x1" - }, - { - "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", - "Counter": "1", - "CounterHTOff": "1", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.PREC_DIST", - "PEBS": "2", - "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xA8", - "EventName": "LSD.CYCLES_4_UOPS", - "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x4" }, { "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", @@ -389,241 +378,259 @@ "UMask": "0x8" }, { - "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", + "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.STORE_FORWARD", - "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", - "SampleAfterValue": "100003", - "UMask": "0x2" + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", + "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0x5E", - "EventName": "RS_EVENTS.EMPTY_END", - "Invert": "1", - "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x40" }, { - "AnyThread": "1", - "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", - "SampleAfterValue": "25003", + "EventCode": "0xA6", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles where the pipeline is stalled due to serializing operations.", + "BriefDescription": "Stalls caused by changing prefix length of the instruction.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x59", - "EventName": "PARTIAL_RAT_STALLS.SCOREBOARD", - "PublicDescription": "This event counts cycles during which the microcode scoreboard stalls happen.", + "EventCode": "0x87", + "EventName": "ILD_STALL.LCP", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "BriefDescription": "Instructions retired from execution.", + "Counter": "Fixed counter 0", + "CounterHTOff": "Fixed counter 0", + "EventName": "INST_RETIRED.ANY", + "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Not taken branch instructions retired.", + "BriefDescription": "Number of instructions retired. General Counter - architectural event", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xc4", - "EventName": "BR_INST_RETIRED.COND_NTAKEN", - "PublicDescription": "This event counts not taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x10" + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.ANY_P", + "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", + "SampleAfterValue": "2000003" }, { - "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", + "Counter": "1", + "CounterHTOff": "1", + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.PREC_DIST", + "PEBS": "2", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", + "Counter": "0,2,3", + "CounterHTOff": "0,2,3", + "CounterMask": "10", + "Errata": "SKL091, SKL044", + "EventCode": "0xC0", + "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", + "Invert": "1", + "PEBS": "2", + "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "3", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "EventCode": "0x0D", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x80" }, { - "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "EventCode": "0x0D", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "AnyThread": "1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "EventCode": "0x0D", + "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Reference cycles when the core is not in halt state.", - "Counter": "Fixed counter 2", - "CounterHTOff": "Fixed counter 2", - "EventName": "CPU_CLK_UNHALTED.REF_TSC", - "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", - "SampleAfterValue": "2000003", - "UMask": "0x3" + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x03", + "EventName": "LD_BLOCKS.NO_SR", + "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "SampleAfterValue": "100003", + "UMask": "0x8" }, { - "BriefDescription": "All mispredicted macro branch instructions retired.", + "BriefDescription": "Loads blocked due to overlapping with a preceding store that cannot be forwarded.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", - "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", - "SampleAfterValue": "400009" + "EventCode": "0x03", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "PublicDescription": "Counts the number of times where store forwarding was prevented for a load operation. The most common case is a load blocked due to the address of memory access (partially) overlapping with a preceding uncompleted store. Note: See the table of not supported store forwards in the Optimization Guide.", + "SampleAfterValue": "100003", + "UMask": "0x2" }, { - "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", + "BriefDescription": "False dependencies in MOB due to partial compare on address.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC1", - "EventName": "OTHER_ASSISTS.ANY", + "EventCode": "0x07", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", "SampleAfterValue": "100003", - "UMask": "0x3f" + "UMask": "0x1" }, { - "BriefDescription": "Cycles without actually retired uops.", + "BriefDescription": "Demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.STALL_CYCLES", - "Invert": "1", - "PublicDescription": "This event counts cycles without actually retired uops.", - "SampleAfterValue": "2000003", - "UMask": "0x2" + "EventCode": "0x4C", + "EventName": "LOAD_HIT_PRE.SW_PF", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Number of Uops delivered by the LSD.", + "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", "EventCode": "0xA8", - "EventName": "LSD.UOPS", - "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "EventName": "LSD.CYCLES_4_UOPS", + "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", - "SampleAfterValue": "25003", - "UMask": "0x2" + "CounterMask": "1", + "EventCode": "0xA8", + "EventName": "LSD.CYCLES_ACTIVE", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Stalls caused by changing prefix length of the instruction.", + "BriefDescription": "Number of Uops delivered by the LSD.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x87", - "EventName": "ILD_STALL.LCP", - "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", + "EventCode": "0xA8", + "EventName": "LSD.UOPS", + "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "BriefDescription": "Number of machine clears (nukes) of any type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "16", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.COUNT", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "Taken branch instructions retired.", + "BriefDescription": "Self-modifying code (SMC) detected.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_TAKEN", - "PEBS": "1", - "PublicDescription": "This event counts taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x20" + "EventCode": "0xC3", + "EventName": "MACHINE_CLEARS.SMC", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "SampleAfterValue": "100003", + "UMask": "0x4" }, { - "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", + "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x03", - "EventName": "LD_BLOCKS.NO_SR", - "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "EventCode": "0xC1", + "EventName": "OTHER_ASSISTS.ANY", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x3f" }, { - "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", + "BriefDescription": "Cycles where the pipeline is stalled due to serializing operations.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.ANY", - "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "EventCode": "0x59", + "EventName": "PARTIAL_RAT_STALLS.SCOREBOARD", + "PublicDescription": "This event counts cycles during which the microcode scoreboard stalls happen.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Core cycles when the thread is not in halt state", - "Counter": "Fixed counter 1", - "CounterHTOff": "Fixed counter 1", - "EventName": "CPU_CLK_UNHALTED.THREAD", - "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", + "BriefDescription": "Resource-related stall cycles", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xa2", + "EventName": "RESOURCE_STALLS.ANY", + "PublicDescription": "Counts resource-related stall cycles.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "AnyThread": "1", - "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", - "SampleAfterValue": "25003", - "UMask": "0x1" + "EventCode": "0xA2", + "EventName": "RESOURCE_STALLS.SB", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Direct and indirect near call instructions retired.", + "BriefDescription": "Increments whenever there is an update to the LBR array.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_CALL", - "PEBS": "1", - "PublicDescription": "This event counts both direct and indirect near call instructions retired.", - "SampleAfterValue": "100007", - "UMask": "0x2" + "EventCode": "0xCC", + "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "SampleAfterValue": "2000003", + "UMask": "0x20" }, { "BriefDescription": "Number of retired PAUSE instructions (that do not end up with a VMExit to the VMM; TSX aborted Instructions may be counted). This event is not supported on first SKL and KBL products.", @@ -635,325 +642,328 @@ "UMask": "0x40" }, { - "BriefDescription": "Resource-related stall cycles", + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xa2", - "EventName": "RESOURCE_STALLS.ANY", - "PublicDescription": "Counts resource-related stall cycles.", + "EventCode": "0x5E", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Self-modifying code (SMC) detected.", + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC3", - "EventName": "MACHINE_CLEARS.SMC", - "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", - "SampleAfterValue": "100003", - "UMask": "0x4" + "CounterMask": "1", + "EdgeDetect": "1", + "EventCode": "0x5E", + "EventName": "RS_EVENTS.EMPTY_END", + "Invert": "1", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "BriefDescription": "Cycles per thread when uops are executed in port 0", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", - "SampleAfterValue": "25003", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_0", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "SampleAfterValue": "2000003", + "UMask": "0x1" + }, + { + "BriefDescription": "Cycles per thread when uops are executed in port 1", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_1", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "BriefDescription": "Cycles per thread when uops are executed in port 2", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "4", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", - "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x4" }, { - "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", + "BriefDescription": "Cycles per thread when uops are executed in port 3", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", - "PEBS": "1", - "SampleAfterValue": "400009", - "UMask": "0x20" + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_3", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", + "SampleAfterValue": "2000003", + "UMask": "0x8" }, { - "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", + "BriefDescription": "Cycles per thread when uops are executed in port 4", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "CounterMask": "20", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_4", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", "SampleAfterValue": "2000003", - "UMask": "0x14" + "UMask": "0x10" }, { - "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", + "BriefDescription": "Cycles per thread when uops are executed in port 5", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", - "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_5", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x20" }, { - "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", - "Counter": "0,2,3", - "CounterHTOff": "0,2,3", - "CounterMask": "10", - "Errata": "SKL091, SKL044", - "EventCode": "0xC0", - "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", - "Invert": "1", - "PEBS": "2", - "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", + "BriefDescription": "Cycles per thread when uops are executed in port 6", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_6", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x40" }, { - "BriefDescription": "Retirement slots used.", + "BriefDescription": "Cycles per thread when uops are executed in port 7", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC2", - "EventName": "UOPS_RETIRED.RETIRE_SLOTS", - "PublicDescription": "Counts the retirement slots used.", + "EventCode": "0xA1", + "EventName": "UOPS_DISPATCHED_PORT.PORT_7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x80" }, { - "AnyThread": "1", - "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "BriefDescription": "Number of uops executed on the core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", - "SampleAfterValue": "2000003" + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE", + "PublicDescription": "Number of uops executed from any thread.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0E", - "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", - "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to Mixing Intel AVX and Intel SSE Code section of the Optimization Guide.", + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Increments whenever there is an update to the LBR array.", + "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xCC", - "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", - "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "CounterMask": "2", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x2" }, { - "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x5E", - "EventName": "RS_EVENTS.EMPTY_CYCLES", - "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", + "CounterMask": "3", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Return instructions retired.", + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NEAR_RETURN", - "PEBS": "1", - "PublicDescription": "This event counts return instructions retired.", - "SampleAfterValue": "100007", - "UMask": "0x8" - }, - { - "BriefDescription": "Instructions retired from execution.", - "Counter": "Fixed counter 0", - "CounterHTOff": "Fixed counter 0", - "EventName": "INST_RETIRED.ANY", - "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", + "CounterMask": "4", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", + "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "2", + "CounterMask": "1", "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", + "Invert": "1", "SampleAfterValue": "2000003", "UMask": "0x2" }, { - "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA2", - "EventName": "RESOURCE_STALLS.SB", - "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", "SampleAfterValue": "2000003", - "UMask": "0x8" + "UMask": "0x1" }, { - "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EdgeDetect": "1", - "EventCode": "0x3C", - "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", - "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", - "SampleAfterValue": "100007" + "CounterMask": "2", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "All (macro) branch instructions retired.", + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", - "PEBS": "2", - "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "3", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Mispredicted macro branch instructions retired.", + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", - "PEBS": "2", - "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x4" + "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "4", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", - "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "CounterMask": "1", + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x1" }, { - "BriefDescription": "Not taken branch instructions retired.", + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.NOT_TAKEN", - "PublicDescription": "This event counts not taken branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x10" + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.THREAD", + "PublicDescription": "Number of uops to be executed per-thread each cycle.", + "SampleAfterValue": "2000003", + "UMask": "0x1" }, { - "BriefDescription": "Conditional branch instructions retired.", + "BriefDescription": "Counts the number of x87 uops dispatched.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.CONDITIONAL", - "PEBS": "1", - "PublicDescription": "This event counts conditional branch instructions retired.", - "SampleAfterValue": "400009", - "UMask": "0x1" + "EventCode": "0xB1", + "EventName": "UOPS_EXECUTED.X87", + "PublicDescription": "Counts the number of x87 uops executed.", + "SampleAfterValue": "2000003", + "UMask": "0x10" }, { - "BriefDescription": "Mispredicted conditional branch instructions retired.", + "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xC5", - "EventName": "BR_MISP_RETIRED.CONDITIONAL", - "PEBS": "1", - "PublicDescription": "This event counts mispredicted conditional branch instructions retired.", - "SampleAfterValue": "400009", + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.ANY", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "SampleAfterValue": "2000003", "UMask": "0x1" }, { - "BriefDescription": "Number of uops executed on the core.", + "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CORE", - "PublicDescription": "Number of uops executed from any thread.", + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.SLOW_LEA", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x20" }, { - "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "12", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "CounterMask": "1", + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", "SampleAfterValue": "2000003", - "UMask": "0xc" + "UMask": "0x1" }, { - "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", + "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xA6", - "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", - "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", + "EventCode": "0x0E", + "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", + "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to Mixing Intel AVX and Intel SSE Code section of the Optimization Guide.", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x2" }, { - "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", + "BriefDescription": "Number of macro-fused uops retired. (non precise)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x0D", - "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", + "EventCode": "0xc2", + "EventName": "UOPS_RETIRED.MACRO_FUSED", + "PublicDescription": "Counts the number of macro-fused uops retired. (non precise)", "SampleAfterValue": "2000003", - "UMask": "0x80" + "UMask": "0x4" }, { - "BriefDescription": "All (macro) branch instructions retired.", + "BriefDescription": "Retirement slots used.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "Errata": "SKL091", - "EventCode": "0xC4", - "EventName": "BR_INST_RETIRED.ALL_BRANCHES", - "PublicDescription": "Counts all (macro) branch instructions retired.", - "SampleAfterValue": "400009" + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.RETIRE_SLOTS", + "PublicDescription": "Counts the retirement slots used.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { - "BriefDescription": "Cycles where at least 1 uop was executed per-thread", + "BriefDescription": "Cycles without actually retired uops.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "CounterMask": "1", - "EventCode": "0xB1", - "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", - "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.STALL_CYCLES", + "Invert": "1", + "PublicDescription": "This event counts cycles without actually retired uops.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" }, { - "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "BriefDescription": "Cycles with less than 10 actually retired uops.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0xA3", - "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "CounterMask": "10", + "EventCode": "0xC2", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "Invert": "1", + "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", "SampleAfterValue": "2000003", - "UMask": "0x1" + "UMask": "0x2" } ] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json index bbeee1058096..792ca39f013a 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json @@ -1,103 +1,74 @@ [ { - "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.STLB_HIT", - "SampleAfterValue": "100003", - "UMask": "0x20" - }, - { - "BriefDescription": "Store misses in all DTLB levels that cause page walks", + "BriefDescription": "Load misses in all DTLB levels that cause page walks", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", - "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data loads that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", "SampleAfterValue": "100003", "UMask": "0x1" }, { - "BriefDescription": "Page walk completed due to a demand data store to a 2M/4M page", + "BriefDescription": "Loads that miss the DTLB and hit the STLB.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "100003", - "UMask": "0x4" + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "SampleAfterValue": "2000003", + "UMask": "0x20" }, { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a load. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_PENDING", - "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture.", + "CounterMask": "1", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a load.", "SampleAfterValue": "100003", "UMask": "0x10" }, { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts completed page walks (4K page size) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", - "SampleAfterValue": "100003", - "UMask": "0x2" - }, - { - "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xAE", - "EventName": "ITLB.ITLB_FLUSH", - "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", - "SampleAfterValue": "100007", - "UMask": "0x1" - }, - { - "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_ACTIVE", - "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data loads. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x10" + "UMask": "0xe" }, { - "BriefDescription": "Loads that miss the DTLB and hit the STLB.", + "BriefDescription": "Page walk completed due to a demand data load to a 1G page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.STLB_HIT", - "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "2000003", - "UMask": "0x20" + "UMask": "0x8" }, { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Page walk completed due to a demand data load to a 2M/4M page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_PENDING", - "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture.", + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "2000003", - "UMask": "0x10" + "UMask": "0x4" }, { - "BriefDescription": "DTLB flush attempts of the thread-specific entries", + "BriefDescription": "Page walk completed due to a demand data load to a 4K page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xBD", - "EventName": "TLB_FLUSH.DTLB_THREAD", - "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", - "SampleAfterValue": "100007", - "UMask": "0x1" + "EventCode": "0x08", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data loads. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "UMask": "0x2" }, { "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake.", @@ -110,23 +81,12 @@ "UMask": "0x10" }, { - "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Store misses in all DTLB levels that cause page walks", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", - "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", - "SampleAfterValue": "100003", - "UMask": "0x10" - }, - { - "BriefDescription": "Misses at all ITLB levels that cause page walks", - "Counter": "0,1,2,3", - "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", - "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", + "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", "SampleAfterValue": "100003", "UMask": "0x1" }, @@ -141,125 +101,135 @@ "UMask": "0x20" }, { - "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", + "CounterMask": "1", "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts demand data stores that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", "SampleAfterValue": "100003", - "UMask": "0xe" + "UMask": "0x10" }, { - "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts demand data loads that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by demand data stores. This implies it missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", "UMask": "0xe" }, { - "BriefDescription": "Page walk completed due to a demand data store to a 4K page", + "BriefDescription": "Page walk completed due to a demand data store to a 1G page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x2" + "UMask": "0x8" }, { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "BriefDescription": "Page walk completed due to a demand data store to a 2M/4M page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks (2M/4M sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x4" }, { - "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", + "BriefDescription": "Page walk completed due to a demand data store to a 4K page", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x85", - "EventName": "ITLB_MISSES.WALK_COMPLETED", - "PublicDescription": "Counts completed page walks (2M and 4M page sizes) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K sizes) caused by demand data stores. This implies address translations missed in the DTLB and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0xe" + "UMask": "0x2" }, { - "BriefDescription": "Page walk completed due to a demand data load to a 4K page", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", + "EventCode": "0x49", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture.", "SampleAfterValue": "2000003", - "UMask": "0x2" + "UMask": "0x10" }, { - "BriefDescription": "Page walk completed due to a demand data load to a 2M/4M page", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 2M/4M pages. The page walks can end with or without a page fault.", + "EventCode": "0x4f", + "EventName": "EPT.WALK_PENDING", + "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", "SampleAfterValue": "2000003", - "UMask": "0x4" + "UMask": "0x10" }, { - "BriefDescription": "Load misses in all DTLB levels that cause page walks", + "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", - "PublicDescription": "Counts demand data loads that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", - "SampleAfterValue": "100003", + "EventCode": "0xAE", + "EventName": "ITLB.ITLB_FLUSH", + "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", + "SampleAfterValue": "100007", "UMask": "0x1" }, { - "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", + "BriefDescription": "Misses at all ITLB levels that cause page walks", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x4F", - "EventName": "EPT.WALK_PENDING", - "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", - "SampleAfterValue": "2000003", - "UMask": "0x10" + "EventCode": "0x85", + "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", + "SampleAfterValue": "100003", + "UMask": "0x1" }, { - "BriefDescription": "STLB flush attempts", + "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0xBD", - "EventName": "TLB_FLUSH.STLB_ANY", - "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", - "SampleAfterValue": "100007", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.STLB_HIT", + "SampleAfterValue": "100003", "UMask": "0x20" }, { - "BriefDescription": "Page walk completed due to a demand data load to a 1G page", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts page walks completed due to demand data loads whose address translations missed in the TLB and were mapped to 4K pages. The page walks can end with or without a page fault.", - "SampleAfterValue": "2000003", - "UMask": "0x8" + "CounterMask": "1", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "SampleAfterValue": "100003", + "UMask": "0x10" }, { - "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a load. EPT page walk duration are excluded in Skylake.", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "CounterMask": "1", - "EventCode": "0x08", - "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", - "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a load.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (all page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x10" + "UMask": "0xe" + }, + { + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts completed page walks (1G page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "UMask": "0x8" }, { "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)", @@ -267,18 +237,48 @@ "CounterHTOff": "0,1,2,3,4,5,6,7", "EventCode": "0x85", "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", - "PublicDescription": "Counts code misses in all ITLB levels that caused a completed page walk (2M and 4M page sizes). The page walk can end with or without a fault.", + "PublicDescription": "Counts completed page walks (2M/4M page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", "UMask": "0x4" }, { - "BriefDescription": "Page walk completed due to a demand data store to a 1G page", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", "Counter": "0,1,2,3", "CounterHTOff": "0,1,2,3,4,5,6,7", - "EventCode": "0x49", - "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", - "PublicDescription": "Counts page walks completed due to demand data stores whose address translations missed in the TLB and were mapped to 1G pages. The page walks can end with or without a page fault.", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K page sizes) caused by a code fetch. This implies it missed in the ITLB (Instruction TLB) and further levels of TLB. The page walk can end with or without a fault.", "SampleAfterValue": "100003", - "UMask": "0x8" + "UMask": "0x2" + }, + { + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake.", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0x85", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture.", + "SampleAfterValue": "100003", + "UMask": "0x10" + }, + { + "BriefDescription": "DTLB flush attempts of the thread-specific entries", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xBD", + "EventName": "TLB_FLUSH.DTLB_THREAD", + "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", + "SampleAfterValue": "100007", + "UMask": "0x1" + }, + { + "BriefDescription": "STLB flush attempts", + "Counter": "0,1,2,3", + "CounterHTOff": "0,1,2,3,4,5,6,7", + "EventCode": "0xBD", + "EventName": "TLB_FLUSH.STLB_ANY", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "SampleAfterValue": "100007", + "UMask": "0x20" } ] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 211ff31b3d33b56aa12937e898c9280d07daf0d9 Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Tue, 10 Aug 2021 10:14:00 +0530 Subject: iommu: Fix race condition during default domain allocation When two devices with same SID are getting probed concurrently through iommu_probe_device(), the iommu_domain sometimes is getting allocated more than once as call to iommu_alloc_default_domain() is not protected for concurrency. Furthermore, it leads to each device holding a different iommu_domain pointer, separate IOVA space and only one of the devices' domain is used for translations from IOMMU. This causes accesses from other device to fault or see incorrect translations. Fix this by protecting iommu_alloc_default_domain() call with group->mutex and let all devices with same SID share same iommu_domain. Signed-off-by: Ashish Mhetre Link: https://lore.kernel.org/r/1628570641-9127-2-git-send-email-amhetre@nvidia.com Signed-off-by: Will Deacon --- drivers/iommu/iommu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 5419c4b9f27a..80c5a1c57216 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -273,7 +273,9 @@ int iommu_probe_device(struct device *dev) * support default domains, so the return value is not yet * checked. */ + mutex_lock(&group->mutex); iommu_alloc_default_domain(group, dev); + mutex_unlock(&group->mutex); if (group->default_domain) { ret = __iommu_attach_device(group->default_domain, dev); -- cgit v1.2.3-70-g09d2 From b1a1347912a742a4e1fcdc9df6302dd9dd2c3405 Mon Sep 17 00:00:00 2001 From: Krishna Reddy Date: Tue, 10 Aug 2021 10:14:01 +0530 Subject: iommu/arm-smmu: Fix race condition during iommu_group creation When two devices with same SID are getting probed concurrently through iommu_probe_device(), the iommu_group sometimes is getting allocated more than once as call to arm_smmu_device_group() is not protected for concurrency. Furthermore, it leads to each device holding a different iommu_group and domain pointer, separate IOVA space and only one of the devices' domain is used for translations from IOMMU. This causes accesses from other device to fault or see incorrect translations. Fix this by protecting iommu_group allocation from concurrency in arm_smmu_device_group(). Signed-off-by: Krishna Reddy Signed-off-by: Ashish Mhetre Link: https://lore.kernel.org/r/1628570641-9127-3-git-send-email-amhetre@nvidia.com Signed-off-by: Will Deacon --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index fc8b932b47d4..f7da8953afbe 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -1478,6 +1478,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) struct iommu_group *group = NULL; int i, idx; + mutex_lock(&smmu->stream_map_mutex); for_each_cfg_sme(cfg, fwspec, i, idx) { if (group && smmu->s2crs[idx].group && group != smmu->s2crs[idx].group) @@ -1486,8 +1487,10 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) group = smmu->s2crs[idx].group; } - if (group) + if (group) { + mutex_unlock(&smmu->stream_map_mutex); return iommu_group_ref_get(group); + } if (dev_is_pci(dev)) group = pci_device_group(dev); @@ -1501,6 +1504,7 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) for_each_cfg_sme(cfg, fwspec, i, idx) smmu->s2crs[idx].group = group; + mutex_unlock(&smmu->stream_map_mutex); return group; } -- cgit v1.2.3-70-g09d2 From d5c0a8d554dfc46e5d03334155f5f656ca10e70c Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 11:03:44 +0800 Subject: perf vendor events intel: Update uncore event list for SkyLake Server Update JSON uncore events for SkyLake Server. Based on JSON list v1.24: https://download.01.org/perfmon/SKX/ Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-6-yao.jin@linux.intel.com Signed-off-by: Jin Yao --- .../arch/x86/skylakex/uncore-memory.json | 9 -- .../pmu-events/arch/x86/skylakex/uncore-other.json | 171 +++++++++++++++++++-- 2 files changed, 156 insertions(+), 24 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json index b80b5d66385d..0b66e6af8177 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json @@ -64,15 +64,6 @@ "UMask": "0x4", "Unit": "iMC" }, - { - "BriefDescription": "Pre-charge for writes", - "Counter": "0,1,2,3", - "EventCode": "0x2", - "EventName": "UNC_M_PRE_COUNT.WR", - "PerPkg": "1", - "UMask": "0x8", - "Unit": "iMC" - }, { "BriefDescription": "DRAM Page Activate commands sent due to a write request", "Counter": "0,1,2,3", diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json index d7a0270de983..6ed92bc5c129 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json @@ -103,15 +103,6 @@ "UMask": "0x04", "Unit": "CHA" }, - { - "BriefDescription": "write requests from remote home agent", - "Counter": "0,1,2,3", - "EventCode": "0x50", - "EventName": "UNC_CHA_REQUESTS.WRITES_REMOTE", - "PerPkg": "1", - "UMask": "0x08", - "Unit": "CHA" - }, { "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", "Counter": "0,1,2,3", @@ -533,7 +524,7 @@ "EventCode": "0x5C", "EventName": "UNC_CHA_SNOOP_RESP.RSP_WBWB", "PerPkg": "1", - "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This response will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This reponse will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", "UMask": "0x10", "Unit": "CHA" }, @@ -546,6 +537,98 @@ "PublicDescription": "Counts clockticks of the 1GHz trafiic controller clock in the IIO unit.", "Unit": "IIO" }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 0", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART0", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 0", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 1", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART1", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 1", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 2", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART2", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 2", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer Inserts of completions with data: Part 3", + "Counter": "0,1,2,3", + "EventCode": "0xC2", + "EventName": "UNC_IIO_COMP_BUF_INSERTS.CMPD.PART3", + "FCMask": "0x4", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "PCIe Completion Buffer Inserts of completions with data: Part 3", + "UMask": "0x03", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 0", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART0", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 0", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 1", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART1", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 1", + "UMask": "0x02", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 2", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART2", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 2", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCIe Completion Buffer occupancy of completions with data: Part 3", + "Counter": "2,3", + "EventCode": "0xD5", + "EventName": "UNC_IIO_COMP_BUF_OCCUPANCY.CMPD.PART3", + "FCMask": "0x04", + "PerPkg": "1", + "PublicDescription": "PCIe Completion Buffer occupancy of completions with data: Part 3", + "UMask": "0x08", + "Unit": "IIO" + }, { "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part0", "Counter": "2,3", @@ -1218,6 +1301,64 @@ "UMask": "0x02", "Unit": "IIO" }, + { + "BriefDescription": "Total IRP occupancy of inbound read and write requests.", + "Counter": "0,1", + "EventCode": "0xF", + "EventName": "UNC_I_CACHE_TOTAL_OCCUPANCY.MEM", + "PerPkg": "1", + "PublicDescription": "Total IRP occupancy of inbound read and write requests. This is effectively the sum of read occupancy and write occupancy.", + "UMask": "0x4", + "Unit": "IRP" + }, + { + "BriefDescription": "PCIITOM request issued by the IRP unit to the mesh with the intention of writing a full cacheline.", + "Counter": "0,1", + "EventCode": "0x10", + "EventName": "UNC_I_COHERENT_OPS.PCITOM", + "PerPkg": "1", + "PublicDescription": "PCIITOM request issued by the IRP unit to the mesh with the intention of writing a full cacheline to coherent memory, without a RFO. PCIITOM is a speculative Invalidate to Modified command that requests ownership of the cacheline and does not move data from the mesh to IRP cache.", + "UMask": "0x10", + "Unit": "IRP" + }, + { + "BriefDescription": "RFO request issued by the IRP unit to the mesh with the intention of writing a partial cacheline.", + "Counter": "0,1", + "EventCode": "0x10", + "EventName": "UNC_I_COHERENT_OPS.RFO", + "PerPkg": "1", + "PublicDescription": "RFO request issued by the IRP unit to the mesh with the intention of writing a partial cacheline to coherent memory. RFO is a Read For Ownership command that requests ownership of the cacheline and moves data from the mesh to IRP cache.", + "UMask": "0x8", + "Unit": "IRP" + }, + { + "BriefDescription": "Inbound read requests received by the IRP and inserted into the FAF queue.", + "Counter": "0,1", + "EventCode": "0x18", + "EventName": "UNC_I_FAF_INSERTS", + "PerPkg": "1", + "PublicDescription": "Inbound read requests to coherent memory, received by the IRP and inserted into the Fire and Forget queue (FAF), a queue used for processing inbound reads in the IRP.", + "Unit": "IRP" + }, + { + "BriefDescription": "Occupancy of the IRP FAF queue.", + "Counter": "0,1", + "EventCode": "0x19", + "EventName": "UNC_I_FAF_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Occupancy of the IRP Fire and Forget (FAF) queue, a queue used for processing inbound reads in the IRP.", + "Unit": "IRP" + }, + { + "BriefDescription": "Inbound write (fast path) requests received by the IRP.", + "Counter": "0,1", + "EventCode": "0x11", + "EventName": "UNC_I_TRANSACTIONS.WR_PREF", + "PerPkg": "1", + "PublicDescription": "Inbound write (fast path) requests to coherent memory, received by the IRP resulting in write ownership requests issued by IRP to the mesh.", + "UMask": "0x8", + "Unit": "IRP" + }, { "BriefDescription": "Traffic in which the M2M to iMC Bypass was not taken", "Counter": "0,1,2,3", @@ -1466,7 +1607,7 @@ "EventCode": "0x57", "EventName": "UNC_M2M_PREFCAM_INSERTS", "PerPkg": "1", - "PublicDescription": "Counts when the M2M (Mesh to Memory) receives a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", + "PublicDescription": "Counts when the M2M (Mesh to Memory) recieves a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", "Unit": "M2M" }, { @@ -1605,7 +1746,7 @@ "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT0", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x1", "Unit": "UPI LL" }, @@ -1615,17 +1756,17 @@ "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT1", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x2", "Unit": "UPI LL" }, { - "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", + "BriefDescription": "FLITs received which bypassed the Slot0 Recieve Buffer", "Counter": "0,1,2,3", "EventCode": "0x31", "EventName": "UNC_UPI_RxL_BYPASSED.SLOT2", "PerPkg": "1", - "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transferred, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) whcih bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", "UMask": "0x4", "Unit": "UPI LL" }, -- cgit v1.2.3-70-g09d2 From c4ad8fabd03f76ed3a2a4c8aef6baf6cd4f24542 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Mon, 9 Aug 2021 13:24:57 +0800 Subject: perf vendor events: Update metrics for SkyLake Server Update JSON metrics for SkyLake Server. Based on TMA metrics 4.21 at 01.org. https://download.01.org/perfmon/ Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Linux-kernel@vger.kernel.org Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210810020508.31261-7-yao.jin@linux.intel.com Signed-off-by: Jin Yao --- .../pmu-events/arch/x86/skylakex/skx-metrics.json | 247 +++++++-------------- 1 file changed, 83 insertions(+), 164 deletions(-) diff --git a/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json b/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json index 0dd8b13b5cfb..863c9e103969 100644 --- a/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json +++ b/tools/perf/pmu-events/arch/x86/skylakex/skx-metrics.json @@ -1,61 +1,4 @@ [ - { - "BriefDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend", - "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Frontend_Bound", - "PublicDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. Frontend denotes the first part of the processor core responsible to fetch operations that are executed later on by the Backend part. Within the Frontend; a branch predictor predicts the next address to fetch; cache-lines are fetched from the memory subsystem; parsed into instructions; and lastly decoded into micro-operations (uops). Ideally the Frontend can issue Machine_Width uops every cycle to the Backend. Frontend Bound denotes unutilized issue-slots when there is no Backend stall; i.e. bubbles where Frontend delivered no uops while Backend could have accepted them. For example; stalls due to instruction-cache misses would be categorized under Frontend Bound." - }, - { - "BriefDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "IDQ_UOPS_NOT_DELIVERED.CORE / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Frontend_Bound_SMT", - "PublicDescription": "This category represents fraction of slots where the processor's Frontend undersupplies its Backend. Frontend denotes the first part of the processor core responsible to fetch operations that are executed later on by the Backend part. Within the Frontend; a branch predictor predicts the next address to fetch; cache-lines are fetched from the memory subsystem; parsed into instructions; and lastly decoded into micro-operations (uops). Ideally the Frontend can issue Machine_Width uops every cycle to the Backend. Frontend Bound denotes unutilized issue-slots when there is no Backend stall; i.e. bubbles where Frontend delivered no uops while Backend could have accepted them. For example; stalls due to instruction-cache misses would be categorized under Frontend Bound. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots wasted due to incorrect speculations", - "MetricExpr": "( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Bad_Speculation", - "PublicDescription": "This category represents fraction of slots wasted due to incorrect speculations. This include slots used to issue uops that do not eventually get retired and slots for which the issue-pipeline was blocked due to recovery from earlier incorrect speculation. For example; wasted work due to miss-predicted branches are categorized under Bad Speculation category. Incorrect data speculation followed by Memory Ordering Nukes is another example." - }, - { - "BriefDescription": "This category represents fraction of slots wasted due to incorrect speculations. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Bad_Speculation_SMT", - "PublicDescription": "This category represents fraction of slots wasted due to incorrect speculations. This include slots used to issue uops that do not eventually get retired and slots for which the issue-pipeline was blocked due to recovery from earlier incorrect speculation. For example; wasted work due to miss-predicted branches are categorized under Bad Speculation category. Incorrect data speculation followed by Memory Ordering Nukes is another example. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend", - "MetricConstraint": "NO_NMI_WATCHDOG", - "MetricExpr": "1 - ( (IDQ_UOPS_NOT_DELIVERED.CORE / (4 * cycles)) + (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles)) + (UOPS_RETIRED.RETIRE_SLOTS / (4 * cycles)) )", - "MetricGroup": "TopdownL1", - "MetricName": "Backend_Bound", - "PublicDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. Backend is the portion of the processor core where the out-of-order scheduler dispatches ready uops into their respective execution units; and once completed these uops get retired according to program order. For example; stalls due to data-cache misses or stalls due to the divider unit being overloaded are both categorized under Backend Bound. Backend Bound is further divided into two main categories: Memory Bound and Core Bound." - }, - { - "BriefDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "1 - ( (IDQ_UOPS_NOT_DELIVERED.CORE / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) + (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) + (UOPS_RETIRED.RETIRE_SLOTS / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) )", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Backend_Bound_SMT", - "PublicDescription": "This category represents fraction of slots where no uops are being delivered due to a lack of required resources for accepting new uops in the Backend. Backend is the portion of the processor core where the out-of-order scheduler dispatches ready uops into their respective execution units; and once completed these uops get retired according to program order. For example; stalls due to data-cache misses or stalls due to the divider unit being overloaded are both categorized under Backend Bound. Backend Bound is further divided into two main categories: Memory Bound and Core Bound. SMT version; use when SMT is enabled and measuring per logical CPU." - }, - { - "BriefDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired", - "MetricExpr": "UOPS_RETIRED.RETIRE_SLOTS / (4 * cycles)", - "MetricGroup": "TopdownL1", - "MetricName": "Retiring", - "PublicDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. Ideally; all pipeline slots would be attributed to the Retiring category. Retiring of 100% would indicate the maximum 4 uops retired per cycle has been achieved. Maximizing Retiring typically increases the Instruction-Per-Cycle metric. Note that a high Retiring value does not necessary mean there is no room for more performance. For example; Microcode assists are categorized under Retiring. They hurt performance and can often be avoided. " - }, - { - "BriefDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. SMT version; use when SMT is enabled and measuring per logical CPU.", - "MetricExpr": "UOPS_RETIRED.RETIRE_SLOTS / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))", - "MetricGroup": "TopdownL1_SMT", - "MetricName": "Retiring_SMT", - "PublicDescription": "This category represents fraction of slots utilized by useful work i.e. issued uops that eventually get retired. Ideally; all pipeline slots would be attributed to the Retiring category. Retiring of 100% would indicate the maximum 4 uops retired per cycle has been achieved. Maximizing Retiring typically increases the Instruction-Per-Cycle metric. Note that a high Retiring value does not necessary mean there is no room for more performance. For example; Microcode assists are categorized under Retiring. They hurt performance and can often be avoided. SMT version; use when SMT is enabled and measuring per logical CPU." - }, { "BriefDescription": "Instructions Per Cycle (per Logical Processor)", "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", @@ -71,49 +14,79 @@ { "BriefDescription": "Instruction per taken branch", "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.NEAR_TAKEN", - "MetricGroup": "Branches;Fetch_BW;PGO", + "MetricGroup": "Branches;FetchBW;PGO", "MetricName": "IpTB" }, { "BriefDescription": "Cycles Per Instruction (per Logical Processor)", - "MetricExpr": "1 / (INST_RETIRED.ANY / cycles)", - "MetricGroup": "Pipeline;Summary", + "MetricExpr": "1 / (INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD)", + "MetricGroup": "Pipeline", "MetricName": "CPI" }, { "BriefDescription": "Per-Logical Processor actual clocks when the Logical Processor is active.", "MetricExpr": "CPU_CLK_UNHALTED.THREAD", - "MetricGroup": "Summary", + "MetricGroup": "Pipeline", "MetricName": "CLKS" }, { - "BriefDescription": "Total issue-pipeline slots (per-Physical Core till ICL; per-Logical Processor ICL onward)", - "MetricExpr": "4 * cycles", - "MetricGroup": "TopDownL1", - "MetricName": "SLOTS" + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC" }, { - "BriefDescription": "Total issue-pipeline slots (per-Physical Core till ICL; per-Logical Processor ICL onward)", - "MetricExpr": "4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "TopDownL1_SMT", - "MetricName": "SLOTS_SMT" + "BriefDescription": "Instructions Per Cycle (per physical core)", + "MetricExpr": "INST_RETIRED.ANY / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", + "MetricGroup": "SMT;TmaL1", + "MetricName": "CoreIPC_SMT" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "Flops", + "MetricName": "FLOPc" + }, + { + "BriefDescription": "Floating Point Operations Per Cycle", + "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", + "MetricGroup": "Flops_SMT", + "MetricName": "FLOPc_SMT" + }, + { + "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", + "MetricExpr": "UOPS_EXECUTED.THREAD / (( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 ) if #SMT_on else UOPS_EXECUTED.CORE_CYCLES_GE_1)", + "MetricGroup": "Pipeline;PortsUtil", + "MetricName": "ILP" + }, + { + "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", + "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", + "MetricGroup": "BrMispredicts", + "MetricName": "IpMispredict" + }, + { + "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", + "MetricExpr": "( CPU_CLK_UNHALTED.THREAD_ANY / 2 ) if #SMT_on else CPU_CLK_UNHALTED.THREAD", + "MetricGroup": "SMT", + "MetricName": "CORE_CLKS" }, { "BriefDescription": "Instructions per Load (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_LOADS", - "MetricGroup": "Instruction_Type", + "MetricGroup": "InsType", "MetricName": "IpLoad" }, { "BriefDescription": "Instructions per Store (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / MEM_INST_RETIRED.ALL_STORES", - "MetricGroup": "Instruction_Type", + "MetricGroup": "InsType", "MetricName": "IpStore" }, { "BriefDescription": "Instructions per Branch (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.ALL_BRANCHES", - "MetricGroup": "Branches;Instruction_Type", + "MetricGroup": "Branches;InsType", "MetricName": "IpBranch" }, { @@ -131,176 +104,122 @@ { "BriefDescription": "Instructions per Floating Point (FP) Operation (lower number means higher occurrence rate)", "MetricExpr": "INST_RETIRED.ANY / ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE )", - "MetricGroup": "FLOPS;FP_Arith;Instruction_Type", + "MetricGroup": "Flops;FpArith;InsType", "MetricName": "IpFLOP" }, { - "BriefDescription": "Total number of retired Instructions", + "BriefDescription": "Total number of retired Instructions, Sample with: INST_RETIRED.PREC_DIST", "MetricExpr": "INST_RETIRED.ANY", - "MetricGroup": "Summary;TopDownL1", + "MetricGroup": "Summary;TmaL1", "MetricName": "Instructions" }, { "BriefDescription": "Fraction of Uops delivered by the DSB (aka Decoded ICache; or Uop Cache)", "MetricExpr": "IDQ.DSB_UOPS / (IDQ.DSB_UOPS + IDQ.MITE_UOPS + IDQ.MS_UOPS)", - "MetricGroup": "DSB;Fetch_BW", + "MetricGroup": "DSB;FetchBW", "MetricName": "DSB_Coverage" }, - { - "BriefDescription": "Instructions Per Cycle (per physical core)", - "MetricExpr": "INST_RETIRED.ANY / cycles", - "MetricGroup": "SMT;TopDownL1", - "MetricName": "CoreIPC" - }, - { - "BriefDescription": "Instructions Per Cycle (per physical core)", - "MetricExpr": "INST_RETIRED.ANY / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "SMT;TopDownL1", - "MetricName": "CoreIPC_SMT" - }, - { - "BriefDescription": "Floating Point Operations Per Cycle", - "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / cycles", - "MetricGroup": "FLOPS", - "MetricName": "FLOPc" - }, - { - "BriefDescription": "Floating Point Operations Per Cycle", - "MetricExpr": "( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "FLOPS_SMT", - "MetricName": "FLOPc_SMT" - }, - { - "BriefDescription": "Instruction-Level-Parallelism (average number of uops executed when there is at least 1 uop executed)", - "MetricExpr": "UOPS_EXECUTED.THREAD / ( UOPS_EXECUTED.CORE_CYCLES_GE_1 / 2 )", - "MetricGroup": "Pipeline;Ports_Utilization", - "MetricName": "ILP" - }, - { - "BriefDescription": "Branch Misprediction Cost: Fraction of TopDown slots wasted per non-speculative branch misprediction (jeclear)", - "MetricExpr": "( ((BR_MISP_RETIRED.ALL_BRANCHES / ( BR_MISP_RETIRED.ALL_BRANCHES + MACHINE_CLEARS.COUNT )) * (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * INT_MISC.RECOVERY_CYCLES ) / (4 * cycles))) + (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * cycles)) * (( INT_MISC.CLEAR_RESTEER_CYCLES + 9 * BACLEARS.ANY ) / cycles) / (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * cycles)) ) * (4 * cycles) / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts", - "MetricName": "Branch_Misprediction_Cost" - }, - { - "BriefDescription": "Branch Misprediction Cost: Fraction of TopDown slots wasted per non-speculative branch misprediction (jeclear)", - "MetricExpr": "( ((BR_MISP_RETIRED.ALL_BRANCHES / ( BR_MISP_RETIRED.ALL_BRANCHES + MACHINE_CLEARS.COUNT )) * (( UOPS_ISSUED.ANY - UOPS_RETIRED.RETIRE_SLOTS + 4 * ( INT_MISC.RECOVERY_CYCLES_ANY / 2 ) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )))) + (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) * (( INT_MISC.CLEAR_RESTEER_CYCLES + 9 * BACLEARS.ANY ) / cycles) / (4 * ( IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE - ( FRONTEND_RETIRED.LATENCY_GE_1 - FRONTEND_RETIRED.LATENCY_GE_2 ) / (UOPS_RETIRED.RETIRE_SLOTS / UOPS_ISSUED.ANY) ) / (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ))) ) * (4 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )) / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts_SMT", - "MetricName": "Branch_Misprediction_Cost_SMT" - }, - { - "BriefDescription": "Number of Instructions per non-speculative Branch Misprediction (JEClear)", - "MetricExpr": "INST_RETIRED.ANY / BR_MISP_RETIRED.ALL_BRANCHES", - "MetricGroup": "BrMispredicts", - "MetricName": "IpMispredict" - }, - { - "BriefDescription": "Core actual clocks when any Logical Processor is active on the Physical Core", - "MetricExpr": "( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) )", - "MetricGroup": "SMT", - "MetricName": "CORE_CLKS" - }, { "BriefDescription": "Actual Average Latency for L1 data-cache miss demand loads (in core cycles)", "MetricExpr": "L1D_PEND_MISS.PENDING / ( MEM_LOAD_RETIRED.L1_MISS + MEM_LOAD_RETIRED.FB_HIT )", - "MetricGroup": "Memory_Bound;Memory_Lat", + "MetricGroup": "MemoryBound;MemoryLat", "MetricName": "Load_Miss_Real_Latency" }, { "BriefDescription": "Memory-Level-Parallelism (average number of L1 miss demand load when there is at least one such miss. Per-Logical Processor)", "MetricExpr": "L1D_PEND_MISS.PENDING / L1D_PEND_MISS.PENDING_CYCLES", - "MetricGroup": "Memory_Bound;Memory_BW", + "MetricGroup": "MemoryBound;MemoryBW", "MetricName": "MLP" }, { "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", "MetricConstraint": "NO_NMI_WATCHDOG", - "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * cycles )", - "MetricGroup": "TLB", + "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * CORE_CLKS )", + "MetricGroup": "MemoryTLB", "MetricName": "Page_Walks_Utilization" }, - { - "BriefDescription": "Utilization of the core's Page Walker(s) serving STLB misses triggered by instruction/Load/Store accesses", - "MetricExpr": "( ITLB_MISSES.WALK_PENDING + DTLB_LOAD_MISSES.WALK_PENDING + DTLB_STORE_MISSES.WALK_PENDING + EPT.WALK_PENDING ) / ( 2 * ( ( CPU_CLK_UNHALTED.THREAD / 2 ) * ( 1 + CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / CPU_CLK_UNHALTED.REF_XCLK ) ) )", - "MetricGroup": "TLB_SMT", - "MetricName": "Page_Walks_Utilization_SMT" - }, { "BriefDescription": "Average data fill bandwidth to the L1 data cache [GB / sec]", "MetricExpr": "64 * L1D.REPLACEMENT / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L1D_Cache_Fill_BW" }, { "BriefDescription": "Average data fill bandwidth to the L2 cache [GB / sec]", "MetricExpr": "64 * L2_LINES_IN.ALL / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L2_Cache_Fill_BW" }, { "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", "MetricExpr": "64 * LONGEST_LAT_CACHE.MISS / 1000000000 / duration_time", - "MetricGroup": "Memory_BW", + "MetricGroup": "MemoryBW", "MetricName": "L3_Cache_Fill_BW" }, { - "BriefDescription": "Average per-core data fill bandwidth to the L3 cache [GB / sec]", + "BriefDescription": "Average per-core data access bandwidth to the L3 cache [GB / sec]", "MetricExpr": "64 * OFFCORE_REQUESTS.ALL_REQUESTS / 1000000000 / duration_time", - "MetricGroup": "Memory_BW;Offcore", + "MetricGroup": "MemoryBW;Offcore", "MetricName": "L3_Cache_Access_BW" }, { "BriefDescription": "L1 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L1_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L1MPKI" }, { "BriefDescription": "L2 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L2_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L2MPKI" }, { "BriefDescription": "L2 cache misses per kilo instruction for all request types (including speculative)", "MetricExpr": "1000 * L2_RQSTS.MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses;Offcore", + "MetricGroup": "CacheMisses;Offcore", "MetricName": "L2MPKI_All" }, { "BriefDescription": "L2 cache hits per kilo instruction for all request types (including speculative)", "MetricExpr": "1000 * ( L2_RQSTS.REFERENCES - L2_RQSTS.MISS ) / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L2HPKI_All" }, { "BriefDescription": "L3 cache true misses per kilo instruction for retired demand loads", "MetricExpr": "1000 * MEM_LOAD_RETIRED.L3_MISS / INST_RETIRED.ANY", - "MetricGroup": "Cache_Misses", + "MetricGroup": "CacheMisses", "MetricName": "L3MPKI" }, { "BriefDescription": "Rate of silent evictions from the L2 cache per Kilo instruction where the evicted lines are dropped (no writeback to L3 or memory)", "MetricExpr": "1000 * L2_LINES_OUT.SILENT / INST_RETIRED.ANY", - "MetricGroup": "", + "MetricGroup": "L2Evicts;Server", "MetricName": "L2_Evictions_Silent_PKI" }, { "BriefDescription": "Rate of non silent evictions from the L2 cache per Kilo instruction", "MetricExpr": "1000 * L2_LINES_OUT.NON_SILENT / INST_RETIRED.ANY", - "MetricGroup": "", + "MetricGroup": "L2Evicts;Server", "MetricName": "L2_Evictions_NonSilent_PKI" }, { "BriefDescription": "Average CPU Utilization", "MetricExpr": "CPU_CLK_UNHALTED.REF_TSC / msr@tsc@", - "MetricGroup": "Summary", + "MetricGroup": "HPC;Summary", "MetricName": "CPU_Utilization" }, + { + "BriefDescription": "Measured Average Frequency for unhalted processors [GHz]", + "MetricExpr": "(CPU_CLK_UNHALTED.THREAD / CPU_CLK_UNHALTED.REF_TSC) * msr@tsc@ / 1000000000 / duration_time", + "MetricGroup": "Summary;Power", + "MetricName": "Average_Frequency" + }, { "BriefDescription": "Giga Floating Point Operations Per Second", "MetricExpr": "( ( 1 * ( FP_ARITH_INST_RETIRED.SCALAR_SINGLE + FP_ARITH_INST_RETIRED.SCALAR_DOUBLE ) + 2 * FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE + 4 * ( FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE ) + 8 * ( FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE + FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE ) + 16 * FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE ) / 1000000000 ) / duration_time", - "MetricGroup": "FLOPS;Summary", + "MetricGroup": "Flops;HPC", "MetricName": "GFLOPs" }, { @@ -311,44 +230,44 @@ }, { "BriefDescription": "Fraction of cycles where both hardware Logical Processors were active", - "MetricExpr": "1 - CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE / ( CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY / 2 )", - "MetricGroup": "SMT;Summary", + "MetricExpr": "1 - CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE / ( CPU_CLK_UNHALTED.REF_XCLK_ANY / 2 ) if #SMT_on else 0", + "MetricGroup": "SMT", "MetricName": "SMT_2T_Utilization" }, { "BriefDescription": "Fraction of cycles spent in the Operating System (OS) Kernel mode", - "MetricExpr": "CPU_CLK_UNHALTED.THREAD:k / CPU_CLK_UNHALTED.THREAD", + "MetricExpr": "CPU_CLK_UNHALTED.THREAD_P:k / CPU_CLK_UNHALTED.THREAD", "MetricGroup": "OS", "MetricName": "Kernel_Utilization" }, { "BriefDescription": "Average external Memory Bandwidth Use for reads and writes [GB / sec]", - "MetricExpr": "( ( ( uncore_imc@cas_count_read@ + uncore_imc@cas_count_write@ ) * 1048576 ) / 1000000000 ) / duration_time", - "MetricGroup": "Memory_BW;SoC", + "MetricExpr": "( 64 * ( uncore_imc@cas_count_read@ + uncore_imc@cas_count_write@ ) / 1000000000 ) / duration_time", + "MetricGroup": "HPC;MemoryBW;SoC", "MetricName": "DRAM_BW_Use" }, { "BriefDescription": "Average latency of data read request to external memory (in nanoseconds). Accounts for demand loads and L1/L2 prefetches", "MetricExpr": "1000000000 * ( cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433@ / cha@event\\=0x35\\,umask\\=0x21\\,config\\=0x40433@ ) / ( cha_0@event\\=0x0@ / duration_time )", - "MetricGroup": "Memory_Lat;SoC", + "MetricGroup": "MemoryLat;SoC", "MetricName": "MEM_Read_Latency" }, { "BriefDescription": "Average number of parallel data read requests to external memory. Accounts for demand loads and L1/L2 prefetches", "MetricExpr": "cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433@ / cha@event\\=0x36\\,umask\\=0x21\\,config\\=0x40433\\,thresh\\=1@", - "MetricGroup": "Memory_BW;SoC", + "MetricGroup": "MemoryBW;SoC", "MetricName": "MEM_Parallel_Reads" }, { "BriefDescription": "Average IO (network or disk) Bandwidth Use for Writes [GB / sec]", "MetricExpr": "( UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3 ) * 4 / 1000000000 / duration_time", - "MetricGroup": "IO_BW;SoC;Server", + "MetricGroup": "IoBW;SoC;Server", "MetricName": "IO_Write_BW" }, { "BriefDescription": "Average IO (network or disk) Bandwidth Use for Reads [GB / sec]", "MetricExpr": "( UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3 ) * 4 / 1000000000 / duration_time", - "MetricGroup": "IO_BW;SoC;Server", + "MetricGroup": "IoBW;SoC;Server", "MetricName": "IO_Read_BW" }, { @@ -359,7 +278,7 @@ }, { "BriefDescription": "Instructions per Far Branch ( Far Branches apply upon transition from application to operating system, handling interrupts, exceptions) [lower number means higher occurrence rate]", - "MetricExpr": "INST_RETIRED.ANY / ( BR_INST_RETIRED.FAR_BRANCH / 2 )", + "MetricExpr": "INST_RETIRED.ANY / BR_INST_RETIRED.FAR_BRANCH:u", "MetricGroup": "Branches;OS", "MetricName": "IpFarBranch" }, -- cgit v1.2.3-70-g09d2 From f847502ad8e3299e7ad256aa0bd7eaf184646117 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Tue, 10 Aug 2021 11:57:59 -0700 Subject: cxl/mem: Account for partitionable space in ram/pmem ranges Memory devices may specify volatile only, persistent only, and partitionable space which when added together result in a total capacity. If Identify Memory Device.Partition Alignment != 0 the device supports partitionable space. This partitionable space can be split between volatile and persistent space. The total volatile and persistent sizes are reported in Get Partition Info. ie active volatile memory = volatile only + partitionable volatile active persistent memory = persistent only + partitionable persistent Define cxl_mem_get_partition(), check for partitionable support, and use cxl_mem_get_partition() if applicable. Reviewed-by: Jonathan Cameron Signed-off-by: Ira Weiny Reported-by: kernel test robot Signed-off-by: Dan Williams --- drivers/cxl/cxlmem.h | 5 +++ drivers/cxl/pci.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 22344fda8ca5..6c0b1e2ea97c 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -99,5 +99,10 @@ struct cxl_mem { u64 volatile_only_bytes; u64 persistent_only_bytes; u64 partition_align_bytes; + + u64 active_volatile_bytes; + u64 active_persistent_bytes; + u64 next_volatile_bytes; + u64 next_persistent_bytes; }; #endif /* __CXL_MEM_H__ */ diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index cf4f593f426e..3f5db8960098 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1263,6 +1263,53 @@ static struct cxl_mbox_get_supported_logs *cxl_get_gsl(struct cxl_mem *cxlm) return ret; } +/** + * cxl_mem_get_partition_info - Get partition info + * @cxlm: The device to act on + * @active_volatile_bytes: returned active volatile capacity + * @active_persistent_bytes: returned active persistent capacity + * @next_volatile_bytes: return next volatile capacity + * @next_persistent_bytes: return next persistent capacity + * + * Retrieve the current partition info for the device specified. If not 0, the + * 'next' values are pending and take affect on next cold reset. + * + * Return: 0 if no error: or the result of the mailbox command. + * + * See CXL @8.2.9.5.2.1 Get Partition Info + */ +static int cxl_mem_get_partition_info(struct cxl_mem *cxlm, + u64 *active_volatile_bytes, + u64 *active_persistent_bytes, + u64 *next_volatile_bytes, + u64 *next_persistent_bytes) +{ + struct cxl_mbox_get_partition_info { + __le64 active_volatile_cap; + __le64 active_persistent_cap; + __le64 next_volatile_cap; + __le64 next_persistent_cap; + } __packed pi; + int rc; + + rc = cxl_mem_mbox_send_cmd(cxlm, CXL_MBOX_OP_GET_PARTITION_INFO, + NULL, 0, &pi, sizeof(pi)); + if (rc) + return rc; + + *active_volatile_bytes = le64_to_cpu(pi.active_volatile_cap); + *active_persistent_bytes = le64_to_cpu(pi.active_persistent_cap); + *next_volatile_bytes = le64_to_cpu(pi.next_volatile_cap); + *next_persistent_bytes = le64_to_cpu(pi.next_volatile_cap); + + *active_volatile_bytes *= CXL_CAPACITY_MULTIPLIER; + *active_persistent_bytes *= CXL_CAPACITY_MULTIPLIER; + *next_volatile_bytes *= CXL_CAPACITY_MULTIPLIER; + *next_persistent_bytes *= CXL_CAPACITY_MULTIPLIER; + + return 0; +} + /** * cxl_mem_enumerate_cmds() - Enumerate commands for a device. * @cxlm: The device. @@ -1381,18 +1428,53 @@ static int cxl_mem_identify(struct cxl_mem *cxlm) cxlm->persistent_only_bytes, cxlm->partition_align_bytes); + cxlm->lsa_size = le32_to_cpu(id.lsa_size); + memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision)); + + return 0; +} + +static int cxl_mem_create_range_info(struct cxl_mem *cxlm) +{ + int rc; + + if (cxlm->partition_align_bytes == 0) { + cxlm->ram_range.start = 0; + cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; + cxlm->pmem_range.start = 0; + cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1; + return 0; + } + + rc = cxl_mem_get_partition_info(cxlm, + &cxlm->active_volatile_bytes, + &cxlm->active_persistent_bytes, + &cxlm->next_volatile_bytes, + &cxlm->next_persistent_bytes); + if (rc < 0) { + dev_err(&cxlm->pdev->dev, "Failed to query partition information\n"); + return rc; + } + + dev_dbg(&cxlm->pdev->dev, "Get Partition Info\n" + " active_volatile_bytes = %#llx\n" + " active_persistent_bytes = %#llx\n" + " next_volatile_bytes = %#llx\n" + " next_persistent_bytes = %#llx\n", + cxlm->active_volatile_bytes, + cxlm->active_persistent_bytes, + cxlm->next_volatile_bytes, + cxlm->next_persistent_bytes); + /* * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias. * For now, only the capacity is exported in sysfs */ cxlm->ram_range.start = 0; - cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; + cxlm->ram_range.end = cxlm->active_volatile_bytes - 1; cxlm->pmem_range.start = 0; - cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1; - - cxlm->lsa_size = le32_to_cpu(id.lsa_size); - memcpy(cxlm->firmware_version, id.fw_revision, sizeof(id.fw_revision)); + cxlm->pmem_range.end = cxlm->active_persistent_bytes - 1; return 0; } @@ -1427,6 +1509,10 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; + rc = cxl_mem_create_range_info(cxlm); + if (rc) + return rc; + cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); -- cgit v1.2.3-70-g09d2 From 94effcedaa543825ad9c80831450d4fbfa284880 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Thu, 5 Aug 2021 11:49:36 +0900 Subject: openrisc: Fix compiler warnings in setup This was pointed out with the recent name change of or32_early_setup to or1k_early_setup. Investigating the file I found a few other warnings so cleaning them up here. arch/openrisc/kernel/setup.c:220:13: warning: no previous prototype for 'or1k_early_setup' [-Wmissing-prototypes] 220 | void __init or1k_early_setup(void *fdt) | ^~~~~~~~~~~~~~~~ Fix this the missing or1k_early_setup prototype warning by adding an asm/setup.h file to define the prototype. arch/openrisc/kernel/setup.c:246:13: warning: no previous prototype for 'detect_unit_config' [-Wmissing-prototypes] 246 | void __init detect_unit_config(unsigned long upr, unsigned long mask, | ^~~~~~~~~~~~~~~~~~ The function detect_unit_config is not used, just remove it. arch/openrisc/kernel/setup.c:221: warning: Function parameter or member 'fdt' not described in 'or1k_early_setup' Add @fdt docs to the function comment to suppress this warning. Reported-by: kernel test robot Signed-off-by: Stafford Horne Reviewed-by: Randy Dunlap --- arch/openrisc/include/asm/setup.h | 15 +++++++++++++++ arch/openrisc/kernel/setup.c | 16 +--------------- 2 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 arch/openrisc/include/asm/setup.h diff --git a/arch/openrisc/include/asm/setup.h b/arch/openrisc/include/asm/setup.h new file mode 100644 index 000000000000..9acbc5deda69 --- /dev/null +++ b/arch/openrisc/include/asm/setup.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 Stafford Horne + */ +#ifndef _ASM_OR1K_SETUP_H +#define _ASM_OR1K_SETUP_H + +#include +#include + +#ifndef __ASSEMBLY__ +void __init or1k_early_setup(void *fdt); +#endif + +#endif /* _ASM_OR1K_SETUP_H */ diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c index 7eddcac0ef2f..0cd04d936a7a 100644 --- a/arch/openrisc/kernel/setup.c +++ b/arch/openrisc/kernel/setup.c @@ -210,6 +210,7 @@ void __init setup_cpuinfo(void) /** * or1k_early_setup + * @fdt: pointer to the start of the device tree in memory or NULL * * Handles the pointer to the device tree that this kernel is to use * for establishing the available platform devices. @@ -243,21 +244,6 @@ static inline unsigned long extract_value(unsigned long reg, unsigned long mask) return mask & reg; } -void __init detect_unit_config(unsigned long upr, unsigned long mask, - char *text, void (*func) (void)) -{ - if (text != NULL) - printk("%s", text); - - if (upr & mask) { - if (func != NULL) - func(); - else - printk("present\n"); - } else - printk("not present\n"); -} - /* * calibrate_delay * -- cgit v1.2.3-70-g09d2 From 5546e3dfb65a4389e747766ac455a50c3675fb0f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 10 Aug 2021 23:20:06 +0200 Subject: rtc: lib_test: add MODULE_LICENSE As the documentation states, "The exact license information can only be determined via the license information in the corresponding source files." and the SPDX identifier has the proper information. Reported-by: Stephen Rothwell Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210810212008.631359-1-alexandre.belloni@bootlin.com --- drivers/rtc/lib_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/rtc/lib_test.c b/drivers/rtc/lib_test.c index 2124b67a2f43..d5caf36c56cd 100644 --- a/drivers/rtc/lib_test.c +++ b/drivers/rtc/lib_test.c @@ -77,3 +77,5 @@ static struct kunit_suite rtc_lib_test_suite = { }; kunit_test_suite(rtc_lib_test_suite); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From b02c96464f443e030be74ddd450c46703fe7ba8c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 10 Aug 2021 23:20:07 +0200 Subject: rtc: move RTC_LIB_KUNIT_TEST to proper location Move RTC_LIB_KUNIT_TEST under RTC_LIB so it is clear in the menu this is part of the RTC subsystem. Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20210810212008.631359-2-alexandre.belloni@bootlin.com --- drivers/rtc/Kconfig | 19 +++++++++---------- drivers/rtc/Makefile | 3 ++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b3cf3a274c05..daff06707455 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -10,16 +10,6 @@ config RTC_MC146818_LIB bool select RTC_LIB -config RTC_LIB_KUNIT_TEST - tristate "KUnit test for RTC lib functions" if !KUNIT_ALL_TESTS - depends on KUNIT - default KUNIT_ALL_TESTS - select RTC_LIB - help - Enable this option to test RTC library functions. - - If unsure, say N. - menuconfig RTC_CLASS bool "Real Time Clock" default n @@ -85,6 +75,15 @@ config RTC_DEBUG Say yes here to enable debugging support in the RTC framework and individual RTC drivers. +config RTC_LIB_KUNIT_TEST + tristate "KUnit test for RTC lib functions" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Enable this option to test RTC library functions. + + If unsure, say N. + config RTC_NVMEM bool "RTC non volatile storage support" select NVMEM diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 763d3628c603..5ceeafe4d5b2 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -15,6 +15,8 @@ rtc-core-$(CONFIG_RTC_INTF_DEV) += dev.o rtc-core-$(CONFIG_RTC_INTF_PROC) += proc.o rtc-core-$(CONFIG_RTC_INTF_SYSFS) += sysfs.o +obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += lib_test.o + # Keep the list ordered. obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o @@ -178,4 +180,3 @@ obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_ZYNQMP) += rtc-zynqmp.o -obj-$(CONFIG_RTC_LIB_KUNIT_TEST) += lib_test.o -- cgit v1.2.3-70-g09d2 From f4d4e5fc2b3d03c7e4f3c24ee694a01f8fe27d53 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Tue, 10 Aug 2021 14:54:50 +0800 Subject: erofs: directly use wrapper erofs_page_is_managed() when shrinking We already have the wrapper function to identify managed page. Link: https://lore.kernel.org/r/20210810065450.1320-1-zbestahu@gmail.com Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Signed-off-by: Yue Hu Signed-off-by: Gao Xiang --- fs/erofs/zdata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index cb4d0889eca9..fe724d6d6856 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -309,7 +309,6 @@ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, { struct z_erofs_pcluster *const pcl = container_of(grp, struct z_erofs_pcluster, obj); - struct address_space *const mapping = MNGD_MAPPING(sbi); int i; /* @@ -326,7 +325,7 @@ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, if (!trylock_page(page)) return -EBUSY; - if (page->mapping != mapping) + if (!erofs_page_is_managed(sbi, page)) continue; /* barrier is implied in the following 'unlock_page' */ -- cgit v1.2.3-70-g09d2 From d252ff3de786a28b1bedf4c03fb31d142d32219b Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Tue, 10 Aug 2021 15:24:16 +0800 Subject: erofs: remove the mapping parameter from erofs_try_to_free_cached_page() The mapping is not used at all, remove it and update related code. Link: https://lore.kernel.org/r/20210810072416.1392-1-zbestahu@gmail.com Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Signed-off-by: Yue Hu Signed-off-by: Gao Xiang --- fs/erofs/internal.h | 3 +-- fs/erofs/super.c | 2 +- fs/erofs/zdata.c | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 7c9abfc93109..25b094085ca6 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -445,8 +445,7 @@ int __init z_erofs_init_zip_subsystem(void); void z_erofs_exit_zip_subsystem(void); int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, struct erofs_workgroup *egrp); -int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page); +int erofs_try_to_free_cached_page(struct page *page); int z_erofs_load_lz4_config(struct super_block *sb, struct erofs_super_block *dsb, struct z_erofs_lz4_cfgs *lz4, int len); diff --git a/fs/erofs/super.c b/fs/erofs/super.c index e8de689c94f4..a8d49e8fc83a 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -474,7 +474,7 @@ static int erofs_managed_cache_releasepage(struct page *page, gfp_t gfp_mask) DBG_BUGON(mapping->a_ops != &managed_cache_aops); if (PagePrivate(page)) - ret = erofs_try_to_free_cached_page(mapping, page); + ret = erofs_try_to_free_cached_page(page); return ret; } diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index fe724d6d6856..11c7a1aaebad 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -336,8 +336,7 @@ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi, return 0; } -int erofs_try_to_free_cached_page(struct address_space *mapping, - struct page *page) +int erofs_try_to_free_cached_page(struct page *page) { struct z_erofs_pcluster *const pcl = (void *)page_private(page); int ret = 0; /* 0 - busy */ -- cgit v1.2.3-70-g09d2 From ceeb0da0a0322bcba4c50ab3cf97fe9a7aa8a2e4 Mon Sep 17 00:00:00 2001 From: Ira Weiny Date: Thu, 17 Jun 2021 15:16:20 -0700 Subject: cxl/mem: Adjust ram/pmem range to represent DPA ranges CXL spec defines the volatile DPA range to be 0 to Volatile memory size. It further defines the persistent DPA range to follow directly after the end of the Volatile DPA through the persistent memory size. Essentially Volatile DPA range = [0, Volatile size) Persistent DPA range = [Volatile size, Volatile size + Persistent size) Adjust the pmem_range start to reflect this and remote the TODO. Signed-off-by: Ira Weiny Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/20210617221620.1904031-4-ira.weiny@intel.com Signed-off-by: Dan Williams --- drivers/cxl/pci.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 3f5db8960098..651e8d4ec974 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -1441,8 +1441,9 @@ static int cxl_mem_create_range_info(struct cxl_mem *cxlm) if (cxlm->partition_align_bytes == 0) { cxlm->ram_range.start = 0; cxlm->ram_range.end = cxlm->volatile_only_bytes - 1; - cxlm->pmem_range.start = 0; - cxlm->pmem_range.end = cxlm->persistent_only_bytes - 1; + cxlm->pmem_range.start = cxlm->volatile_only_bytes; + cxlm->pmem_range.end = cxlm->volatile_only_bytes + + cxlm->persistent_only_bytes - 1; return 0; } @@ -1466,15 +1467,12 @@ static int cxl_mem_create_range_info(struct cxl_mem *cxlm) cxlm->next_volatile_bytes, cxlm->next_persistent_bytes); - /* - * TODO: enumerate DPA map, as 'ram' and 'pmem' do not alias. - * For now, only the capacity is exported in sysfs - */ cxlm->ram_range.start = 0; cxlm->ram_range.end = cxlm->active_volatile_bytes - 1; - cxlm->pmem_range.start = 0; - cxlm->pmem_range.end = cxlm->active_persistent_bytes - 1; + cxlm->pmem_range.start = cxlm->active_volatile_bytes; + cxlm->pmem_range.end = cxlm->active_volatile_bytes + + cxlm->active_persistent_bytes - 1; return 0; } -- cgit v1.2.3-70-g09d2 From 28c1caaf492ed941d9dc7ce643515831f4e98117 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sat, 24 Jul 2021 14:36:41 +0800 Subject: pinctrl: Ingenic: Improve the code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.Rename the original "dmicx" ABIs to "dmic-ifx", since these devices have only one DMIC module which has multiple input interfaces. The original naming is easy to make users mistakenly think that the device has multiple dmic modules. Currently, in the mainline, no other devicetree out there is using the "sfc" ABI, so we should be able to replace it safely. 2.Rename the original "ssix-ce0" ABIs to "ssix-ce", since the X2000 have only one ce pin. The original naming is easy to make users mistakenly think that the device has multiple ce pins. Currently, in the mainline, no other devicetree out there is using the "ssix-ce0" ABIs, so we should be able to replace it safely. 3.Split the original "sfc" ABI into "sfc-data", "sfc-ce", "sfc-clk" to increase the flexibility when configuring the pins. Currently, in the mainline, no other devicetree out there is using the "sfc" ABI, so we should be able to replace it safely. 4.There is more than one compatible string in the match table, so renaming "ingenic_xxxx_of_match[]" to "ingenic_xxxx_of_matches" is more reasonable, and remove the unnecessary commas in "ingenic_gpio_of_matches[]" to reduce code size as much as possible. Signed-off-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/1627108604-91304-2-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 155 ++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 66 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 983ba9865f77..1ec05ee4f0c7 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -1827,7 +1827,9 @@ static int x1000_uart1_data_d_pins[] = { 0x62, 0x63, }; static int x1000_uart1_hwflow_pins[] = { 0x64, 0x65, }; static int x1000_uart2_data_a_pins[] = { 0x02, 0x03, }; static int x1000_uart2_data_d_pins[] = { 0x65, 0x64, }; -static int x1000_sfc_pins[] = { 0x1d, 0x1c, 0x1e, 0x1f, 0x1a, 0x1b, }; +static int x1000_sfc_data_pins[] = { 0x1d, 0x1c, 0x1e, 0x1f, }; +static int x1000_sfc_clk_pins[] = { 0x1a, }; +static int x1000_sfc_ce_pins[] = { 0x1b, }; static int x1000_ssi_dt_a_22_pins[] = { 0x16, }; static int x1000_ssi_dt_a_29_pins[] = { 0x1d, }; static int x1000_ssi_dt_d_pins[] = { 0x62, }; @@ -1871,8 +1873,8 @@ static int x1000_i2s_data_tx_pins[] = { 0x24, }; static int x1000_i2s_data_rx_pins[] = { 0x23, }; static int x1000_i2s_clk_txrx_pins[] = { 0x21, 0x22, }; static int x1000_i2s_sysclk_pins[] = { 0x20, }; -static int x1000_dmic0_pins[] = { 0x35, 0x36, }; -static int x1000_dmic1_pins[] = { 0x25, }; +static int x1000_dmic_if0_pins[] = { 0x35, 0x36, }; +static int x1000_dmic_if1_pins[] = { 0x25, }; static int x1000_cim_pins[] = { 0x08, 0x09, 0x0a, 0x0b, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, @@ -1901,7 +1903,9 @@ static const struct group_desc x1000_groups[] = { INGENIC_PIN_GROUP("uart1-hwflow", x1000_uart1_hwflow, 1), INGENIC_PIN_GROUP("uart2-data-a", x1000_uart2_data_a, 2), INGENIC_PIN_GROUP("uart2-data-d", x1000_uart2_data_d, 0), - INGENIC_PIN_GROUP("sfc", x1000_sfc, 1), + INGENIC_PIN_GROUP("sfc-data", x1000_sfc_data, 1), + INGENIC_PIN_GROUP("sfc-clk", x1000_sfc_clk, 1), + INGENIC_PIN_GROUP("sfc-ce", x1000_sfc_ce, 1), INGENIC_PIN_GROUP("ssi-dt-a-22", x1000_ssi_dt_a_22, 2), INGENIC_PIN_GROUP("ssi-dt-a-29", x1000_ssi_dt_a_29, 2), INGENIC_PIN_GROUP("ssi-dt-d", x1000_ssi_dt_d, 0), @@ -1938,8 +1942,8 @@ static const struct group_desc x1000_groups[] = { INGENIC_PIN_GROUP("i2s-data-rx", x1000_i2s_data_rx, 1), INGENIC_PIN_GROUP("i2s-clk-txrx", x1000_i2s_clk_txrx, 1), INGENIC_PIN_GROUP("i2s-sysclk", x1000_i2s_sysclk, 1), - INGENIC_PIN_GROUP("dmic0", x1000_dmic0, 0), - INGENIC_PIN_GROUP("dmic1", x1000_dmic1, 1), + INGENIC_PIN_GROUP("dmic-if0", x1000_dmic_if0, 0), + INGENIC_PIN_GROUP("dmic-if1", x1000_dmic_if1, 1), INGENIC_PIN_GROUP("cim-data", x1000_cim, 2), INGENIC_PIN_GROUP("lcd-8bit", x1000_lcd_8bit, 1), INGENIC_PIN_GROUP("lcd-16bit", x1000_lcd_16bit, 1), @@ -1956,7 +1960,7 @@ static const char *x1000_uart1_groups[] = { "uart1-data-a", "uart1-data-d", "uart1-hwflow", }; static const char *x1000_uart2_groups[] = { "uart2-data-a", "uart2-data-d", }; -static const char *x1000_sfc_groups[] = { "sfc", }; +static const char *x1000_sfc_groups[] = { "sfc-data", "sfc-clk", "sfc-ce", }; static const char *x1000_ssi_groups[] = { "ssi-dt-a-22", "ssi-dt-a-29", "ssi-dt-d", "ssi-dr-a-23", "ssi-dr-a-28", "ssi-dr-d", @@ -1983,7 +1987,7 @@ static const char *x1000_i2c2_groups[] = { "i2c2-data", }; static const char *x1000_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; -static const char *x1000_dmic_groups[] = { "dmic0", "dmic1", }; +static const char *x1000_dmic_groups[] = { "dmic-if0", "dmic-if1", }; static const char *x1000_cim_groups[] = { "cim-data", }; static const char *x1000_lcd_groups[] = { "lcd-8bit", "lcd-16bit", }; static const char *x1000_pwm0_groups[] = { "pwm0", }; @@ -2048,8 +2052,8 @@ static int x1500_i2s_data_tx_pins[] = { 0x24, }; static int x1500_i2s_data_rx_pins[] = { 0x23, }; static int x1500_i2s_clk_txrx_pins[] = { 0x21, 0x22, }; static int x1500_i2s_sysclk_pins[] = { 0x20, }; -static int x1500_dmic0_pins[] = { 0x35, 0x36, }; -static int x1500_dmic1_pins[] = { 0x25, }; +static int x1500_dmic_if0_pins[] = { 0x35, 0x36, }; +static int x1500_dmic_if1_pins[] = { 0x25, }; static int x1500_cim_pins[] = { 0x08, 0x09, 0x0a, 0x0b, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, @@ -2068,7 +2072,9 @@ static const struct group_desc x1500_groups[] = { INGENIC_PIN_GROUP("uart1-hwflow", x1500_uart1_hwflow, 1), INGENIC_PIN_GROUP("uart2-data-a", x1500_uart2_data_a, 2), INGENIC_PIN_GROUP("uart2-data-d", x1500_uart2_data_d, 0), - INGENIC_PIN_GROUP("sfc", x1000_sfc, 1), + INGENIC_PIN_GROUP("sfc-data", x1000_sfc_data, 1), + INGENIC_PIN_GROUP("sfc-clk", x1000_sfc_clk, 1), + INGENIC_PIN_GROUP("sfc-ce", x1000_sfc_ce, 1), INGENIC_PIN_GROUP("mmc-1bit", x1500_mmc_1bit, 1), INGENIC_PIN_GROUP("mmc-4bit", x1500_mmc_4bit, 1), INGENIC_PIN_GROUP("i2c0-data", x1500_i2c0, 0), @@ -2079,8 +2085,8 @@ static const struct group_desc x1500_groups[] = { INGENIC_PIN_GROUP("i2s-data-rx", x1500_i2s_data_rx, 1), INGENIC_PIN_GROUP("i2s-clk-txrx", x1500_i2s_clk_txrx, 1), INGENIC_PIN_GROUP("i2s-sysclk", x1500_i2s_sysclk, 1), - INGENIC_PIN_GROUP("dmic0", x1500_dmic0, 0), - INGENIC_PIN_GROUP("dmic1", x1500_dmic1, 1), + INGENIC_PIN_GROUP("dmic-if0", x1500_dmic_if0, 0), + INGENIC_PIN_GROUP("dmic-if1", x1500_dmic_if1, 1), INGENIC_PIN_GROUP("cim-data", x1500_cim, 2), INGENIC_PIN_GROUP("pwm0", x1500_pwm_pwm0, 0), INGENIC_PIN_GROUP("pwm1", x1500_pwm_pwm1, 1), @@ -2101,7 +2107,7 @@ static const char *x1500_i2c2_groups[] = { "i2c2-data", }; static const char *x1500_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-sysclk", }; -static const char *x1500_dmic_groups[] = { "dmic0", "dmic1", }; +static const char *x1500_dmic_groups[] = { "dmic-if0", "dmic-if1", }; static const char *x1500_cim_groups[] = { "cim-data", }; static const char *x1500_pwm0_groups[] = { "pwm0", }; static const char *x1500_pwm1_groups[] = { "pwm1", }; @@ -2151,7 +2157,9 @@ static const u32 x1830_pull_downs[4] = { static int x1830_uart0_data_pins[] = { 0x33, 0x36, }; static int x1830_uart0_hwflow_pins[] = { 0x34, 0x35, }; static int x1830_uart1_data_pins[] = { 0x38, 0x37, }; -static int x1830_sfc_pins[] = { 0x17, 0x18, 0x1a, 0x19, 0x1b, 0x1c, }; +static int x1830_sfc_data_pins[] = { 0x17, 0x18, 0x1a, 0x19, }; +static int x1830_sfc_clk_pins[] = { 0x1b, }; +static int x1830_sfc_ce_pins[] = { 0x1c, }; static int x1830_ssi0_dt_pins[] = { 0x4c, }; static int x1830_ssi0_dr_pins[] = { 0x4b, }; static int x1830_ssi0_clk_pins[] = { 0x4f, }; @@ -2182,8 +2190,8 @@ static int x1830_i2s_data_rx_pins[] = { 0x54, }; static int x1830_i2s_clk_txrx_pins[] = { 0x58, 0x52, }; static int x1830_i2s_clk_rx_pins[] = { 0x56, 0x55, }; static int x1830_i2s_sysclk_pins[] = { 0x57, }; -static int x1830_dmic0_pins[] = { 0x48, 0x59, }; -static int x1830_dmic1_pins[] = { 0x5a, }; +static int x1830_dmic_if0_pins[] = { 0x48, 0x59, }; +static int x1830_dmic_if1_pins[] = { 0x5a, }; static int x1830_lcd_tft_8bit_pins[] = { 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x73, 0x72, 0x69, @@ -2223,7 +2231,9 @@ static const struct group_desc x1830_groups[] = { INGENIC_PIN_GROUP("uart0-data", x1830_uart0_data, 0), INGENIC_PIN_GROUP("uart0-hwflow", x1830_uart0_hwflow, 0), INGENIC_PIN_GROUP("uart1-data", x1830_uart1_data, 0), - INGENIC_PIN_GROUP("sfc", x1830_sfc, 1), + INGENIC_PIN_GROUP("sfc-data", x1830_sfc_data, 1), + INGENIC_PIN_GROUP("sfc-clk", x1830_sfc_clk, 1), + INGENIC_PIN_GROUP("sfc-ce", x1830_sfc_ce, 1), INGENIC_PIN_GROUP("ssi0-dt", x1830_ssi0_dt, 0), INGENIC_PIN_GROUP("ssi0-dr", x1830_ssi0_dr, 0), INGENIC_PIN_GROUP("ssi0-clk", x1830_ssi0_clk, 0), @@ -2254,8 +2264,8 @@ static const struct group_desc x1830_groups[] = { INGENIC_PIN_GROUP("i2s-clk-txrx", x1830_i2s_clk_txrx, 0), INGENIC_PIN_GROUP("i2s-clk-rx", x1830_i2s_clk_rx, 0), INGENIC_PIN_GROUP("i2s-sysclk", x1830_i2s_sysclk, 0), - INGENIC_PIN_GROUP("dmic0", x1830_dmic0, 2), - INGENIC_PIN_GROUP("dmic1", x1830_dmic1, 2), + INGENIC_PIN_GROUP("dmic-if0", x1830_dmic_if0, 2), + INGENIC_PIN_GROUP("dmic-if1", x1830_dmic_if1, 2), INGENIC_PIN_GROUP("lcd-tft-8bit", x1830_lcd_tft_8bit, 0), INGENIC_PIN_GROUP("lcd-tft-24bit", x1830_lcd_tft_24bit, 0), INGENIC_PIN_GROUP("lcd-slcd-8bit", x1830_lcd_slcd_8bit, 1), @@ -2281,7 +2291,7 @@ static const struct group_desc x1830_groups[] = { static const char *x1830_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; static const char *x1830_uart1_groups[] = { "uart1-data", }; -static const char *x1830_sfc_groups[] = { "sfc", }; +static const char *x1830_sfc_groups[] = { "sfc-data", "sfc-clk", "sfc-ce", }; static const char *x1830_ssi0_groups[] = { "ssi0-dt", "ssi0-dr", "ssi0-clk", "ssi0-gpc", "ssi0-ce0", "ssi0-ce1", }; @@ -2301,7 +2311,7 @@ static const char *x1830_i2c2_groups[] = { "i2c2-data", }; static const char *x1830_i2s_groups[] = { "i2s-data-tx", "i2s-data-rx", "i2s-clk-txrx", "i2s-clk-rx", "i2s-sysclk", }; -static const char *x1830_dmic_groups[] = { "dmic0", "dmic1", }; +static const char *x1830_dmic_groups[] = { "dmic-if0", "dmic-if1", }; static const char *x1830_lcd_groups[] = { "lcd-tft-8bit", "lcd-tft-24bit", "lcd-slcd-8bit", "lcd-slcd-16bit", }; @@ -2381,17 +2391,21 @@ static int x2000_uart7_data_a_pins[] = { 0x08, 0x09, }; static int x2000_uart7_data_c_pins[] = { 0x41, 0x42, }; static int x2000_uart8_data_pins[] = { 0x3c, 0x3d, }; static int x2000_uart9_data_pins[] = { 0x3e, 0x3f, }; -static int x2000_sfc0_d_pins[] = { 0x73, 0x74, 0x75, 0x76, 0x71, 0x72, }; -static int x2000_sfc0_e_pins[] = { 0x92, 0x93, 0x94, 0x95, 0x90, 0x91, }; -static int x2000_sfc1_pins[] = { 0x77, 0x78, 0x79, 0x7a, }; +static int x2000_sfc_data_if0_d_pins[] = { 0x73, 0x74, 0x75, 0x76, }; +static int x2000_sfc_data_if0_e_pins[] = { 0x92, 0x93, 0x94, 0x95, }; +static int x2000_sfc_data_if1_pins[] = { 0x77, 0x78, 0x79, 0x7a, }; +static int x2000_sfc_clk_d_pins[] = { 0x71, }; +static int x2000_sfc_clk_e_pins[] = { 0x90, }; +static int x2000_sfc_ce_d_pins[] = { 0x72, }; +static int x2000_sfc_ce_e_pins[] = { 0x91, }; static int x2000_ssi0_dt_b_pins[] = { 0x3e, }; static int x2000_ssi0_dt_d_pins[] = { 0x69, }; static int x2000_ssi0_dr_b_pins[] = { 0x3d, }; static int x2000_ssi0_dr_d_pins[] = { 0x6a, }; static int x2000_ssi0_clk_b_pins[] = { 0x3f, }; static int x2000_ssi0_clk_d_pins[] = { 0x68, }; -static int x2000_ssi0_ce0_b_pins[] = { 0x3c, }; -static int x2000_ssi0_ce0_d_pins[] = { 0x6d, }; +static int x2000_ssi0_ce_b_pins[] = { 0x3c, }; +static int x2000_ssi0_ce_d_pins[] = { 0x6d, }; static int x2000_ssi1_dt_c_pins[] = { 0x4b, }; static int x2000_ssi1_dt_d_pins[] = { 0x72, }; static int x2000_ssi1_dt_e_pins[] = { 0x91, }; @@ -2401,9 +2415,9 @@ static int x2000_ssi1_dr_e_pins[] = { 0x92, }; static int x2000_ssi1_clk_c_pins[] = { 0x4c, }; static int x2000_ssi1_clk_d_pins[] = { 0x71, }; static int x2000_ssi1_clk_e_pins[] = { 0x90, }; -static int x2000_ssi1_ce0_c_pins[] = { 0x49, }; -static int x2000_ssi1_ce0_d_pins[] = { 0x76, }; -static int x2000_ssi1_ce0_e_pins[] = { 0x95, }; +static int x2000_ssi1_ce_c_pins[] = { 0x49, }; +static int x2000_ssi1_ce_d_pins[] = { 0x76, }; +static int x2000_ssi1_ce_e_pins[] = { 0x95, }; static int x2000_mmc0_1bit_pins[] = { 0x71, 0x72, 0x73, }; static int x2000_mmc0_4bit_pins[] = { 0x74, 0x75, 0x75, }; static int x2000_mmc0_8bit_pins[] = { 0x77, 0x78, 0x79, 0x7a, }; @@ -2455,10 +2469,10 @@ static int x2000_i2s3_data_tx2_pins[] = { 0x05, }; static int x2000_i2s3_data_tx3_pins[] = { 0x06, }; static int x2000_i2s3_clk_tx_pins[] = { 0x10, 0x02, }; static int x2000_i2s3_sysclk_tx_pins[] = { 0x00, }; -static int x2000_dmic0_pins[] = { 0x54, 0x55, }; -static int x2000_dmic1_pins[] = { 0x56, }; -static int x2000_dmic2_pins[] = { 0x57, }; -static int x2000_dmic3_pins[] = { 0x58, }; +static int x2000_dmic_if0_pins[] = { 0x54, 0x55, }; +static int x2000_dmic_if1_pins[] = { 0x56, }; +static int x2000_dmic_if2_pins[] = { 0x57, }; +static int x2000_dmic_if3_pins[] = { 0x58, }; static int x2000_cim_8bit_pins[] = { 0x0e, 0x0c, 0x0d, 0x4f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, @@ -2545,17 +2559,21 @@ static const struct group_desc x2000_groups[] = { INGENIC_PIN_GROUP("uart7-data-c", x2000_uart7_data_c, 3), INGENIC_PIN_GROUP("uart8-data", x2000_uart8_data, 3), INGENIC_PIN_GROUP("uart9-data", x2000_uart9_data, 3), - INGENIC_PIN_GROUP("sfc0-d", x2000_sfc0_d, 1), - INGENIC_PIN_GROUP("sfc0-e", x2000_sfc0_e, 0), - INGENIC_PIN_GROUP("sfc1", x2000_sfc1, 1), + INGENIC_PIN_GROUP("sfc-data-if0-d", x2000_sfc_data_if0_d, 1), + INGENIC_PIN_GROUP("sfc-data-if0-e", x2000_sfc_data_if0_e, 0), + INGENIC_PIN_GROUP("sfc-data-if1", x2000_sfc_data_if1, 1), + INGENIC_PIN_GROUP("sfc-clk-d", x2000_sfc_clk_d, 1), + INGENIC_PIN_GROUP("sfc-clk-e", x2000_sfc_clk_e, 0), + INGENIC_PIN_GROUP("sfc-ce-d", x2000_sfc_ce_d, 1), + INGENIC_PIN_GROUP("sfc-ce-e", x2000_sfc_ce_e, 0), INGENIC_PIN_GROUP("ssi0-dt-b", x2000_ssi0_dt_b, 1), INGENIC_PIN_GROUP("ssi0-dt-d", x2000_ssi0_dt_d, 1), INGENIC_PIN_GROUP("ssi0-dr-b", x2000_ssi0_dr_b, 1), INGENIC_PIN_GROUP("ssi0-dr-d", x2000_ssi0_dr_d, 1), INGENIC_PIN_GROUP("ssi0-clk-b", x2000_ssi0_clk_b, 1), INGENIC_PIN_GROUP("ssi0-clk-d", x2000_ssi0_clk_d, 1), - INGENIC_PIN_GROUP("ssi0-ce0-b", x2000_ssi0_ce0_b, 1), - INGENIC_PIN_GROUP("ssi0-ce0-d", x2000_ssi0_ce0_d, 1), + INGENIC_PIN_GROUP("ssi0-ce-b", x2000_ssi0_ce_b, 1), + INGENIC_PIN_GROUP("ssi0-ce-d", x2000_ssi0_ce_d, 1), INGENIC_PIN_GROUP("ssi1-dt-c", x2000_ssi1_dt_c, 2), INGENIC_PIN_GROUP("ssi1-dt-d", x2000_ssi1_dt_d, 2), INGENIC_PIN_GROUP("ssi1-dt-e", x2000_ssi1_dt_e, 1), @@ -2565,9 +2583,9 @@ static const struct group_desc x2000_groups[] = { INGENIC_PIN_GROUP("ssi1-clk-c", x2000_ssi1_clk_c, 2), INGENIC_PIN_GROUP("ssi1-clk-d", x2000_ssi1_clk_d, 2), INGENIC_PIN_GROUP("ssi1-clk-e", x2000_ssi1_clk_e, 1), - INGENIC_PIN_GROUP("ssi1-ce0-c", x2000_ssi1_ce0_c, 2), - INGENIC_PIN_GROUP("ssi1-ce0-d", x2000_ssi1_ce0_d, 2), - INGENIC_PIN_GROUP("ssi1-ce0-e", x2000_ssi1_ce0_e, 1), + INGENIC_PIN_GROUP("ssi1-ce-c", x2000_ssi1_ce_c, 2), + INGENIC_PIN_GROUP("ssi1-ce-d", x2000_ssi1_ce_d, 2), + INGENIC_PIN_GROUP("ssi1-ce-e", x2000_ssi1_ce_e, 1), INGENIC_PIN_GROUP("mmc0-1bit", x2000_mmc0_1bit, 0), INGENIC_PIN_GROUP("mmc0-4bit", x2000_mmc0_4bit, 0), INGENIC_PIN_GROUP("mmc0-8bit", x2000_mmc0_8bit, 0), @@ -2612,10 +2630,10 @@ static const struct group_desc x2000_groups[] = { INGENIC_PIN_GROUP("i2s3-data-tx3", x2000_i2s3_data_tx3, 2), INGENIC_PIN_GROUP("i2s3-clk-tx", x2000_i2s3_clk_tx, 2), INGENIC_PIN_GROUP("i2s3-sysclk-tx", x2000_i2s3_sysclk_tx, 2), - INGENIC_PIN_GROUP("dmic0", x2000_dmic0, 0), - INGENIC_PIN_GROUP("dmic1", x2000_dmic1, 0), - INGENIC_PIN_GROUP("dmic2", x2000_dmic2, 0), - INGENIC_PIN_GROUP("dmic3", x2000_dmic3, 0), + INGENIC_PIN_GROUP("dmic-if0", x2000_dmic_if0, 0), + INGENIC_PIN_GROUP("dmic-if1", x2000_dmic_if1, 0), + INGENIC_PIN_GROUP("dmic-if2", x2000_dmic_if2, 0), + INGENIC_PIN_GROUP("dmic-if3", x2000_dmic_if3, 0), INGENIC_PIN_GROUP_FUNCS("cim-data-8bit", x2000_cim_8bit, x2000_cim_8bit_funcs), INGENIC_PIN_GROUP("cim-data-12bit", x2000_cim_12bit, 0), @@ -2670,18 +2688,21 @@ static const char *x2000_uart6_groups[] = { "uart6-data-a", "uart6-data-c", }; static const char *x2000_uart7_groups[] = { "uart7-data-a", "uart7-data-c", }; static const char *x2000_uart8_groups[] = { "uart8-data", }; static const char *x2000_uart9_groups[] = { "uart9-data", }; -static const char *x2000_sfc_groups[] = { "sfc0-d", "sfc0-e", "sfc1", }; +static const char *x2000_sfc_groups[] = { + "sfc-data-if0-d", "sfc-data-if0-e", "sfc-data-if1", + "sfc-clk-d", "sfc-clk-e", "sfc-ce-d", "sfc-ce-e", +}; static const char *x2000_ssi0_groups[] = { "ssi0-dt-b", "ssi0-dt-d", "ssi0-dr-b", "ssi0-dr-d", "ssi0-clk-b", "ssi0-clk-d", - "ssi0-ce0-b", "ssi0-ce0-d", + "ssi0-ce-b", "ssi0-ce-d", }; static const char *x2000_ssi1_groups[] = { "ssi1-dt-c", "ssi1-dt-d", "ssi1-dt-e", "ssi1-dr-c", "ssi1-dr-d", "ssi1-dr-e", "ssi1-clk-c", "ssi1-clk-d", "ssi1-clk-e", - "ssi1-ce0-c", "ssi1-ce0-d", "ssi1-ce0-e", + "ssi1-ce-c", "ssi1-ce-d", "ssi1-ce-e", }; static const char *x2000_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", "mmc0-8bit", }; static const char *x2000_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", }; @@ -2711,7 +2732,9 @@ static const char *x2000_i2s3_groups[] = { "i2s3-data-tx0", "i2s3-data-tx1", "i2s3-data-tx2", "i2s3-data-tx3", "i2s3-clk-tx", "i2s3-sysclk-tx", }; -static const char *x2000_dmic_groups[] = { "dmic0", "dmic1", "dmic2", "dmic3", }; +static const char *x2000_dmic_groups[] = { + "dmic-if0", "dmic-if1", "dmic-if2", "dmic-if3", +}; static const char *x2000_cim_groups[] = { "cim-data-8bit", "cim-data-12bit", }; static const char *x2000_lcd_groups[] = { "lcd-tft-8bit", "lcd-tft-16bit", "lcd-tft-18bit", "lcd-tft-24bit", @@ -3654,19 +3677,19 @@ static const struct regmap_config ingenic_pinctrl_regmap_config = { .reg_stride = 4, }; -static const struct of_device_id ingenic_gpio_of_match[] __initconst = { - { .compatible = "ingenic,jz4730-gpio", }, - { .compatible = "ingenic,jz4740-gpio", }, - { .compatible = "ingenic,jz4725b-gpio", }, - { .compatible = "ingenic,jz4750-gpio", }, - { .compatible = "ingenic,jz4755-gpio", }, - { .compatible = "ingenic,jz4760-gpio", }, - { .compatible = "ingenic,jz4770-gpio", }, - { .compatible = "ingenic,jz4775-gpio", }, - { .compatible = "ingenic,jz4780-gpio", }, - { .compatible = "ingenic,x1000-gpio", }, - { .compatible = "ingenic,x1830-gpio", }, - { .compatible = "ingenic,x2000-gpio", }, +static const struct of_device_id ingenic_gpio_of_matches[] __initconst = { + { .compatible = "ingenic,jz4730-gpio" }, + { .compatible = "ingenic,jz4740-gpio" }, + { .compatible = "ingenic,jz4725b-gpio" }, + { .compatible = "ingenic,jz4750-gpio" }, + { .compatible = "ingenic,jz4755-gpio" }, + { .compatible = "ingenic,jz4760-gpio" }, + { .compatible = "ingenic,jz4770-gpio" }, + { .compatible = "ingenic,jz4775-gpio" }, + { .compatible = "ingenic,jz4780-gpio" }, + { .compatible = "ingenic,x1000-gpio" }, + { .compatible = "ingenic,x1830-gpio" }, + { .compatible = "ingenic,x2000-gpio" }, {}, }; @@ -3843,7 +3866,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) dev_set_drvdata(dev, jzpc->map); for_each_child_of_node(dev->of_node, node) { - if (of_match_node(ingenic_gpio_of_match, node)) { + if (of_match_node(ingenic_gpio_of_matches, node)) { err = ingenic_gpio_probe(jzpc, node); if (err) { of_node_put(node); @@ -3857,7 +3880,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) #define IF_ENABLED(cfg, ptr) PTR_IF(IS_ENABLED(cfg), (ptr)) -static const struct of_device_id ingenic_pinctrl_of_match[] = { +static const struct of_device_id ingenic_pinctrl_of_matches[] = { { .compatible = "ingenic,jz4730-pinctrl", .data = IF_ENABLED(CONFIG_MACH_JZ4730, &jz4730_chip_info) @@ -3928,7 +3951,7 @@ static const struct of_device_id ingenic_pinctrl_of_match[] = { static struct platform_driver ingenic_pinctrl_driver = { .driver = { .name = "pinctrl-ingenic", - .of_match_table = ingenic_pinctrl_of_match, + .of_match_table = ingenic_pinctrl_of_matches, }, }; -- cgit v1.2.3-70-g09d2 From b638e0f18dea6f51a8f822a03028676ba2f7cf5b Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sat, 24 Jul 2021 14:36:42 +0800 Subject: pinctrl: Ingenic: Add SSI pins support for JZ4755 and JZ4760. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add SSI pins support for the JZ4755 SoC and the JZ4760 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/1627108604-91304-3-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 155 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 1ec05ee4f0c7..f88bccfb2ff6 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -589,6 +589,18 @@ static int jz4755_uart0_data_pins[] = { 0x7c, 0x7d, }; static int jz4755_uart0_hwflow_pins[] = { 0x7e, 0x7f, }; static int jz4755_uart1_data_pins[] = { 0x97, 0x99, }; static int jz4755_uart2_data_pins[] = { 0x9f, }; +static int jz4755_ssi_dt_b_pins[] = { 0x3b, }; +static int jz4755_ssi_dt_f_pins[] = { 0xa1, }; +static int jz4755_ssi_dr_b_pins[] = { 0x3c, }; +static int jz4755_ssi_dr_f_pins[] = { 0xa2, }; +static int jz4755_ssi_clk_b_pins[] = { 0x3a, }; +static int jz4755_ssi_clk_f_pins[] = { 0xa0, }; +static int jz4755_ssi_gpc_b_pins[] = { 0x3e, }; +static int jz4755_ssi_gpc_f_pins[] = { 0xa4, }; +static int jz4755_ssi_ce0_b_pins[] = { 0x3d, }; +static int jz4755_ssi_ce0_f_pins[] = { 0xa3, }; +static int jz4755_ssi_ce1_b_pins[] = { 0x3f, }; +static int jz4755_ssi_ce1_f_pins[] = { 0xa5, }; static int jz4755_mmc0_1bit_pins[] = { 0x2f, 0x50, 0x5c, }; static int jz4755_mmc0_4bit_pins[] = { 0x5d, 0x5b, 0x51, }; static int jz4755_mmc1_1bit_pins[] = { 0x3a, 0x3d, 0x3c, }; @@ -630,6 +642,18 @@ static const struct group_desc jz4755_groups[] = { INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0), INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0), INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1), + INGENIC_PIN_GROUP("ssi-dt-b", jz4755_ssi_dt_b, 0), + INGENIC_PIN_GROUP("ssi-dt-f", jz4755_ssi_dt_f, 0), + INGENIC_PIN_GROUP("ssi-dr-b", jz4755_ssi_dr_b, 0), + INGENIC_PIN_GROUP("ssi-dr-f", jz4755_ssi_dr_f, 0), + INGENIC_PIN_GROUP("ssi-clk-b", jz4755_ssi_clk_b, 0), + INGENIC_PIN_GROUP("ssi-clk-f", jz4755_ssi_clk_f, 0), + INGENIC_PIN_GROUP("ssi-gpc-b", jz4755_ssi_gpc_b, 0), + INGENIC_PIN_GROUP("ssi-gpc-f", jz4755_ssi_gpc_f, 0), + INGENIC_PIN_GROUP("ssi-ce0-b", jz4755_ssi_ce0_b, 0), + INGENIC_PIN_GROUP("ssi-ce0-f", jz4755_ssi_ce0_f, 0), + INGENIC_PIN_GROUP("ssi-ce1-b", jz4755_ssi_ce1_b, 0), + INGENIC_PIN_GROUP("ssi-ce1-f", jz4755_ssi_ce1_f, 0), INGENIC_PIN_GROUP_FUNCS("mmc0-1bit", jz4755_mmc0_1bit, jz4755_mmc0_1bit_funcs), INGENIC_PIN_GROUP_FUNCS("mmc0-4bit", jz4755_mmc0_4bit, @@ -661,6 +685,14 @@ static const struct group_desc jz4755_groups[] = { static const char *jz4755_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; static const char *jz4755_uart1_groups[] = { "uart1-data", }; static const char *jz4755_uart2_groups[] = { "uart2-data", }; +static const char *jz4755_ssi_groups[] = { + "ssi-dt-b", "ssi-dt-f", + "ssi-dr-b", "ssi-dr-f", + "ssi-clk-b", "ssi-clk-f", + "ssi-gpc-b", "ssi-gpc-f", + "ssi-ce0-b", "ssi-ce0-f", + "ssi-ce1-b", "ssi-ce1-f", +}; static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", }; static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", }; static const char *jz4755_i2c_groups[] = { "i2c-data", }; @@ -683,6 +715,7 @@ static const struct function_desc jz4755_functions[] = { { "uart0", jz4755_uart0_groups, ARRAY_SIZE(jz4755_uart0_groups), }, { "uart1", jz4755_uart1_groups, ARRAY_SIZE(jz4755_uart1_groups), }, { "uart2", jz4755_uart2_groups, ARRAY_SIZE(jz4755_uart2_groups), }, + { "ssi", jz4755_ssi_groups, ARRAY_SIZE(jz4755_ssi_groups), }, { "mmc0", jz4755_mmc0_groups, ARRAY_SIZE(jz4755_mmc0_groups), }, { "mmc1", jz4755_mmc1_groups, ARRAY_SIZE(jz4755_mmc1_groups), }, { "i2c", jz4755_i2c_groups, ARRAY_SIZE(jz4755_i2c_groups), }, @@ -725,6 +758,58 @@ static int jz4760_uart2_data_pins[] = { 0x5c, 0x5e, }; static int jz4760_uart2_hwflow_pins[] = { 0x5d, 0x5f, }; static int jz4760_uart3_data_pins[] = { 0x6c, 0x85, }; static int jz4760_uart3_hwflow_pins[] = { 0x88, 0x89, }; +static int jz4760_ssi0_dt_a_pins[] = { 0x15, }; +static int jz4760_ssi0_dt_b_pins[] = { 0x35, }; +static int jz4760_ssi0_dt_d_pins[] = { 0x75, }; +static int jz4760_ssi0_dt_e_pins[] = { 0x91, }; +static int jz4760_ssi0_dr_a_pins[] = { 0x14, }; +static int jz4760_ssi0_dr_b_pins[] = { 0x34, }; +static int jz4760_ssi0_dr_d_pins[] = { 0x74, }; +static int jz4760_ssi0_dr_e_pins[] = { 0x8e, }; +static int jz4760_ssi0_clk_a_pins[] = { 0x12, }; +static int jz4760_ssi0_clk_b_pins[] = { 0x3c, }; +static int jz4760_ssi0_clk_d_pins[] = { 0x78, }; +static int jz4760_ssi0_clk_e_pins[] = { 0x8f, }; +static int jz4760_ssi0_gpc_b_pins[] = { 0x3e, }; +static int jz4760_ssi0_gpc_d_pins[] = { 0x76, }; +static int jz4760_ssi0_gpc_e_pins[] = { 0x93, }; +static int jz4760_ssi0_ce0_a_pins[] = { 0x13, }; +static int jz4760_ssi0_ce0_b_pins[] = { 0x3d, }; +static int jz4760_ssi0_ce0_d_pins[] = { 0x79, }; +static int jz4760_ssi0_ce0_e_pins[] = { 0x90, }; +static int jz4760_ssi0_ce1_b_pins[] = { 0x3f, }; +static int jz4760_ssi0_ce1_d_pins[] = { 0x77, }; +static int jz4760_ssi0_ce1_e_pins[] = { 0x92, }; +static int jz4760_ssi1_dt_b_9_pins[] = { 0x29, }; +static int jz4760_ssi1_dt_b_21_pins[] = { 0x35, }; +static int jz4760_ssi1_dt_d_12_pins[] = { 0x6c, }; +static int jz4760_ssi1_dt_d_21_pins[] = { 0x75, }; +static int jz4760_ssi1_dt_e_pins[] = { 0x91, }; +static int jz4760_ssi1_dt_f_pins[] = { 0xa3, }; +static int jz4760_ssi1_dr_b_6_pins[] = { 0x26, }; +static int jz4760_ssi1_dr_b_20_pins[] = { 0x34, }; +static int jz4760_ssi1_dr_d_13_pins[] = { 0x6d, }; +static int jz4760_ssi1_dr_d_20_pins[] = { 0x74, }; +static int jz4760_ssi1_dr_e_pins[] = { 0x8e, }; +static int jz4760_ssi1_dr_f_pins[] = { 0xa0, }; +static int jz4760_ssi1_clk_b_7_pins[] = { 0x27, }; +static int jz4760_ssi1_clk_b_28_pins[] = { 0x3c, }; +static int jz4760_ssi1_clk_d_pins[] = { 0x78, }; +static int jz4760_ssi1_clk_e_7_pins[] = { 0x87, }; +static int jz4760_ssi1_clk_e_15_pins[] = { 0x8f, }; +static int jz4760_ssi1_clk_f_pins[] = { 0xa2, }; +static int jz4760_ssi1_gpc_b_pins[] = { 0x3e, }; +static int jz4760_ssi1_gpc_d_pins[] = { 0x76, }; +static int jz4760_ssi1_gpc_e_pins[] = { 0x93, }; +static int jz4760_ssi1_ce0_b_8_pins[] = { 0x28, }; +static int jz4760_ssi1_ce0_b_29_pins[] = { 0x3d, }; +static int jz4760_ssi1_ce0_d_pins[] = { 0x79, }; +static int jz4760_ssi1_ce0_e_6_pins[] = { 0x86, }; +static int jz4760_ssi1_ce0_e_16_pins[] = { 0x90, }; +static int jz4760_ssi1_ce0_f_pins[] = { 0xa1, }; +static int jz4760_ssi1_ce1_b_pins[] = { 0x3f, }; +static int jz4760_ssi1_ce1_d_pins[] = { 0x77, }; +static int jz4760_ssi1_ce1_e_pins[] = { 0x92, }; static int jz4760_mmc0_1bit_a_pins[] = { 0x12, 0x13, 0x14, }; static int jz4760_mmc0_4bit_a_pins[] = { 0x15, 0x16, 0x17, }; static int jz4760_mmc0_1bit_e_pins[] = { 0x9c, 0x9d, 0x94, }; @@ -801,6 +886,58 @@ static const struct group_desc jz4760_groups[] = { INGENIC_PIN_GROUP_FUNCS("uart3-data", jz4760_uart3_data, jz4760_uart3_data_funcs), INGENIC_PIN_GROUP("uart3-hwflow", jz4760_uart3_hwflow, 0), + INGENIC_PIN_GROUP("ssi0-dt-a", jz4760_ssi0_dt_a, 2), + INGENIC_PIN_GROUP("ssi0-dt-b", jz4760_ssi0_dt_b, 1), + INGENIC_PIN_GROUP("ssi0-dt-d", jz4760_ssi0_dt_d, 1), + INGENIC_PIN_GROUP("ssi0-dt-e", jz4760_ssi0_dt_e, 0), + INGENIC_PIN_GROUP("ssi0-dr-a", jz4760_ssi0_dr_a, 1), + INGENIC_PIN_GROUP("ssi0-dr-b", jz4760_ssi0_dr_b, 1), + INGENIC_PIN_GROUP("ssi0-dr-d", jz4760_ssi0_dr_d, 1), + INGENIC_PIN_GROUP("ssi0-dr-e", jz4760_ssi0_dr_e, 0), + INGENIC_PIN_GROUP("ssi0-clk-a", jz4760_ssi0_clk_a, 2), + INGENIC_PIN_GROUP("ssi0-clk-b", jz4760_ssi0_clk_b, 1), + INGENIC_PIN_GROUP("ssi0-clk-d", jz4760_ssi0_clk_d, 1), + INGENIC_PIN_GROUP("ssi0-clk-e", jz4760_ssi0_clk_e, 0), + INGENIC_PIN_GROUP("ssi0-gpc-b", jz4760_ssi0_gpc_b, 1), + INGENIC_PIN_GROUP("ssi0-gpc-d", jz4760_ssi0_gpc_d, 1), + INGENIC_PIN_GROUP("ssi0-gpc-e", jz4760_ssi0_gpc_e, 0), + INGENIC_PIN_GROUP("ssi0-ce0-a", jz4760_ssi0_ce0_a, 2), + INGENIC_PIN_GROUP("ssi0-ce0-b", jz4760_ssi0_ce0_b, 1), + INGENIC_PIN_GROUP("ssi0-ce0-d", jz4760_ssi0_ce0_d, 1), + INGENIC_PIN_GROUP("ssi0-ce0-e", jz4760_ssi0_ce0_e, 0), + INGENIC_PIN_GROUP("ssi0-ce1-b", jz4760_ssi0_ce1_b, 1), + INGENIC_PIN_GROUP("ssi0-ce1-d", jz4760_ssi0_ce1_d, 1), + INGENIC_PIN_GROUP("ssi0-ce1-e", jz4760_ssi0_ce1_e, 0), + INGENIC_PIN_GROUP("ssi1-dt-b-9", jz4760_ssi1_dt_b_9, 2), + INGENIC_PIN_GROUP("ssi1-dt-b-21", jz4760_ssi1_dt_b_21, 2), + INGENIC_PIN_GROUP("ssi1-dt-d-12", jz4760_ssi1_dt_d_12, 2), + INGENIC_PIN_GROUP("ssi1-dt-d-21", jz4760_ssi1_dt_d_21, 2), + INGENIC_PIN_GROUP("ssi1-dt-e", jz4760_ssi1_dt_e, 1), + INGENIC_PIN_GROUP("ssi1-dt-f", jz4760_ssi1_dt_f, 2), + INGENIC_PIN_GROUP("ssi1-dr-b-6", jz4760_ssi1_dr_b_6, 2), + INGENIC_PIN_GROUP("ssi1-dr-b-20", jz4760_ssi1_dr_b_20, 2), + INGENIC_PIN_GROUP("ssi1-dr-d-13", jz4760_ssi1_dr_d_13, 2), + INGENIC_PIN_GROUP("ssi1-dr-d-20", jz4760_ssi1_dr_d_20, 2), + INGENIC_PIN_GROUP("ssi1-dr-e", jz4760_ssi1_dr_e, 1), + INGENIC_PIN_GROUP("ssi1-dr-f", jz4760_ssi1_dr_f, 2), + INGENIC_PIN_GROUP("ssi1-clk-b-7", jz4760_ssi1_clk_b_7, 2), + INGENIC_PIN_GROUP("ssi1-clk-b-28", jz4760_ssi1_clk_b_28, 2), + INGENIC_PIN_GROUP("ssi1-clk-d", jz4760_ssi1_clk_d, 2), + INGENIC_PIN_GROUP("ssi1-clk-e-7", jz4760_ssi1_clk_e_7, 2), + INGENIC_PIN_GROUP("ssi1-clk-e-15", jz4760_ssi1_clk_e_15, 1), + INGENIC_PIN_GROUP("ssi1-clk-f", jz4760_ssi1_clk_f, 2), + INGENIC_PIN_GROUP("ssi1-gpc-b", jz4760_ssi1_gpc_b, 2), + INGENIC_PIN_GROUP("ssi1-gpc-d", jz4760_ssi1_gpc_d, 2), + INGENIC_PIN_GROUP("ssi1-gpc-e", jz4760_ssi1_gpc_e, 1), + INGENIC_PIN_GROUP("ssi1-ce0-b-8", jz4760_ssi1_ce0_b_8, 2), + INGENIC_PIN_GROUP("ssi1-ce0-b-29", jz4760_ssi1_ce0_b_29, 2), + INGENIC_PIN_GROUP("ssi1-ce0-d", jz4760_ssi1_ce0_d, 2), + INGENIC_PIN_GROUP("ssi1-ce0-e-6", jz4760_ssi1_ce0_e_6, 2), + INGENIC_PIN_GROUP("ssi1-ce0-e-16", jz4760_ssi1_ce0_e_16, 1), + INGENIC_PIN_GROUP("ssi1-ce0-f", jz4760_ssi1_ce0_f, 2), + INGENIC_PIN_GROUP("ssi1-ce1-b", jz4760_ssi1_ce1_b, 2), + INGENIC_PIN_GROUP("ssi1-ce1-d", jz4760_ssi1_ce1_d, 2), + INGENIC_PIN_GROUP("ssi1-ce1-e", jz4760_ssi1_ce1_e, 1), INGENIC_PIN_GROUP_FUNCS("mmc0-1bit-a", jz4760_mmc0_1bit_a, jz4760_mmc0_1bit_a_funcs), INGENIC_PIN_GROUP("mmc0-4bit-a", jz4760_mmc0_4bit_a, 1), @@ -854,6 +991,22 @@ static const char *jz4760_uart0_groups[] = { "uart0-data", "uart0-hwflow", }; static const char *jz4760_uart1_groups[] = { "uart1-data", "uart1-hwflow", }; static const char *jz4760_uart2_groups[] = { "uart2-data", "uart2-hwflow", }; static const char *jz4760_uart3_groups[] = { "uart3-data", "uart3-hwflow", }; +static const char *jz4760_ssi0_groups[] = { + "ssi0-dt-a", "ssi0-dt-b", "ssi0-dt-d", "ssi0-dt-e", + "ssi0-dr-a", "ssi0-dr-b", "ssi0-dr-d", "ssi0-dr-e", + "ssi0-clk-a", "ssi0-clk-b", "ssi0-clk-d", "ssi0-clk-e", + "ssi0-gpc-b", "ssi0-gpc-d", "ssi0-gpc-e", + "ssi0-ce0-a", "ssi0-ce0-b", "ssi0-ce0-d", "ssi0-ce0-e", + "ssi0-ce1-b", "ssi0-ce1-d", "ssi0-ce1-e", +}; +static const char *jz4760_ssi1_groups[] = { + "ssi1-dt-b-9", "ssi1-dt-b-21", "ssi1-dt-d-12", "ssi1-dt-d-21", "ssi1-dt-e", "ssi1-dt-f", + "ssi1-dr-b-6", "ssi1-dr-b-20", "ssi1-dr-d-13", "ssi1-dr-d-20", "ssi1-dr-e", "ssi1-dr-f", + "ssi1-clk-b-7", "ssi1-clk-b-28", "ssi1-clk-d", "ssi1-clk-e-7", "ssi1-clk-e-15", "ssi1-clk-f", + "ssi1-gpc-b", "ssi1-gpc-d", "ssi1-gpc-e", + "ssi1-ce0-b-8", "ssi1-ce0-b-29", "ssi1-ce0-d", "ssi1-ce0-e-6", "ssi1-ce0-e-16", "ssi1-ce0-f", + "ssi1-ce1-b", "ssi1-ce1-d", "ssi1-ce1-e", +}; static const char *jz4760_mmc0_groups[] = { "mmc0-1bit-a", "mmc0-4bit-a", "mmc0-1bit-e", "mmc0-4bit-e", "mmc0-8bit-e", @@ -898,6 +1051,8 @@ static const struct function_desc jz4760_functions[] = { { "uart1", jz4760_uart1_groups, ARRAY_SIZE(jz4760_uart1_groups), }, { "uart2", jz4760_uart2_groups, ARRAY_SIZE(jz4760_uart2_groups), }, { "uart3", jz4760_uart3_groups, ARRAY_SIZE(jz4760_uart3_groups), }, + { "ssi0", jz4760_ssi0_groups, ARRAY_SIZE(jz4760_ssi0_groups), }, + { "ssi1", jz4760_ssi1_groups, ARRAY_SIZE(jz4760_ssi1_groups), }, { "mmc0", jz4760_mmc0_groups, ARRAY_SIZE(jz4760_mmc0_groups), }, { "mmc1", jz4760_mmc1_groups, ARRAY_SIZE(jz4760_mmc1_groups), }, { "mmc2", jz4760_mmc2_groups, ARRAY_SIZE(jz4760_mmc2_groups), }, -- cgit v1.2.3-70-g09d2 From bbd33911cf3312dbba9149f544bebf796cd58d58 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sat, 24 Jul 2021 14:36:43 +0800 Subject: dt-bindings: pinctrl: Add bindings for Ingenic X2100. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the pinctrl bindings for the X2100 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Acked-by: Rob Herring Link: https://lore.kernel.org/r/1627108604-91304-4-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml index a4846d78111c..a12d0ceb7637 100644 --- a/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml @@ -19,10 +19,10 @@ description: > pin within that GPIO port. For example PA0 is the first pin in GPIO port A, and PB31 is the last pin in GPIO port B. The JZ4730, the JZ4740, the JZ4725B, the X1000 and the X1830 contains 4 GPIO ports, PA to PD, for a total of 128 - pins. The X2000 contains 5 GPIO ports, PA to PE, for a total of 160 pins. - The JZ4750, the JZ4755 the JZ4760, the JZ4770 and the JZ4780 contains 6 GPIO - ports, PA to PF, for a total of 192 pins. The JZ4775 contains 7 GPIO ports, - PA to PG, for a total of 224 pins. + pins. The X2000 and the X2100 contains 5 GPIO ports, PA to PE, for a total of + 160 pins. The JZ4750, the JZ4755 the JZ4760, the JZ4770 and the JZ4780 contains + 6 GPIO ports, PA to PF, for a total of 192 pins. The JZ4775 contains 7 GPIO + ports, PA to PG, for a total of 224 pins. maintainers: - Paul Cercueil @@ -47,6 +47,7 @@ properties: - ingenic,x1500-pinctrl - ingenic,x1830-pinctrl - ingenic,x2000-pinctrl + - ingenic,x2100-pinctrl - items: - const: ingenic,jz4760b-pinctrl - const: ingenic,jz4760-pinctrl @@ -85,6 +86,7 @@ patternProperties: - ingenic,x1500-gpio - ingenic,x1830-gpio - ingenic,x2000-gpio + - ingenic,x2100-gpio reg: items: -- cgit v1.2.3-70-g09d2 From 2a18211b8ccfa316d1cb68d00d4ceba0e81653f8 Mon Sep 17 00:00:00 2001 From: "周琰杰 (Zhou Yanjie)" Date: Sat, 24 Jul 2021 14:36:44 +0800 Subject: pinctrl: Ingenic: Add pinctrl driver for X2100. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for probing the pinctrl-ingenic driver on the X2100 SoC from Ingenic. Signed-off-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/1627108604-91304-5-git-send-email-zhouyanjie@wanyeetech.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 216 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index f88bccfb2ff6..cd296d98548d 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -104,6 +104,7 @@ enum jz_version { ID_X1500, ID_X1830, ID_X2000, + ID_X2100, }; struct ingenic_chip_info { @@ -2980,6 +2981,216 @@ static const struct ingenic_chip_info x2000_chip_info = { .pull_downs = x2000_pull_downs, }; +static const u32 x2100_pull_ups[5] = { + 0x0003ffff, 0xffffffff, 0x1ff0ffff, 0xc7fe3f3f, 0x0fbf003f, +}; + +static const u32 x2100_pull_downs[5] = { + 0x0003ffff, 0xffffffff, 0x1ff0ffff, 0x00000000, 0x0fbf003f, +}; + +static int x2100_mac_pins[] = { + 0x4b, 0x47, 0x46, 0x4a, 0x43, 0x42, 0x4c, 0x4d, 0x4f, 0x41, +}; + +static const struct group_desc x2100_groups[] = { + INGENIC_PIN_GROUP("uart0-data", x2000_uart0_data, 2), + INGENIC_PIN_GROUP("uart0-hwflow", x2000_uart0_hwflow, 2), + INGENIC_PIN_GROUP("uart1-data", x2000_uart1_data, 1), + INGENIC_PIN_GROUP("uart1-hwflow", x2000_uart1_hwflow, 1), + INGENIC_PIN_GROUP("uart2-data", x2000_uart2_data, 0), + INGENIC_PIN_GROUP("uart3-data-c", x2000_uart3_data_c, 0), + INGENIC_PIN_GROUP("uart3-data-d", x2000_uart3_data_d, 1), + INGENIC_PIN_GROUP("uart3-hwflow-c", x2000_uart3_hwflow_c, 0), + INGENIC_PIN_GROUP("uart3-hwflow-d", x2000_uart3_hwflow_d, 1), + INGENIC_PIN_GROUP("uart4-data-a", x2000_uart4_data_a, 1), + INGENIC_PIN_GROUP("uart4-data-c", x2000_uart4_data_c, 3), + INGENIC_PIN_GROUP("uart4-hwflow-a", x2000_uart4_hwflow_a, 1), + INGENIC_PIN_GROUP("uart4-hwflow-c", x2000_uart4_hwflow_c, 3), + INGENIC_PIN_GROUP("uart5-data-a", x2000_uart5_data_a, 1), + INGENIC_PIN_GROUP("uart5-data-c", x2000_uart5_data_c, 3), + INGENIC_PIN_GROUP("uart6-data-a", x2000_uart6_data_a, 1), + INGENIC_PIN_GROUP("uart6-data-c", x2000_uart6_data_c, 3), + INGENIC_PIN_GROUP("uart7-data-a", x2000_uart7_data_a, 1), + INGENIC_PIN_GROUP("uart7-data-c", x2000_uart7_data_c, 3), + INGENIC_PIN_GROUP("uart8-data", x2000_uart8_data, 3), + INGENIC_PIN_GROUP("uart9-data", x2000_uart9_data, 3), + INGENIC_PIN_GROUP("sfc-data-if0-d", x2000_sfc_data_if0_d, 1), + INGENIC_PIN_GROUP("sfc-data-if0-e", x2000_sfc_data_if0_e, 0), + INGENIC_PIN_GROUP("sfc-data-if1", x2000_sfc_data_if1, 1), + INGENIC_PIN_GROUP("sfc-clk-d", x2000_sfc_clk_d, 1), + INGENIC_PIN_GROUP("sfc-clk-e", x2000_sfc_clk_e, 0), + INGENIC_PIN_GROUP("sfc-ce-d", x2000_sfc_ce_d, 1), + INGENIC_PIN_GROUP("sfc-ce-e", x2000_sfc_ce_e, 0), + INGENIC_PIN_GROUP("ssi0-dt-b", x2000_ssi0_dt_b, 1), + INGENIC_PIN_GROUP("ssi0-dt-d", x2000_ssi0_dt_d, 1), + INGENIC_PIN_GROUP("ssi0-dr-b", x2000_ssi0_dr_b, 1), + INGENIC_PIN_GROUP("ssi0-dr-d", x2000_ssi0_dr_d, 1), + INGENIC_PIN_GROUP("ssi0-clk-b", x2000_ssi0_clk_b, 1), + INGENIC_PIN_GROUP("ssi0-clk-d", x2000_ssi0_clk_d, 1), + INGENIC_PIN_GROUP("ssi0-ce-b", x2000_ssi0_ce_b, 1), + INGENIC_PIN_GROUP("ssi0-ce-d", x2000_ssi0_ce_d, 1), + INGENIC_PIN_GROUP("ssi1-dt-c", x2000_ssi1_dt_c, 2), + INGENIC_PIN_GROUP("ssi1-dt-d", x2000_ssi1_dt_d, 2), + INGENIC_PIN_GROUP("ssi1-dt-e", x2000_ssi1_dt_e, 1), + INGENIC_PIN_GROUP("ssi1-dr-c", x2000_ssi1_dr_c, 2), + INGENIC_PIN_GROUP("ssi1-dr-d", x2000_ssi1_dr_d, 2), + INGENIC_PIN_GROUP("ssi1-dr-e", x2000_ssi1_dr_e, 1), + INGENIC_PIN_GROUP("ssi1-clk-c", x2000_ssi1_clk_c, 2), + INGENIC_PIN_GROUP("ssi1-clk-d", x2000_ssi1_clk_d, 2), + INGENIC_PIN_GROUP("ssi1-clk-e", x2000_ssi1_clk_e, 1), + INGENIC_PIN_GROUP("ssi1-ce-c", x2000_ssi1_ce_c, 2), + INGENIC_PIN_GROUP("ssi1-ce-d", x2000_ssi1_ce_d, 2), + INGENIC_PIN_GROUP("ssi1-ce-e", x2000_ssi1_ce_e, 1), + INGENIC_PIN_GROUP("mmc0-1bit", x2000_mmc0_1bit, 0), + INGENIC_PIN_GROUP("mmc0-4bit", x2000_mmc0_4bit, 0), + INGENIC_PIN_GROUP("mmc0-8bit", x2000_mmc0_8bit, 0), + INGENIC_PIN_GROUP("mmc1-1bit", x2000_mmc1_1bit, 0), + INGENIC_PIN_GROUP("mmc1-4bit", x2000_mmc1_4bit, 0), + INGENIC_PIN_GROUP("mmc2-1bit", x2000_mmc2_1bit, 0), + INGENIC_PIN_GROUP("mmc2-4bit", x2000_mmc2_4bit, 0), + INGENIC_PIN_GROUP("emc-8bit-data", x2000_emc_8bit_data, 0), + INGENIC_PIN_GROUP("emc-16bit-data", x2000_emc_16bit_data, 0), + INGENIC_PIN_GROUP("emc-addr", x2000_emc_addr, 0), + INGENIC_PIN_GROUP("emc-rd-we", x2000_emc_rd_we, 0), + INGENIC_PIN_GROUP("emc-wait", x2000_emc_wait, 0), + INGENIC_PIN_GROUP("emc-cs1", x2000_emc_cs1, 3), + INGENIC_PIN_GROUP("emc-cs2", x2000_emc_cs2, 3), + INGENIC_PIN_GROUP("i2c0-data", x2000_i2c0, 3), + INGENIC_PIN_GROUP("i2c1-data-c", x2000_i2c1_c, 2), + INGENIC_PIN_GROUP("i2c1-data-d", x2000_i2c1_d, 1), + INGENIC_PIN_GROUP("i2c2-data-b", x2000_i2c2_b, 2), + INGENIC_PIN_GROUP("i2c2-data-d", x2000_i2c2_d, 2), + INGENIC_PIN_GROUP("i2c2-data-e", x2000_i2c2_e, 1), + INGENIC_PIN_GROUP("i2c3-data-a", x2000_i2c3_a, 0), + INGENIC_PIN_GROUP("i2c3-data-d", x2000_i2c3_d, 1), + INGENIC_PIN_GROUP("i2c4-data-c", x2000_i2c4_c, 1), + INGENIC_PIN_GROUP("i2c4-data-d", x2000_i2c4_d, 2), + INGENIC_PIN_GROUP("i2c5-data-c", x2000_i2c5_c, 1), + INGENIC_PIN_GROUP("i2c5-data-d", x2000_i2c5_d, 1), + INGENIC_PIN_GROUP("i2s1-data-tx", x2000_i2s1_data_tx, 2), + INGENIC_PIN_GROUP("i2s1-data-rx", x2000_i2s1_data_rx, 2), + INGENIC_PIN_GROUP("i2s1-clk-tx", x2000_i2s1_clk_tx, 2), + INGENIC_PIN_GROUP("i2s1-clk-rx", x2000_i2s1_clk_rx, 2), + INGENIC_PIN_GROUP("i2s1-sysclk-tx", x2000_i2s1_sysclk_tx, 2), + INGENIC_PIN_GROUP("i2s1-sysclk-rx", x2000_i2s1_sysclk_rx, 2), + INGENIC_PIN_GROUP("i2s2-data-rx0", x2000_i2s2_data_rx0, 2), + INGENIC_PIN_GROUP("i2s2-data-rx1", x2000_i2s2_data_rx1, 2), + INGENIC_PIN_GROUP("i2s2-data-rx2", x2000_i2s2_data_rx2, 2), + INGENIC_PIN_GROUP("i2s2-data-rx3", x2000_i2s2_data_rx3, 2), + INGENIC_PIN_GROUP("i2s2-clk-rx", x2000_i2s2_clk_rx, 2), + INGENIC_PIN_GROUP("i2s2-sysclk-rx", x2000_i2s2_sysclk_rx, 2), + INGENIC_PIN_GROUP("i2s3-data-tx0", x2000_i2s3_data_tx0, 2), + INGENIC_PIN_GROUP("i2s3-data-tx1", x2000_i2s3_data_tx1, 2), + INGENIC_PIN_GROUP("i2s3-data-tx2", x2000_i2s3_data_tx2, 2), + INGENIC_PIN_GROUP("i2s3-data-tx3", x2000_i2s3_data_tx3, 2), + INGENIC_PIN_GROUP("i2s3-clk-tx", x2000_i2s3_clk_tx, 2), + INGENIC_PIN_GROUP("i2s3-sysclk-tx", x2000_i2s3_sysclk_tx, 2), + INGENIC_PIN_GROUP("dmic-if0", x2000_dmic_if0, 0), + INGENIC_PIN_GROUP("dmic-if1", x2000_dmic_if1, 0), + INGENIC_PIN_GROUP("dmic-if2", x2000_dmic_if2, 0), + INGENIC_PIN_GROUP("dmic-if3", x2000_dmic_if3, 0), + INGENIC_PIN_GROUP_FUNCS("cim-data-8bit", x2000_cim_8bit, + x2000_cim_8bit_funcs), + INGENIC_PIN_GROUP("cim-data-12bit", x2000_cim_12bit, 0), + INGENIC_PIN_GROUP("lcd-tft-8bit", x2000_lcd_tft_8bit, 1), + INGENIC_PIN_GROUP("lcd-tft-16bit", x2000_lcd_tft_16bit, 1), + INGENIC_PIN_GROUP("lcd-tft-18bit", x2000_lcd_tft_18bit, 1), + INGENIC_PIN_GROUP("lcd-tft-24bit", x2000_lcd_tft_24bit, 1), + INGENIC_PIN_GROUP("lcd-slcd-8bit", x2000_lcd_slcd_8bit, 2), + INGENIC_PIN_GROUP("lcd-slcd-16bit", x2000_lcd_tft_16bit, 2), + INGENIC_PIN_GROUP("pwm0-c", x2000_pwm_pwm0_c, 0), + INGENIC_PIN_GROUP("pwm0-d", x2000_pwm_pwm0_d, 2), + INGENIC_PIN_GROUP("pwm1-c", x2000_pwm_pwm1_c, 0), + INGENIC_PIN_GROUP("pwm1-d", x2000_pwm_pwm1_d, 2), + INGENIC_PIN_GROUP("pwm2-c", x2000_pwm_pwm2_c, 0), + INGENIC_PIN_GROUP("pwm2-e", x2000_pwm_pwm2_e, 1), + INGENIC_PIN_GROUP("pwm3-c", x2000_pwm_pwm3_c, 0), + INGENIC_PIN_GROUP("pwm3-e", x2000_pwm_pwm3_e, 1), + INGENIC_PIN_GROUP("pwm4-c", x2000_pwm_pwm4_c, 0), + INGENIC_PIN_GROUP("pwm4-e", x2000_pwm_pwm4_e, 1), + INGENIC_PIN_GROUP("pwm5-c", x2000_pwm_pwm5_c, 0), + INGENIC_PIN_GROUP("pwm5-e", x2000_pwm_pwm5_e, 1), + INGENIC_PIN_GROUP("pwm6-c", x2000_pwm_pwm6_c, 0), + INGENIC_PIN_GROUP("pwm6-e", x2000_pwm_pwm6_e, 1), + INGENIC_PIN_GROUP("pwm7-c", x2000_pwm_pwm7_c, 0), + INGENIC_PIN_GROUP("pwm7-e", x2000_pwm_pwm7_e, 1), + INGENIC_PIN_GROUP("pwm8", x2000_pwm_pwm8, 0), + INGENIC_PIN_GROUP("pwm9", x2000_pwm_pwm9, 0), + INGENIC_PIN_GROUP("pwm10", x2000_pwm_pwm10, 0), + INGENIC_PIN_GROUP("pwm11", x2000_pwm_pwm11, 0), + INGENIC_PIN_GROUP("pwm12", x2000_pwm_pwm12, 0), + INGENIC_PIN_GROUP("pwm13", x2000_pwm_pwm13, 0), + INGENIC_PIN_GROUP("pwm14", x2000_pwm_pwm14, 0), + INGENIC_PIN_GROUP("pwm15", x2000_pwm_pwm15, 0), + INGENIC_PIN_GROUP("mac", x2100_mac, 1), +}; + +static const char *x2100_mac_groups[] = { "mac", }; + +static const struct function_desc x2100_functions[] = { + { "uart0", x2000_uart0_groups, ARRAY_SIZE(x2000_uart0_groups), }, + { "uart1", x2000_uart1_groups, ARRAY_SIZE(x2000_uart1_groups), }, + { "uart2", x2000_uart2_groups, ARRAY_SIZE(x2000_uart2_groups), }, + { "uart3", x2000_uart3_groups, ARRAY_SIZE(x2000_uart3_groups), }, + { "uart4", x2000_uart4_groups, ARRAY_SIZE(x2000_uart4_groups), }, + { "uart5", x2000_uart5_groups, ARRAY_SIZE(x2000_uart5_groups), }, + { "uart6", x2000_uart6_groups, ARRAY_SIZE(x2000_uart6_groups), }, + { "uart7", x2000_uart7_groups, ARRAY_SIZE(x2000_uart7_groups), }, + { "uart8", x2000_uart8_groups, ARRAY_SIZE(x2000_uart8_groups), }, + { "uart9", x2000_uart9_groups, ARRAY_SIZE(x2000_uart9_groups), }, + { "sfc", x2000_sfc_groups, ARRAY_SIZE(x2000_sfc_groups), }, + { "ssi0", x2000_ssi0_groups, ARRAY_SIZE(x2000_ssi0_groups), }, + { "ssi1", x2000_ssi1_groups, ARRAY_SIZE(x2000_ssi1_groups), }, + { "mmc0", x2000_mmc0_groups, ARRAY_SIZE(x2000_mmc0_groups), }, + { "mmc1", x2000_mmc1_groups, ARRAY_SIZE(x2000_mmc1_groups), }, + { "mmc2", x2000_mmc2_groups, ARRAY_SIZE(x2000_mmc2_groups), }, + { "emc", x2000_emc_groups, ARRAY_SIZE(x2000_emc_groups), }, + { "emc-cs1", x2000_cs1_groups, ARRAY_SIZE(x2000_cs1_groups), }, + { "emc-cs2", x2000_cs2_groups, ARRAY_SIZE(x2000_cs2_groups), }, + { "i2c0", x2000_i2c0_groups, ARRAY_SIZE(x2000_i2c0_groups), }, + { "i2c1", x2000_i2c1_groups, ARRAY_SIZE(x2000_i2c1_groups), }, + { "i2c2", x2000_i2c2_groups, ARRAY_SIZE(x2000_i2c2_groups), }, + { "i2c3", x2000_i2c3_groups, ARRAY_SIZE(x2000_i2c3_groups), }, + { "i2c4", x2000_i2c4_groups, ARRAY_SIZE(x2000_i2c4_groups), }, + { "i2c5", x2000_i2c5_groups, ARRAY_SIZE(x2000_i2c5_groups), }, + { "i2s1", x2000_i2s1_groups, ARRAY_SIZE(x2000_i2s1_groups), }, + { "i2s2", x2000_i2s2_groups, ARRAY_SIZE(x2000_i2s2_groups), }, + { "i2s3", x2000_i2s3_groups, ARRAY_SIZE(x2000_i2s3_groups), }, + { "dmic", x2000_dmic_groups, ARRAY_SIZE(x2000_dmic_groups), }, + { "cim", x2000_cim_groups, ARRAY_SIZE(x2000_cim_groups), }, + { "lcd", x2000_lcd_groups, ARRAY_SIZE(x2000_lcd_groups), }, + { "pwm0", x2000_pwm0_groups, ARRAY_SIZE(x2000_pwm0_groups), }, + { "pwm1", x2000_pwm1_groups, ARRAY_SIZE(x2000_pwm1_groups), }, + { "pwm2", x2000_pwm2_groups, ARRAY_SIZE(x2000_pwm2_groups), }, + { "pwm3", x2000_pwm3_groups, ARRAY_SIZE(x2000_pwm3_groups), }, + { "pwm4", x2000_pwm4_groups, ARRAY_SIZE(x2000_pwm4_groups), }, + { "pwm5", x2000_pwm5_groups, ARRAY_SIZE(x2000_pwm5_groups), }, + { "pwm6", x2000_pwm6_groups, ARRAY_SIZE(x2000_pwm6_groups), }, + { "pwm7", x2000_pwm7_groups, ARRAY_SIZE(x2000_pwm7_groups), }, + { "pwm8", x2000_pwm8_groups, ARRAY_SIZE(x2000_pwm8_groups), }, + { "pwm9", x2000_pwm9_groups, ARRAY_SIZE(x2000_pwm9_groups), }, + { "pwm10", x2000_pwm10_groups, ARRAY_SIZE(x2000_pwm10_groups), }, + { "pwm11", x2000_pwm11_groups, ARRAY_SIZE(x2000_pwm11_groups), }, + { "pwm12", x2000_pwm12_groups, ARRAY_SIZE(x2000_pwm12_groups), }, + { "pwm13", x2000_pwm13_groups, ARRAY_SIZE(x2000_pwm13_groups), }, + { "pwm14", x2000_pwm14_groups, ARRAY_SIZE(x2000_pwm14_groups), }, + { "pwm15", x2000_pwm15_groups, ARRAY_SIZE(x2000_pwm15_groups), }, + { "mac", x2100_mac_groups, ARRAY_SIZE(x2100_mac_groups), }, +}; + +static const struct ingenic_chip_info x2100_chip_info = { + .num_chips = 5, + .reg_offset = 0x100, + .version = ID_X2100, + .groups = x2100_groups, + .num_groups = ARRAY_SIZE(x2100_groups), + .functions = x2100_functions, + .num_functions = ARRAY_SIZE(x2100_functions), + .pull_ups = x2100_pull_ups, + .pull_downs = x2100_pull_downs, +}; + static u32 ingenic_gpio_read_reg(struct ingenic_gpio_chip *jzgc, u8 reg) { unsigned int val; @@ -3845,6 +4056,7 @@ static const struct of_device_id ingenic_gpio_of_matches[] __initconst = { { .compatible = "ingenic,x1000-gpio" }, { .compatible = "ingenic,x1830-gpio" }, { .compatible = "ingenic,x2000-gpio" }, + { .compatible = "ingenic,x2100-gpio" }, {}, }; @@ -4100,6 +4312,10 @@ static const struct of_device_id ingenic_pinctrl_of_matches[] = { .compatible = "ingenic,x2000e-pinctrl", .data = IF_ENABLED(CONFIG_MACH_X2000, &x2000_chip_info) }, + { + .compatible = "ingenic,x2100-pinctrl", + .data = IF_ENABLED(CONFIG_MACH_X2100, &x2100_chip_info) + }, { /* sentinel */ }, }; -- cgit v1.2.3-70-g09d2 From d5e931403942b3af39212960c2592b5ba741b2bf Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 17 Jul 2021 18:48:34 +0100 Subject: pinctrl: ingenic: Fix incorrect pull up/down info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the pull up/down info for both the JZ4760 and JZ4770 SoCs, as the previous values sometimes contradicted what's written in the programming manual. Fixes: b5c23aa46537 ("pinctrl: add a pinctrl driver for the Ingenic jz47xx SoCs") Cc: # v4.12 Signed-off-by: Paul Cercueil Tested-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/20210717174836.14776-1-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index cd296d98548d..5a602e6479b9 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -744,7 +744,7 @@ static const struct ingenic_chip_info jz4755_chip_info = { }; static const u32 jz4760_pull_ups[6] = { - 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f, + 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0x0000000f, }; static const u32 jz4760_pull_downs[6] = { @@ -1092,11 +1092,11 @@ static const struct ingenic_chip_info jz4760_chip_info = { }; static const u32 jz4770_pull_ups[6] = { - 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f, + 0x3fffffff, 0xfff0f3fc, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0x0024f00f, }; static const u32 jz4770_pull_downs[6] = { - 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0, + 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x005b0ff0, }; static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, }; -- cgit v1.2.3-70-g09d2 From 7261851e938f4b0fe8c0f5a8e627ae90e1ba9875 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 17 Jul 2021 18:48:35 +0100 Subject: pinctrl: ingenic: Fix bias config for X2000(E) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ingenic_set_bias() function's "bias" argument is not a "enum pin_config_param", so its value should not be compared against values of that enum. This should fix the bias config not working on the X2000(E) SoCs. Fixes: 943e0da15370 ("pinctrl: Ingenic: Add pinctrl driver for X2000.") Cc: # v5.12 Signed-off-by: Paul Cercueil Tested-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/20210717174836.14776-2-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 5a602e6479b9..2b894db1029b 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -3830,17 +3830,17 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, { if (jzpc->info->version >= ID_X2000) { switch (bias) { - case PIN_CONFIG_BIAS_PULL_UP: + case GPIO_PULL_UP: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, true); break; - case PIN_CONFIG_BIAS_PULL_DOWN: + case GPIO_PULL_DOWN: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, true); break; - case PIN_CONFIG_BIAS_DISABLE: + case GPIO_PULL_DIS: default: ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPU, false); ingenic_config_pin(jzpc, pin, X2000_GPIO_PEPD, false); -- cgit v1.2.3-70-g09d2 From 6626a76ef857c937ba7b96f0ea8bb5451c1419eb Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Sat, 17 Jul 2021 18:48:36 +0100 Subject: pinctrl: ingenic: Add .max_register in regmap_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compute the max register from the GPIO chip offset and number of GPIO chips. This permits to read all registers from debugfs. Signed-off-by: Paul Cercueil Tested-by: 周琰杰 (Zhou Yanjie) Link: https://lore.kernel.org/r/20210717174836.14776-3-paul@crapouillou.net Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-ingenic.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c index 2b894db1029b..cf4cc8f129f4 100644 --- a/drivers/pinctrl/pinctrl-ingenic.c +++ b/drivers/pinctrl/pinctrl-ingenic.c @@ -4149,6 +4149,7 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) void __iomem *base; const struct ingenic_chip_info *chip_info; struct device_node *node; + struct regmap_config regmap_config; unsigned int i; int err; @@ -4166,8 +4167,10 @@ static int __init ingenic_pinctrl_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - jzpc->map = devm_regmap_init_mmio(dev, base, - &ingenic_pinctrl_regmap_config); + regmap_config = ingenic_pinctrl_regmap_config; + regmap_config.max_register = chip_info->num_chips * chip_info->reg_offset; + + jzpc->map = devm_regmap_init_mmio(dev, base, ®map_config); if (IS_ERR(jzpc->map)) { dev_err(dev, "Failed to create regmap\n"); return PTR_ERR(jzpc->map); -- cgit v1.2.3-70-g09d2 From 3acd5d8b7cf614d8724986b0dbfee52b0944d027 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 4 Aug 2021 12:40:31 +0800 Subject: arm: dts: mt8135: Move pinfunc to include/dt-bindings/pinctrl Move mt8135-pinfunc.h into include/dt-bindings/pinctrl so that we can include it in yaml examples. Signed-off-by: Hsin-Yi Wang Link: https://lore.kernel.org/r/20210804044033.3047296-1-hsinyi@chromium.org Signed-off-by: Linus Walleij --- arch/arm/boot/dts/mt8135-pinfunc.h | 1294 -------------------------- arch/arm/boot/dts/mt8135.dtsi | 2 +- include/dt-bindings/pinctrl/mt8135-pinfunc.h | 1294 ++++++++++++++++++++++++++ 3 files changed, 1295 insertions(+), 1295 deletions(-) delete mode 100644 arch/arm/boot/dts/mt8135-pinfunc.h create mode 100644 include/dt-bindings/pinctrl/mt8135-pinfunc.h diff --git a/arch/arm/boot/dts/mt8135-pinfunc.h b/arch/arm/boot/dts/mt8135-pinfunc.h deleted file mode 100644 index ce0cb5a440eb..000000000000 --- a/arch/arm/boot/dts/mt8135-pinfunc.h +++ /dev/null @@ -1,1294 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2014 MediaTek Inc. - * Author: Hongzhou.Yang - */ - -#ifndef __DTS_MT8135_PINFUNC_H -#define __DTS_MT8135_PINFUNC_H - -#include - -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(0) | 1) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_EINT49 (MTK_PIN_NO(0) | 2) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_I2SOUT_DAT (MTK_PIN_NO(0) | 3) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_DAC_DAT_OUT (MTK_PIN_NO(0) | 4) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_PCM1_DO (MTK_PIN_NO(0) | 5) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_SPI1_MO (MTK_PIN_NO(0) | 6) -#define MT8135_PIN_0_MSDC0_DAT7__FUNC_NALE (MTK_PIN_NO(0) | 7) - -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(1) | 1) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_EINT48 (MTK_PIN_NO(1) | 2) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_I2SIN_WS (MTK_PIN_NO(1) | 3) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_DAC_WS (MTK_PIN_NO(1) | 4) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_PCM1_WS (MTK_PIN_NO(1) | 5) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_SPI1_CSN (MTK_PIN_NO(1) | 6) -#define MT8135_PIN_1_MSDC0_DAT6__FUNC_NCLE (MTK_PIN_NO(1) | 7) - -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(2) | 1) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_EINT47 (MTK_PIN_NO(2) | 2) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_I2SIN_CK (MTK_PIN_NO(2) | 3) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_DAC_CK (MTK_PIN_NO(2) | 4) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_PCM1_CK (MTK_PIN_NO(2) | 5) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_SPI1_CLK (MTK_PIN_NO(2) | 6) -#define MT8135_PIN_2_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(2) | 7) - -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(3) | 1) -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_EINT46 (MTK_PIN_NO(3) | 2) -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_A_FUNC_CK (MTK_PIN_NO(3) | 3) -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_LSCE1B_2X (MTK_PIN_NO(3) | 6) -#define MT8135_PIN_3_MSDC0_DAT4__FUNC_NLD5 (MTK_PIN_NO(3) | 7) - -#define MT8135_PIN_4_MSDC0_CMD__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(4) | 1) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_EINT41 (MTK_PIN_NO(4) | 2) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_A_FUNC_DOUT_0 (MTK_PIN_NO(4) | 3) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_USB_TEST_IO_0 (MTK_PIN_NO(4) | 5) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_LRSTB_2X (MTK_PIN_NO(4) | 6) -#define MT8135_PIN_4_MSDC0_CMD__FUNC_NRNB (MTK_PIN_NO(4) | 7) - -#define MT8135_PIN_5_MSDC0_CLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(5) | 1) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_EINT40 (MTK_PIN_NO(5) | 2) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_A_FUNC_DOUT_1 (MTK_PIN_NO(5) | 3) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_USB_TEST_IO_1 (MTK_PIN_NO(5) | 5) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_LPTE (MTK_PIN_NO(5) | 6) -#define MT8135_PIN_5_MSDC0_CLK__FUNC_NREB (MTK_PIN_NO(5) | 7) - -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(6) | 1) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_EINT45 (MTK_PIN_NO(6) | 2) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_A_FUNC_DOUT_2 (MTK_PIN_NO(6) | 3) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_USB_TEST_IO_2 (MTK_PIN_NO(6) | 5) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_LSCE0B_2X (MTK_PIN_NO(6) | 6) -#define MT8135_PIN_6_MSDC0_DAT3__FUNC_NLD7 (MTK_PIN_NO(6) | 7) - -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(7) | 1) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_EINT44 (MTK_PIN_NO(7) | 2) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_A_FUNC_DOUT_3 (MTK_PIN_NO(7) | 3) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_USB_TEST_IO_3 (MTK_PIN_NO(7) | 5) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_LSA0_2X (MTK_PIN_NO(7) | 6) -#define MT8135_PIN_7_MSDC0_DAT2__FUNC_NLD14 (MTK_PIN_NO(7) | 7) - -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(8) | 1) -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_EINT43 (MTK_PIN_NO(8) | 2) -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_USB_TEST_IO_4 (MTK_PIN_NO(8) | 5) -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_LSCK_2X (MTK_PIN_NO(8) | 6) -#define MT8135_PIN_8_MSDC0_DAT1__FUNC_NLD11 (MTK_PIN_NO(8) | 7) - -#define MT8135_PIN_9_MSDC0_DAT0__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) -#define MT8135_PIN_9_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(9) | 1) -#define MT8135_PIN_9_MSDC0_DAT0__FUNC_EINT42 (MTK_PIN_NO(9) | 2) -#define MT8135_PIN_9_MSDC0_DAT0__FUNC_USB_TEST_IO_5 (MTK_PIN_NO(9) | 5) -#define MT8135_PIN_9_MSDC0_DAT0__FUNC_LSDA_2X (MTK_PIN_NO(9) | 6) - -#define MT8135_PIN_10_NCEB0__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) -#define MT8135_PIN_10_NCEB0__FUNC_NCEB0 (MTK_PIN_NO(10) | 1) -#define MT8135_PIN_10_NCEB0__FUNC_EINT139 (MTK_PIN_NO(10) | 2) -#define MT8135_PIN_10_NCEB0__FUNC_TESTA_OUT4 (MTK_PIN_NO(10) | 7) - -#define MT8135_PIN_11_NCEB1__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) -#define MT8135_PIN_11_NCEB1__FUNC_NCEB1 (MTK_PIN_NO(11) | 1) -#define MT8135_PIN_11_NCEB1__FUNC_EINT140 (MTK_PIN_NO(11) | 2) -#define MT8135_PIN_11_NCEB1__FUNC_USB_DRVVBUS (MTK_PIN_NO(11) | 6) -#define MT8135_PIN_11_NCEB1__FUNC_TESTA_OUT5 (MTK_PIN_NO(11) | 7) - -#define MT8135_PIN_12_NRNB__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) -#define MT8135_PIN_12_NRNB__FUNC_NRNB (MTK_PIN_NO(12) | 1) -#define MT8135_PIN_12_NRNB__FUNC_EINT141 (MTK_PIN_NO(12) | 2) -#define MT8135_PIN_12_NRNB__FUNC_A_FUNC_DOUT_4 (MTK_PIN_NO(12) | 3) -#define MT8135_PIN_12_NRNB__FUNC_TESTA_OUT6 (MTK_PIN_NO(12) | 7) - -#define MT8135_PIN_13_NCLE__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) -#define MT8135_PIN_13_NCLE__FUNC_NCLE (MTK_PIN_NO(13) | 1) -#define MT8135_PIN_13_NCLE__FUNC_EINT142 (MTK_PIN_NO(13) | 2) -#define MT8135_PIN_13_NCLE__FUNC_A_FUNC_DOUT_5 (MTK_PIN_NO(13) | 3) -#define MT8135_PIN_13_NCLE__FUNC_CM2PDN_1X (MTK_PIN_NO(13) | 4) -#define MT8135_PIN_13_NCLE__FUNC_NALE (MTK_PIN_NO(13) | 6) -#define MT8135_PIN_13_NCLE__FUNC_TESTA_OUT7 (MTK_PIN_NO(13) | 7) - -#define MT8135_PIN_14_NALE__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) -#define MT8135_PIN_14_NALE__FUNC_NALE (MTK_PIN_NO(14) | 1) -#define MT8135_PIN_14_NALE__FUNC_EINT143 (MTK_PIN_NO(14) | 2) -#define MT8135_PIN_14_NALE__FUNC_A_FUNC_DOUT_6 (MTK_PIN_NO(14) | 3) -#define MT8135_PIN_14_NALE__FUNC_CM2MCLK_1X (MTK_PIN_NO(14) | 4) -#define MT8135_PIN_14_NALE__FUNC_IRDA_RXD (MTK_PIN_NO(14) | 5) -#define MT8135_PIN_14_NALE__FUNC_NCLE (MTK_PIN_NO(14) | 6) -#define MT8135_PIN_14_NALE__FUNC_TESTA_OUT8 (MTK_PIN_NO(14) | 7) - -#define MT8135_PIN_15_NREB__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) -#define MT8135_PIN_15_NREB__FUNC_NREB (MTK_PIN_NO(15) | 1) -#define MT8135_PIN_15_NREB__FUNC_EINT144 (MTK_PIN_NO(15) | 2) -#define MT8135_PIN_15_NREB__FUNC_A_FUNC_DOUT_7 (MTK_PIN_NO(15) | 3) -#define MT8135_PIN_15_NREB__FUNC_CM2RST_1X (MTK_PIN_NO(15) | 4) -#define MT8135_PIN_15_NREB__FUNC_IRDA_TXD (MTK_PIN_NO(15) | 5) -#define MT8135_PIN_15_NREB__FUNC_TESTA_OUT9 (MTK_PIN_NO(15) | 7) - -#define MT8135_PIN_16_NWEB__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) -#define MT8135_PIN_16_NWEB__FUNC_NWEB (MTK_PIN_NO(16) | 1) -#define MT8135_PIN_16_NWEB__FUNC_EINT145 (MTK_PIN_NO(16) | 2) -#define MT8135_PIN_16_NWEB__FUNC_A_FUNC_DIN_0 (MTK_PIN_NO(16) | 3) -#define MT8135_PIN_16_NWEB__FUNC_CM2PCLK_1X (MTK_PIN_NO(16) | 4) -#define MT8135_PIN_16_NWEB__FUNC_IRDA_PDN (MTK_PIN_NO(16) | 5) -#define MT8135_PIN_16_NWEB__FUNC_TESTA_OUT10 (MTK_PIN_NO(16) | 7) - -#define MT8135_PIN_17_NLD0__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) -#define MT8135_PIN_17_NLD0__FUNC_NLD0 (MTK_PIN_NO(17) | 1) -#define MT8135_PIN_17_NLD0__FUNC_EINT146 (MTK_PIN_NO(17) | 2) -#define MT8135_PIN_17_NLD0__FUNC_A_FUNC_DIN_1 (MTK_PIN_NO(17) | 3) -#define MT8135_PIN_17_NLD0__FUNC_CM2DAT_1X_0 (MTK_PIN_NO(17) | 4) -#define MT8135_PIN_17_NLD0__FUNC_I2SIN_CK (MTK_PIN_NO(17) | 5) -#define MT8135_PIN_17_NLD0__FUNC_DAC_CK (MTK_PIN_NO(17) | 6) -#define MT8135_PIN_17_NLD0__FUNC_TESTA_OUT11 (MTK_PIN_NO(17) | 7) - -#define MT8135_PIN_18_NLD1__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) -#define MT8135_PIN_18_NLD1__FUNC_NLD1 (MTK_PIN_NO(18) | 1) -#define MT8135_PIN_18_NLD1__FUNC_EINT147 (MTK_PIN_NO(18) | 2) -#define MT8135_PIN_18_NLD1__FUNC_A_FUNC_DIN_2 (MTK_PIN_NO(18) | 3) -#define MT8135_PIN_18_NLD1__FUNC_CM2DAT_1X_1 (MTK_PIN_NO(18) | 4) -#define MT8135_PIN_18_NLD1__FUNC_I2SIN_WS (MTK_PIN_NO(18) | 5) -#define MT8135_PIN_18_NLD1__FUNC_DAC_WS (MTK_PIN_NO(18) | 6) -#define MT8135_PIN_18_NLD1__FUNC_TESTA_OUT12 (MTK_PIN_NO(18) | 7) - -#define MT8135_PIN_19_NLD2__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) -#define MT8135_PIN_19_NLD2__FUNC_NLD2 (MTK_PIN_NO(19) | 1) -#define MT8135_PIN_19_NLD2__FUNC_EINT148 (MTK_PIN_NO(19) | 2) -#define MT8135_PIN_19_NLD2__FUNC_A_FUNC_DIN_3 (MTK_PIN_NO(19) | 3) -#define MT8135_PIN_19_NLD2__FUNC_CM2DAT_1X_2 (MTK_PIN_NO(19) | 4) -#define MT8135_PIN_19_NLD2__FUNC_I2SOUT_DAT (MTK_PIN_NO(19) | 5) -#define MT8135_PIN_19_NLD2__FUNC_DAC_DAT_OUT (MTK_PIN_NO(19) | 6) -#define MT8135_PIN_19_NLD2__FUNC_TESTA_OUT13 (MTK_PIN_NO(19) | 7) - -#define MT8135_PIN_20_NLD3__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) -#define MT8135_PIN_20_NLD3__FUNC_NLD3 (MTK_PIN_NO(20) | 1) -#define MT8135_PIN_20_NLD3__FUNC_EINT149 (MTK_PIN_NO(20) | 2) -#define MT8135_PIN_20_NLD3__FUNC_A_FUNC_DIN_4 (MTK_PIN_NO(20) | 3) -#define MT8135_PIN_20_NLD3__FUNC_CM2DAT_1X_3 (MTK_PIN_NO(20) | 4) -#define MT8135_PIN_20_NLD3__FUNC_TESTA_OUT14 (MTK_PIN_NO(20) | 7) - -#define MT8135_PIN_21_NLD4__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) -#define MT8135_PIN_21_NLD4__FUNC_NLD4 (MTK_PIN_NO(21) | 1) -#define MT8135_PIN_21_NLD4__FUNC_EINT150 (MTK_PIN_NO(21) | 2) -#define MT8135_PIN_21_NLD4__FUNC_A_FUNC_DIN_5 (MTK_PIN_NO(21) | 3) -#define MT8135_PIN_21_NLD4__FUNC_CM2DAT_1X_4 (MTK_PIN_NO(21) | 4) -#define MT8135_PIN_21_NLD4__FUNC_TESTA_OUT15 (MTK_PIN_NO(21) | 7) - -#define MT8135_PIN_22_NLD5__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) -#define MT8135_PIN_22_NLD5__FUNC_NLD5 (MTK_PIN_NO(22) | 1) -#define MT8135_PIN_22_NLD5__FUNC_EINT151 (MTK_PIN_NO(22) | 2) -#define MT8135_PIN_22_NLD5__FUNC_A_FUNC_DIN_6 (MTK_PIN_NO(22) | 3) -#define MT8135_PIN_22_NLD5__FUNC_CM2DAT_1X_5 (MTK_PIN_NO(22) | 4) -#define MT8135_PIN_22_NLD5__FUNC_TESTA_OUT16 (MTK_PIN_NO(22) | 7) - -#define MT8135_PIN_23_NLD6__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) -#define MT8135_PIN_23_NLD6__FUNC_NLD6 (MTK_PIN_NO(23) | 1) -#define MT8135_PIN_23_NLD6__FUNC_EINT152 (MTK_PIN_NO(23) | 2) -#define MT8135_PIN_23_NLD6__FUNC_A_FUNC_DIN_7 (MTK_PIN_NO(23) | 3) -#define MT8135_PIN_23_NLD6__FUNC_CM2DAT_1X_6 (MTK_PIN_NO(23) | 4) -#define MT8135_PIN_23_NLD6__FUNC_TESTA_OUT17 (MTK_PIN_NO(23) | 7) - -#define MT8135_PIN_24_NLD7__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) -#define MT8135_PIN_24_NLD7__FUNC_NLD7 (MTK_PIN_NO(24) | 1) -#define MT8135_PIN_24_NLD7__FUNC_EINT153 (MTK_PIN_NO(24) | 2) -#define MT8135_PIN_24_NLD7__FUNC_A_FUNC_DIN_8 (MTK_PIN_NO(24) | 3) -#define MT8135_PIN_24_NLD7__FUNC_CM2DAT_1X_7 (MTK_PIN_NO(24) | 4) -#define MT8135_PIN_24_NLD7__FUNC_TESTA_OUT18 (MTK_PIN_NO(24) | 7) - -#define MT8135_PIN_25_NLD8__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) -#define MT8135_PIN_25_NLD8__FUNC_NLD8 (MTK_PIN_NO(25) | 1) -#define MT8135_PIN_25_NLD8__FUNC_EINT154 (MTK_PIN_NO(25) | 2) -#define MT8135_PIN_25_NLD8__FUNC_CM2DAT_1X_8 (MTK_PIN_NO(25) | 4) - -#define MT8135_PIN_26_NLD9__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) -#define MT8135_PIN_26_NLD9__FUNC_NLD9 (MTK_PIN_NO(26) | 1) -#define MT8135_PIN_26_NLD9__FUNC_EINT155 (MTK_PIN_NO(26) | 2) -#define MT8135_PIN_26_NLD9__FUNC_CM2DAT_1X_9 (MTK_PIN_NO(26) | 4) -#define MT8135_PIN_26_NLD9__FUNC_PWM1 (MTK_PIN_NO(26) | 5) - -#define MT8135_PIN_27_NLD10__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) -#define MT8135_PIN_27_NLD10__FUNC_NLD10 (MTK_PIN_NO(27) | 1) -#define MT8135_PIN_27_NLD10__FUNC_EINT156 (MTK_PIN_NO(27) | 2) -#define MT8135_PIN_27_NLD10__FUNC_CM2VSYNC_1X (MTK_PIN_NO(27) | 4) -#define MT8135_PIN_27_NLD10__FUNC_PWM2 (MTK_PIN_NO(27) | 5) - -#define MT8135_PIN_28_NLD11__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) -#define MT8135_PIN_28_NLD11__FUNC_NLD11 (MTK_PIN_NO(28) | 1) -#define MT8135_PIN_28_NLD11__FUNC_EINT157 (MTK_PIN_NO(28) | 2) -#define MT8135_PIN_28_NLD11__FUNC_CM2HSYNC_1X (MTK_PIN_NO(28) | 4) -#define MT8135_PIN_28_NLD11__FUNC_PWM3 (MTK_PIN_NO(28) | 5) - -#define MT8135_PIN_29_NLD12__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) -#define MT8135_PIN_29_NLD12__FUNC_NLD12 (MTK_PIN_NO(29) | 1) -#define MT8135_PIN_29_NLD12__FUNC_EINT158 (MTK_PIN_NO(29) | 2) -#define MT8135_PIN_29_NLD12__FUNC_I2SIN_CK (MTK_PIN_NO(29) | 3) -#define MT8135_PIN_29_NLD12__FUNC_DAC_CK (MTK_PIN_NO(29) | 4) -#define MT8135_PIN_29_NLD12__FUNC_PCM1_CK (MTK_PIN_NO(29) | 5) - -#define MT8135_PIN_30_NLD13__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) -#define MT8135_PIN_30_NLD13__FUNC_NLD13 (MTK_PIN_NO(30) | 1) -#define MT8135_PIN_30_NLD13__FUNC_EINT159 (MTK_PIN_NO(30) | 2) -#define MT8135_PIN_30_NLD13__FUNC_I2SIN_WS (MTK_PIN_NO(30) | 3) -#define MT8135_PIN_30_NLD13__FUNC_DAC_WS (MTK_PIN_NO(30) | 4) -#define MT8135_PIN_30_NLD13__FUNC_PCM1_WS (MTK_PIN_NO(30) | 5) - -#define MT8135_PIN_31_NLD14__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) -#define MT8135_PIN_31_NLD14__FUNC_NLD14 (MTK_PIN_NO(31) | 1) -#define MT8135_PIN_31_NLD14__FUNC_EINT160 (MTK_PIN_NO(31) | 2) -#define MT8135_PIN_31_NLD14__FUNC_I2SOUT_DAT (MTK_PIN_NO(31) | 3) -#define MT8135_PIN_31_NLD14__FUNC_DAC_DAT_OUT (MTK_PIN_NO(31) | 4) -#define MT8135_PIN_31_NLD14__FUNC_PCM1_DO (MTK_PIN_NO(31) | 5) - -#define MT8135_PIN_32_NLD15__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) -#define MT8135_PIN_32_NLD15__FUNC_NLD15 (MTK_PIN_NO(32) | 1) -#define MT8135_PIN_32_NLD15__FUNC_EINT161 (MTK_PIN_NO(32) | 2) -#define MT8135_PIN_32_NLD15__FUNC_DISP_PWM (MTK_PIN_NO(32) | 3) -#define MT8135_PIN_32_NLD15__FUNC_PWM4 (MTK_PIN_NO(32) | 4) -#define MT8135_PIN_32_NLD15__FUNC_PCM1_DI (MTK_PIN_NO(32) | 5) - -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(33) | 1) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_EINT50 (MTK_PIN_NO(33) | 2) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_I2SIN_DAT (MTK_PIN_NO(33) | 3) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_PCM1_DI (MTK_PIN_NO(33) | 5) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_SPI1_MI (MTK_PIN_NO(33) | 6) -#define MT8135_PIN_33_MSDC0_RSTB__FUNC_NLD10 (MTK_PIN_NO(33) | 7) - -#define MT8135_PIN_34_IDDIG__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) -#define MT8135_PIN_34_IDDIG__FUNC_IDDIG (MTK_PIN_NO(34) | 1) -#define MT8135_PIN_34_IDDIG__FUNC_EINT34 (MTK_PIN_NO(34) | 2) - -#define MT8135_PIN_35_SCL3__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) -#define MT8135_PIN_35_SCL3__FUNC_SCL3 (MTK_PIN_NO(35) | 1) -#define MT8135_PIN_35_SCL3__FUNC_EINT96 (MTK_PIN_NO(35) | 2) -#define MT8135_PIN_35_SCL3__FUNC_CLKM6 (MTK_PIN_NO(35) | 3) -#define MT8135_PIN_35_SCL3__FUNC_PWM6 (MTK_PIN_NO(35) | 4) - -#define MT8135_PIN_36_SDA3__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) -#define MT8135_PIN_36_SDA3__FUNC_SDA3 (MTK_PIN_NO(36) | 1) -#define MT8135_PIN_36_SDA3__FUNC_EINT97 (MTK_PIN_NO(36) | 2) - -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(37) | 1) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_ADC_CK (MTK_PIN_NO(37) | 2) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_HDMI_SDATA0 (MTK_PIN_NO(37) | 3) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_EINT19 (MTK_PIN_NO(37) | 4) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_USB_TEST_IO_6 (MTK_PIN_NO(37) | 5) -#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_TESTA_OUT19 (MTK_PIN_NO(37) | 7) - -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(38) | 1) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_ADC_WS (MTK_PIN_NO(38) | 2) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MISO (MTK_PIN_NO(38) | 3) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_EINT21 (MTK_PIN_NO(38) | 4) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_USB_TEST_IO_7 (MTK_PIN_NO(38) | 5) -#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_TESTA_OUT20 (MTK_PIN_NO(38) | 7) - -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MISO (MTK_PIN_NO(39) | 1) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_ADC_DAT_IN (MTK_PIN_NO(39) | 2) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(39) | 3) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_EINT20 (MTK_PIN_NO(39) | 4) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_USB_TEST_IO_8 (MTK_PIN_NO(39) | 5) -#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_TESTA_OUT21 (MTK_PIN_NO(39) | 7) - -#define MT8135_PIN_40_DAC_CLK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) -#define MT8135_PIN_40_DAC_CLK__FUNC_DAC_CK (MTK_PIN_NO(40) | 1) -#define MT8135_PIN_40_DAC_CLK__FUNC_EINT22 (MTK_PIN_NO(40) | 2) -#define MT8135_PIN_40_DAC_CLK__FUNC_HDMI_SDATA1 (MTK_PIN_NO(40) | 3) -#define MT8135_PIN_40_DAC_CLK__FUNC_USB_TEST_IO_9 (MTK_PIN_NO(40) | 5) -#define MT8135_PIN_40_DAC_CLK__FUNC_TESTA_OUT22 (MTK_PIN_NO(40) | 7) - -#define MT8135_PIN_41_DAC_WS__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) -#define MT8135_PIN_41_DAC_WS__FUNC_DAC_WS (MTK_PIN_NO(41) | 1) -#define MT8135_PIN_41_DAC_WS__FUNC_EINT24 (MTK_PIN_NO(41) | 2) -#define MT8135_PIN_41_DAC_WS__FUNC_HDMI_SDATA2 (MTK_PIN_NO(41) | 3) -#define MT8135_PIN_41_DAC_WS__FUNC_USB_TEST_IO_10 (MTK_PIN_NO(41) | 5) -#define MT8135_PIN_41_DAC_WS__FUNC_TESTA_OUT23 (MTK_PIN_NO(41) | 7) - -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(42) | 1) -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_EINT23 (MTK_PIN_NO(42) | 2) -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_HDMI_SDATA3 (MTK_PIN_NO(42) | 3) -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_USB_TEST_IO_11 (MTK_PIN_NO(42) | 5) -#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_TESTA_OUT24 (MTK_PIN_NO(42) | 7) - -#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) -#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(43) | 1) -#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_EINT29 (MTK_PIN_NO(43) | 2) - -#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) -#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(44) | 1) -#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_EINT28 (MTK_PIN_NO(44) | 2) - -#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) -#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(45) | 1) -#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_EINT27 (MTK_PIN_NO(45) | 2) - -#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) -#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(46) | 1) -#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_EINT26 (MTK_PIN_NO(46) | 2) - -#define MT8135_PIN_47_PWRAP_EVENT__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) -#define MT8135_PIN_47_PWRAP_EVENT__FUNC_PWRAP_EVENT_IN (MTK_PIN_NO(47) | 1) -#define MT8135_PIN_47_PWRAP_EVENT__FUNC_EINT25 (MTK_PIN_NO(47) | 2) -#define MT8135_PIN_47_PWRAP_EVENT__FUNC_TESTA_OUT2 (MTK_PIN_NO(47) | 7) - -#define MT8135_PIN_48_RTC32K_CK__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) -#define MT8135_PIN_48_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(48) | 1) - -#define MT8135_PIN_49_WATCHDOG__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) -#define MT8135_PIN_49_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(49) | 1) -#define MT8135_PIN_49_WATCHDOG__FUNC_EINT36 (MTK_PIN_NO(49) | 2) - -#define MT8135_PIN_50_SRCLKENA__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) -#define MT8135_PIN_50_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(50) | 1) -#define MT8135_PIN_50_SRCLKENA__FUNC_EINT38 (MTK_PIN_NO(50) | 2) - -#define MT8135_PIN_51_SRCVOLTEN__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) -#define MT8135_PIN_51_SRCVOLTEN__FUNC_SRCVOLTEN (MTK_PIN_NO(51) | 1) -#define MT8135_PIN_51_SRCVOLTEN__FUNC_EINT37 (MTK_PIN_NO(51) | 2) - -#define MT8135_PIN_52_EINT0__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) -#define MT8135_PIN_52_EINT0__FUNC_EINT0 (MTK_PIN_NO(52) | 1) -#define MT8135_PIN_52_EINT0__FUNC_PWM1 (MTK_PIN_NO(52) | 2) -#define MT8135_PIN_52_EINT0__FUNC_CLKM0 (MTK_PIN_NO(52) | 3) -#define MT8135_PIN_52_EINT0__FUNC_SPDIF_OUT (MTK_PIN_NO(52) | 4) -#define MT8135_PIN_52_EINT0__FUNC_USB_TEST_IO_12 (MTK_PIN_NO(52) | 5) -#define MT8135_PIN_52_EINT0__FUNC_USB_SCL (MTK_PIN_NO(52) | 7) - -#define MT8135_PIN_53_URXD2__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) -#define MT8135_PIN_53_URXD2__FUNC_URXD2 (MTK_PIN_NO(53) | 1) -#define MT8135_PIN_53_URXD2__FUNC_EINT83 (MTK_PIN_NO(53) | 2) -#define MT8135_PIN_53_URXD2__FUNC_HDMI_LRCK (MTK_PIN_NO(53) | 4) -#define MT8135_PIN_53_URXD2__FUNC_CLKM3 (MTK_PIN_NO(53) | 5) -#define MT8135_PIN_53_URXD2__FUNC_UTXD2 (MTK_PIN_NO(53) | 7) - -#define MT8135_PIN_54_UTXD2__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) -#define MT8135_PIN_54_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(54) | 1) -#define MT8135_PIN_54_UTXD2__FUNC_EINT82 (MTK_PIN_NO(54) | 2) -#define MT8135_PIN_54_UTXD2__FUNC_HDMI_BCK_OUT (MTK_PIN_NO(54) | 4) -#define MT8135_PIN_54_UTXD2__FUNC_CLKM2 (MTK_PIN_NO(54) | 5) -#define MT8135_PIN_54_UTXD2__FUNC_URXD2 (MTK_PIN_NO(54) | 7) - -#define MT8135_PIN_55_UCTS2__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) -#define MT8135_PIN_55_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(55) | 1) -#define MT8135_PIN_55_UCTS2__FUNC_EINT84 (MTK_PIN_NO(55) | 2) -#define MT8135_PIN_55_UCTS2__FUNC_PWM1 (MTK_PIN_NO(55) | 5) -#define MT8135_PIN_55_UCTS2__FUNC_URTS2 (MTK_PIN_NO(55) | 7) - -#define MT8135_PIN_56_URTS2__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) -#define MT8135_PIN_56_URTS2__FUNC_URTS2 (MTK_PIN_NO(56) | 1) -#define MT8135_PIN_56_URTS2__FUNC_EINT85 (MTK_PIN_NO(56) | 2) -#define MT8135_PIN_56_URTS2__FUNC_PWM2 (MTK_PIN_NO(56) | 5) -#define MT8135_PIN_56_URTS2__FUNC_UCTS2 (MTK_PIN_NO(56) | 7) - -#define MT8135_PIN_57_JTCK__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) -#define MT8135_PIN_57_JTCK__FUNC_JTCK (MTK_PIN_NO(57) | 1) -#define MT8135_PIN_57_JTCK__FUNC_EINT188 (MTK_PIN_NO(57) | 2) -#define MT8135_PIN_57_JTCK__FUNC_DSP1_ICK (MTK_PIN_NO(57) | 3) - -#define MT8135_PIN_58_JTDO__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) -#define MT8135_PIN_58_JTDO__FUNC_JTDO (MTK_PIN_NO(58) | 1) -#define MT8135_PIN_58_JTDO__FUNC_EINT190 (MTK_PIN_NO(58) | 2) -#define MT8135_PIN_58_JTDO__FUNC_DSP2_IMS (MTK_PIN_NO(58) | 3) - -#define MT8135_PIN_59_JTRST_B__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) -#define MT8135_PIN_59_JTRST_B__FUNC_JTRST_B (MTK_PIN_NO(59) | 1) -#define MT8135_PIN_59_JTRST_B__FUNC_EINT0 (MTK_PIN_NO(59) | 2) -#define MT8135_PIN_59_JTRST_B__FUNC_DSP2_ICK (MTK_PIN_NO(59) | 3) - -#define MT8135_PIN_60_JTDI__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) -#define MT8135_PIN_60_JTDI__FUNC_JTDI (MTK_PIN_NO(60) | 1) -#define MT8135_PIN_60_JTDI__FUNC_EINT189 (MTK_PIN_NO(60) | 2) -#define MT8135_PIN_60_JTDI__FUNC_DSP1_IMS (MTK_PIN_NO(60) | 3) - -#define MT8135_PIN_61_JRTCK__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) -#define MT8135_PIN_61_JRTCK__FUNC_JRTCK (MTK_PIN_NO(61) | 1) -#define MT8135_PIN_61_JRTCK__FUNC_EINT187 (MTK_PIN_NO(61) | 2) -#define MT8135_PIN_61_JRTCK__FUNC_DSP1_ID (MTK_PIN_NO(61) | 3) - -#define MT8135_PIN_62_JTMS__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) -#define MT8135_PIN_62_JTMS__FUNC_JTMS (MTK_PIN_NO(62) | 1) -#define MT8135_PIN_62_JTMS__FUNC_EINT191 (MTK_PIN_NO(62) | 2) -#define MT8135_PIN_62_JTMS__FUNC_DSP2_ID (MTK_PIN_NO(62) | 3) - -#define MT8135_PIN_63_MSDC1_INSI__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) -#define MT8135_PIN_63_MSDC1_INSI__FUNC_MSDC1_INSI (MTK_PIN_NO(63) | 1) -#define MT8135_PIN_63_MSDC1_INSI__FUNC_SCL5 (MTK_PIN_NO(63) | 3) -#define MT8135_PIN_63_MSDC1_INSI__FUNC_PWM6 (MTK_PIN_NO(63) | 4) -#define MT8135_PIN_63_MSDC1_INSI__FUNC_CLKM5 (MTK_PIN_NO(63) | 5) -#define MT8135_PIN_63_MSDC1_INSI__FUNC_TESTB_OUT6 (MTK_PIN_NO(63) | 7) - -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_MSDC1_SDWPI (MTK_PIN_NO(64) | 1) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_EINT58 (MTK_PIN_NO(64) | 2) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_SDA5 (MTK_PIN_NO(64) | 3) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_PWM7 (MTK_PIN_NO(64) | 4) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_CLKM6 (MTK_PIN_NO(64) | 5) -#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_TESTB_OUT7 (MTK_PIN_NO(64) | 7) - -#define MT8135_PIN_65_MSDC2_INSI__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) -#define MT8135_PIN_65_MSDC2_INSI__FUNC_MSDC2_INSI (MTK_PIN_NO(65) | 1) -#define MT8135_PIN_65_MSDC2_INSI__FUNC_USB_TEST_IO_27 (MTK_PIN_NO(65) | 5) -#define MT8135_PIN_65_MSDC2_INSI__FUNC_TESTA_OUT3 (MTK_PIN_NO(65) | 7) - -#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) -#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_MSDC2_SDWPI (MTK_PIN_NO(66) | 1) -#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_EINT66 (MTK_PIN_NO(66) | 2) -#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_USB_TEST_IO_28 (MTK_PIN_NO(66) | 5) - -#define MT8135_PIN_67_URXD4__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) -#define MT8135_PIN_67_URXD4__FUNC_URXD4 (MTK_PIN_NO(67) | 1) -#define MT8135_PIN_67_URXD4__FUNC_EINT89 (MTK_PIN_NO(67) | 2) -#define MT8135_PIN_67_URXD4__FUNC_URXD1 (MTK_PIN_NO(67) | 3) -#define MT8135_PIN_67_URXD4__FUNC_UTXD4 (MTK_PIN_NO(67) | 6) -#define MT8135_PIN_67_URXD4__FUNC_TESTB_OUT10 (MTK_PIN_NO(67) | 7) - -#define MT8135_PIN_68_UTXD4__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) -#define MT8135_PIN_68_UTXD4__FUNC_UTXD4 (MTK_PIN_NO(68) | 1) -#define MT8135_PIN_68_UTXD4__FUNC_EINT88 (MTK_PIN_NO(68) | 2) -#define MT8135_PIN_68_UTXD4__FUNC_UTXD1 (MTK_PIN_NO(68) | 3) -#define MT8135_PIN_68_UTXD4__FUNC_URXD4 (MTK_PIN_NO(68) | 6) -#define MT8135_PIN_68_UTXD4__FUNC_TESTB_OUT11 (MTK_PIN_NO(68) | 7) - -#define MT8135_PIN_69_URXD1__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) -#define MT8135_PIN_69_URXD1__FUNC_URXD1 (MTK_PIN_NO(69) | 1) -#define MT8135_PIN_69_URXD1__FUNC_EINT79 (MTK_PIN_NO(69) | 2) -#define MT8135_PIN_69_URXD1__FUNC_URXD4 (MTK_PIN_NO(69) | 3) -#define MT8135_PIN_69_URXD1__FUNC_UTXD1 (MTK_PIN_NO(69) | 6) -#define MT8135_PIN_69_URXD1__FUNC_TESTB_OUT24 (MTK_PIN_NO(69) | 7) - -#define MT8135_PIN_70_UTXD1__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) -#define MT8135_PIN_70_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(70) | 1) -#define MT8135_PIN_70_UTXD1__FUNC_EINT78 (MTK_PIN_NO(70) | 2) -#define MT8135_PIN_70_UTXD1__FUNC_UTXD4 (MTK_PIN_NO(70) | 3) -#define MT8135_PIN_70_UTXD1__FUNC_URXD1 (MTK_PIN_NO(70) | 6) -#define MT8135_PIN_70_UTXD1__FUNC_TESTB_OUT25 (MTK_PIN_NO(70) | 7) - -#define MT8135_PIN_71_UCTS1__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) -#define MT8135_PIN_71_UCTS1__FUNC_UCTS1 (MTK_PIN_NO(71) | 1) -#define MT8135_PIN_71_UCTS1__FUNC_EINT80 (MTK_PIN_NO(71) | 2) -#define MT8135_PIN_71_UCTS1__FUNC_CLKM0 (MTK_PIN_NO(71) | 5) -#define MT8135_PIN_71_UCTS1__FUNC_URTS1 (MTK_PIN_NO(71) | 6) -#define MT8135_PIN_71_UCTS1__FUNC_TESTB_OUT31 (MTK_PIN_NO(71) | 7) - -#define MT8135_PIN_72_URTS1__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) -#define MT8135_PIN_72_URTS1__FUNC_URTS1 (MTK_PIN_NO(72) | 1) -#define MT8135_PIN_72_URTS1__FUNC_EINT81 (MTK_PIN_NO(72) | 2) -#define MT8135_PIN_72_URTS1__FUNC_CLKM1 (MTK_PIN_NO(72) | 5) -#define MT8135_PIN_72_URTS1__FUNC_UCTS1 (MTK_PIN_NO(72) | 6) -#define MT8135_PIN_72_URTS1__FUNC_TESTB_OUT21 (MTK_PIN_NO(72) | 7) - -#define MT8135_PIN_73_PWM1__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) -#define MT8135_PIN_73_PWM1__FUNC_PWM1 (MTK_PIN_NO(73) | 1) -#define MT8135_PIN_73_PWM1__FUNC_EINT73 (MTK_PIN_NO(73) | 2) -#define MT8135_PIN_73_PWM1__FUNC_USB_DRVVBUS (MTK_PIN_NO(73) | 5) -#define MT8135_PIN_73_PWM1__FUNC_DISP_PWM (MTK_PIN_NO(73) | 6) -#define MT8135_PIN_73_PWM1__FUNC_TESTB_OUT8 (MTK_PIN_NO(73) | 7) - -#define MT8135_PIN_74_PWM2__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) -#define MT8135_PIN_74_PWM2__FUNC_PWM2 (MTK_PIN_NO(74) | 1) -#define MT8135_PIN_74_PWM2__FUNC_EINT74 (MTK_PIN_NO(74) | 2) -#define MT8135_PIN_74_PWM2__FUNC_DPI33_CK (MTK_PIN_NO(74) | 3) -#define MT8135_PIN_74_PWM2__FUNC_PWM5 (MTK_PIN_NO(74) | 4) -#define MT8135_PIN_74_PWM2__FUNC_URXD2 (MTK_PIN_NO(74) | 5) -#define MT8135_PIN_74_PWM2__FUNC_DISP_PWM (MTK_PIN_NO(74) | 6) -#define MT8135_PIN_74_PWM2__FUNC_TESTB_OUT9 (MTK_PIN_NO(74) | 7) - -#define MT8135_PIN_75_PWM3__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) -#define MT8135_PIN_75_PWM3__FUNC_PWM3 (MTK_PIN_NO(75) | 1) -#define MT8135_PIN_75_PWM3__FUNC_EINT75 (MTK_PIN_NO(75) | 2) -#define MT8135_PIN_75_PWM3__FUNC_DPI33_D0 (MTK_PIN_NO(75) | 3) -#define MT8135_PIN_75_PWM3__FUNC_PWM6 (MTK_PIN_NO(75) | 4) -#define MT8135_PIN_75_PWM3__FUNC_UTXD2 (MTK_PIN_NO(75) | 5) -#define MT8135_PIN_75_PWM3__FUNC_DISP_PWM (MTK_PIN_NO(75) | 6) -#define MT8135_PIN_75_PWM3__FUNC_TESTB_OUT12 (MTK_PIN_NO(75) | 7) - -#define MT8135_PIN_76_PWM4__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) -#define MT8135_PIN_76_PWM4__FUNC_PWM4 (MTK_PIN_NO(76) | 1) -#define MT8135_PIN_76_PWM4__FUNC_EINT76 (MTK_PIN_NO(76) | 2) -#define MT8135_PIN_76_PWM4__FUNC_DPI33_D1 (MTK_PIN_NO(76) | 3) -#define MT8135_PIN_76_PWM4__FUNC_PWM7 (MTK_PIN_NO(76) | 4) -#define MT8135_PIN_76_PWM4__FUNC_DISP_PWM (MTK_PIN_NO(76) | 6) -#define MT8135_PIN_76_PWM4__FUNC_TESTB_OUT13 (MTK_PIN_NO(76) | 7) - -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(77) | 1) -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_EINT63 (MTK_PIN_NO(77) | 2) -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DSP2_IMS (MTK_PIN_NO(77) | 4) -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DPI33_D6 (MTK_PIN_NO(77) | 6) -#define MT8135_PIN_77_MSDC2_DAT2__FUNC_TESTA_OUT25 (MTK_PIN_NO(77) | 7) - -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(78) | 1) -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_EINT64 (MTK_PIN_NO(78) | 2) -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DSP2_ID (MTK_PIN_NO(78) | 4) -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DPI33_D7 (MTK_PIN_NO(78) | 6) -#define MT8135_PIN_78_MSDC2_DAT3__FUNC_TESTA_OUT26 (MTK_PIN_NO(78) | 7) - -#define MT8135_PIN_79_MSDC2_CMD__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(79) | 1) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_EINT60 (MTK_PIN_NO(79) | 2) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_DSP1_IMS (MTK_PIN_NO(79) | 4) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_PCM1_WS (MTK_PIN_NO(79) | 5) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_DPI33_D3 (MTK_PIN_NO(79) | 6) -#define MT8135_PIN_79_MSDC2_CMD__FUNC_TESTA_OUT0 (MTK_PIN_NO(79) | 7) - -#define MT8135_PIN_80_MSDC2_CLK__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(80) | 1) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_EINT59 (MTK_PIN_NO(80) | 2) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_DSP1_ICK (MTK_PIN_NO(80) | 4) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_PCM1_CK (MTK_PIN_NO(80) | 5) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_DPI33_D2 (MTK_PIN_NO(80) | 6) -#define MT8135_PIN_80_MSDC2_CLK__FUNC_TESTA_OUT1 (MTK_PIN_NO(80) | 7) - -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(81) | 1) -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_EINT62 (MTK_PIN_NO(81) | 2) -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DSP2_ICK (MTK_PIN_NO(81) | 4) -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_PCM1_DO (MTK_PIN_NO(81) | 5) -#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DPI33_D5 (MTK_PIN_NO(81) | 6) - -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(82) | 1) -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_EINT61 (MTK_PIN_NO(82) | 2) -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DSP1_ID (MTK_PIN_NO(82) | 4) -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_PCM1_DI (MTK_PIN_NO(82) | 5) -#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DPI33_D4 (MTK_PIN_NO(82) | 6) - -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(83) | 1) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_EINT53 (MTK_PIN_NO(83) | 2) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_SCL1 (MTK_PIN_NO(83) | 3) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_PWM2 (MTK_PIN_NO(83) | 4) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_CLKM1 (MTK_PIN_NO(83) | 5) -#define MT8135_PIN_83_MSDC1_DAT0__FUNC_TESTB_OUT2 (MTK_PIN_NO(83) | 7) - -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(84) | 1) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_EINT54 (MTK_PIN_NO(84) | 2) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_SDA1 (MTK_PIN_NO(84) | 3) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_PWM3 (MTK_PIN_NO(84) | 4) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_CLKM2 (MTK_PIN_NO(84) | 5) -#define MT8135_PIN_84_MSDC1_DAT1__FUNC_TESTB_OUT3 (MTK_PIN_NO(84) | 7) - -#define MT8135_PIN_85_MSDC1_CMD__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(85) | 1) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_EINT52 (MTK_PIN_NO(85) | 2) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_SDA0 (MTK_PIN_NO(85) | 3) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_PWM1 (MTK_PIN_NO(85) | 4) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_CLKM0 (MTK_PIN_NO(85) | 5) -#define MT8135_PIN_85_MSDC1_CMD__FUNC_TESTB_OUT1 (MTK_PIN_NO(85) | 7) - -#define MT8135_PIN_86_MSDC1_CLK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) -#define MT8135_PIN_86_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(86) | 1) -#define MT8135_PIN_86_MSDC1_CLK__FUNC_EINT51 (MTK_PIN_NO(86) | 2) -#define MT8135_PIN_86_MSDC1_CLK__FUNC_SCL0 (MTK_PIN_NO(86) | 3) -#define MT8135_PIN_86_MSDC1_CLK__FUNC_DISP_PWM (MTK_PIN_NO(86) | 4) -#define MT8135_PIN_86_MSDC1_CLK__FUNC_TESTB_OUT0 (MTK_PIN_NO(86) | 7) - -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(87) | 1) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_EINT55 (MTK_PIN_NO(87) | 2) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_SCL4 (MTK_PIN_NO(87) | 3) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_PWM4 (MTK_PIN_NO(87) | 4) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_CLKM3 (MTK_PIN_NO(87) | 5) -#define MT8135_PIN_87_MSDC1_DAT2__FUNC_TESTB_OUT4 (MTK_PIN_NO(87) | 7) - -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(88) | 1) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_EINT56 (MTK_PIN_NO(88) | 2) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_SDA4 (MTK_PIN_NO(88) | 3) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_PWM5 (MTK_PIN_NO(88) | 4) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_CLKM4 (MTK_PIN_NO(88) | 5) -#define MT8135_PIN_88_MSDC1_DAT3__FUNC_TESTB_OUT5 (MTK_PIN_NO(88) | 7) - -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_MSDC4_DAT0 (MTK_PIN_NO(89) | 1) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EINT133 (MTK_PIN_NO(89) | 2) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(89) | 4) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_USB_DRVVBUS (MTK_PIN_NO(89) | 5) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_A_FUNC_DIN_9 (MTK_PIN_NO(89) | 6) -#define MT8135_PIN_89_MSDC4_DAT0__FUNC_LPTE (MTK_PIN_NO(89) | 7) - -#define MT8135_PIN_90_MSDC4_DAT1__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) -#define MT8135_PIN_90_MSDC4_DAT1__FUNC_MSDC4_DAT1 (MTK_PIN_NO(90) | 1) -#define MT8135_PIN_90_MSDC4_DAT1__FUNC_EINT134 (MTK_PIN_NO(90) | 2) -#define MT8135_PIN_90_MSDC4_DAT1__FUNC_A_FUNC_DIN_10 (MTK_PIN_NO(90) | 6) -#define MT8135_PIN_90_MSDC4_DAT1__FUNC_LRSTB_1X (MTK_PIN_NO(90) | 7) - -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_MSDC4_DAT5 (MTK_PIN_NO(91) | 1) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_EINT136 (MTK_PIN_NO(91) | 2) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_I2SIN_WS (MTK_PIN_NO(91) | 3) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_DAC_WS (MTK_PIN_NO(91) | 4) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_PCM1_WS (MTK_PIN_NO(91) | 5) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_A_FUNC_DIN_11 (MTK_PIN_NO(91) | 6) -#define MT8135_PIN_91_MSDC4_DAT5__FUNC_SPI1_CSN (MTK_PIN_NO(91) | 7) - -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_MSDC4_DAT6 (MTK_PIN_NO(92) | 1) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_EINT137 (MTK_PIN_NO(92) | 2) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_I2SOUT_DAT (MTK_PIN_NO(92) | 3) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_DAC_DAT_OUT (MTK_PIN_NO(92) | 4) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_PCM1_DO (MTK_PIN_NO(92) | 5) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_A_FUNC_DIN_12 (MTK_PIN_NO(92) | 6) -#define MT8135_PIN_92_MSDC4_DAT6__FUNC_SPI1_MO (MTK_PIN_NO(92) | 7) - -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_MSDC4_DAT7 (MTK_PIN_NO(93) | 1) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_EINT138 (MTK_PIN_NO(93) | 2) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_I2SIN_DAT (MTK_PIN_NO(93) | 3) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_PCM1_DI (MTK_PIN_NO(93) | 5) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_A_FUNC_DIN_13 (MTK_PIN_NO(93) | 6) -#define MT8135_PIN_93_MSDC4_DAT7__FUNC_SPI1_MI (MTK_PIN_NO(93) | 7) - -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_MSDC4_DAT4 (MTK_PIN_NO(94) | 1) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_EINT135 (MTK_PIN_NO(94) | 2) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_I2SIN_CK (MTK_PIN_NO(94) | 3) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_DAC_CK (MTK_PIN_NO(94) | 4) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_PCM1_CK (MTK_PIN_NO(94) | 5) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_A_FUNC_DIN_14 (MTK_PIN_NO(94) | 6) -#define MT8135_PIN_94_MSDC4_DAT4__FUNC_SPI1_CLK (MTK_PIN_NO(94) | 7) - -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_MSDC4_DAT2 (MTK_PIN_NO(95) | 1) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_EINT131 (MTK_PIN_NO(95) | 2) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_I2SIN_WS (MTK_PIN_NO(95) | 3) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_CM2PDN_2X (MTK_PIN_NO(95) | 4) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_DAC_WS (MTK_PIN_NO(95) | 5) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_PCM1_WS (MTK_PIN_NO(95) | 6) -#define MT8135_PIN_95_MSDC4_DAT2__FUNC_LSCE0B_1X (MTK_PIN_NO(95) | 7) - -#define MT8135_PIN_96_MSDC4_CLK__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_MSDC4_CLK (MTK_PIN_NO(96) | 1) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_EINT129 (MTK_PIN_NO(96) | 2) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_DPI1_CK_2X (MTK_PIN_NO(96) | 3) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_CM2PCLK_2X (MTK_PIN_NO(96) | 4) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_PWM4 (MTK_PIN_NO(96) | 5) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_PCM1_DI (MTK_PIN_NO(96) | 6) -#define MT8135_PIN_96_MSDC4_CLK__FUNC_LSCK_1X (MTK_PIN_NO(96) | 7) - -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_MSDC4_DAT3 (MTK_PIN_NO(97) | 1) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_EINT132 (MTK_PIN_NO(97) | 2) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_I2SOUT_DAT (MTK_PIN_NO(97) | 3) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_CM2RST_2X (MTK_PIN_NO(97) | 4) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_DAC_DAT_OUT (MTK_PIN_NO(97) | 5) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_PCM1_DO (MTK_PIN_NO(97) | 6) -#define MT8135_PIN_97_MSDC4_DAT3__FUNC_LSCE1B_1X (MTK_PIN_NO(97) | 7) - -#define MT8135_PIN_98_MSDC4_CMD__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) -#define MT8135_PIN_98_MSDC4_CMD__FUNC_MSDC4_CMD (MTK_PIN_NO(98) | 1) -#define MT8135_PIN_98_MSDC4_CMD__FUNC_EINT128 (MTK_PIN_NO(98) | 2) -#define MT8135_PIN_98_MSDC4_CMD__FUNC_DPI1_DE_2X (MTK_PIN_NO(98) | 3) -#define MT8135_PIN_98_MSDC4_CMD__FUNC_PWM3 (MTK_PIN_NO(98) | 5) -#define MT8135_PIN_98_MSDC4_CMD__FUNC_LSDA_1X (MTK_PIN_NO(98) | 7) - -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_MSDC4_RSTB (MTK_PIN_NO(99) | 1) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_EINT130 (MTK_PIN_NO(99) | 2) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_I2SIN_CK (MTK_PIN_NO(99) | 3) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_CM2MCLK_2X (MTK_PIN_NO(99) | 4) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_DAC_CK (MTK_PIN_NO(99) | 5) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_PCM1_CK (MTK_PIN_NO(99) | 6) -#define MT8135_PIN_99_MSDC4_RSTB__FUNC_LSA0_1X (MTK_PIN_NO(99) | 7) - -#define MT8135_PIN_100_SDA0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) -#define MT8135_PIN_100_SDA0__FUNC_SDA0 (MTK_PIN_NO(100) | 1) -#define MT8135_PIN_100_SDA0__FUNC_EINT91 (MTK_PIN_NO(100) | 2) -#define MT8135_PIN_100_SDA0__FUNC_CLKM1 (MTK_PIN_NO(100) | 3) -#define MT8135_PIN_100_SDA0__FUNC_PWM1 (MTK_PIN_NO(100) | 4) -#define MT8135_PIN_100_SDA0__FUNC_A_FUNC_DIN_15 (MTK_PIN_NO(100) | 7) - -#define MT8135_PIN_101_SCL0__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) -#define MT8135_PIN_101_SCL0__FUNC_SCL0 (MTK_PIN_NO(101) | 1) -#define MT8135_PIN_101_SCL0__FUNC_EINT90 (MTK_PIN_NO(101) | 2) -#define MT8135_PIN_101_SCL0__FUNC_CLKM0 (MTK_PIN_NO(101) | 3) -#define MT8135_PIN_101_SCL0__FUNC_DISP_PWM (MTK_PIN_NO(101) | 4) -#define MT8135_PIN_101_SCL0__FUNC_A_FUNC_DIN_16 (MTK_PIN_NO(101) | 7) - -#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) -#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_EINT10 (MTK_PIN_NO(102) | 1) -#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_USB_TEST_IO_16 (MTK_PIN_NO(102) | 5) -#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_TESTB_OUT16 (MTK_PIN_NO(102) | 6) -#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_A_FUNC_DIN_17 (MTK_PIN_NO(102) | 7) - -#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) -#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_EINT11 (MTK_PIN_NO(103) | 1) -#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_USB_TEST_IO_17 (MTK_PIN_NO(103) | 5) -#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_TESTB_OUT17 (MTK_PIN_NO(103) | 6) -#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_A_FUNC_DIN_18 (MTK_PIN_NO(103) | 7) - -#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) -#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_EINT16 (MTK_PIN_NO(104) | 1) -#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_USB_TEST_IO_18 (MTK_PIN_NO(104) | 5) -#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_TESTB_OUT18 (MTK_PIN_NO(104) | 6) -#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_A_FUNC_DIN_19 (MTK_PIN_NO(104) | 7) - -#define MT8135_PIN_105_I2S_CLK__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) -#define MT8135_PIN_105_I2S_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(105) | 1) -#define MT8135_PIN_105_I2S_CLK__FUNC_EINT10 (MTK_PIN_NO(105) | 2) -#define MT8135_PIN_105_I2S_CLK__FUNC_DAC_CK (MTK_PIN_NO(105) | 3) -#define MT8135_PIN_105_I2S_CLK__FUNC_PCM1_CK (MTK_PIN_NO(105) | 4) -#define MT8135_PIN_105_I2S_CLK__FUNC_USB_TEST_IO_19 (MTK_PIN_NO(105) | 5) -#define MT8135_PIN_105_I2S_CLK__FUNC_TESTB_OUT19 (MTK_PIN_NO(105) | 6) -#define MT8135_PIN_105_I2S_CLK__FUNC_A_FUNC_DIN_20 (MTK_PIN_NO(105) | 7) - -#define MT8135_PIN_106_I2S_WS__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) -#define MT8135_PIN_106_I2S_WS__FUNC_I2SIN_WS (MTK_PIN_NO(106) | 1) -#define MT8135_PIN_106_I2S_WS__FUNC_EINT13 (MTK_PIN_NO(106) | 2) -#define MT8135_PIN_106_I2S_WS__FUNC_DAC_WS (MTK_PIN_NO(106) | 3) -#define MT8135_PIN_106_I2S_WS__FUNC_PCM1_WS (MTK_PIN_NO(106) | 4) -#define MT8135_PIN_106_I2S_WS__FUNC_USB_TEST_IO_20 (MTK_PIN_NO(106) | 5) -#define MT8135_PIN_106_I2S_WS__FUNC_TESTB_OUT20 (MTK_PIN_NO(106) | 6) -#define MT8135_PIN_106_I2S_WS__FUNC_A_FUNC_DIN_21 (MTK_PIN_NO(106) | 7) - -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_I2SIN_DAT (MTK_PIN_NO(107) | 1) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_EINT11 (MTK_PIN_NO(107) | 2) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_PCM1_DI (MTK_PIN_NO(107) | 4) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_USB_TEST_IO_21 (MTK_PIN_NO(107) | 5) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_TESTB_OUT22 (MTK_PIN_NO(107) | 6) -#define MT8135_PIN_107_I2S_DATA_IN__FUNC_A_FUNC_DIN_22 (MTK_PIN_NO(107) | 7) - -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_I2SOUT_DAT (MTK_PIN_NO(108) | 1) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_EINT12 (MTK_PIN_NO(108) | 2) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(108) | 3) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_PCM1_DO (MTK_PIN_NO(108) | 4) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_USB_TEST_IO_22 (MTK_PIN_NO(108) | 5) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_TESTB_OUT23 (MTK_PIN_NO(108) | 6) -#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_A_FUNC_DIN_23 (MTK_PIN_NO(108) | 7) - -#define MT8135_PIN_109_EINT5__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) -#define MT8135_PIN_109_EINT5__FUNC_EINT5 (MTK_PIN_NO(109) | 1) -#define MT8135_PIN_109_EINT5__FUNC_PWM5 (MTK_PIN_NO(109) | 2) -#define MT8135_PIN_109_EINT5__FUNC_CLKM3 (MTK_PIN_NO(109) | 3) -#define MT8135_PIN_109_EINT5__FUNC_GPU_JTRSTB (MTK_PIN_NO(109) | 4) -#define MT8135_PIN_109_EINT5__FUNC_USB_TEST_IO_23 (MTK_PIN_NO(109) | 5) -#define MT8135_PIN_109_EINT5__FUNC_TESTB_OUT26 (MTK_PIN_NO(109) | 6) -#define MT8135_PIN_109_EINT5__FUNC_A_FUNC_DIN_24 (MTK_PIN_NO(109) | 7) - -#define MT8135_PIN_110_EINT6__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) -#define MT8135_PIN_110_EINT6__FUNC_EINT6 (MTK_PIN_NO(110) | 1) -#define MT8135_PIN_110_EINT6__FUNC_PWM6 (MTK_PIN_NO(110) | 2) -#define MT8135_PIN_110_EINT6__FUNC_CLKM4 (MTK_PIN_NO(110) | 3) -#define MT8135_PIN_110_EINT6__FUNC_GPU_JTMS (MTK_PIN_NO(110) | 4) -#define MT8135_PIN_110_EINT6__FUNC_USB_TEST_IO_24 (MTK_PIN_NO(110) | 5) -#define MT8135_PIN_110_EINT6__FUNC_TESTB_OUT27 (MTK_PIN_NO(110) | 6) -#define MT8135_PIN_110_EINT6__FUNC_A_FUNC_DIN_25 (MTK_PIN_NO(110) | 7) - -#define MT8135_PIN_111_EINT7__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) -#define MT8135_PIN_111_EINT7__FUNC_EINT7 (MTK_PIN_NO(111) | 1) -#define MT8135_PIN_111_EINT7__FUNC_PWM7 (MTK_PIN_NO(111) | 2) -#define MT8135_PIN_111_EINT7__FUNC_CLKM5 (MTK_PIN_NO(111) | 3) -#define MT8135_PIN_111_EINT7__FUNC_GPU_JTDO (MTK_PIN_NO(111) | 4) -#define MT8135_PIN_111_EINT7__FUNC_USB_TEST_IO_25 (MTK_PIN_NO(111) | 5) -#define MT8135_PIN_111_EINT7__FUNC_TESTB_OUT28 (MTK_PIN_NO(111) | 6) -#define MT8135_PIN_111_EINT7__FUNC_A_FUNC_DIN_26 (MTK_PIN_NO(111) | 7) - -#define MT8135_PIN_112_EINT8__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) -#define MT8135_PIN_112_EINT8__FUNC_EINT8 (MTK_PIN_NO(112) | 1) -#define MT8135_PIN_112_EINT8__FUNC_DISP_PWM (MTK_PIN_NO(112) | 2) -#define MT8135_PIN_112_EINT8__FUNC_CLKM6 (MTK_PIN_NO(112) | 3) -#define MT8135_PIN_112_EINT8__FUNC_GPU_JTDI (MTK_PIN_NO(112) | 4) -#define MT8135_PIN_112_EINT8__FUNC_USB_TEST_IO_26 (MTK_PIN_NO(112) | 5) -#define MT8135_PIN_112_EINT8__FUNC_TESTB_OUT29 (MTK_PIN_NO(112) | 6) -#define MT8135_PIN_112_EINT8__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(112) | 7) - -#define MT8135_PIN_113_EINT9__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) -#define MT8135_PIN_113_EINT9__FUNC_EINT9 (MTK_PIN_NO(113) | 1) -#define MT8135_PIN_113_EINT9__FUNC_GPU_JTCK (MTK_PIN_NO(113) | 4) -#define MT8135_PIN_113_EINT9__FUNC_USB_DRVVBUS (MTK_PIN_NO(113) | 5) -#define MT8135_PIN_113_EINT9__FUNC_TESTB_OUT30 (MTK_PIN_NO(113) | 6) -#define MT8135_PIN_113_EINT9__FUNC_A_FUNC_DIN_27 (MTK_PIN_NO(113) | 7) - -#define MT8135_PIN_114_LPCE1B__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) -#define MT8135_PIN_114_LPCE1B__FUNC_LPCE1B (MTK_PIN_NO(114) | 1) -#define MT8135_PIN_114_LPCE1B__FUNC_EINT127 (MTK_PIN_NO(114) | 2) -#define MT8135_PIN_114_LPCE1B__FUNC_PWM2 (MTK_PIN_NO(114) | 5) -#define MT8135_PIN_114_LPCE1B__FUNC_TESTB_OUT14 (MTK_PIN_NO(114) | 6) -#define MT8135_PIN_114_LPCE1B__FUNC_A_FUNC_DIN_28 (MTK_PIN_NO(114) | 7) - -#define MT8135_PIN_115_LPCE0B__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) -#define MT8135_PIN_115_LPCE0B__FUNC_LPCE0B (MTK_PIN_NO(115) | 1) -#define MT8135_PIN_115_LPCE0B__FUNC_EINT126 (MTK_PIN_NO(115) | 2) -#define MT8135_PIN_115_LPCE0B__FUNC_PWM1 (MTK_PIN_NO(115) | 5) -#define MT8135_PIN_115_LPCE0B__FUNC_TESTB_OUT15 (MTK_PIN_NO(115) | 6) -#define MT8135_PIN_115_LPCE0B__FUNC_A_FUNC_DIN_29 (MTK_PIN_NO(115) | 7) - -#define MT8135_PIN_116_DISP_PWM__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) -#define MT8135_PIN_116_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(116) | 1) -#define MT8135_PIN_116_DISP_PWM__FUNC_EINT77 (MTK_PIN_NO(116) | 2) -#define MT8135_PIN_116_DISP_PWM__FUNC_LSDI (MTK_PIN_NO(116) | 3) -#define MT8135_PIN_116_DISP_PWM__FUNC_PWM1 (MTK_PIN_NO(116) | 4) -#define MT8135_PIN_116_DISP_PWM__FUNC_PWM2 (MTK_PIN_NO(116) | 5) -#define MT8135_PIN_116_DISP_PWM__FUNC_PWM3 (MTK_PIN_NO(116) | 7) - -#define MT8135_PIN_117_EINT1__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) -#define MT8135_PIN_117_EINT1__FUNC_EINT1 (MTK_PIN_NO(117) | 1) -#define MT8135_PIN_117_EINT1__FUNC_PWM2 (MTK_PIN_NO(117) | 2) -#define MT8135_PIN_117_EINT1__FUNC_CLKM1 (MTK_PIN_NO(117) | 3) -#define MT8135_PIN_117_EINT1__FUNC_USB_TEST_IO_13 (MTK_PIN_NO(117) | 5) -#define MT8135_PIN_117_EINT1__FUNC_USB_SDA (MTK_PIN_NO(117) | 7) - -#define MT8135_PIN_118_EINT2__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) -#define MT8135_PIN_118_EINT2__FUNC_EINT2 (MTK_PIN_NO(118) | 1) -#define MT8135_PIN_118_EINT2__FUNC_PWM3 (MTK_PIN_NO(118) | 2) -#define MT8135_PIN_118_EINT2__FUNC_CLKM2 (MTK_PIN_NO(118) | 3) -#define MT8135_PIN_118_EINT2__FUNC_USB_TEST_IO_14 (MTK_PIN_NO(118) | 5) -#define MT8135_PIN_118_EINT2__FUNC_SRCLKENAI2 (MTK_PIN_NO(118) | 6) -#define MT8135_PIN_118_EINT2__FUNC_A_FUNC_DIN_30 (MTK_PIN_NO(118) | 7) - -#define MT8135_PIN_119_EINT3__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) -#define MT8135_PIN_119_EINT3__FUNC_EINT3 (MTK_PIN_NO(119) | 1) -#define MT8135_PIN_119_EINT3__FUNC_USB_TEST_IO_15 (MTK_PIN_NO(119) | 5) -#define MT8135_PIN_119_EINT3__FUNC_SRCLKENAI1 (MTK_PIN_NO(119) | 6) -#define MT8135_PIN_119_EINT3__FUNC_EXT_26M_CK (MTK_PIN_NO(119) | 7) - -#define MT8135_PIN_120_EINT4__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) -#define MT8135_PIN_120_EINT4__FUNC_EINT4 (MTK_PIN_NO(120) | 1) -#define MT8135_PIN_120_EINT4__FUNC_PWM4 (MTK_PIN_NO(120) | 2) -#define MT8135_PIN_120_EINT4__FUNC_USB_DRVVBUS (MTK_PIN_NO(120) | 5) -#define MT8135_PIN_120_EINT4__FUNC_A_FUNC_DIN_31 (MTK_PIN_NO(120) | 7) - -#define MT8135_PIN_121_DPIDE__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) -#define MT8135_PIN_121_DPIDE__FUNC_DPI0_DE (MTK_PIN_NO(121) | 1) -#define MT8135_PIN_121_DPIDE__FUNC_EINT100 (MTK_PIN_NO(121) | 2) -#define MT8135_PIN_121_DPIDE__FUNC_I2SOUT_DAT (MTK_PIN_NO(121) | 3) -#define MT8135_PIN_121_DPIDE__FUNC_DAC_DAT_OUT (MTK_PIN_NO(121) | 4) -#define MT8135_PIN_121_DPIDE__FUNC_PCM1_DO (MTK_PIN_NO(121) | 5) -#define MT8135_PIN_121_DPIDE__FUNC_IRDA_TXD (MTK_PIN_NO(121) | 6) - -#define MT8135_PIN_122_DPICK__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) -#define MT8135_PIN_122_DPICK__FUNC_DPI0_CK (MTK_PIN_NO(122) | 1) -#define MT8135_PIN_122_DPICK__FUNC_EINT101 (MTK_PIN_NO(122) | 2) -#define MT8135_PIN_122_DPICK__FUNC_I2SIN_DAT (MTK_PIN_NO(122) | 3) -#define MT8135_PIN_122_DPICK__FUNC_PCM1_DI (MTK_PIN_NO(122) | 5) -#define MT8135_PIN_122_DPICK__FUNC_IRDA_PDN (MTK_PIN_NO(122) | 6) - -#define MT8135_PIN_123_DPIG4__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) -#define MT8135_PIN_123_DPIG4__FUNC_DPI0_G4 (MTK_PIN_NO(123) | 1) -#define MT8135_PIN_123_DPIG4__FUNC_EINT114 (MTK_PIN_NO(123) | 2) -#define MT8135_PIN_123_DPIG4__FUNC_CM2DAT_2X_0 (MTK_PIN_NO(123) | 4) -#define MT8135_PIN_123_DPIG4__FUNC_DSP2_ID (MTK_PIN_NO(123) | 5) - -#define MT8135_PIN_124_DPIG5__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) -#define MT8135_PIN_124_DPIG5__FUNC_DPI0_G5 (MTK_PIN_NO(124) | 1) -#define MT8135_PIN_124_DPIG5__FUNC_EINT115 (MTK_PIN_NO(124) | 2) -#define MT8135_PIN_124_DPIG5__FUNC_CM2DAT_2X_1 (MTK_PIN_NO(124) | 4) -#define MT8135_PIN_124_DPIG5__FUNC_DSP2_ICK (MTK_PIN_NO(124) | 5) - -#define MT8135_PIN_125_DPIR3__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) -#define MT8135_PIN_125_DPIR3__FUNC_DPI0_R3 (MTK_PIN_NO(125) | 1) -#define MT8135_PIN_125_DPIR3__FUNC_EINT121 (MTK_PIN_NO(125) | 2) -#define MT8135_PIN_125_DPIR3__FUNC_CM2DAT_2X_7 (MTK_PIN_NO(125) | 4) - -#define MT8135_PIN_126_DPIG1__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) -#define MT8135_PIN_126_DPIG1__FUNC_DPI0_G1 (MTK_PIN_NO(126) | 1) -#define MT8135_PIN_126_DPIG1__FUNC_EINT111 (MTK_PIN_NO(126) | 2) -#define MT8135_PIN_126_DPIG1__FUNC_DSP1_ICK (MTK_PIN_NO(126) | 5) - -#define MT8135_PIN_127_DPIVSYNC__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) -#define MT8135_PIN_127_DPIVSYNC__FUNC_DPI0_VSYNC (MTK_PIN_NO(127) | 1) -#define MT8135_PIN_127_DPIVSYNC__FUNC_EINT98 (MTK_PIN_NO(127) | 2) -#define MT8135_PIN_127_DPIVSYNC__FUNC_I2SIN_CK (MTK_PIN_NO(127) | 3) -#define MT8135_PIN_127_DPIVSYNC__FUNC_DAC_CK (MTK_PIN_NO(127) | 4) -#define MT8135_PIN_127_DPIVSYNC__FUNC_PCM1_CK (MTK_PIN_NO(127) | 5) - -#define MT8135_PIN_128_DPIHSYNC__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) -#define MT8135_PIN_128_DPIHSYNC__FUNC_DPI0_HSYNC (MTK_PIN_NO(128) | 1) -#define MT8135_PIN_128_DPIHSYNC__FUNC_EINT99 (MTK_PIN_NO(128) | 2) -#define MT8135_PIN_128_DPIHSYNC__FUNC_I2SIN_WS (MTK_PIN_NO(128) | 3) -#define MT8135_PIN_128_DPIHSYNC__FUNC_DAC_WS (MTK_PIN_NO(128) | 4) -#define MT8135_PIN_128_DPIHSYNC__FUNC_PCM1_WS (MTK_PIN_NO(128) | 5) -#define MT8135_PIN_128_DPIHSYNC__FUNC_IRDA_RXD (MTK_PIN_NO(128) | 6) - -#define MT8135_PIN_129_DPIB0__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) -#define MT8135_PIN_129_DPIB0__FUNC_DPI0_B0 (MTK_PIN_NO(129) | 1) -#define MT8135_PIN_129_DPIB0__FUNC_EINT102 (MTK_PIN_NO(129) | 2) -#define MT8135_PIN_129_DPIB0__FUNC_SCL0 (MTK_PIN_NO(129) | 4) -#define MT8135_PIN_129_DPIB0__FUNC_DISP_PWM (MTK_PIN_NO(129) | 5) - -#define MT8135_PIN_130_DPIB1__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) -#define MT8135_PIN_130_DPIB1__FUNC_DPI0_B1 (MTK_PIN_NO(130) | 1) -#define MT8135_PIN_130_DPIB1__FUNC_EINT103 (MTK_PIN_NO(130) | 2) -#define MT8135_PIN_130_DPIB1__FUNC_CLKM0 (MTK_PIN_NO(130) | 3) -#define MT8135_PIN_130_DPIB1__FUNC_SDA0 (MTK_PIN_NO(130) | 4) -#define MT8135_PIN_130_DPIB1__FUNC_PWM1 (MTK_PIN_NO(130) | 5) - -#define MT8135_PIN_131_DPIB2__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) -#define MT8135_PIN_131_DPIB2__FUNC_DPI0_B2 (MTK_PIN_NO(131) | 1) -#define MT8135_PIN_131_DPIB2__FUNC_EINT104 (MTK_PIN_NO(131) | 2) -#define MT8135_PIN_131_DPIB2__FUNC_CLKM1 (MTK_PIN_NO(131) | 3) -#define MT8135_PIN_131_DPIB2__FUNC_SCL1 (MTK_PIN_NO(131) | 4) -#define MT8135_PIN_131_DPIB2__FUNC_PWM2 (MTK_PIN_NO(131) | 5) - -#define MT8135_PIN_132_DPIB3__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) -#define MT8135_PIN_132_DPIB3__FUNC_DPI0_B3 (MTK_PIN_NO(132) | 1) -#define MT8135_PIN_132_DPIB3__FUNC_EINT105 (MTK_PIN_NO(132) | 2) -#define MT8135_PIN_132_DPIB3__FUNC_CLKM2 (MTK_PIN_NO(132) | 3) -#define MT8135_PIN_132_DPIB3__FUNC_SDA1 (MTK_PIN_NO(132) | 4) -#define MT8135_PIN_132_DPIB3__FUNC_PWM3 (MTK_PIN_NO(132) | 5) - -#define MT8135_PIN_133_DPIB4__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) -#define MT8135_PIN_133_DPIB4__FUNC_DPI0_B4 (MTK_PIN_NO(133) | 1) -#define MT8135_PIN_133_DPIB4__FUNC_EINT106 (MTK_PIN_NO(133) | 2) -#define MT8135_PIN_133_DPIB4__FUNC_CLKM3 (MTK_PIN_NO(133) | 3) -#define MT8135_PIN_133_DPIB4__FUNC_SCL2 (MTK_PIN_NO(133) | 4) -#define MT8135_PIN_133_DPIB4__FUNC_PWM4 (MTK_PIN_NO(133) | 5) - -#define MT8135_PIN_134_DPIB5__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) -#define MT8135_PIN_134_DPIB5__FUNC_DPI0_B5 (MTK_PIN_NO(134) | 1) -#define MT8135_PIN_134_DPIB5__FUNC_EINT107 (MTK_PIN_NO(134) | 2) -#define MT8135_PIN_134_DPIB5__FUNC_CLKM4 (MTK_PIN_NO(134) | 3) -#define MT8135_PIN_134_DPIB5__FUNC_SDA2 (MTK_PIN_NO(134) | 4) -#define MT8135_PIN_134_DPIB5__FUNC_PWM5 (MTK_PIN_NO(134) | 5) - -#define MT8135_PIN_135_DPIB6__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) -#define MT8135_PIN_135_DPIB6__FUNC_DPI0_B6 (MTK_PIN_NO(135) | 1) -#define MT8135_PIN_135_DPIB6__FUNC_EINT108 (MTK_PIN_NO(135) | 2) -#define MT8135_PIN_135_DPIB6__FUNC_CLKM5 (MTK_PIN_NO(135) | 3) -#define MT8135_PIN_135_DPIB6__FUNC_SCL3 (MTK_PIN_NO(135) | 4) -#define MT8135_PIN_135_DPIB6__FUNC_PWM6 (MTK_PIN_NO(135) | 5) - -#define MT8135_PIN_136_DPIB7__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) -#define MT8135_PIN_136_DPIB7__FUNC_DPI0_B7 (MTK_PIN_NO(136) | 1) -#define MT8135_PIN_136_DPIB7__FUNC_EINT109 (MTK_PIN_NO(136) | 2) -#define MT8135_PIN_136_DPIB7__FUNC_CLKM6 (MTK_PIN_NO(136) | 3) -#define MT8135_PIN_136_DPIB7__FUNC_SDA3 (MTK_PIN_NO(136) | 4) -#define MT8135_PIN_136_DPIB7__FUNC_PWM7 (MTK_PIN_NO(136) | 5) - -#define MT8135_PIN_137_DPIG0__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) -#define MT8135_PIN_137_DPIG0__FUNC_DPI0_G0 (MTK_PIN_NO(137) | 1) -#define MT8135_PIN_137_DPIG0__FUNC_EINT110 (MTK_PIN_NO(137) | 2) -#define MT8135_PIN_137_DPIG0__FUNC_DSP1_ID (MTK_PIN_NO(137) | 5) - -#define MT8135_PIN_138_DPIG2__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) -#define MT8135_PIN_138_DPIG2__FUNC_DPI0_G2 (MTK_PIN_NO(138) | 1) -#define MT8135_PIN_138_DPIG2__FUNC_EINT112 (MTK_PIN_NO(138) | 2) -#define MT8135_PIN_138_DPIG2__FUNC_DSP1_IMS (MTK_PIN_NO(138) | 5) - -#define MT8135_PIN_139_DPIG3__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) -#define MT8135_PIN_139_DPIG3__FUNC_DPI0_G3 (MTK_PIN_NO(139) | 1) -#define MT8135_PIN_139_DPIG3__FUNC_EINT113 (MTK_PIN_NO(139) | 2) -#define MT8135_PIN_139_DPIG3__FUNC_DSP2_IMS (MTK_PIN_NO(139) | 5) - -#define MT8135_PIN_140_DPIG6__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) -#define MT8135_PIN_140_DPIG6__FUNC_DPI0_G6 (MTK_PIN_NO(140) | 1) -#define MT8135_PIN_140_DPIG6__FUNC_EINT116 (MTK_PIN_NO(140) | 2) -#define MT8135_PIN_140_DPIG6__FUNC_CM2DAT_2X_2 (MTK_PIN_NO(140) | 4) - -#define MT8135_PIN_141_DPIG7__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) -#define MT8135_PIN_141_DPIG7__FUNC_DPI0_G7 (MTK_PIN_NO(141) | 1) -#define MT8135_PIN_141_DPIG7__FUNC_EINT117 (MTK_PIN_NO(141) | 2) -#define MT8135_PIN_141_DPIG7__FUNC_CM2DAT_2X_3 (MTK_PIN_NO(141) | 4) - -#define MT8135_PIN_142_DPIR0__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) -#define MT8135_PIN_142_DPIR0__FUNC_DPI0_R0 (MTK_PIN_NO(142) | 1) -#define MT8135_PIN_142_DPIR0__FUNC_EINT118 (MTK_PIN_NO(142) | 2) -#define MT8135_PIN_142_DPIR0__FUNC_CM2DAT_2X_4 (MTK_PIN_NO(142) | 4) - -#define MT8135_PIN_143_DPIR1__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) -#define MT8135_PIN_143_DPIR1__FUNC_DPI0_R1 (MTK_PIN_NO(143) | 1) -#define MT8135_PIN_143_DPIR1__FUNC_EINT119 (MTK_PIN_NO(143) | 2) -#define MT8135_PIN_143_DPIR1__FUNC_CM2DAT_2X_5 (MTK_PIN_NO(143) | 4) - -#define MT8135_PIN_144_DPIR2__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) -#define MT8135_PIN_144_DPIR2__FUNC_DPI0_R2 (MTK_PIN_NO(144) | 1) -#define MT8135_PIN_144_DPIR2__FUNC_EINT120 (MTK_PIN_NO(144) | 2) -#define MT8135_PIN_144_DPIR2__FUNC_CM2DAT_2X_6 (MTK_PIN_NO(144) | 4) - -#define MT8135_PIN_145_DPIR4__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) -#define MT8135_PIN_145_DPIR4__FUNC_DPI0_R4 (MTK_PIN_NO(145) | 1) -#define MT8135_PIN_145_DPIR4__FUNC_EINT122 (MTK_PIN_NO(145) | 2) -#define MT8135_PIN_145_DPIR4__FUNC_CM2DAT_2X_8 (MTK_PIN_NO(145) | 4) - -#define MT8135_PIN_146_DPIR5__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) -#define MT8135_PIN_146_DPIR5__FUNC_DPI0_R5 (MTK_PIN_NO(146) | 1) -#define MT8135_PIN_146_DPIR5__FUNC_EINT123 (MTK_PIN_NO(146) | 2) -#define MT8135_PIN_146_DPIR5__FUNC_CM2DAT_2X_9 (MTK_PIN_NO(146) | 4) - -#define MT8135_PIN_147_DPIR6__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) -#define MT8135_PIN_147_DPIR6__FUNC_DPI0_R6 (MTK_PIN_NO(147) | 1) -#define MT8135_PIN_147_DPIR6__FUNC_EINT124 (MTK_PIN_NO(147) | 2) -#define MT8135_PIN_147_DPIR6__FUNC_CM2VSYNC_2X (MTK_PIN_NO(147) | 4) - -#define MT8135_PIN_148_DPIR7__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) -#define MT8135_PIN_148_DPIR7__FUNC_DPI0_R7 (MTK_PIN_NO(148) | 1) -#define MT8135_PIN_148_DPIR7__FUNC_EINT125 (MTK_PIN_NO(148) | 2) -#define MT8135_PIN_148_DPIR7__FUNC_CM2HSYNC_2X (MTK_PIN_NO(148) | 4) - -#define MT8135_PIN_149_TDN3__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) -#define MT8135_PIN_149_TDN3__FUNC_EINT36 (MTK_PIN_NO(149) | 2) - -#define MT8135_PIN_150_TDP3__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) -#define MT8135_PIN_150_TDP3__FUNC_EINT35 (MTK_PIN_NO(150) | 2) - -#define MT8135_PIN_151_TDN2__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) -#define MT8135_PIN_151_TDN2__FUNC_EINT169 (MTK_PIN_NO(151) | 2) - -#define MT8135_PIN_152_TDP2__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) -#define MT8135_PIN_152_TDP2__FUNC_EINT168 (MTK_PIN_NO(152) | 2) - -#define MT8135_PIN_153_TCN__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) -#define MT8135_PIN_153_TCN__FUNC_EINT163 (MTK_PIN_NO(153) | 2) - -#define MT8135_PIN_154_TCP__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) -#define MT8135_PIN_154_TCP__FUNC_EINT162 (MTK_PIN_NO(154) | 2) - -#define MT8135_PIN_155_TDN1__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) -#define MT8135_PIN_155_TDN1__FUNC_EINT167 (MTK_PIN_NO(155) | 2) - -#define MT8135_PIN_156_TDP1__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) -#define MT8135_PIN_156_TDP1__FUNC_EINT166 (MTK_PIN_NO(156) | 2) - -#define MT8135_PIN_157_TDN0__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) -#define MT8135_PIN_157_TDN0__FUNC_EINT165 (MTK_PIN_NO(157) | 2) - -#define MT8135_PIN_158_TDP0__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) -#define MT8135_PIN_158_TDP0__FUNC_EINT164 (MTK_PIN_NO(158) | 2) - -#define MT8135_PIN_159_RDN3__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) -#define MT8135_PIN_159_RDN3__FUNC_EINT18 (MTK_PIN_NO(159) | 2) - -#define MT8135_PIN_160_RDP3__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) -#define MT8135_PIN_160_RDP3__FUNC_EINT30 (MTK_PIN_NO(160) | 2) - -#define MT8135_PIN_161_RDN2__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) -#define MT8135_PIN_161_RDN2__FUNC_EINT31 (MTK_PIN_NO(161) | 2) - -#define MT8135_PIN_162_RDP2__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) -#define MT8135_PIN_162_RDP2__FUNC_EINT32 (MTK_PIN_NO(162) | 2) - -#define MT8135_PIN_163_RCN__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) -#define MT8135_PIN_163_RCN__FUNC_EINT33 (MTK_PIN_NO(163) | 2) - -#define MT8135_PIN_164_RCP__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) -#define MT8135_PIN_164_RCP__FUNC_EINT39 (MTK_PIN_NO(164) | 2) - -#define MT8135_PIN_165_RDN1__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) - -#define MT8135_PIN_166_RDP1__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) - -#define MT8135_PIN_167_RDN0__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) - -#define MT8135_PIN_168_RDP0__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) - -#define MT8135_PIN_169_RDN1_A__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) -#define MT8135_PIN_169_RDN1_A__FUNC_CMDAT6 (MTK_PIN_NO(169) | 1) -#define MT8135_PIN_169_RDN1_A__FUNC_EINT175 (MTK_PIN_NO(169) | 2) - -#define MT8135_PIN_170_RDP1_A__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) -#define MT8135_PIN_170_RDP1_A__FUNC_CMDAT7 (MTK_PIN_NO(170) | 1) -#define MT8135_PIN_170_RDP1_A__FUNC_EINT174 (MTK_PIN_NO(170) | 2) - -#define MT8135_PIN_171_RCN_A__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) -#define MT8135_PIN_171_RCN_A__FUNC_CMDAT8 (MTK_PIN_NO(171) | 1) -#define MT8135_PIN_171_RCN_A__FUNC_EINT171 (MTK_PIN_NO(171) | 2) - -#define MT8135_PIN_172_RCP_A__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) -#define MT8135_PIN_172_RCP_A__FUNC_CMDAT9 (MTK_PIN_NO(172) | 1) -#define MT8135_PIN_172_RCP_A__FUNC_EINT170 (MTK_PIN_NO(172) | 2) - -#define MT8135_PIN_173_RDN0_A__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) -#define MT8135_PIN_173_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(173) | 1) -#define MT8135_PIN_173_RDN0_A__FUNC_EINT173 (MTK_PIN_NO(173) | 2) - -#define MT8135_PIN_174_RDP0_A__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) -#define MT8135_PIN_174_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(174) | 1) -#define MT8135_PIN_174_RDP0_A__FUNC_EINT172 (MTK_PIN_NO(174) | 2) - -#define MT8135_PIN_175_RDN1_B__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) -#define MT8135_PIN_175_RDN1_B__FUNC_CMDAT2 (MTK_PIN_NO(175) | 1) -#define MT8135_PIN_175_RDN1_B__FUNC_EINT181 (MTK_PIN_NO(175) | 2) -#define MT8135_PIN_175_RDN1_B__FUNC_CMCSD2 (MTK_PIN_NO(175) | 3) - -#define MT8135_PIN_176_RDP1_B__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) -#define MT8135_PIN_176_RDP1_B__FUNC_CMDAT3 (MTK_PIN_NO(176) | 1) -#define MT8135_PIN_176_RDP1_B__FUNC_EINT180 (MTK_PIN_NO(176) | 2) -#define MT8135_PIN_176_RDP1_B__FUNC_CMCSD3 (MTK_PIN_NO(176) | 3) - -#define MT8135_PIN_177_RCN_B__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) -#define MT8135_PIN_177_RCN_B__FUNC_CMDAT4 (MTK_PIN_NO(177) | 1) -#define MT8135_PIN_177_RCN_B__FUNC_EINT177 (MTK_PIN_NO(177) | 2) - -#define MT8135_PIN_178_RCP_B__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) -#define MT8135_PIN_178_RCP_B__FUNC_CMDAT5 (MTK_PIN_NO(178) | 1) -#define MT8135_PIN_178_RCP_B__FUNC_EINT176 (MTK_PIN_NO(178) | 2) - -#define MT8135_PIN_179_RDN0_B__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) -#define MT8135_PIN_179_RDN0_B__FUNC_CMDAT0 (MTK_PIN_NO(179) | 1) -#define MT8135_PIN_179_RDN0_B__FUNC_EINT179 (MTK_PIN_NO(179) | 2) -#define MT8135_PIN_179_RDN0_B__FUNC_CMCSD0 (MTK_PIN_NO(179) | 3) - -#define MT8135_PIN_180_RDP0_B__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) -#define MT8135_PIN_180_RDP0_B__FUNC_CMDAT1 (MTK_PIN_NO(180) | 1) -#define MT8135_PIN_180_RDP0_B__FUNC_EINT178 (MTK_PIN_NO(180) | 2) -#define MT8135_PIN_180_RDP0_B__FUNC_CMCSD1 (MTK_PIN_NO(180) | 3) - -#define MT8135_PIN_181_CMPCLK__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) -#define MT8135_PIN_181_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(181) | 1) -#define MT8135_PIN_181_CMPCLK__FUNC_EINT182 (MTK_PIN_NO(181) | 2) -#define MT8135_PIN_181_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(181) | 3) -#define MT8135_PIN_181_CMPCLK__FUNC_CM2MCLK_4X (MTK_PIN_NO(181) | 4) -#define MT8135_PIN_181_CMPCLK__FUNC_TS_AUXADC_SEL_3 (MTK_PIN_NO(181) | 5) -#define MT8135_PIN_181_CMPCLK__FUNC_VENC_TEST_CK (MTK_PIN_NO(181) | 6) -#define MT8135_PIN_181_CMPCLK__FUNC_TESTA_OUT27 (MTK_PIN_NO(181) | 7) - -#define MT8135_PIN_182_CMMCLK__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) -#define MT8135_PIN_182_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(182) | 1) -#define MT8135_PIN_182_CMMCLK__FUNC_EINT183 (MTK_PIN_NO(182) | 2) -#define MT8135_PIN_182_CMMCLK__FUNC_TS_AUXADC_SEL_2 (MTK_PIN_NO(182) | 5) -#define MT8135_PIN_182_CMMCLK__FUNC_TESTA_OUT28 (MTK_PIN_NO(182) | 7) - -#define MT8135_PIN_183_CMRST__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) -#define MT8135_PIN_183_CMRST__FUNC_CMRST (MTK_PIN_NO(183) | 1) -#define MT8135_PIN_183_CMRST__FUNC_EINT185 (MTK_PIN_NO(183) | 2) -#define MT8135_PIN_183_CMRST__FUNC_TS_AUXADC_SEL_1 (MTK_PIN_NO(183) | 5) -#define MT8135_PIN_183_CMRST__FUNC_TESTA_OUT30 (MTK_PIN_NO(183) | 7) - -#define MT8135_PIN_184_CMPDN__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) -#define MT8135_PIN_184_CMPDN__FUNC_CMPDN (MTK_PIN_NO(184) | 1) -#define MT8135_PIN_184_CMPDN__FUNC_EINT184 (MTK_PIN_NO(184) | 2) -#define MT8135_PIN_184_CMPDN__FUNC_TS_AUXADC_SEL_0 (MTK_PIN_NO(184) | 5) -#define MT8135_PIN_184_CMPDN__FUNC_TESTA_OUT29 (MTK_PIN_NO(184) | 7) - -#define MT8135_PIN_185_CMFLASH__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) -#define MT8135_PIN_185_CMFLASH__FUNC_CMFLASH (MTK_PIN_NO(185) | 1) -#define MT8135_PIN_185_CMFLASH__FUNC_EINT186 (MTK_PIN_NO(185) | 2) -#define MT8135_PIN_185_CMFLASH__FUNC_CM2MCLK_3X (MTK_PIN_NO(185) | 3) -#define MT8135_PIN_185_CMFLASH__FUNC_MFG_TEST_CK_1 (MTK_PIN_NO(185) | 6) -#define MT8135_PIN_185_CMFLASH__FUNC_TESTA_OUT31 (MTK_PIN_NO(185) | 7) - -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_MRG_I2S_P_CLK (MTK_PIN_NO(186) | 1) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_EINT14 (MTK_PIN_NO(186) | 2) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(186) | 3) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_PCM0_CK (MTK_PIN_NO(186) | 4) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_DSP2_ICK (MTK_PIN_NO(186) | 5) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_IMG_TEST_CK (MTK_PIN_NO(186) | 6) -#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_USB_SCL (MTK_PIN_NO(186) | 7) - -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_MRG_I2S_SYNC (MTK_PIN_NO(187) | 1) -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_EINT16 (MTK_PIN_NO(187) | 2) -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_I2SIN_WS (MTK_PIN_NO(187) | 3) -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_PCM0_WS (MTK_PIN_NO(187) | 4) -#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_DISP_TEST_CK (MTK_PIN_NO(187) | 6) - -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MRG_I2S_PCM_RX (MTK_PIN_NO(188) | 1) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_EINT15 (MTK_PIN_NO(188) | 2) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_I2SIN_DAT (MTK_PIN_NO(188) | 3) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_PCM0_DI (MTK_PIN_NO(188) | 4) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_DSP2_ID (MTK_PIN_NO(188) | 5) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MFG_TEST_CK (MTK_PIN_NO(188) | 6) -#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_USB_SDA (MTK_PIN_NO(188) | 7) - -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_MRG_I2S_PCM_TX (MTK_PIN_NO(189) | 1) -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_EINT17 (MTK_PIN_NO(189) | 2) -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_I2SOUT_DAT (MTK_PIN_NO(189) | 3) -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_PCM0_DO (MTK_PIN_NO(189) | 4) -#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_VDEC_TEST_CK (MTK_PIN_NO(189) | 6) - -#define MT8135_PIN_190_SRCLKENAI__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) -#define MT8135_PIN_190_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(190) | 1) - -#define MT8135_PIN_191_URXD3__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) -#define MT8135_PIN_191_URXD3__FUNC_URXD3 (MTK_PIN_NO(191) | 1) -#define MT8135_PIN_191_URXD3__FUNC_EINT87 (MTK_PIN_NO(191) | 2) -#define MT8135_PIN_191_URXD3__FUNC_UTXD3 (MTK_PIN_NO(191) | 3) -#define MT8135_PIN_191_URXD3__FUNC_TS_AUX_ST (MTK_PIN_NO(191) | 5) -#define MT8135_PIN_191_URXD3__FUNC_PWM4 (MTK_PIN_NO(191) | 6) - -#define MT8135_PIN_192_UTXD3__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) -#define MT8135_PIN_192_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(192) | 1) -#define MT8135_PIN_192_UTXD3__FUNC_EINT86 (MTK_PIN_NO(192) | 2) -#define MT8135_PIN_192_UTXD3__FUNC_URXD3 (MTK_PIN_NO(192) | 3) -#define MT8135_PIN_192_UTXD3__FUNC_TS_AUX_CS_B (MTK_PIN_NO(192) | 5) -#define MT8135_PIN_192_UTXD3__FUNC_PWM3 (MTK_PIN_NO(192) | 6) - -#define MT8135_PIN_193_SDA2__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) -#define MT8135_PIN_193_SDA2__FUNC_SDA2 (MTK_PIN_NO(193) | 1) -#define MT8135_PIN_193_SDA2__FUNC_EINT95 (MTK_PIN_NO(193) | 2) -#define MT8135_PIN_193_SDA2__FUNC_CLKM5 (MTK_PIN_NO(193) | 3) -#define MT8135_PIN_193_SDA2__FUNC_PWM5 (MTK_PIN_NO(193) | 4) -#define MT8135_PIN_193_SDA2__FUNC_TS_AUX_PWDB (MTK_PIN_NO(193) | 5) - -#define MT8135_PIN_194_SCL2__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) -#define MT8135_PIN_194_SCL2__FUNC_SCL2 (MTK_PIN_NO(194) | 1) -#define MT8135_PIN_194_SCL2__FUNC_EINT94 (MTK_PIN_NO(194) | 2) -#define MT8135_PIN_194_SCL2__FUNC_CLKM4 (MTK_PIN_NO(194) | 3) -#define MT8135_PIN_194_SCL2__FUNC_PWM4 (MTK_PIN_NO(194) | 4) -#define MT8135_PIN_194_SCL2__FUNC_TS_AUXADC_TEST_CK (MTK_PIN_NO(194) | 5) - -#define MT8135_PIN_195_SDA1__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) -#define MT8135_PIN_195_SDA1__FUNC_SDA1 (MTK_PIN_NO(195) | 1) -#define MT8135_PIN_195_SDA1__FUNC_EINT93 (MTK_PIN_NO(195) | 2) -#define MT8135_PIN_195_SDA1__FUNC_CLKM3 (MTK_PIN_NO(195) | 3) -#define MT8135_PIN_195_SDA1__FUNC_PWM3 (MTK_PIN_NO(195) | 4) -#define MT8135_PIN_195_SDA1__FUNC_TS_AUX_SCLK_PWDB (MTK_PIN_NO(195) | 5) - -#define MT8135_PIN_196_SCL1__FUNC_GPIO196 (MTK_PIN_NO(196) | 0) -#define MT8135_PIN_196_SCL1__FUNC_SCL1 (MTK_PIN_NO(196) | 1) -#define MT8135_PIN_196_SCL1__FUNC_EINT92 (MTK_PIN_NO(196) | 2) -#define MT8135_PIN_196_SCL1__FUNC_CLKM2 (MTK_PIN_NO(196) | 3) -#define MT8135_PIN_196_SCL1__FUNC_PWM2 (MTK_PIN_NO(196) | 4) -#define MT8135_PIN_196_SCL1__FUNC_TS_AUX_DIN (MTK_PIN_NO(196) | 5) - -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_GPIO197 (MTK_PIN_NO(197) | 0) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(197) | 1) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_EINT71 (MTK_PIN_NO(197) | 2) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_SCL6 (MTK_PIN_NO(197) | 3) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_PWM5 (MTK_PIN_NO(197) | 4) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_CLKM4 (MTK_PIN_NO(197) | 5) -#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MFG_TEST_CK_2 (MTK_PIN_NO(197) | 6) - -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_GPIO198 (MTK_PIN_NO(198) | 0) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(198) | 1) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_EINT72 (MTK_PIN_NO(198) | 2) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_SDA6 (MTK_PIN_NO(198) | 3) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_PWM6 (MTK_PIN_NO(198) | 4) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_CLKM5 (MTK_PIN_NO(198) | 5) -#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MFG_TEST_CK_3 (MTK_PIN_NO(198) | 6) - -#define MT8135_PIN_199_MSDC3_CMD__FUNC_GPIO199 (MTK_PIN_NO(199) | 0) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(199) | 1) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_EINT68 (MTK_PIN_NO(199) | 2) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_SDA2 (MTK_PIN_NO(199) | 3) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_PWM2 (MTK_PIN_NO(199) | 4) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_CLKM1 (MTK_PIN_NO(199) | 5) -#define MT8135_PIN_199_MSDC3_CMD__FUNC_MFG_TEST_CK_4 (MTK_PIN_NO(199) | 6) - -#define MT8135_PIN_200_MSDC3_CLK__FUNC_GPIO200 (MTK_PIN_NO(200) | 0) -#define MT8135_PIN_200_MSDC3_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(200) | 1) -#define MT8135_PIN_200_MSDC3_CLK__FUNC_EINT67 (MTK_PIN_NO(200) | 2) -#define MT8135_PIN_200_MSDC3_CLK__FUNC_SCL2 (MTK_PIN_NO(200) | 3) -#define MT8135_PIN_200_MSDC3_CLK__FUNC_PWM1 (MTK_PIN_NO(200) | 4) -#define MT8135_PIN_200_MSDC3_CLK__FUNC_CLKM0 (MTK_PIN_NO(200) | 5) - -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_GPIO201 (MTK_PIN_NO(201) | 0) -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(201) | 1) -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_EINT70 (MTK_PIN_NO(201) | 2) -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_SDA3 (MTK_PIN_NO(201) | 3) -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_PWM4 (MTK_PIN_NO(201) | 4) -#define MT8135_PIN_201_MSDC3_DAT1__FUNC_CLKM3 (MTK_PIN_NO(201) | 5) - -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_GPIO202 (MTK_PIN_NO(202) | 0) -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(202) | 1) -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_EINT69 (MTK_PIN_NO(202) | 2) -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_SCL3 (MTK_PIN_NO(202) | 3) -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_PWM3 (MTK_PIN_NO(202) | 4) -#define MT8135_PIN_202_MSDC3_DAT0__FUNC_CLKM2 (MTK_PIN_NO(202) | 5) - -#endif /* __DTS_MT8135_PINFUNC_H */ diff --git a/arch/arm/boot/dts/mt8135.dtsi b/arch/arm/boot/dts/mt8135.dtsi index 0e4e835026db..a031b3636318 100644 --- a/arch/arm/boot/dts/mt8135.dtsi +++ b/arch/arm/boot/dts/mt8135.dtsi @@ -9,7 +9,7 @@ #include #include #include -#include "mt8135-pinfunc.h" +#include / { #address-cells = <2>; diff --git a/include/dt-bindings/pinctrl/mt8135-pinfunc.h b/include/dt-bindings/pinctrl/mt8135-pinfunc.h new file mode 100644 index 000000000000..ce0cb5a440eb --- /dev/null +++ b/include/dt-bindings/pinctrl/mt8135-pinfunc.h @@ -0,0 +1,1294 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Hongzhou.Yang + */ + +#ifndef __DTS_MT8135_PINFUNC_H +#define __DTS_MT8135_PINFUNC_H + +#include + +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(0) | 1) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_EINT49 (MTK_PIN_NO(0) | 2) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_I2SOUT_DAT (MTK_PIN_NO(0) | 3) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_DAC_DAT_OUT (MTK_PIN_NO(0) | 4) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_PCM1_DO (MTK_PIN_NO(0) | 5) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_SPI1_MO (MTK_PIN_NO(0) | 6) +#define MT8135_PIN_0_MSDC0_DAT7__FUNC_NALE (MTK_PIN_NO(0) | 7) + +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(1) | 1) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_EINT48 (MTK_PIN_NO(1) | 2) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_I2SIN_WS (MTK_PIN_NO(1) | 3) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_DAC_WS (MTK_PIN_NO(1) | 4) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_PCM1_WS (MTK_PIN_NO(1) | 5) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_SPI1_CSN (MTK_PIN_NO(1) | 6) +#define MT8135_PIN_1_MSDC0_DAT6__FUNC_NCLE (MTK_PIN_NO(1) | 7) + +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(2) | 1) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_EINT47 (MTK_PIN_NO(2) | 2) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_I2SIN_CK (MTK_PIN_NO(2) | 3) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_DAC_CK (MTK_PIN_NO(2) | 4) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_PCM1_CK (MTK_PIN_NO(2) | 5) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_SPI1_CLK (MTK_PIN_NO(2) | 6) +#define MT8135_PIN_2_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(2) | 7) + +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(3) | 1) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_EINT46 (MTK_PIN_NO(3) | 2) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_A_FUNC_CK (MTK_PIN_NO(3) | 3) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_LSCE1B_2X (MTK_PIN_NO(3) | 6) +#define MT8135_PIN_3_MSDC0_DAT4__FUNC_NLD5 (MTK_PIN_NO(3) | 7) + +#define MT8135_PIN_4_MSDC0_CMD__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(4) | 1) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_EINT41 (MTK_PIN_NO(4) | 2) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_A_FUNC_DOUT_0 (MTK_PIN_NO(4) | 3) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_USB_TEST_IO_0 (MTK_PIN_NO(4) | 5) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_LRSTB_2X (MTK_PIN_NO(4) | 6) +#define MT8135_PIN_4_MSDC0_CMD__FUNC_NRNB (MTK_PIN_NO(4) | 7) + +#define MT8135_PIN_5_MSDC0_CLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(5) | 1) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_EINT40 (MTK_PIN_NO(5) | 2) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_A_FUNC_DOUT_1 (MTK_PIN_NO(5) | 3) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_USB_TEST_IO_1 (MTK_PIN_NO(5) | 5) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_LPTE (MTK_PIN_NO(5) | 6) +#define MT8135_PIN_5_MSDC0_CLK__FUNC_NREB (MTK_PIN_NO(5) | 7) + +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(6) | 1) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_EINT45 (MTK_PIN_NO(6) | 2) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_A_FUNC_DOUT_2 (MTK_PIN_NO(6) | 3) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_USB_TEST_IO_2 (MTK_PIN_NO(6) | 5) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_LSCE0B_2X (MTK_PIN_NO(6) | 6) +#define MT8135_PIN_6_MSDC0_DAT3__FUNC_NLD7 (MTK_PIN_NO(6) | 7) + +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(7) | 1) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_EINT44 (MTK_PIN_NO(7) | 2) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_A_FUNC_DOUT_3 (MTK_PIN_NO(7) | 3) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_USB_TEST_IO_3 (MTK_PIN_NO(7) | 5) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_LSA0_2X (MTK_PIN_NO(7) | 6) +#define MT8135_PIN_7_MSDC0_DAT2__FUNC_NLD14 (MTK_PIN_NO(7) | 7) + +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(8) | 1) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_EINT43 (MTK_PIN_NO(8) | 2) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_USB_TEST_IO_4 (MTK_PIN_NO(8) | 5) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_LSCK_2X (MTK_PIN_NO(8) | 6) +#define MT8135_PIN_8_MSDC0_DAT1__FUNC_NLD11 (MTK_PIN_NO(8) | 7) + +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(9) | 1) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_EINT42 (MTK_PIN_NO(9) | 2) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_USB_TEST_IO_5 (MTK_PIN_NO(9) | 5) +#define MT8135_PIN_9_MSDC0_DAT0__FUNC_LSDA_2X (MTK_PIN_NO(9) | 6) + +#define MT8135_PIN_10_NCEB0__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define MT8135_PIN_10_NCEB0__FUNC_NCEB0 (MTK_PIN_NO(10) | 1) +#define MT8135_PIN_10_NCEB0__FUNC_EINT139 (MTK_PIN_NO(10) | 2) +#define MT8135_PIN_10_NCEB0__FUNC_TESTA_OUT4 (MTK_PIN_NO(10) | 7) + +#define MT8135_PIN_11_NCEB1__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define MT8135_PIN_11_NCEB1__FUNC_NCEB1 (MTK_PIN_NO(11) | 1) +#define MT8135_PIN_11_NCEB1__FUNC_EINT140 (MTK_PIN_NO(11) | 2) +#define MT8135_PIN_11_NCEB1__FUNC_USB_DRVVBUS (MTK_PIN_NO(11) | 6) +#define MT8135_PIN_11_NCEB1__FUNC_TESTA_OUT5 (MTK_PIN_NO(11) | 7) + +#define MT8135_PIN_12_NRNB__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define MT8135_PIN_12_NRNB__FUNC_NRNB (MTK_PIN_NO(12) | 1) +#define MT8135_PIN_12_NRNB__FUNC_EINT141 (MTK_PIN_NO(12) | 2) +#define MT8135_PIN_12_NRNB__FUNC_A_FUNC_DOUT_4 (MTK_PIN_NO(12) | 3) +#define MT8135_PIN_12_NRNB__FUNC_TESTA_OUT6 (MTK_PIN_NO(12) | 7) + +#define MT8135_PIN_13_NCLE__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define MT8135_PIN_13_NCLE__FUNC_NCLE (MTK_PIN_NO(13) | 1) +#define MT8135_PIN_13_NCLE__FUNC_EINT142 (MTK_PIN_NO(13) | 2) +#define MT8135_PIN_13_NCLE__FUNC_A_FUNC_DOUT_5 (MTK_PIN_NO(13) | 3) +#define MT8135_PIN_13_NCLE__FUNC_CM2PDN_1X (MTK_PIN_NO(13) | 4) +#define MT8135_PIN_13_NCLE__FUNC_NALE (MTK_PIN_NO(13) | 6) +#define MT8135_PIN_13_NCLE__FUNC_TESTA_OUT7 (MTK_PIN_NO(13) | 7) + +#define MT8135_PIN_14_NALE__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define MT8135_PIN_14_NALE__FUNC_NALE (MTK_PIN_NO(14) | 1) +#define MT8135_PIN_14_NALE__FUNC_EINT143 (MTK_PIN_NO(14) | 2) +#define MT8135_PIN_14_NALE__FUNC_A_FUNC_DOUT_6 (MTK_PIN_NO(14) | 3) +#define MT8135_PIN_14_NALE__FUNC_CM2MCLK_1X (MTK_PIN_NO(14) | 4) +#define MT8135_PIN_14_NALE__FUNC_IRDA_RXD (MTK_PIN_NO(14) | 5) +#define MT8135_PIN_14_NALE__FUNC_NCLE (MTK_PIN_NO(14) | 6) +#define MT8135_PIN_14_NALE__FUNC_TESTA_OUT8 (MTK_PIN_NO(14) | 7) + +#define MT8135_PIN_15_NREB__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define MT8135_PIN_15_NREB__FUNC_NREB (MTK_PIN_NO(15) | 1) +#define MT8135_PIN_15_NREB__FUNC_EINT144 (MTK_PIN_NO(15) | 2) +#define MT8135_PIN_15_NREB__FUNC_A_FUNC_DOUT_7 (MTK_PIN_NO(15) | 3) +#define MT8135_PIN_15_NREB__FUNC_CM2RST_1X (MTK_PIN_NO(15) | 4) +#define MT8135_PIN_15_NREB__FUNC_IRDA_TXD (MTK_PIN_NO(15) | 5) +#define MT8135_PIN_15_NREB__FUNC_TESTA_OUT9 (MTK_PIN_NO(15) | 7) + +#define MT8135_PIN_16_NWEB__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define MT8135_PIN_16_NWEB__FUNC_NWEB (MTK_PIN_NO(16) | 1) +#define MT8135_PIN_16_NWEB__FUNC_EINT145 (MTK_PIN_NO(16) | 2) +#define MT8135_PIN_16_NWEB__FUNC_A_FUNC_DIN_0 (MTK_PIN_NO(16) | 3) +#define MT8135_PIN_16_NWEB__FUNC_CM2PCLK_1X (MTK_PIN_NO(16) | 4) +#define MT8135_PIN_16_NWEB__FUNC_IRDA_PDN (MTK_PIN_NO(16) | 5) +#define MT8135_PIN_16_NWEB__FUNC_TESTA_OUT10 (MTK_PIN_NO(16) | 7) + +#define MT8135_PIN_17_NLD0__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define MT8135_PIN_17_NLD0__FUNC_NLD0 (MTK_PIN_NO(17) | 1) +#define MT8135_PIN_17_NLD0__FUNC_EINT146 (MTK_PIN_NO(17) | 2) +#define MT8135_PIN_17_NLD0__FUNC_A_FUNC_DIN_1 (MTK_PIN_NO(17) | 3) +#define MT8135_PIN_17_NLD0__FUNC_CM2DAT_1X_0 (MTK_PIN_NO(17) | 4) +#define MT8135_PIN_17_NLD0__FUNC_I2SIN_CK (MTK_PIN_NO(17) | 5) +#define MT8135_PIN_17_NLD0__FUNC_DAC_CK (MTK_PIN_NO(17) | 6) +#define MT8135_PIN_17_NLD0__FUNC_TESTA_OUT11 (MTK_PIN_NO(17) | 7) + +#define MT8135_PIN_18_NLD1__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define MT8135_PIN_18_NLD1__FUNC_NLD1 (MTK_PIN_NO(18) | 1) +#define MT8135_PIN_18_NLD1__FUNC_EINT147 (MTK_PIN_NO(18) | 2) +#define MT8135_PIN_18_NLD1__FUNC_A_FUNC_DIN_2 (MTK_PIN_NO(18) | 3) +#define MT8135_PIN_18_NLD1__FUNC_CM2DAT_1X_1 (MTK_PIN_NO(18) | 4) +#define MT8135_PIN_18_NLD1__FUNC_I2SIN_WS (MTK_PIN_NO(18) | 5) +#define MT8135_PIN_18_NLD1__FUNC_DAC_WS (MTK_PIN_NO(18) | 6) +#define MT8135_PIN_18_NLD1__FUNC_TESTA_OUT12 (MTK_PIN_NO(18) | 7) + +#define MT8135_PIN_19_NLD2__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define MT8135_PIN_19_NLD2__FUNC_NLD2 (MTK_PIN_NO(19) | 1) +#define MT8135_PIN_19_NLD2__FUNC_EINT148 (MTK_PIN_NO(19) | 2) +#define MT8135_PIN_19_NLD2__FUNC_A_FUNC_DIN_3 (MTK_PIN_NO(19) | 3) +#define MT8135_PIN_19_NLD2__FUNC_CM2DAT_1X_2 (MTK_PIN_NO(19) | 4) +#define MT8135_PIN_19_NLD2__FUNC_I2SOUT_DAT (MTK_PIN_NO(19) | 5) +#define MT8135_PIN_19_NLD2__FUNC_DAC_DAT_OUT (MTK_PIN_NO(19) | 6) +#define MT8135_PIN_19_NLD2__FUNC_TESTA_OUT13 (MTK_PIN_NO(19) | 7) + +#define MT8135_PIN_20_NLD3__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define MT8135_PIN_20_NLD3__FUNC_NLD3 (MTK_PIN_NO(20) | 1) +#define MT8135_PIN_20_NLD3__FUNC_EINT149 (MTK_PIN_NO(20) | 2) +#define MT8135_PIN_20_NLD3__FUNC_A_FUNC_DIN_4 (MTK_PIN_NO(20) | 3) +#define MT8135_PIN_20_NLD3__FUNC_CM2DAT_1X_3 (MTK_PIN_NO(20) | 4) +#define MT8135_PIN_20_NLD3__FUNC_TESTA_OUT14 (MTK_PIN_NO(20) | 7) + +#define MT8135_PIN_21_NLD4__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define MT8135_PIN_21_NLD4__FUNC_NLD4 (MTK_PIN_NO(21) | 1) +#define MT8135_PIN_21_NLD4__FUNC_EINT150 (MTK_PIN_NO(21) | 2) +#define MT8135_PIN_21_NLD4__FUNC_A_FUNC_DIN_5 (MTK_PIN_NO(21) | 3) +#define MT8135_PIN_21_NLD4__FUNC_CM2DAT_1X_4 (MTK_PIN_NO(21) | 4) +#define MT8135_PIN_21_NLD4__FUNC_TESTA_OUT15 (MTK_PIN_NO(21) | 7) + +#define MT8135_PIN_22_NLD5__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define MT8135_PIN_22_NLD5__FUNC_NLD5 (MTK_PIN_NO(22) | 1) +#define MT8135_PIN_22_NLD5__FUNC_EINT151 (MTK_PIN_NO(22) | 2) +#define MT8135_PIN_22_NLD5__FUNC_A_FUNC_DIN_6 (MTK_PIN_NO(22) | 3) +#define MT8135_PIN_22_NLD5__FUNC_CM2DAT_1X_5 (MTK_PIN_NO(22) | 4) +#define MT8135_PIN_22_NLD5__FUNC_TESTA_OUT16 (MTK_PIN_NO(22) | 7) + +#define MT8135_PIN_23_NLD6__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define MT8135_PIN_23_NLD6__FUNC_NLD6 (MTK_PIN_NO(23) | 1) +#define MT8135_PIN_23_NLD6__FUNC_EINT152 (MTK_PIN_NO(23) | 2) +#define MT8135_PIN_23_NLD6__FUNC_A_FUNC_DIN_7 (MTK_PIN_NO(23) | 3) +#define MT8135_PIN_23_NLD6__FUNC_CM2DAT_1X_6 (MTK_PIN_NO(23) | 4) +#define MT8135_PIN_23_NLD6__FUNC_TESTA_OUT17 (MTK_PIN_NO(23) | 7) + +#define MT8135_PIN_24_NLD7__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define MT8135_PIN_24_NLD7__FUNC_NLD7 (MTK_PIN_NO(24) | 1) +#define MT8135_PIN_24_NLD7__FUNC_EINT153 (MTK_PIN_NO(24) | 2) +#define MT8135_PIN_24_NLD7__FUNC_A_FUNC_DIN_8 (MTK_PIN_NO(24) | 3) +#define MT8135_PIN_24_NLD7__FUNC_CM2DAT_1X_7 (MTK_PIN_NO(24) | 4) +#define MT8135_PIN_24_NLD7__FUNC_TESTA_OUT18 (MTK_PIN_NO(24) | 7) + +#define MT8135_PIN_25_NLD8__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define MT8135_PIN_25_NLD8__FUNC_NLD8 (MTK_PIN_NO(25) | 1) +#define MT8135_PIN_25_NLD8__FUNC_EINT154 (MTK_PIN_NO(25) | 2) +#define MT8135_PIN_25_NLD8__FUNC_CM2DAT_1X_8 (MTK_PIN_NO(25) | 4) + +#define MT8135_PIN_26_NLD9__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define MT8135_PIN_26_NLD9__FUNC_NLD9 (MTK_PIN_NO(26) | 1) +#define MT8135_PIN_26_NLD9__FUNC_EINT155 (MTK_PIN_NO(26) | 2) +#define MT8135_PIN_26_NLD9__FUNC_CM2DAT_1X_9 (MTK_PIN_NO(26) | 4) +#define MT8135_PIN_26_NLD9__FUNC_PWM1 (MTK_PIN_NO(26) | 5) + +#define MT8135_PIN_27_NLD10__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define MT8135_PIN_27_NLD10__FUNC_NLD10 (MTK_PIN_NO(27) | 1) +#define MT8135_PIN_27_NLD10__FUNC_EINT156 (MTK_PIN_NO(27) | 2) +#define MT8135_PIN_27_NLD10__FUNC_CM2VSYNC_1X (MTK_PIN_NO(27) | 4) +#define MT8135_PIN_27_NLD10__FUNC_PWM2 (MTK_PIN_NO(27) | 5) + +#define MT8135_PIN_28_NLD11__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define MT8135_PIN_28_NLD11__FUNC_NLD11 (MTK_PIN_NO(28) | 1) +#define MT8135_PIN_28_NLD11__FUNC_EINT157 (MTK_PIN_NO(28) | 2) +#define MT8135_PIN_28_NLD11__FUNC_CM2HSYNC_1X (MTK_PIN_NO(28) | 4) +#define MT8135_PIN_28_NLD11__FUNC_PWM3 (MTK_PIN_NO(28) | 5) + +#define MT8135_PIN_29_NLD12__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define MT8135_PIN_29_NLD12__FUNC_NLD12 (MTK_PIN_NO(29) | 1) +#define MT8135_PIN_29_NLD12__FUNC_EINT158 (MTK_PIN_NO(29) | 2) +#define MT8135_PIN_29_NLD12__FUNC_I2SIN_CK (MTK_PIN_NO(29) | 3) +#define MT8135_PIN_29_NLD12__FUNC_DAC_CK (MTK_PIN_NO(29) | 4) +#define MT8135_PIN_29_NLD12__FUNC_PCM1_CK (MTK_PIN_NO(29) | 5) + +#define MT8135_PIN_30_NLD13__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define MT8135_PIN_30_NLD13__FUNC_NLD13 (MTK_PIN_NO(30) | 1) +#define MT8135_PIN_30_NLD13__FUNC_EINT159 (MTK_PIN_NO(30) | 2) +#define MT8135_PIN_30_NLD13__FUNC_I2SIN_WS (MTK_PIN_NO(30) | 3) +#define MT8135_PIN_30_NLD13__FUNC_DAC_WS (MTK_PIN_NO(30) | 4) +#define MT8135_PIN_30_NLD13__FUNC_PCM1_WS (MTK_PIN_NO(30) | 5) + +#define MT8135_PIN_31_NLD14__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define MT8135_PIN_31_NLD14__FUNC_NLD14 (MTK_PIN_NO(31) | 1) +#define MT8135_PIN_31_NLD14__FUNC_EINT160 (MTK_PIN_NO(31) | 2) +#define MT8135_PIN_31_NLD14__FUNC_I2SOUT_DAT (MTK_PIN_NO(31) | 3) +#define MT8135_PIN_31_NLD14__FUNC_DAC_DAT_OUT (MTK_PIN_NO(31) | 4) +#define MT8135_PIN_31_NLD14__FUNC_PCM1_DO (MTK_PIN_NO(31) | 5) + +#define MT8135_PIN_32_NLD15__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define MT8135_PIN_32_NLD15__FUNC_NLD15 (MTK_PIN_NO(32) | 1) +#define MT8135_PIN_32_NLD15__FUNC_EINT161 (MTK_PIN_NO(32) | 2) +#define MT8135_PIN_32_NLD15__FUNC_DISP_PWM (MTK_PIN_NO(32) | 3) +#define MT8135_PIN_32_NLD15__FUNC_PWM4 (MTK_PIN_NO(32) | 4) +#define MT8135_PIN_32_NLD15__FUNC_PCM1_DI (MTK_PIN_NO(32) | 5) + +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(33) | 1) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_EINT50 (MTK_PIN_NO(33) | 2) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_I2SIN_DAT (MTK_PIN_NO(33) | 3) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_PCM1_DI (MTK_PIN_NO(33) | 5) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_SPI1_MI (MTK_PIN_NO(33) | 6) +#define MT8135_PIN_33_MSDC0_RSTB__FUNC_NLD10 (MTK_PIN_NO(33) | 7) + +#define MT8135_PIN_34_IDDIG__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define MT8135_PIN_34_IDDIG__FUNC_IDDIG (MTK_PIN_NO(34) | 1) +#define MT8135_PIN_34_IDDIG__FUNC_EINT34 (MTK_PIN_NO(34) | 2) + +#define MT8135_PIN_35_SCL3__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define MT8135_PIN_35_SCL3__FUNC_SCL3 (MTK_PIN_NO(35) | 1) +#define MT8135_PIN_35_SCL3__FUNC_EINT96 (MTK_PIN_NO(35) | 2) +#define MT8135_PIN_35_SCL3__FUNC_CLKM6 (MTK_PIN_NO(35) | 3) +#define MT8135_PIN_35_SCL3__FUNC_PWM6 (MTK_PIN_NO(35) | 4) + +#define MT8135_PIN_36_SDA3__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define MT8135_PIN_36_SDA3__FUNC_SDA3 (MTK_PIN_NO(36) | 1) +#define MT8135_PIN_36_SDA3__FUNC_EINT97 (MTK_PIN_NO(36) | 2) + +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(37) | 1) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_ADC_CK (MTK_PIN_NO(37) | 2) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_HDMI_SDATA0 (MTK_PIN_NO(37) | 3) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_EINT19 (MTK_PIN_NO(37) | 4) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_USB_TEST_IO_6 (MTK_PIN_NO(37) | 5) +#define MT8135_PIN_37_AUD_CLK_MOSI__FUNC_TESTA_OUT19 (MTK_PIN_NO(37) | 7) + +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(38) | 1) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_ADC_WS (MTK_PIN_NO(38) | 2) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_AUD_DAT_MISO (MTK_PIN_NO(38) | 3) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_EINT21 (MTK_PIN_NO(38) | 4) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_USB_TEST_IO_7 (MTK_PIN_NO(38) | 5) +#define MT8135_PIN_38_AUD_DAT_MOSI__FUNC_TESTA_OUT20 (MTK_PIN_NO(38) | 7) + +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MISO (MTK_PIN_NO(39) | 1) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_ADC_DAT_IN (MTK_PIN_NO(39) | 2) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_AUD_DAT_MOSI (MTK_PIN_NO(39) | 3) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_EINT20 (MTK_PIN_NO(39) | 4) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_USB_TEST_IO_8 (MTK_PIN_NO(39) | 5) +#define MT8135_PIN_39_AUD_DAT_MISO__FUNC_TESTA_OUT21 (MTK_PIN_NO(39) | 7) + +#define MT8135_PIN_40_DAC_CLK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define MT8135_PIN_40_DAC_CLK__FUNC_DAC_CK (MTK_PIN_NO(40) | 1) +#define MT8135_PIN_40_DAC_CLK__FUNC_EINT22 (MTK_PIN_NO(40) | 2) +#define MT8135_PIN_40_DAC_CLK__FUNC_HDMI_SDATA1 (MTK_PIN_NO(40) | 3) +#define MT8135_PIN_40_DAC_CLK__FUNC_USB_TEST_IO_9 (MTK_PIN_NO(40) | 5) +#define MT8135_PIN_40_DAC_CLK__FUNC_TESTA_OUT22 (MTK_PIN_NO(40) | 7) + +#define MT8135_PIN_41_DAC_WS__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define MT8135_PIN_41_DAC_WS__FUNC_DAC_WS (MTK_PIN_NO(41) | 1) +#define MT8135_PIN_41_DAC_WS__FUNC_EINT24 (MTK_PIN_NO(41) | 2) +#define MT8135_PIN_41_DAC_WS__FUNC_HDMI_SDATA2 (MTK_PIN_NO(41) | 3) +#define MT8135_PIN_41_DAC_WS__FUNC_USB_TEST_IO_10 (MTK_PIN_NO(41) | 5) +#define MT8135_PIN_41_DAC_WS__FUNC_TESTA_OUT23 (MTK_PIN_NO(41) | 7) + +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(42) | 1) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_EINT23 (MTK_PIN_NO(42) | 2) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_HDMI_SDATA3 (MTK_PIN_NO(42) | 3) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_USB_TEST_IO_11 (MTK_PIN_NO(42) | 5) +#define MT8135_PIN_42_DAC_DAT_OUT__FUNC_TESTA_OUT24 (MTK_PIN_NO(42) | 7) + +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(43) | 1) +#define MT8135_PIN_43_PWRAP_SPI0_MO__FUNC_EINT29 (MTK_PIN_NO(43) | 2) + +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(44) | 1) +#define MT8135_PIN_44_PWRAP_SPI0_MI__FUNC_EINT28 (MTK_PIN_NO(44) | 2) + +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(45) | 1) +#define MT8135_PIN_45_PWRAP_SPI0_CSN__FUNC_EINT27 (MTK_PIN_NO(45) | 2) + +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(46) | 1) +#define MT8135_PIN_46_PWRAP_SPI0_CLK__FUNC_EINT26 (MTK_PIN_NO(46) | 2) + +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_PWRAP_EVENT_IN (MTK_PIN_NO(47) | 1) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_EINT25 (MTK_PIN_NO(47) | 2) +#define MT8135_PIN_47_PWRAP_EVENT__FUNC_TESTA_OUT2 (MTK_PIN_NO(47) | 7) + +#define MT8135_PIN_48_RTC32K_CK__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define MT8135_PIN_48_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(48) | 1) + +#define MT8135_PIN_49_WATCHDOG__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define MT8135_PIN_49_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(49) | 1) +#define MT8135_PIN_49_WATCHDOG__FUNC_EINT36 (MTK_PIN_NO(49) | 2) + +#define MT8135_PIN_50_SRCLKENA__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define MT8135_PIN_50_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(50) | 1) +#define MT8135_PIN_50_SRCLKENA__FUNC_EINT38 (MTK_PIN_NO(50) | 2) + +#define MT8135_PIN_51_SRCVOLTEN__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define MT8135_PIN_51_SRCVOLTEN__FUNC_SRCVOLTEN (MTK_PIN_NO(51) | 1) +#define MT8135_PIN_51_SRCVOLTEN__FUNC_EINT37 (MTK_PIN_NO(51) | 2) + +#define MT8135_PIN_52_EINT0__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define MT8135_PIN_52_EINT0__FUNC_EINT0 (MTK_PIN_NO(52) | 1) +#define MT8135_PIN_52_EINT0__FUNC_PWM1 (MTK_PIN_NO(52) | 2) +#define MT8135_PIN_52_EINT0__FUNC_CLKM0 (MTK_PIN_NO(52) | 3) +#define MT8135_PIN_52_EINT0__FUNC_SPDIF_OUT (MTK_PIN_NO(52) | 4) +#define MT8135_PIN_52_EINT0__FUNC_USB_TEST_IO_12 (MTK_PIN_NO(52) | 5) +#define MT8135_PIN_52_EINT0__FUNC_USB_SCL (MTK_PIN_NO(52) | 7) + +#define MT8135_PIN_53_URXD2__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define MT8135_PIN_53_URXD2__FUNC_URXD2 (MTK_PIN_NO(53) | 1) +#define MT8135_PIN_53_URXD2__FUNC_EINT83 (MTK_PIN_NO(53) | 2) +#define MT8135_PIN_53_URXD2__FUNC_HDMI_LRCK (MTK_PIN_NO(53) | 4) +#define MT8135_PIN_53_URXD2__FUNC_CLKM3 (MTK_PIN_NO(53) | 5) +#define MT8135_PIN_53_URXD2__FUNC_UTXD2 (MTK_PIN_NO(53) | 7) + +#define MT8135_PIN_54_UTXD2__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define MT8135_PIN_54_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(54) | 1) +#define MT8135_PIN_54_UTXD2__FUNC_EINT82 (MTK_PIN_NO(54) | 2) +#define MT8135_PIN_54_UTXD2__FUNC_HDMI_BCK_OUT (MTK_PIN_NO(54) | 4) +#define MT8135_PIN_54_UTXD2__FUNC_CLKM2 (MTK_PIN_NO(54) | 5) +#define MT8135_PIN_54_UTXD2__FUNC_URXD2 (MTK_PIN_NO(54) | 7) + +#define MT8135_PIN_55_UCTS2__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define MT8135_PIN_55_UCTS2__FUNC_UCTS2 (MTK_PIN_NO(55) | 1) +#define MT8135_PIN_55_UCTS2__FUNC_EINT84 (MTK_PIN_NO(55) | 2) +#define MT8135_PIN_55_UCTS2__FUNC_PWM1 (MTK_PIN_NO(55) | 5) +#define MT8135_PIN_55_UCTS2__FUNC_URTS2 (MTK_PIN_NO(55) | 7) + +#define MT8135_PIN_56_URTS2__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define MT8135_PIN_56_URTS2__FUNC_URTS2 (MTK_PIN_NO(56) | 1) +#define MT8135_PIN_56_URTS2__FUNC_EINT85 (MTK_PIN_NO(56) | 2) +#define MT8135_PIN_56_URTS2__FUNC_PWM2 (MTK_PIN_NO(56) | 5) +#define MT8135_PIN_56_URTS2__FUNC_UCTS2 (MTK_PIN_NO(56) | 7) + +#define MT8135_PIN_57_JTCK__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define MT8135_PIN_57_JTCK__FUNC_JTCK (MTK_PIN_NO(57) | 1) +#define MT8135_PIN_57_JTCK__FUNC_EINT188 (MTK_PIN_NO(57) | 2) +#define MT8135_PIN_57_JTCK__FUNC_DSP1_ICK (MTK_PIN_NO(57) | 3) + +#define MT8135_PIN_58_JTDO__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define MT8135_PIN_58_JTDO__FUNC_JTDO (MTK_PIN_NO(58) | 1) +#define MT8135_PIN_58_JTDO__FUNC_EINT190 (MTK_PIN_NO(58) | 2) +#define MT8135_PIN_58_JTDO__FUNC_DSP2_IMS (MTK_PIN_NO(58) | 3) + +#define MT8135_PIN_59_JTRST_B__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define MT8135_PIN_59_JTRST_B__FUNC_JTRST_B (MTK_PIN_NO(59) | 1) +#define MT8135_PIN_59_JTRST_B__FUNC_EINT0 (MTK_PIN_NO(59) | 2) +#define MT8135_PIN_59_JTRST_B__FUNC_DSP2_ICK (MTK_PIN_NO(59) | 3) + +#define MT8135_PIN_60_JTDI__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define MT8135_PIN_60_JTDI__FUNC_JTDI (MTK_PIN_NO(60) | 1) +#define MT8135_PIN_60_JTDI__FUNC_EINT189 (MTK_PIN_NO(60) | 2) +#define MT8135_PIN_60_JTDI__FUNC_DSP1_IMS (MTK_PIN_NO(60) | 3) + +#define MT8135_PIN_61_JRTCK__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define MT8135_PIN_61_JRTCK__FUNC_JRTCK (MTK_PIN_NO(61) | 1) +#define MT8135_PIN_61_JRTCK__FUNC_EINT187 (MTK_PIN_NO(61) | 2) +#define MT8135_PIN_61_JRTCK__FUNC_DSP1_ID (MTK_PIN_NO(61) | 3) + +#define MT8135_PIN_62_JTMS__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define MT8135_PIN_62_JTMS__FUNC_JTMS (MTK_PIN_NO(62) | 1) +#define MT8135_PIN_62_JTMS__FUNC_EINT191 (MTK_PIN_NO(62) | 2) +#define MT8135_PIN_62_JTMS__FUNC_DSP2_ID (MTK_PIN_NO(62) | 3) + +#define MT8135_PIN_63_MSDC1_INSI__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_MSDC1_INSI (MTK_PIN_NO(63) | 1) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_SCL5 (MTK_PIN_NO(63) | 3) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_PWM6 (MTK_PIN_NO(63) | 4) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_CLKM5 (MTK_PIN_NO(63) | 5) +#define MT8135_PIN_63_MSDC1_INSI__FUNC_TESTB_OUT6 (MTK_PIN_NO(63) | 7) + +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_MSDC1_SDWPI (MTK_PIN_NO(64) | 1) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_EINT58 (MTK_PIN_NO(64) | 2) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_SDA5 (MTK_PIN_NO(64) | 3) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_PWM7 (MTK_PIN_NO(64) | 4) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_CLKM6 (MTK_PIN_NO(64) | 5) +#define MT8135_PIN_64_MSDC1_SDWPI__FUNC_TESTB_OUT7 (MTK_PIN_NO(64) | 7) + +#define MT8135_PIN_65_MSDC2_INSI__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_MSDC2_INSI (MTK_PIN_NO(65) | 1) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_USB_TEST_IO_27 (MTK_PIN_NO(65) | 5) +#define MT8135_PIN_65_MSDC2_INSI__FUNC_TESTA_OUT3 (MTK_PIN_NO(65) | 7) + +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_MSDC2_SDWPI (MTK_PIN_NO(66) | 1) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_EINT66 (MTK_PIN_NO(66) | 2) +#define MT8135_PIN_66_MSDC2_SDWPI__FUNC_USB_TEST_IO_28 (MTK_PIN_NO(66) | 5) + +#define MT8135_PIN_67_URXD4__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define MT8135_PIN_67_URXD4__FUNC_URXD4 (MTK_PIN_NO(67) | 1) +#define MT8135_PIN_67_URXD4__FUNC_EINT89 (MTK_PIN_NO(67) | 2) +#define MT8135_PIN_67_URXD4__FUNC_URXD1 (MTK_PIN_NO(67) | 3) +#define MT8135_PIN_67_URXD4__FUNC_UTXD4 (MTK_PIN_NO(67) | 6) +#define MT8135_PIN_67_URXD4__FUNC_TESTB_OUT10 (MTK_PIN_NO(67) | 7) + +#define MT8135_PIN_68_UTXD4__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define MT8135_PIN_68_UTXD4__FUNC_UTXD4 (MTK_PIN_NO(68) | 1) +#define MT8135_PIN_68_UTXD4__FUNC_EINT88 (MTK_PIN_NO(68) | 2) +#define MT8135_PIN_68_UTXD4__FUNC_UTXD1 (MTK_PIN_NO(68) | 3) +#define MT8135_PIN_68_UTXD4__FUNC_URXD4 (MTK_PIN_NO(68) | 6) +#define MT8135_PIN_68_UTXD4__FUNC_TESTB_OUT11 (MTK_PIN_NO(68) | 7) + +#define MT8135_PIN_69_URXD1__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define MT8135_PIN_69_URXD1__FUNC_URXD1 (MTK_PIN_NO(69) | 1) +#define MT8135_PIN_69_URXD1__FUNC_EINT79 (MTK_PIN_NO(69) | 2) +#define MT8135_PIN_69_URXD1__FUNC_URXD4 (MTK_PIN_NO(69) | 3) +#define MT8135_PIN_69_URXD1__FUNC_UTXD1 (MTK_PIN_NO(69) | 6) +#define MT8135_PIN_69_URXD1__FUNC_TESTB_OUT24 (MTK_PIN_NO(69) | 7) + +#define MT8135_PIN_70_UTXD1__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define MT8135_PIN_70_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(70) | 1) +#define MT8135_PIN_70_UTXD1__FUNC_EINT78 (MTK_PIN_NO(70) | 2) +#define MT8135_PIN_70_UTXD1__FUNC_UTXD4 (MTK_PIN_NO(70) | 3) +#define MT8135_PIN_70_UTXD1__FUNC_URXD1 (MTK_PIN_NO(70) | 6) +#define MT8135_PIN_70_UTXD1__FUNC_TESTB_OUT25 (MTK_PIN_NO(70) | 7) + +#define MT8135_PIN_71_UCTS1__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define MT8135_PIN_71_UCTS1__FUNC_UCTS1 (MTK_PIN_NO(71) | 1) +#define MT8135_PIN_71_UCTS1__FUNC_EINT80 (MTK_PIN_NO(71) | 2) +#define MT8135_PIN_71_UCTS1__FUNC_CLKM0 (MTK_PIN_NO(71) | 5) +#define MT8135_PIN_71_UCTS1__FUNC_URTS1 (MTK_PIN_NO(71) | 6) +#define MT8135_PIN_71_UCTS1__FUNC_TESTB_OUT31 (MTK_PIN_NO(71) | 7) + +#define MT8135_PIN_72_URTS1__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define MT8135_PIN_72_URTS1__FUNC_URTS1 (MTK_PIN_NO(72) | 1) +#define MT8135_PIN_72_URTS1__FUNC_EINT81 (MTK_PIN_NO(72) | 2) +#define MT8135_PIN_72_URTS1__FUNC_CLKM1 (MTK_PIN_NO(72) | 5) +#define MT8135_PIN_72_URTS1__FUNC_UCTS1 (MTK_PIN_NO(72) | 6) +#define MT8135_PIN_72_URTS1__FUNC_TESTB_OUT21 (MTK_PIN_NO(72) | 7) + +#define MT8135_PIN_73_PWM1__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define MT8135_PIN_73_PWM1__FUNC_PWM1 (MTK_PIN_NO(73) | 1) +#define MT8135_PIN_73_PWM1__FUNC_EINT73 (MTK_PIN_NO(73) | 2) +#define MT8135_PIN_73_PWM1__FUNC_USB_DRVVBUS (MTK_PIN_NO(73) | 5) +#define MT8135_PIN_73_PWM1__FUNC_DISP_PWM (MTK_PIN_NO(73) | 6) +#define MT8135_PIN_73_PWM1__FUNC_TESTB_OUT8 (MTK_PIN_NO(73) | 7) + +#define MT8135_PIN_74_PWM2__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define MT8135_PIN_74_PWM2__FUNC_PWM2 (MTK_PIN_NO(74) | 1) +#define MT8135_PIN_74_PWM2__FUNC_EINT74 (MTK_PIN_NO(74) | 2) +#define MT8135_PIN_74_PWM2__FUNC_DPI33_CK (MTK_PIN_NO(74) | 3) +#define MT8135_PIN_74_PWM2__FUNC_PWM5 (MTK_PIN_NO(74) | 4) +#define MT8135_PIN_74_PWM2__FUNC_URXD2 (MTK_PIN_NO(74) | 5) +#define MT8135_PIN_74_PWM2__FUNC_DISP_PWM (MTK_PIN_NO(74) | 6) +#define MT8135_PIN_74_PWM2__FUNC_TESTB_OUT9 (MTK_PIN_NO(74) | 7) + +#define MT8135_PIN_75_PWM3__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define MT8135_PIN_75_PWM3__FUNC_PWM3 (MTK_PIN_NO(75) | 1) +#define MT8135_PIN_75_PWM3__FUNC_EINT75 (MTK_PIN_NO(75) | 2) +#define MT8135_PIN_75_PWM3__FUNC_DPI33_D0 (MTK_PIN_NO(75) | 3) +#define MT8135_PIN_75_PWM3__FUNC_PWM6 (MTK_PIN_NO(75) | 4) +#define MT8135_PIN_75_PWM3__FUNC_UTXD2 (MTK_PIN_NO(75) | 5) +#define MT8135_PIN_75_PWM3__FUNC_DISP_PWM (MTK_PIN_NO(75) | 6) +#define MT8135_PIN_75_PWM3__FUNC_TESTB_OUT12 (MTK_PIN_NO(75) | 7) + +#define MT8135_PIN_76_PWM4__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define MT8135_PIN_76_PWM4__FUNC_PWM4 (MTK_PIN_NO(76) | 1) +#define MT8135_PIN_76_PWM4__FUNC_EINT76 (MTK_PIN_NO(76) | 2) +#define MT8135_PIN_76_PWM4__FUNC_DPI33_D1 (MTK_PIN_NO(76) | 3) +#define MT8135_PIN_76_PWM4__FUNC_PWM7 (MTK_PIN_NO(76) | 4) +#define MT8135_PIN_76_PWM4__FUNC_DISP_PWM (MTK_PIN_NO(76) | 6) +#define MT8135_PIN_76_PWM4__FUNC_TESTB_OUT13 (MTK_PIN_NO(76) | 7) + +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(77) | 1) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_EINT63 (MTK_PIN_NO(77) | 2) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DSP2_IMS (MTK_PIN_NO(77) | 4) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_DPI33_D6 (MTK_PIN_NO(77) | 6) +#define MT8135_PIN_77_MSDC2_DAT2__FUNC_TESTA_OUT25 (MTK_PIN_NO(77) | 7) + +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(78) | 1) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_EINT64 (MTK_PIN_NO(78) | 2) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DSP2_ID (MTK_PIN_NO(78) | 4) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_DPI33_D7 (MTK_PIN_NO(78) | 6) +#define MT8135_PIN_78_MSDC2_DAT3__FUNC_TESTA_OUT26 (MTK_PIN_NO(78) | 7) + +#define MT8135_PIN_79_MSDC2_CMD__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(79) | 1) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_EINT60 (MTK_PIN_NO(79) | 2) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_DSP1_IMS (MTK_PIN_NO(79) | 4) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_PCM1_WS (MTK_PIN_NO(79) | 5) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_DPI33_D3 (MTK_PIN_NO(79) | 6) +#define MT8135_PIN_79_MSDC2_CMD__FUNC_TESTA_OUT0 (MTK_PIN_NO(79) | 7) + +#define MT8135_PIN_80_MSDC2_CLK__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(80) | 1) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_EINT59 (MTK_PIN_NO(80) | 2) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_DSP1_ICK (MTK_PIN_NO(80) | 4) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_PCM1_CK (MTK_PIN_NO(80) | 5) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_DPI33_D2 (MTK_PIN_NO(80) | 6) +#define MT8135_PIN_80_MSDC2_CLK__FUNC_TESTA_OUT1 (MTK_PIN_NO(80) | 7) + +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(81) | 1) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_EINT62 (MTK_PIN_NO(81) | 2) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DSP2_ICK (MTK_PIN_NO(81) | 4) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_PCM1_DO (MTK_PIN_NO(81) | 5) +#define MT8135_PIN_81_MSDC2_DAT1__FUNC_DPI33_D5 (MTK_PIN_NO(81) | 6) + +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(82) | 1) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_EINT61 (MTK_PIN_NO(82) | 2) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DSP1_ID (MTK_PIN_NO(82) | 4) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_PCM1_DI (MTK_PIN_NO(82) | 5) +#define MT8135_PIN_82_MSDC2_DAT0__FUNC_DPI33_D4 (MTK_PIN_NO(82) | 6) + +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(83) | 1) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_EINT53 (MTK_PIN_NO(83) | 2) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_SCL1 (MTK_PIN_NO(83) | 3) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_PWM2 (MTK_PIN_NO(83) | 4) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_CLKM1 (MTK_PIN_NO(83) | 5) +#define MT8135_PIN_83_MSDC1_DAT0__FUNC_TESTB_OUT2 (MTK_PIN_NO(83) | 7) + +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(84) | 1) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_EINT54 (MTK_PIN_NO(84) | 2) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_SDA1 (MTK_PIN_NO(84) | 3) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_PWM3 (MTK_PIN_NO(84) | 4) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_CLKM2 (MTK_PIN_NO(84) | 5) +#define MT8135_PIN_84_MSDC1_DAT1__FUNC_TESTB_OUT3 (MTK_PIN_NO(84) | 7) + +#define MT8135_PIN_85_MSDC1_CMD__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(85) | 1) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_EINT52 (MTK_PIN_NO(85) | 2) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_SDA0 (MTK_PIN_NO(85) | 3) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_PWM1 (MTK_PIN_NO(85) | 4) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_CLKM0 (MTK_PIN_NO(85) | 5) +#define MT8135_PIN_85_MSDC1_CMD__FUNC_TESTB_OUT1 (MTK_PIN_NO(85) | 7) + +#define MT8135_PIN_86_MSDC1_CLK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(86) | 1) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_EINT51 (MTK_PIN_NO(86) | 2) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_SCL0 (MTK_PIN_NO(86) | 3) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_DISP_PWM (MTK_PIN_NO(86) | 4) +#define MT8135_PIN_86_MSDC1_CLK__FUNC_TESTB_OUT0 (MTK_PIN_NO(86) | 7) + +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(87) | 1) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_EINT55 (MTK_PIN_NO(87) | 2) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_SCL4 (MTK_PIN_NO(87) | 3) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_PWM4 (MTK_PIN_NO(87) | 4) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_CLKM3 (MTK_PIN_NO(87) | 5) +#define MT8135_PIN_87_MSDC1_DAT2__FUNC_TESTB_OUT4 (MTK_PIN_NO(87) | 7) + +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(88) | 1) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_EINT56 (MTK_PIN_NO(88) | 2) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_SDA4 (MTK_PIN_NO(88) | 3) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_PWM5 (MTK_PIN_NO(88) | 4) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_CLKM4 (MTK_PIN_NO(88) | 5) +#define MT8135_PIN_88_MSDC1_DAT3__FUNC_TESTB_OUT5 (MTK_PIN_NO(88) | 7) + +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_MSDC4_DAT0 (MTK_PIN_NO(89) | 1) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EINT133 (MTK_PIN_NO(89) | 2) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(89) | 4) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_USB_DRVVBUS (MTK_PIN_NO(89) | 5) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_A_FUNC_DIN_9 (MTK_PIN_NO(89) | 6) +#define MT8135_PIN_89_MSDC4_DAT0__FUNC_LPTE (MTK_PIN_NO(89) | 7) + +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_MSDC4_DAT1 (MTK_PIN_NO(90) | 1) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_EINT134 (MTK_PIN_NO(90) | 2) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_A_FUNC_DIN_10 (MTK_PIN_NO(90) | 6) +#define MT8135_PIN_90_MSDC4_DAT1__FUNC_LRSTB_1X (MTK_PIN_NO(90) | 7) + +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_MSDC4_DAT5 (MTK_PIN_NO(91) | 1) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_EINT136 (MTK_PIN_NO(91) | 2) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_I2SIN_WS (MTK_PIN_NO(91) | 3) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_DAC_WS (MTK_PIN_NO(91) | 4) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_PCM1_WS (MTK_PIN_NO(91) | 5) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_A_FUNC_DIN_11 (MTK_PIN_NO(91) | 6) +#define MT8135_PIN_91_MSDC4_DAT5__FUNC_SPI1_CSN (MTK_PIN_NO(91) | 7) + +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_MSDC4_DAT6 (MTK_PIN_NO(92) | 1) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_EINT137 (MTK_PIN_NO(92) | 2) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_I2SOUT_DAT (MTK_PIN_NO(92) | 3) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_DAC_DAT_OUT (MTK_PIN_NO(92) | 4) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_PCM1_DO (MTK_PIN_NO(92) | 5) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_A_FUNC_DIN_12 (MTK_PIN_NO(92) | 6) +#define MT8135_PIN_92_MSDC4_DAT6__FUNC_SPI1_MO (MTK_PIN_NO(92) | 7) + +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_MSDC4_DAT7 (MTK_PIN_NO(93) | 1) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_EINT138 (MTK_PIN_NO(93) | 2) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_I2SIN_DAT (MTK_PIN_NO(93) | 3) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_PCM1_DI (MTK_PIN_NO(93) | 5) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_A_FUNC_DIN_13 (MTK_PIN_NO(93) | 6) +#define MT8135_PIN_93_MSDC4_DAT7__FUNC_SPI1_MI (MTK_PIN_NO(93) | 7) + +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_MSDC4_DAT4 (MTK_PIN_NO(94) | 1) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_EINT135 (MTK_PIN_NO(94) | 2) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_I2SIN_CK (MTK_PIN_NO(94) | 3) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_DAC_CK (MTK_PIN_NO(94) | 4) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_PCM1_CK (MTK_PIN_NO(94) | 5) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_A_FUNC_DIN_14 (MTK_PIN_NO(94) | 6) +#define MT8135_PIN_94_MSDC4_DAT4__FUNC_SPI1_CLK (MTK_PIN_NO(94) | 7) + +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_MSDC4_DAT2 (MTK_PIN_NO(95) | 1) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_EINT131 (MTK_PIN_NO(95) | 2) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_I2SIN_WS (MTK_PIN_NO(95) | 3) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_CM2PDN_2X (MTK_PIN_NO(95) | 4) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_DAC_WS (MTK_PIN_NO(95) | 5) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_PCM1_WS (MTK_PIN_NO(95) | 6) +#define MT8135_PIN_95_MSDC4_DAT2__FUNC_LSCE0B_1X (MTK_PIN_NO(95) | 7) + +#define MT8135_PIN_96_MSDC4_CLK__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_MSDC4_CLK (MTK_PIN_NO(96) | 1) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_EINT129 (MTK_PIN_NO(96) | 2) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_DPI1_CK_2X (MTK_PIN_NO(96) | 3) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_CM2PCLK_2X (MTK_PIN_NO(96) | 4) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_PWM4 (MTK_PIN_NO(96) | 5) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_PCM1_DI (MTK_PIN_NO(96) | 6) +#define MT8135_PIN_96_MSDC4_CLK__FUNC_LSCK_1X (MTK_PIN_NO(96) | 7) + +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_MSDC4_DAT3 (MTK_PIN_NO(97) | 1) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_EINT132 (MTK_PIN_NO(97) | 2) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_I2SOUT_DAT (MTK_PIN_NO(97) | 3) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_CM2RST_2X (MTK_PIN_NO(97) | 4) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_DAC_DAT_OUT (MTK_PIN_NO(97) | 5) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_PCM1_DO (MTK_PIN_NO(97) | 6) +#define MT8135_PIN_97_MSDC4_DAT3__FUNC_LSCE1B_1X (MTK_PIN_NO(97) | 7) + +#define MT8135_PIN_98_MSDC4_CMD__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_MSDC4_CMD (MTK_PIN_NO(98) | 1) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_EINT128 (MTK_PIN_NO(98) | 2) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_DPI1_DE_2X (MTK_PIN_NO(98) | 3) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_PWM3 (MTK_PIN_NO(98) | 5) +#define MT8135_PIN_98_MSDC4_CMD__FUNC_LSDA_1X (MTK_PIN_NO(98) | 7) + +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_MSDC4_RSTB (MTK_PIN_NO(99) | 1) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_EINT130 (MTK_PIN_NO(99) | 2) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_I2SIN_CK (MTK_PIN_NO(99) | 3) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_CM2MCLK_2X (MTK_PIN_NO(99) | 4) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_DAC_CK (MTK_PIN_NO(99) | 5) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_PCM1_CK (MTK_PIN_NO(99) | 6) +#define MT8135_PIN_99_MSDC4_RSTB__FUNC_LSA0_1X (MTK_PIN_NO(99) | 7) + +#define MT8135_PIN_100_SDA0__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define MT8135_PIN_100_SDA0__FUNC_SDA0 (MTK_PIN_NO(100) | 1) +#define MT8135_PIN_100_SDA0__FUNC_EINT91 (MTK_PIN_NO(100) | 2) +#define MT8135_PIN_100_SDA0__FUNC_CLKM1 (MTK_PIN_NO(100) | 3) +#define MT8135_PIN_100_SDA0__FUNC_PWM1 (MTK_PIN_NO(100) | 4) +#define MT8135_PIN_100_SDA0__FUNC_A_FUNC_DIN_15 (MTK_PIN_NO(100) | 7) + +#define MT8135_PIN_101_SCL0__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define MT8135_PIN_101_SCL0__FUNC_SCL0 (MTK_PIN_NO(101) | 1) +#define MT8135_PIN_101_SCL0__FUNC_EINT90 (MTK_PIN_NO(101) | 2) +#define MT8135_PIN_101_SCL0__FUNC_CLKM0 (MTK_PIN_NO(101) | 3) +#define MT8135_PIN_101_SCL0__FUNC_DISP_PWM (MTK_PIN_NO(101) | 4) +#define MT8135_PIN_101_SCL0__FUNC_A_FUNC_DIN_16 (MTK_PIN_NO(101) | 7) + +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_EINT10 (MTK_PIN_NO(102) | 1) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_USB_TEST_IO_16 (MTK_PIN_NO(102) | 5) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_TESTB_OUT16 (MTK_PIN_NO(102) | 6) +#define MT8135_PIN_102_EINT10_AUXIN2__FUNC_A_FUNC_DIN_17 (MTK_PIN_NO(102) | 7) + +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_EINT11 (MTK_PIN_NO(103) | 1) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_USB_TEST_IO_17 (MTK_PIN_NO(103) | 5) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_TESTB_OUT17 (MTK_PIN_NO(103) | 6) +#define MT8135_PIN_103_EINT11_AUXIN3__FUNC_A_FUNC_DIN_18 (MTK_PIN_NO(103) | 7) + +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_EINT16 (MTK_PIN_NO(104) | 1) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_USB_TEST_IO_18 (MTK_PIN_NO(104) | 5) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_TESTB_OUT18 (MTK_PIN_NO(104) | 6) +#define MT8135_PIN_104_EINT16_AUXIN4__FUNC_A_FUNC_DIN_19 (MTK_PIN_NO(104) | 7) + +#define MT8135_PIN_105_I2S_CLK__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define MT8135_PIN_105_I2S_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(105) | 1) +#define MT8135_PIN_105_I2S_CLK__FUNC_EINT10 (MTK_PIN_NO(105) | 2) +#define MT8135_PIN_105_I2S_CLK__FUNC_DAC_CK (MTK_PIN_NO(105) | 3) +#define MT8135_PIN_105_I2S_CLK__FUNC_PCM1_CK (MTK_PIN_NO(105) | 4) +#define MT8135_PIN_105_I2S_CLK__FUNC_USB_TEST_IO_19 (MTK_PIN_NO(105) | 5) +#define MT8135_PIN_105_I2S_CLK__FUNC_TESTB_OUT19 (MTK_PIN_NO(105) | 6) +#define MT8135_PIN_105_I2S_CLK__FUNC_A_FUNC_DIN_20 (MTK_PIN_NO(105) | 7) + +#define MT8135_PIN_106_I2S_WS__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define MT8135_PIN_106_I2S_WS__FUNC_I2SIN_WS (MTK_PIN_NO(106) | 1) +#define MT8135_PIN_106_I2S_WS__FUNC_EINT13 (MTK_PIN_NO(106) | 2) +#define MT8135_PIN_106_I2S_WS__FUNC_DAC_WS (MTK_PIN_NO(106) | 3) +#define MT8135_PIN_106_I2S_WS__FUNC_PCM1_WS (MTK_PIN_NO(106) | 4) +#define MT8135_PIN_106_I2S_WS__FUNC_USB_TEST_IO_20 (MTK_PIN_NO(106) | 5) +#define MT8135_PIN_106_I2S_WS__FUNC_TESTB_OUT20 (MTK_PIN_NO(106) | 6) +#define MT8135_PIN_106_I2S_WS__FUNC_A_FUNC_DIN_21 (MTK_PIN_NO(106) | 7) + +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_I2SIN_DAT (MTK_PIN_NO(107) | 1) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_EINT11 (MTK_PIN_NO(107) | 2) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_PCM1_DI (MTK_PIN_NO(107) | 4) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_USB_TEST_IO_21 (MTK_PIN_NO(107) | 5) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_TESTB_OUT22 (MTK_PIN_NO(107) | 6) +#define MT8135_PIN_107_I2S_DATA_IN__FUNC_A_FUNC_DIN_22 (MTK_PIN_NO(107) | 7) + +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_I2SOUT_DAT (MTK_PIN_NO(108) | 1) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_EINT12 (MTK_PIN_NO(108) | 2) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_DAC_DAT_OUT (MTK_PIN_NO(108) | 3) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_PCM1_DO (MTK_PIN_NO(108) | 4) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_USB_TEST_IO_22 (MTK_PIN_NO(108) | 5) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_TESTB_OUT23 (MTK_PIN_NO(108) | 6) +#define MT8135_PIN_108_I2S_DATA_OUT__FUNC_A_FUNC_DIN_23 (MTK_PIN_NO(108) | 7) + +#define MT8135_PIN_109_EINT5__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define MT8135_PIN_109_EINT5__FUNC_EINT5 (MTK_PIN_NO(109) | 1) +#define MT8135_PIN_109_EINT5__FUNC_PWM5 (MTK_PIN_NO(109) | 2) +#define MT8135_PIN_109_EINT5__FUNC_CLKM3 (MTK_PIN_NO(109) | 3) +#define MT8135_PIN_109_EINT5__FUNC_GPU_JTRSTB (MTK_PIN_NO(109) | 4) +#define MT8135_PIN_109_EINT5__FUNC_USB_TEST_IO_23 (MTK_PIN_NO(109) | 5) +#define MT8135_PIN_109_EINT5__FUNC_TESTB_OUT26 (MTK_PIN_NO(109) | 6) +#define MT8135_PIN_109_EINT5__FUNC_A_FUNC_DIN_24 (MTK_PIN_NO(109) | 7) + +#define MT8135_PIN_110_EINT6__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define MT8135_PIN_110_EINT6__FUNC_EINT6 (MTK_PIN_NO(110) | 1) +#define MT8135_PIN_110_EINT6__FUNC_PWM6 (MTK_PIN_NO(110) | 2) +#define MT8135_PIN_110_EINT6__FUNC_CLKM4 (MTK_PIN_NO(110) | 3) +#define MT8135_PIN_110_EINT6__FUNC_GPU_JTMS (MTK_PIN_NO(110) | 4) +#define MT8135_PIN_110_EINT6__FUNC_USB_TEST_IO_24 (MTK_PIN_NO(110) | 5) +#define MT8135_PIN_110_EINT6__FUNC_TESTB_OUT27 (MTK_PIN_NO(110) | 6) +#define MT8135_PIN_110_EINT6__FUNC_A_FUNC_DIN_25 (MTK_PIN_NO(110) | 7) + +#define MT8135_PIN_111_EINT7__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define MT8135_PIN_111_EINT7__FUNC_EINT7 (MTK_PIN_NO(111) | 1) +#define MT8135_PIN_111_EINT7__FUNC_PWM7 (MTK_PIN_NO(111) | 2) +#define MT8135_PIN_111_EINT7__FUNC_CLKM5 (MTK_PIN_NO(111) | 3) +#define MT8135_PIN_111_EINT7__FUNC_GPU_JTDO (MTK_PIN_NO(111) | 4) +#define MT8135_PIN_111_EINT7__FUNC_USB_TEST_IO_25 (MTK_PIN_NO(111) | 5) +#define MT8135_PIN_111_EINT7__FUNC_TESTB_OUT28 (MTK_PIN_NO(111) | 6) +#define MT8135_PIN_111_EINT7__FUNC_A_FUNC_DIN_26 (MTK_PIN_NO(111) | 7) + +#define MT8135_PIN_112_EINT8__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define MT8135_PIN_112_EINT8__FUNC_EINT8 (MTK_PIN_NO(112) | 1) +#define MT8135_PIN_112_EINT8__FUNC_DISP_PWM (MTK_PIN_NO(112) | 2) +#define MT8135_PIN_112_EINT8__FUNC_CLKM6 (MTK_PIN_NO(112) | 3) +#define MT8135_PIN_112_EINT8__FUNC_GPU_JTDI (MTK_PIN_NO(112) | 4) +#define MT8135_PIN_112_EINT8__FUNC_USB_TEST_IO_26 (MTK_PIN_NO(112) | 5) +#define MT8135_PIN_112_EINT8__FUNC_TESTB_OUT29 (MTK_PIN_NO(112) | 6) +#define MT8135_PIN_112_EINT8__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(112) | 7) + +#define MT8135_PIN_113_EINT9__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define MT8135_PIN_113_EINT9__FUNC_EINT9 (MTK_PIN_NO(113) | 1) +#define MT8135_PIN_113_EINT9__FUNC_GPU_JTCK (MTK_PIN_NO(113) | 4) +#define MT8135_PIN_113_EINT9__FUNC_USB_DRVVBUS (MTK_PIN_NO(113) | 5) +#define MT8135_PIN_113_EINT9__FUNC_TESTB_OUT30 (MTK_PIN_NO(113) | 6) +#define MT8135_PIN_113_EINT9__FUNC_A_FUNC_DIN_27 (MTK_PIN_NO(113) | 7) + +#define MT8135_PIN_114_LPCE1B__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define MT8135_PIN_114_LPCE1B__FUNC_LPCE1B (MTK_PIN_NO(114) | 1) +#define MT8135_PIN_114_LPCE1B__FUNC_EINT127 (MTK_PIN_NO(114) | 2) +#define MT8135_PIN_114_LPCE1B__FUNC_PWM2 (MTK_PIN_NO(114) | 5) +#define MT8135_PIN_114_LPCE1B__FUNC_TESTB_OUT14 (MTK_PIN_NO(114) | 6) +#define MT8135_PIN_114_LPCE1B__FUNC_A_FUNC_DIN_28 (MTK_PIN_NO(114) | 7) + +#define MT8135_PIN_115_LPCE0B__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define MT8135_PIN_115_LPCE0B__FUNC_LPCE0B (MTK_PIN_NO(115) | 1) +#define MT8135_PIN_115_LPCE0B__FUNC_EINT126 (MTK_PIN_NO(115) | 2) +#define MT8135_PIN_115_LPCE0B__FUNC_PWM1 (MTK_PIN_NO(115) | 5) +#define MT8135_PIN_115_LPCE0B__FUNC_TESTB_OUT15 (MTK_PIN_NO(115) | 6) +#define MT8135_PIN_115_LPCE0B__FUNC_A_FUNC_DIN_29 (MTK_PIN_NO(115) | 7) + +#define MT8135_PIN_116_DISP_PWM__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define MT8135_PIN_116_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(116) | 1) +#define MT8135_PIN_116_DISP_PWM__FUNC_EINT77 (MTK_PIN_NO(116) | 2) +#define MT8135_PIN_116_DISP_PWM__FUNC_LSDI (MTK_PIN_NO(116) | 3) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM1 (MTK_PIN_NO(116) | 4) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM2 (MTK_PIN_NO(116) | 5) +#define MT8135_PIN_116_DISP_PWM__FUNC_PWM3 (MTK_PIN_NO(116) | 7) + +#define MT8135_PIN_117_EINT1__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define MT8135_PIN_117_EINT1__FUNC_EINT1 (MTK_PIN_NO(117) | 1) +#define MT8135_PIN_117_EINT1__FUNC_PWM2 (MTK_PIN_NO(117) | 2) +#define MT8135_PIN_117_EINT1__FUNC_CLKM1 (MTK_PIN_NO(117) | 3) +#define MT8135_PIN_117_EINT1__FUNC_USB_TEST_IO_13 (MTK_PIN_NO(117) | 5) +#define MT8135_PIN_117_EINT1__FUNC_USB_SDA (MTK_PIN_NO(117) | 7) + +#define MT8135_PIN_118_EINT2__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define MT8135_PIN_118_EINT2__FUNC_EINT2 (MTK_PIN_NO(118) | 1) +#define MT8135_PIN_118_EINT2__FUNC_PWM3 (MTK_PIN_NO(118) | 2) +#define MT8135_PIN_118_EINT2__FUNC_CLKM2 (MTK_PIN_NO(118) | 3) +#define MT8135_PIN_118_EINT2__FUNC_USB_TEST_IO_14 (MTK_PIN_NO(118) | 5) +#define MT8135_PIN_118_EINT2__FUNC_SRCLKENAI2 (MTK_PIN_NO(118) | 6) +#define MT8135_PIN_118_EINT2__FUNC_A_FUNC_DIN_30 (MTK_PIN_NO(118) | 7) + +#define MT8135_PIN_119_EINT3__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define MT8135_PIN_119_EINT3__FUNC_EINT3 (MTK_PIN_NO(119) | 1) +#define MT8135_PIN_119_EINT3__FUNC_USB_TEST_IO_15 (MTK_PIN_NO(119) | 5) +#define MT8135_PIN_119_EINT3__FUNC_SRCLKENAI1 (MTK_PIN_NO(119) | 6) +#define MT8135_PIN_119_EINT3__FUNC_EXT_26M_CK (MTK_PIN_NO(119) | 7) + +#define MT8135_PIN_120_EINT4__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define MT8135_PIN_120_EINT4__FUNC_EINT4 (MTK_PIN_NO(120) | 1) +#define MT8135_PIN_120_EINT4__FUNC_PWM4 (MTK_PIN_NO(120) | 2) +#define MT8135_PIN_120_EINT4__FUNC_USB_DRVVBUS (MTK_PIN_NO(120) | 5) +#define MT8135_PIN_120_EINT4__FUNC_A_FUNC_DIN_31 (MTK_PIN_NO(120) | 7) + +#define MT8135_PIN_121_DPIDE__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define MT8135_PIN_121_DPIDE__FUNC_DPI0_DE (MTK_PIN_NO(121) | 1) +#define MT8135_PIN_121_DPIDE__FUNC_EINT100 (MTK_PIN_NO(121) | 2) +#define MT8135_PIN_121_DPIDE__FUNC_I2SOUT_DAT (MTK_PIN_NO(121) | 3) +#define MT8135_PIN_121_DPIDE__FUNC_DAC_DAT_OUT (MTK_PIN_NO(121) | 4) +#define MT8135_PIN_121_DPIDE__FUNC_PCM1_DO (MTK_PIN_NO(121) | 5) +#define MT8135_PIN_121_DPIDE__FUNC_IRDA_TXD (MTK_PIN_NO(121) | 6) + +#define MT8135_PIN_122_DPICK__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define MT8135_PIN_122_DPICK__FUNC_DPI0_CK (MTK_PIN_NO(122) | 1) +#define MT8135_PIN_122_DPICK__FUNC_EINT101 (MTK_PIN_NO(122) | 2) +#define MT8135_PIN_122_DPICK__FUNC_I2SIN_DAT (MTK_PIN_NO(122) | 3) +#define MT8135_PIN_122_DPICK__FUNC_PCM1_DI (MTK_PIN_NO(122) | 5) +#define MT8135_PIN_122_DPICK__FUNC_IRDA_PDN (MTK_PIN_NO(122) | 6) + +#define MT8135_PIN_123_DPIG4__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define MT8135_PIN_123_DPIG4__FUNC_DPI0_G4 (MTK_PIN_NO(123) | 1) +#define MT8135_PIN_123_DPIG4__FUNC_EINT114 (MTK_PIN_NO(123) | 2) +#define MT8135_PIN_123_DPIG4__FUNC_CM2DAT_2X_0 (MTK_PIN_NO(123) | 4) +#define MT8135_PIN_123_DPIG4__FUNC_DSP2_ID (MTK_PIN_NO(123) | 5) + +#define MT8135_PIN_124_DPIG5__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define MT8135_PIN_124_DPIG5__FUNC_DPI0_G5 (MTK_PIN_NO(124) | 1) +#define MT8135_PIN_124_DPIG5__FUNC_EINT115 (MTK_PIN_NO(124) | 2) +#define MT8135_PIN_124_DPIG5__FUNC_CM2DAT_2X_1 (MTK_PIN_NO(124) | 4) +#define MT8135_PIN_124_DPIG5__FUNC_DSP2_ICK (MTK_PIN_NO(124) | 5) + +#define MT8135_PIN_125_DPIR3__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define MT8135_PIN_125_DPIR3__FUNC_DPI0_R3 (MTK_PIN_NO(125) | 1) +#define MT8135_PIN_125_DPIR3__FUNC_EINT121 (MTK_PIN_NO(125) | 2) +#define MT8135_PIN_125_DPIR3__FUNC_CM2DAT_2X_7 (MTK_PIN_NO(125) | 4) + +#define MT8135_PIN_126_DPIG1__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define MT8135_PIN_126_DPIG1__FUNC_DPI0_G1 (MTK_PIN_NO(126) | 1) +#define MT8135_PIN_126_DPIG1__FUNC_EINT111 (MTK_PIN_NO(126) | 2) +#define MT8135_PIN_126_DPIG1__FUNC_DSP1_ICK (MTK_PIN_NO(126) | 5) + +#define MT8135_PIN_127_DPIVSYNC__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define MT8135_PIN_127_DPIVSYNC__FUNC_DPI0_VSYNC (MTK_PIN_NO(127) | 1) +#define MT8135_PIN_127_DPIVSYNC__FUNC_EINT98 (MTK_PIN_NO(127) | 2) +#define MT8135_PIN_127_DPIVSYNC__FUNC_I2SIN_CK (MTK_PIN_NO(127) | 3) +#define MT8135_PIN_127_DPIVSYNC__FUNC_DAC_CK (MTK_PIN_NO(127) | 4) +#define MT8135_PIN_127_DPIVSYNC__FUNC_PCM1_CK (MTK_PIN_NO(127) | 5) + +#define MT8135_PIN_128_DPIHSYNC__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define MT8135_PIN_128_DPIHSYNC__FUNC_DPI0_HSYNC (MTK_PIN_NO(128) | 1) +#define MT8135_PIN_128_DPIHSYNC__FUNC_EINT99 (MTK_PIN_NO(128) | 2) +#define MT8135_PIN_128_DPIHSYNC__FUNC_I2SIN_WS (MTK_PIN_NO(128) | 3) +#define MT8135_PIN_128_DPIHSYNC__FUNC_DAC_WS (MTK_PIN_NO(128) | 4) +#define MT8135_PIN_128_DPIHSYNC__FUNC_PCM1_WS (MTK_PIN_NO(128) | 5) +#define MT8135_PIN_128_DPIHSYNC__FUNC_IRDA_RXD (MTK_PIN_NO(128) | 6) + +#define MT8135_PIN_129_DPIB0__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define MT8135_PIN_129_DPIB0__FUNC_DPI0_B0 (MTK_PIN_NO(129) | 1) +#define MT8135_PIN_129_DPIB0__FUNC_EINT102 (MTK_PIN_NO(129) | 2) +#define MT8135_PIN_129_DPIB0__FUNC_SCL0 (MTK_PIN_NO(129) | 4) +#define MT8135_PIN_129_DPIB0__FUNC_DISP_PWM (MTK_PIN_NO(129) | 5) + +#define MT8135_PIN_130_DPIB1__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define MT8135_PIN_130_DPIB1__FUNC_DPI0_B1 (MTK_PIN_NO(130) | 1) +#define MT8135_PIN_130_DPIB1__FUNC_EINT103 (MTK_PIN_NO(130) | 2) +#define MT8135_PIN_130_DPIB1__FUNC_CLKM0 (MTK_PIN_NO(130) | 3) +#define MT8135_PIN_130_DPIB1__FUNC_SDA0 (MTK_PIN_NO(130) | 4) +#define MT8135_PIN_130_DPIB1__FUNC_PWM1 (MTK_PIN_NO(130) | 5) + +#define MT8135_PIN_131_DPIB2__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define MT8135_PIN_131_DPIB2__FUNC_DPI0_B2 (MTK_PIN_NO(131) | 1) +#define MT8135_PIN_131_DPIB2__FUNC_EINT104 (MTK_PIN_NO(131) | 2) +#define MT8135_PIN_131_DPIB2__FUNC_CLKM1 (MTK_PIN_NO(131) | 3) +#define MT8135_PIN_131_DPIB2__FUNC_SCL1 (MTK_PIN_NO(131) | 4) +#define MT8135_PIN_131_DPIB2__FUNC_PWM2 (MTK_PIN_NO(131) | 5) + +#define MT8135_PIN_132_DPIB3__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define MT8135_PIN_132_DPIB3__FUNC_DPI0_B3 (MTK_PIN_NO(132) | 1) +#define MT8135_PIN_132_DPIB3__FUNC_EINT105 (MTK_PIN_NO(132) | 2) +#define MT8135_PIN_132_DPIB3__FUNC_CLKM2 (MTK_PIN_NO(132) | 3) +#define MT8135_PIN_132_DPIB3__FUNC_SDA1 (MTK_PIN_NO(132) | 4) +#define MT8135_PIN_132_DPIB3__FUNC_PWM3 (MTK_PIN_NO(132) | 5) + +#define MT8135_PIN_133_DPIB4__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define MT8135_PIN_133_DPIB4__FUNC_DPI0_B4 (MTK_PIN_NO(133) | 1) +#define MT8135_PIN_133_DPIB4__FUNC_EINT106 (MTK_PIN_NO(133) | 2) +#define MT8135_PIN_133_DPIB4__FUNC_CLKM3 (MTK_PIN_NO(133) | 3) +#define MT8135_PIN_133_DPIB4__FUNC_SCL2 (MTK_PIN_NO(133) | 4) +#define MT8135_PIN_133_DPIB4__FUNC_PWM4 (MTK_PIN_NO(133) | 5) + +#define MT8135_PIN_134_DPIB5__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define MT8135_PIN_134_DPIB5__FUNC_DPI0_B5 (MTK_PIN_NO(134) | 1) +#define MT8135_PIN_134_DPIB5__FUNC_EINT107 (MTK_PIN_NO(134) | 2) +#define MT8135_PIN_134_DPIB5__FUNC_CLKM4 (MTK_PIN_NO(134) | 3) +#define MT8135_PIN_134_DPIB5__FUNC_SDA2 (MTK_PIN_NO(134) | 4) +#define MT8135_PIN_134_DPIB5__FUNC_PWM5 (MTK_PIN_NO(134) | 5) + +#define MT8135_PIN_135_DPIB6__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define MT8135_PIN_135_DPIB6__FUNC_DPI0_B6 (MTK_PIN_NO(135) | 1) +#define MT8135_PIN_135_DPIB6__FUNC_EINT108 (MTK_PIN_NO(135) | 2) +#define MT8135_PIN_135_DPIB6__FUNC_CLKM5 (MTK_PIN_NO(135) | 3) +#define MT8135_PIN_135_DPIB6__FUNC_SCL3 (MTK_PIN_NO(135) | 4) +#define MT8135_PIN_135_DPIB6__FUNC_PWM6 (MTK_PIN_NO(135) | 5) + +#define MT8135_PIN_136_DPIB7__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define MT8135_PIN_136_DPIB7__FUNC_DPI0_B7 (MTK_PIN_NO(136) | 1) +#define MT8135_PIN_136_DPIB7__FUNC_EINT109 (MTK_PIN_NO(136) | 2) +#define MT8135_PIN_136_DPIB7__FUNC_CLKM6 (MTK_PIN_NO(136) | 3) +#define MT8135_PIN_136_DPIB7__FUNC_SDA3 (MTK_PIN_NO(136) | 4) +#define MT8135_PIN_136_DPIB7__FUNC_PWM7 (MTK_PIN_NO(136) | 5) + +#define MT8135_PIN_137_DPIG0__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define MT8135_PIN_137_DPIG0__FUNC_DPI0_G0 (MTK_PIN_NO(137) | 1) +#define MT8135_PIN_137_DPIG0__FUNC_EINT110 (MTK_PIN_NO(137) | 2) +#define MT8135_PIN_137_DPIG0__FUNC_DSP1_ID (MTK_PIN_NO(137) | 5) + +#define MT8135_PIN_138_DPIG2__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define MT8135_PIN_138_DPIG2__FUNC_DPI0_G2 (MTK_PIN_NO(138) | 1) +#define MT8135_PIN_138_DPIG2__FUNC_EINT112 (MTK_PIN_NO(138) | 2) +#define MT8135_PIN_138_DPIG2__FUNC_DSP1_IMS (MTK_PIN_NO(138) | 5) + +#define MT8135_PIN_139_DPIG3__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define MT8135_PIN_139_DPIG3__FUNC_DPI0_G3 (MTK_PIN_NO(139) | 1) +#define MT8135_PIN_139_DPIG3__FUNC_EINT113 (MTK_PIN_NO(139) | 2) +#define MT8135_PIN_139_DPIG3__FUNC_DSP2_IMS (MTK_PIN_NO(139) | 5) + +#define MT8135_PIN_140_DPIG6__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define MT8135_PIN_140_DPIG6__FUNC_DPI0_G6 (MTK_PIN_NO(140) | 1) +#define MT8135_PIN_140_DPIG6__FUNC_EINT116 (MTK_PIN_NO(140) | 2) +#define MT8135_PIN_140_DPIG6__FUNC_CM2DAT_2X_2 (MTK_PIN_NO(140) | 4) + +#define MT8135_PIN_141_DPIG7__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define MT8135_PIN_141_DPIG7__FUNC_DPI0_G7 (MTK_PIN_NO(141) | 1) +#define MT8135_PIN_141_DPIG7__FUNC_EINT117 (MTK_PIN_NO(141) | 2) +#define MT8135_PIN_141_DPIG7__FUNC_CM2DAT_2X_3 (MTK_PIN_NO(141) | 4) + +#define MT8135_PIN_142_DPIR0__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define MT8135_PIN_142_DPIR0__FUNC_DPI0_R0 (MTK_PIN_NO(142) | 1) +#define MT8135_PIN_142_DPIR0__FUNC_EINT118 (MTK_PIN_NO(142) | 2) +#define MT8135_PIN_142_DPIR0__FUNC_CM2DAT_2X_4 (MTK_PIN_NO(142) | 4) + +#define MT8135_PIN_143_DPIR1__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define MT8135_PIN_143_DPIR1__FUNC_DPI0_R1 (MTK_PIN_NO(143) | 1) +#define MT8135_PIN_143_DPIR1__FUNC_EINT119 (MTK_PIN_NO(143) | 2) +#define MT8135_PIN_143_DPIR1__FUNC_CM2DAT_2X_5 (MTK_PIN_NO(143) | 4) + +#define MT8135_PIN_144_DPIR2__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define MT8135_PIN_144_DPIR2__FUNC_DPI0_R2 (MTK_PIN_NO(144) | 1) +#define MT8135_PIN_144_DPIR2__FUNC_EINT120 (MTK_PIN_NO(144) | 2) +#define MT8135_PIN_144_DPIR2__FUNC_CM2DAT_2X_6 (MTK_PIN_NO(144) | 4) + +#define MT8135_PIN_145_DPIR4__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define MT8135_PIN_145_DPIR4__FUNC_DPI0_R4 (MTK_PIN_NO(145) | 1) +#define MT8135_PIN_145_DPIR4__FUNC_EINT122 (MTK_PIN_NO(145) | 2) +#define MT8135_PIN_145_DPIR4__FUNC_CM2DAT_2X_8 (MTK_PIN_NO(145) | 4) + +#define MT8135_PIN_146_DPIR5__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define MT8135_PIN_146_DPIR5__FUNC_DPI0_R5 (MTK_PIN_NO(146) | 1) +#define MT8135_PIN_146_DPIR5__FUNC_EINT123 (MTK_PIN_NO(146) | 2) +#define MT8135_PIN_146_DPIR5__FUNC_CM2DAT_2X_9 (MTK_PIN_NO(146) | 4) + +#define MT8135_PIN_147_DPIR6__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define MT8135_PIN_147_DPIR6__FUNC_DPI0_R6 (MTK_PIN_NO(147) | 1) +#define MT8135_PIN_147_DPIR6__FUNC_EINT124 (MTK_PIN_NO(147) | 2) +#define MT8135_PIN_147_DPIR6__FUNC_CM2VSYNC_2X (MTK_PIN_NO(147) | 4) + +#define MT8135_PIN_148_DPIR7__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define MT8135_PIN_148_DPIR7__FUNC_DPI0_R7 (MTK_PIN_NO(148) | 1) +#define MT8135_PIN_148_DPIR7__FUNC_EINT125 (MTK_PIN_NO(148) | 2) +#define MT8135_PIN_148_DPIR7__FUNC_CM2HSYNC_2X (MTK_PIN_NO(148) | 4) + +#define MT8135_PIN_149_TDN3__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define MT8135_PIN_149_TDN3__FUNC_EINT36 (MTK_PIN_NO(149) | 2) + +#define MT8135_PIN_150_TDP3__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define MT8135_PIN_150_TDP3__FUNC_EINT35 (MTK_PIN_NO(150) | 2) + +#define MT8135_PIN_151_TDN2__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define MT8135_PIN_151_TDN2__FUNC_EINT169 (MTK_PIN_NO(151) | 2) + +#define MT8135_PIN_152_TDP2__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define MT8135_PIN_152_TDP2__FUNC_EINT168 (MTK_PIN_NO(152) | 2) + +#define MT8135_PIN_153_TCN__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define MT8135_PIN_153_TCN__FUNC_EINT163 (MTK_PIN_NO(153) | 2) + +#define MT8135_PIN_154_TCP__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define MT8135_PIN_154_TCP__FUNC_EINT162 (MTK_PIN_NO(154) | 2) + +#define MT8135_PIN_155_TDN1__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define MT8135_PIN_155_TDN1__FUNC_EINT167 (MTK_PIN_NO(155) | 2) + +#define MT8135_PIN_156_TDP1__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define MT8135_PIN_156_TDP1__FUNC_EINT166 (MTK_PIN_NO(156) | 2) + +#define MT8135_PIN_157_TDN0__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define MT8135_PIN_157_TDN0__FUNC_EINT165 (MTK_PIN_NO(157) | 2) + +#define MT8135_PIN_158_TDP0__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define MT8135_PIN_158_TDP0__FUNC_EINT164 (MTK_PIN_NO(158) | 2) + +#define MT8135_PIN_159_RDN3__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define MT8135_PIN_159_RDN3__FUNC_EINT18 (MTK_PIN_NO(159) | 2) + +#define MT8135_PIN_160_RDP3__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define MT8135_PIN_160_RDP3__FUNC_EINT30 (MTK_PIN_NO(160) | 2) + +#define MT8135_PIN_161_RDN2__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define MT8135_PIN_161_RDN2__FUNC_EINT31 (MTK_PIN_NO(161) | 2) + +#define MT8135_PIN_162_RDP2__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define MT8135_PIN_162_RDP2__FUNC_EINT32 (MTK_PIN_NO(162) | 2) + +#define MT8135_PIN_163_RCN__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define MT8135_PIN_163_RCN__FUNC_EINT33 (MTK_PIN_NO(163) | 2) + +#define MT8135_PIN_164_RCP__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define MT8135_PIN_164_RCP__FUNC_EINT39 (MTK_PIN_NO(164) | 2) + +#define MT8135_PIN_165_RDN1__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) + +#define MT8135_PIN_166_RDP1__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) + +#define MT8135_PIN_167_RDN0__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) + +#define MT8135_PIN_168_RDP0__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) + +#define MT8135_PIN_169_RDN1_A__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define MT8135_PIN_169_RDN1_A__FUNC_CMDAT6 (MTK_PIN_NO(169) | 1) +#define MT8135_PIN_169_RDN1_A__FUNC_EINT175 (MTK_PIN_NO(169) | 2) + +#define MT8135_PIN_170_RDP1_A__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define MT8135_PIN_170_RDP1_A__FUNC_CMDAT7 (MTK_PIN_NO(170) | 1) +#define MT8135_PIN_170_RDP1_A__FUNC_EINT174 (MTK_PIN_NO(170) | 2) + +#define MT8135_PIN_171_RCN_A__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define MT8135_PIN_171_RCN_A__FUNC_CMDAT8 (MTK_PIN_NO(171) | 1) +#define MT8135_PIN_171_RCN_A__FUNC_EINT171 (MTK_PIN_NO(171) | 2) + +#define MT8135_PIN_172_RCP_A__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define MT8135_PIN_172_RCP_A__FUNC_CMDAT9 (MTK_PIN_NO(172) | 1) +#define MT8135_PIN_172_RCP_A__FUNC_EINT170 (MTK_PIN_NO(172) | 2) + +#define MT8135_PIN_173_RDN0_A__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define MT8135_PIN_173_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(173) | 1) +#define MT8135_PIN_173_RDN0_A__FUNC_EINT173 (MTK_PIN_NO(173) | 2) + +#define MT8135_PIN_174_RDP0_A__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define MT8135_PIN_174_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(174) | 1) +#define MT8135_PIN_174_RDP0_A__FUNC_EINT172 (MTK_PIN_NO(174) | 2) + +#define MT8135_PIN_175_RDN1_B__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define MT8135_PIN_175_RDN1_B__FUNC_CMDAT2 (MTK_PIN_NO(175) | 1) +#define MT8135_PIN_175_RDN1_B__FUNC_EINT181 (MTK_PIN_NO(175) | 2) +#define MT8135_PIN_175_RDN1_B__FUNC_CMCSD2 (MTK_PIN_NO(175) | 3) + +#define MT8135_PIN_176_RDP1_B__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) +#define MT8135_PIN_176_RDP1_B__FUNC_CMDAT3 (MTK_PIN_NO(176) | 1) +#define MT8135_PIN_176_RDP1_B__FUNC_EINT180 (MTK_PIN_NO(176) | 2) +#define MT8135_PIN_176_RDP1_B__FUNC_CMCSD3 (MTK_PIN_NO(176) | 3) + +#define MT8135_PIN_177_RCN_B__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) +#define MT8135_PIN_177_RCN_B__FUNC_CMDAT4 (MTK_PIN_NO(177) | 1) +#define MT8135_PIN_177_RCN_B__FUNC_EINT177 (MTK_PIN_NO(177) | 2) + +#define MT8135_PIN_178_RCP_B__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) +#define MT8135_PIN_178_RCP_B__FUNC_CMDAT5 (MTK_PIN_NO(178) | 1) +#define MT8135_PIN_178_RCP_B__FUNC_EINT176 (MTK_PIN_NO(178) | 2) + +#define MT8135_PIN_179_RDN0_B__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) +#define MT8135_PIN_179_RDN0_B__FUNC_CMDAT0 (MTK_PIN_NO(179) | 1) +#define MT8135_PIN_179_RDN0_B__FUNC_EINT179 (MTK_PIN_NO(179) | 2) +#define MT8135_PIN_179_RDN0_B__FUNC_CMCSD0 (MTK_PIN_NO(179) | 3) + +#define MT8135_PIN_180_RDP0_B__FUNC_GPIO180 (MTK_PIN_NO(180) | 0) +#define MT8135_PIN_180_RDP0_B__FUNC_CMDAT1 (MTK_PIN_NO(180) | 1) +#define MT8135_PIN_180_RDP0_B__FUNC_EINT178 (MTK_PIN_NO(180) | 2) +#define MT8135_PIN_180_RDP0_B__FUNC_CMCSD1 (MTK_PIN_NO(180) | 3) + +#define MT8135_PIN_181_CMPCLK__FUNC_GPIO181 (MTK_PIN_NO(181) | 0) +#define MT8135_PIN_181_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(181) | 1) +#define MT8135_PIN_181_CMPCLK__FUNC_EINT182 (MTK_PIN_NO(181) | 2) +#define MT8135_PIN_181_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(181) | 3) +#define MT8135_PIN_181_CMPCLK__FUNC_CM2MCLK_4X (MTK_PIN_NO(181) | 4) +#define MT8135_PIN_181_CMPCLK__FUNC_TS_AUXADC_SEL_3 (MTK_PIN_NO(181) | 5) +#define MT8135_PIN_181_CMPCLK__FUNC_VENC_TEST_CK (MTK_PIN_NO(181) | 6) +#define MT8135_PIN_181_CMPCLK__FUNC_TESTA_OUT27 (MTK_PIN_NO(181) | 7) + +#define MT8135_PIN_182_CMMCLK__FUNC_GPIO182 (MTK_PIN_NO(182) | 0) +#define MT8135_PIN_182_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(182) | 1) +#define MT8135_PIN_182_CMMCLK__FUNC_EINT183 (MTK_PIN_NO(182) | 2) +#define MT8135_PIN_182_CMMCLK__FUNC_TS_AUXADC_SEL_2 (MTK_PIN_NO(182) | 5) +#define MT8135_PIN_182_CMMCLK__FUNC_TESTA_OUT28 (MTK_PIN_NO(182) | 7) + +#define MT8135_PIN_183_CMRST__FUNC_GPIO183 (MTK_PIN_NO(183) | 0) +#define MT8135_PIN_183_CMRST__FUNC_CMRST (MTK_PIN_NO(183) | 1) +#define MT8135_PIN_183_CMRST__FUNC_EINT185 (MTK_PIN_NO(183) | 2) +#define MT8135_PIN_183_CMRST__FUNC_TS_AUXADC_SEL_1 (MTK_PIN_NO(183) | 5) +#define MT8135_PIN_183_CMRST__FUNC_TESTA_OUT30 (MTK_PIN_NO(183) | 7) + +#define MT8135_PIN_184_CMPDN__FUNC_GPIO184 (MTK_PIN_NO(184) | 0) +#define MT8135_PIN_184_CMPDN__FUNC_CMPDN (MTK_PIN_NO(184) | 1) +#define MT8135_PIN_184_CMPDN__FUNC_EINT184 (MTK_PIN_NO(184) | 2) +#define MT8135_PIN_184_CMPDN__FUNC_TS_AUXADC_SEL_0 (MTK_PIN_NO(184) | 5) +#define MT8135_PIN_184_CMPDN__FUNC_TESTA_OUT29 (MTK_PIN_NO(184) | 7) + +#define MT8135_PIN_185_CMFLASH__FUNC_GPIO185 (MTK_PIN_NO(185) | 0) +#define MT8135_PIN_185_CMFLASH__FUNC_CMFLASH (MTK_PIN_NO(185) | 1) +#define MT8135_PIN_185_CMFLASH__FUNC_EINT186 (MTK_PIN_NO(185) | 2) +#define MT8135_PIN_185_CMFLASH__FUNC_CM2MCLK_3X (MTK_PIN_NO(185) | 3) +#define MT8135_PIN_185_CMFLASH__FUNC_MFG_TEST_CK_1 (MTK_PIN_NO(185) | 6) +#define MT8135_PIN_185_CMFLASH__FUNC_TESTA_OUT31 (MTK_PIN_NO(185) | 7) + +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_GPIO186 (MTK_PIN_NO(186) | 0) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_MRG_I2S_P_CLK (MTK_PIN_NO(186) | 1) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_EINT14 (MTK_PIN_NO(186) | 2) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_I2SIN_CK (MTK_PIN_NO(186) | 3) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_PCM0_CK (MTK_PIN_NO(186) | 4) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_DSP2_ICK (MTK_PIN_NO(186) | 5) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_IMG_TEST_CK (MTK_PIN_NO(186) | 6) +#define MT8135_PIN_186_MRG_I2S_PCM_CLK__FUNC_USB_SCL (MTK_PIN_NO(186) | 7) + +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_GPIO187 (MTK_PIN_NO(187) | 0) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_MRG_I2S_SYNC (MTK_PIN_NO(187) | 1) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_EINT16 (MTK_PIN_NO(187) | 2) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_I2SIN_WS (MTK_PIN_NO(187) | 3) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_PCM0_WS (MTK_PIN_NO(187) | 4) +#define MT8135_PIN_187_MRG_I2S_PCM_SYNC__FUNC_DISP_TEST_CK (MTK_PIN_NO(187) | 6) + +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_GPIO188 (MTK_PIN_NO(188) | 0) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MRG_I2S_PCM_RX (MTK_PIN_NO(188) | 1) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_EINT15 (MTK_PIN_NO(188) | 2) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_I2SIN_DAT (MTK_PIN_NO(188) | 3) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_PCM0_DI (MTK_PIN_NO(188) | 4) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_DSP2_ID (MTK_PIN_NO(188) | 5) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_MFG_TEST_CK (MTK_PIN_NO(188) | 6) +#define MT8135_PIN_188_MRG_I2S_PCM_RX__FUNC_USB_SDA (MTK_PIN_NO(188) | 7) + +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_GPIO189 (MTK_PIN_NO(189) | 0) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_MRG_I2S_PCM_TX (MTK_PIN_NO(189) | 1) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_EINT17 (MTK_PIN_NO(189) | 2) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_I2SOUT_DAT (MTK_PIN_NO(189) | 3) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_PCM0_DO (MTK_PIN_NO(189) | 4) +#define MT8135_PIN_189_MRG_I2S_PCM_TX__FUNC_VDEC_TEST_CK (MTK_PIN_NO(189) | 6) + +#define MT8135_PIN_190_SRCLKENAI__FUNC_GPIO190 (MTK_PIN_NO(190) | 0) +#define MT8135_PIN_190_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(190) | 1) + +#define MT8135_PIN_191_URXD3__FUNC_GPIO191 (MTK_PIN_NO(191) | 0) +#define MT8135_PIN_191_URXD3__FUNC_URXD3 (MTK_PIN_NO(191) | 1) +#define MT8135_PIN_191_URXD3__FUNC_EINT87 (MTK_PIN_NO(191) | 2) +#define MT8135_PIN_191_URXD3__FUNC_UTXD3 (MTK_PIN_NO(191) | 3) +#define MT8135_PIN_191_URXD3__FUNC_TS_AUX_ST (MTK_PIN_NO(191) | 5) +#define MT8135_PIN_191_URXD3__FUNC_PWM4 (MTK_PIN_NO(191) | 6) + +#define MT8135_PIN_192_UTXD3__FUNC_GPIO192 (MTK_PIN_NO(192) | 0) +#define MT8135_PIN_192_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(192) | 1) +#define MT8135_PIN_192_UTXD3__FUNC_EINT86 (MTK_PIN_NO(192) | 2) +#define MT8135_PIN_192_UTXD3__FUNC_URXD3 (MTK_PIN_NO(192) | 3) +#define MT8135_PIN_192_UTXD3__FUNC_TS_AUX_CS_B (MTK_PIN_NO(192) | 5) +#define MT8135_PIN_192_UTXD3__FUNC_PWM3 (MTK_PIN_NO(192) | 6) + +#define MT8135_PIN_193_SDA2__FUNC_GPIO193 (MTK_PIN_NO(193) | 0) +#define MT8135_PIN_193_SDA2__FUNC_SDA2 (MTK_PIN_NO(193) | 1) +#define MT8135_PIN_193_SDA2__FUNC_EINT95 (MTK_PIN_NO(193) | 2) +#define MT8135_PIN_193_SDA2__FUNC_CLKM5 (MTK_PIN_NO(193) | 3) +#define MT8135_PIN_193_SDA2__FUNC_PWM5 (MTK_PIN_NO(193) | 4) +#define MT8135_PIN_193_SDA2__FUNC_TS_AUX_PWDB (MTK_PIN_NO(193) | 5) + +#define MT8135_PIN_194_SCL2__FUNC_GPIO194 (MTK_PIN_NO(194) | 0) +#define MT8135_PIN_194_SCL2__FUNC_SCL2 (MTK_PIN_NO(194) | 1) +#define MT8135_PIN_194_SCL2__FUNC_EINT94 (MTK_PIN_NO(194) | 2) +#define MT8135_PIN_194_SCL2__FUNC_CLKM4 (MTK_PIN_NO(194) | 3) +#define MT8135_PIN_194_SCL2__FUNC_PWM4 (MTK_PIN_NO(194) | 4) +#define MT8135_PIN_194_SCL2__FUNC_TS_AUXADC_TEST_CK (MTK_PIN_NO(194) | 5) + +#define MT8135_PIN_195_SDA1__FUNC_GPIO195 (MTK_PIN_NO(195) | 0) +#define MT8135_PIN_195_SDA1__FUNC_SDA1 (MTK_PIN_NO(195) | 1) +#define MT8135_PIN_195_SDA1__FUNC_EINT93 (MTK_PIN_NO(195) | 2) +#define MT8135_PIN_195_SDA1__FUNC_CLKM3 (MTK_PIN_NO(195) | 3) +#define MT8135_PIN_195_SDA1__FUNC_PWM3 (MTK_PIN_NO(195) | 4) +#define MT8135_PIN_195_SDA1__FUNC_TS_AUX_SCLK_PWDB (MTK_PIN_NO(195) | 5) + +#define MT8135_PIN_196_SCL1__FUNC_GPIO196 (MTK_PIN_NO(196) | 0) +#define MT8135_PIN_196_SCL1__FUNC_SCL1 (MTK_PIN_NO(196) | 1) +#define MT8135_PIN_196_SCL1__FUNC_EINT92 (MTK_PIN_NO(196) | 2) +#define MT8135_PIN_196_SCL1__FUNC_CLKM2 (MTK_PIN_NO(196) | 3) +#define MT8135_PIN_196_SCL1__FUNC_PWM2 (MTK_PIN_NO(196) | 4) +#define MT8135_PIN_196_SCL1__FUNC_TS_AUX_DIN (MTK_PIN_NO(196) | 5) + +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_GPIO197 (MTK_PIN_NO(197) | 0) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MSDC3_DAT2 (MTK_PIN_NO(197) | 1) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_EINT71 (MTK_PIN_NO(197) | 2) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_SCL6 (MTK_PIN_NO(197) | 3) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_PWM5 (MTK_PIN_NO(197) | 4) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_CLKM4 (MTK_PIN_NO(197) | 5) +#define MT8135_PIN_197_MSDC3_DAT2__FUNC_MFG_TEST_CK_2 (MTK_PIN_NO(197) | 6) + +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_GPIO198 (MTK_PIN_NO(198) | 0) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MSDC3_DAT3 (MTK_PIN_NO(198) | 1) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_EINT72 (MTK_PIN_NO(198) | 2) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_SDA6 (MTK_PIN_NO(198) | 3) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_PWM6 (MTK_PIN_NO(198) | 4) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_CLKM5 (MTK_PIN_NO(198) | 5) +#define MT8135_PIN_198_MSDC3_DAT3__FUNC_MFG_TEST_CK_3 (MTK_PIN_NO(198) | 6) + +#define MT8135_PIN_199_MSDC3_CMD__FUNC_GPIO199 (MTK_PIN_NO(199) | 0) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_MSDC3_CMD (MTK_PIN_NO(199) | 1) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_EINT68 (MTK_PIN_NO(199) | 2) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_SDA2 (MTK_PIN_NO(199) | 3) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_PWM2 (MTK_PIN_NO(199) | 4) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_CLKM1 (MTK_PIN_NO(199) | 5) +#define MT8135_PIN_199_MSDC3_CMD__FUNC_MFG_TEST_CK_4 (MTK_PIN_NO(199) | 6) + +#define MT8135_PIN_200_MSDC3_CLK__FUNC_GPIO200 (MTK_PIN_NO(200) | 0) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_MSDC3_CLK (MTK_PIN_NO(200) | 1) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_EINT67 (MTK_PIN_NO(200) | 2) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_SCL2 (MTK_PIN_NO(200) | 3) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_PWM1 (MTK_PIN_NO(200) | 4) +#define MT8135_PIN_200_MSDC3_CLK__FUNC_CLKM0 (MTK_PIN_NO(200) | 5) + +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_GPIO201 (MTK_PIN_NO(201) | 0) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_MSDC3_DAT1 (MTK_PIN_NO(201) | 1) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_EINT70 (MTK_PIN_NO(201) | 2) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_SDA3 (MTK_PIN_NO(201) | 3) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_PWM4 (MTK_PIN_NO(201) | 4) +#define MT8135_PIN_201_MSDC3_DAT1__FUNC_CLKM3 (MTK_PIN_NO(201) | 5) + +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_GPIO202 (MTK_PIN_NO(202) | 0) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_MSDC3_DAT0 (MTK_PIN_NO(202) | 1) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_EINT69 (MTK_PIN_NO(202) | 2) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_SCL3 (MTK_PIN_NO(202) | 3) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_PWM3 (MTK_PIN_NO(202) | 4) +#define MT8135_PIN_202_MSDC3_DAT0__FUNC_CLKM2 (MTK_PIN_NO(202) | 5) + +#endif /* __DTS_MT8135_PINFUNC_H */ -- cgit v1.2.3-70-g09d2 From 4e233326e50bf2787a632f7625b9ef89819478ff Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 4 Aug 2021 12:40:32 +0800 Subject: arm: dts: mt8183: Move pinfunc to include/dt-bindings/pinctrl Move mt8183-pinfunc.h into include/dt-bindings/pinctrl so that we can include it in yaml examples. Signed-off-by: Hsin-Yi Wang Link: https://lore.kernel.org/r/20210804044033.3047296-2-hsinyi@chromium.org Signed-off-by: Linus Walleij --- arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h | 1120 ------------------------- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 2 +- include/dt-bindings/pinctrl/mt8183-pinfunc.h | 1120 +++++++++++++++++++++++++ 3 files changed, 1121 insertions(+), 1121 deletions(-) delete mode 100644 arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h create mode 100644 include/dt-bindings/pinctrl/mt8183-pinfunc.h diff --git a/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h deleted file mode 100644 index 6221cd712718..000000000000 --- a/arch/arm64/boot/dts/mediatek/mt8183-pinfunc.h +++ /dev/null @@ -1,1120 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2018 MediaTek Inc. - * Author: Zhiyong Tao - * - */ - -#ifndef __MT8183_PINFUNC_H -#define __MT8183_PINFUNC_H - -#include - -#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) -#define PINMUX_GPIO0__FUNC_MRG_SYNC (MTK_PIN_NO(0) | 1) -#define PINMUX_GPIO0__FUNC_PCM0_SYNC (MTK_PIN_NO(0) | 2) -#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 3) -#define PINMUX_GPIO0__FUNC_SRCLKENAI0 (MTK_PIN_NO(0) | 4) -#define PINMUX_GPIO0__FUNC_SCP_SPI2_CS (MTK_PIN_NO(0) | 5) -#define PINMUX_GPIO0__FUNC_I2S3_MCK (MTK_PIN_NO(0) | 6) -#define PINMUX_GPIO0__FUNC_SPI2_CSB (MTK_PIN_NO(0) | 7) - -#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) -#define PINMUX_GPIO1__FUNC_MRG_CLK (MTK_PIN_NO(1) | 1) -#define PINMUX_GPIO1__FUNC_PCM0_CLK (MTK_PIN_NO(1) | 2) -#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 3) -#define PINMUX_GPIO1__FUNC_CLKM3 (MTK_PIN_NO(1) | 4) -#define PINMUX_GPIO1__FUNC_SCP_SPI2_MO (MTK_PIN_NO(1) | 5) -#define PINMUX_GPIO1__FUNC_I2S3_BCK (MTK_PIN_NO(1) | 6) -#define PINMUX_GPIO1__FUNC_SPI2_MO (MTK_PIN_NO(1) | 7) - -#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) -#define PINMUX_GPIO2__FUNC_MRG_DO (MTK_PIN_NO(2) | 1) -#define PINMUX_GPIO2__FUNC_PCM0_DO (MTK_PIN_NO(2) | 2) -#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 3) -#define PINMUX_GPIO2__FUNC_SCL6 (MTK_PIN_NO(2) | 4) -#define PINMUX_GPIO2__FUNC_SCP_SPI2_CK (MTK_PIN_NO(2) | 5) -#define PINMUX_GPIO2__FUNC_I2S3_LRCK (MTK_PIN_NO(2) | 6) -#define PINMUX_GPIO2__FUNC_SPI2_CLK (MTK_PIN_NO(2) | 7) - -#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) -#define PINMUX_GPIO3__FUNC_MRG_DI (MTK_PIN_NO(3) | 1) -#define PINMUX_GPIO3__FUNC_PCM0_DI (MTK_PIN_NO(3) | 2) -#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 3) -#define PINMUX_GPIO3__FUNC_SDA6 (MTK_PIN_NO(3) | 4) -#define PINMUX_GPIO3__FUNC_TDM_MCK (MTK_PIN_NO(3) | 5) -#define PINMUX_GPIO3__FUNC_I2S3_DO (MTK_PIN_NO(3) | 6) -#define PINMUX_GPIO3__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(3) | 7) - -#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) -#define PINMUX_GPIO4__FUNC_PWM_B (MTK_PIN_NO(4) | 1) -#define PINMUX_GPIO4__FUNC_I2S0_MCK (MTK_PIN_NO(4) | 2) -#define PINMUX_GPIO4__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(4) | 3) -#define PINMUX_GPIO4__FUNC_MD_URXD1 (MTK_PIN_NO(4) | 4) -#define PINMUX_GPIO4__FUNC_TDM_BCK (MTK_PIN_NO(4) | 5) -#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6) -#define PINMUX_GPIO4__FUNC_DAP_MD32_SWD (MTK_PIN_NO(4) | 7) - -#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) -#define PINMUX_GPIO5__FUNC_PWM_C (MTK_PIN_NO(5) | 1) -#define PINMUX_GPIO5__FUNC_I2S0_BCK (MTK_PIN_NO(5) | 2) -#define PINMUX_GPIO5__FUNC_SSPM_URXD_AO (MTK_PIN_NO(5) | 3) -#define PINMUX_GPIO5__FUNC_MD_UTXD1 (MTK_PIN_NO(5) | 4) -#define PINMUX_GPIO5__FUNC_TDM_LRCK (MTK_PIN_NO(5) | 5) -#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6) -#define PINMUX_GPIO5__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(5) | 7) - -#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) -#define PINMUX_GPIO6__FUNC_PWM_A (MTK_PIN_NO(6) | 1) -#define PINMUX_GPIO6__FUNC_I2S0_LRCK (MTK_PIN_NO(6) | 2) -#define PINMUX_GPIO6__FUNC_IDDIG (MTK_PIN_NO(6) | 3) -#define PINMUX_GPIO6__FUNC_MD_URXD0 (MTK_PIN_NO(6) | 4) -#define PINMUX_GPIO6__FUNC_TDM_DATA0 (MTK_PIN_NO(6) | 5) -#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6) -#define PINMUX_GPIO6__FUNC_CMFLASH (MTK_PIN_NO(6) | 7) - -#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) -#define PINMUX_GPIO7__FUNC_SPI1_B_MI (MTK_PIN_NO(7) | 1) -#define PINMUX_GPIO7__FUNC_I2S0_DI (MTK_PIN_NO(7) | 2) -#define PINMUX_GPIO7__FUNC_USB_DRVVBUS (MTK_PIN_NO(7) | 3) -#define PINMUX_GPIO7__FUNC_MD_UTXD0 (MTK_PIN_NO(7) | 4) -#define PINMUX_GPIO7__FUNC_TDM_DATA1 (MTK_PIN_NO(7) | 5) -#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6) -#define PINMUX_GPIO7__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(7) | 7) - -#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) -#define PINMUX_GPIO8__FUNC_SPI1_B_CSB (MTK_PIN_NO(8) | 1) -#define PINMUX_GPIO8__FUNC_ANT_SEL3 (MTK_PIN_NO(8) | 2) -#define PINMUX_GPIO8__FUNC_SCL7 (MTK_PIN_NO(8) | 3) -#define PINMUX_GPIO8__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(8) | 4) -#define PINMUX_GPIO8__FUNC_TDM_DATA2 (MTK_PIN_NO(8) | 5) -#define PINMUX_GPIO8__FUNC_MD_INT0 (MTK_PIN_NO(8) | 6) -#define PINMUX_GPIO8__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(8) | 7) - -#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) -#define PINMUX_GPIO9__FUNC_SPI1_B_MO (MTK_PIN_NO(9) | 1) -#define PINMUX_GPIO9__FUNC_ANT_SEL4 (MTK_PIN_NO(9) | 2) -#define PINMUX_GPIO9__FUNC_CMMCLK2 (MTK_PIN_NO(9) | 3) -#define PINMUX_GPIO9__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(9) | 4) -#define PINMUX_GPIO9__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(9) | 5) -#define PINMUX_GPIO9__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(9) | 6) -#define PINMUX_GPIO9__FUNC_DBG_MON_B10 (MTK_PIN_NO(9) | 7) - -#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) -#define PINMUX_GPIO10__FUNC_SPI1_B_CLK (MTK_PIN_NO(10) | 1) -#define PINMUX_GPIO10__FUNC_ANT_SEL5 (MTK_PIN_NO(10) | 2) -#define PINMUX_GPIO10__FUNC_CMMCLK3 (MTK_PIN_NO(10) | 3) -#define PINMUX_GPIO10__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(10) | 4) -#define PINMUX_GPIO10__FUNC_TDM_DATA3 (MTK_PIN_NO(10) | 5) -#define PINMUX_GPIO10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(10) | 6) -#define PINMUX_GPIO10__FUNC_DBG_MON_B11 (MTK_PIN_NO(10) | 7) - -#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) -#define PINMUX_GPIO11__FUNC_TP_URXD1_AO (MTK_PIN_NO(11) | 1) -#define PINMUX_GPIO11__FUNC_IDDIG (MTK_PIN_NO(11) | 2) -#define PINMUX_GPIO11__FUNC_SCL6 (MTK_PIN_NO(11) | 3) -#define PINMUX_GPIO11__FUNC_UCTS1 (MTK_PIN_NO(11) | 4) -#define PINMUX_GPIO11__FUNC_UCTS0 (MTK_PIN_NO(11) | 5) -#define PINMUX_GPIO11__FUNC_SRCLKENAI1 (MTK_PIN_NO(11) | 6) -#define PINMUX_GPIO11__FUNC_I2S5_MCK (MTK_PIN_NO(11) | 7) - -#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) -#define PINMUX_GPIO12__FUNC_TP_UTXD1_AO (MTK_PIN_NO(12) | 1) -#define PINMUX_GPIO12__FUNC_USB_DRVVBUS (MTK_PIN_NO(12) | 2) -#define PINMUX_GPIO12__FUNC_SDA6 (MTK_PIN_NO(12) | 3) -#define PINMUX_GPIO12__FUNC_URTS1 (MTK_PIN_NO(12) | 4) -#define PINMUX_GPIO12__FUNC_URTS0 (MTK_PIN_NO(12) | 5) -#define PINMUX_GPIO12__FUNC_I2S2_DI2 (MTK_PIN_NO(12) | 6) -#define PINMUX_GPIO12__FUNC_I2S5_BCK (MTK_PIN_NO(12) | 7) - -#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) -#define PINMUX_GPIO13__FUNC_DBPI_D0 (MTK_PIN_NO(13) | 1) -#define PINMUX_GPIO13__FUNC_SPI5_MI (MTK_PIN_NO(13) | 2) -#define PINMUX_GPIO13__FUNC_PCM0_SYNC (MTK_PIN_NO(13) | 3) -#define PINMUX_GPIO13__FUNC_MD_URXD0 (MTK_PIN_NO(13) | 4) -#define PINMUX_GPIO13__FUNC_ANT_SEL3 (MTK_PIN_NO(13) | 5) -#define PINMUX_GPIO13__FUNC_I2S0_MCK (MTK_PIN_NO(13) | 6) -#define PINMUX_GPIO13__FUNC_DBG_MON_B15 (MTK_PIN_NO(13) | 7) - -#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) -#define PINMUX_GPIO14__FUNC_DBPI_D1 (MTK_PIN_NO(14) | 1) -#define PINMUX_GPIO14__FUNC_SPI5_CSB (MTK_PIN_NO(14) | 2) -#define PINMUX_GPIO14__FUNC_PCM0_CLK (MTK_PIN_NO(14) | 3) -#define PINMUX_GPIO14__FUNC_MD_UTXD0 (MTK_PIN_NO(14) | 4) -#define PINMUX_GPIO14__FUNC_ANT_SEL4 (MTK_PIN_NO(14) | 5) -#define PINMUX_GPIO14__FUNC_I2S0_BCK (MTK_PIN_NO(14) | 6) -#define PINMUX_GPIO14__FUNC_DBG_MON_B16 (MTK_PIN_NO(14) | 7) - -#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) -#define PINMUX_GPIO15__FUNC_DBPI_D2 (MTK_PIN_NO(15) | 1) -#define PINMUX_GPIO15__FUNC_SPI5_MO (MTK_PIN_NO(15) | 2) -#define PINMUX_GPIO15__FUNC_PCM0_DO (MTK_PIN_NO(15) | 3) -#define PINMUX_GPIO15__FUNC_MD_URXD1 (MTK_PIN_NO(15) | 4) -#define PINMUX_GPIO15__FUNC_ANT_SEL5 (MTK_PIN_NO(15) | 5) -#define PINMUX_GPIO15__FUNC_I2S0_LRCK (MTK_PIN_NO(15) | 6) -#define PINMUX_GPIO15__FUNC_DBG_MON_B17 (MTK_PIN_NO(15) | 7) - -#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) -#define PINMUX_GPIO16__FUNC_DBPI_D3 (MTK_PIN_NO(16) | 1) -#define PINMUX_GPIO16__FUNC_SPI5_CLK (MTK_PIN_NO(16) | 2) -#define PINMUX_GPIO16__FUNC_PCM0_DI (MTK_PIN_NO(16) | 3) -#define PINMUX_GPIO16__FUNC_MD_UTXD1 (MTK_PIN_NO(16) | 4) -#define PINMUX_GPIO16__FUNC_ANT_SEL6 (MTK_PIN_NO(16) | 5) -#define PINMUX_GPIO16__FUNC_I2S0_DI (MTK_PIN_NO(16) | 6) -#define PINMUX_GPIO16__FUNC_DBG_MON_B23 (MTK_PIN_NO(16) | 7) - -#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) -#define PINMUX_GPIO17__FUNC_DBPI_D4 (MTK_PIN_NO(17) | 1) -#define PINMUX_GPIO17__FUNC_SPI4_MI (MTK_PIN_NO(17) | 2) -#define PINMUX_GPIO17__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(17) | 3) -#define PINMUX_GPIO17__FUNC_MD_INT0 (MTK_PIN_NO(17) | 4) -#define PINMUX_GPIO17__FUNC_ANT_SEL7 (MTK_PIN_NO(17) | 5) -#define PINMUX_GPIO17__FUNC_I2S3_MCK (MTK_PIN_NO(17) | 6) -#define PINMUX_GPIO17__FUNC_DBG_MON_A1 (MTK_PIN_NO(17) | 7) - -#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) -#define PINMUX_GPIO18__FUNC_DBPI_D5 (MTK_PIN_NO(18) | 1) -#define PINMUX_GPIO18__FUNC_SPI4_CSB (MTK_PIN_NO(18) | 2) -#define PINMUX_GPIO18__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(18) | 3) -#define PINMUX_GPIO18__FUNC_MD_INT0 (MTK_PIN_NO(18) | 4) -#define PINMUX_GPIO18__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(18) | 5) -#define PINMUX_GPIO18__FUNC_I2S3_BCK (MTK_PIN_NO(18) | 6) -#define PINMUX_GPIO18__FUNC_DBG_MON_A2 (MTK_PIN_NO(18) | 7) - -#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) -#define PINMUX_GPIO19__FUNC_DBPI_D6 (MTK_PIN_NO(19) | 1) -#define PINMUX_GPIO19__FUNC_SPI4_MO (MTK_PIN_NO(19) | 2) -#define PINMUX_GPIO19__FUNC_CONN_MCU_TDO (MTK_PIN_NO(19) | 3) -#define PINMUX_GPIO19__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(19) | 4) -#define PINMUX_GPIO19__FUNC_URXD1 (MTK_PIN_NO(19) | 5) -#define PINMUX_GPIO19__FUNC_I2S3_LRCK (MTK_PIN_NO(19) | 6) -#define PINMUX_GPIO19__FUNC_DBG_MON_A3 (MTK_PIN_NO(19) | 7) - -#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) -#define PINMUX_GPIO20__FUNC_DBPI_D7 (MTK_PIN_NO(20) | 1) -#define PINMUX_GPIO20__FUNC_SPI4_CLK (MTK_PIN_NO(20) | 2) -#define PINMUX_GPIO20__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(20) | 3) -#define PINMUX_GPIO20__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(20) | 4) -#define PINMUX_GPIO20__FUNC_UTXD1 (MTK_PIN_NO(20) | 5) -#define PINMUX_GPIO20__FUNC_I2S3_DO (MTK_PIN_NO(20) | 6) -#define PINMUX_GPIO20__FUNC_DBG_MON_A19 (MTK_PIN_NO(20) | 7) - -#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) -#define PINMUX_GPIO21__FUNC_DBPI_D8 (MTK_PIN_NO(21) | 1) -#define PINMUX_GPIO21__FUNC_SPI3_MI (MTK_PIN_NO(21) | 2) -#define PINMUX_GPIO21__FUNC_CONN_MCU_TMS (MTK_PIN_NO(21) | 3) -#define PINMUX_GPIO21__FUNC_DAP_MD32_SWD (MTK_PIN_NO(21) | 4) -#define PINMUX_GPIO21__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(21) | 5) -#define PINMUX_GPIO21__FUNC_I2S2_MCK (MTK_PIN_NO(21) | 6) -#define PINMUX_GPIO21__FUNC_DBG_MON_B5 (MTK_PIN_NO(21) | 7) - -#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) -#define PINMUX_GPIO22__FUNC_DBPI_D9 (MTK_PIN_NO(22) | 1) -#define PINMUX_GPIO22__FUNC_SPI3_CSB (MTK_PIN_NO(22) | 2) -#define PINMUX_GPIO22__FUNC_CONN_MCU_TCK (MTK_PIN_NO(22) | 3) -#define PINMUX_GPIO22__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(22) | 4) -#define PINMUX_GPIO22__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(22) | 5) -#define PINMUX_GPIO22__FUNC_I2S2_BCK (MTK_PIN_NO(22) | 6) -#define PINMUX_GPIO22__FUNC_DBG_MON_B6 (MTK_PIN_NO(22) | 7) - -#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) -#define PINMUX_GPIO23__FUNC_DBPI_D10 (MTK_PIN_NO(23) | 1) -#define PINMUX_GPIO23__FUNC_SPI3_MO (MTK_PIN_NO(23) | 2) -#define PINMUX_GPIO23__FUNC_CONN_MCU_TDI (MTK_PIN_NO(23) | 3) -#define PINMUX_GPIO23__FUNC_UCTS1 (MTK_PIN_NO(23) | 4) -#define PINMUX_GPIO23__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(23) | 5) -#define PINMUX_GPIO23__FUNC_I2S2_LRCK (MTK_PIN_NO(23) | 6) -#define PINMUX_GPIO23__FUNC_DBG_MON_B7 (MTK_PIN_NO(23) | 7) - -#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) -#define PINMUX_GPIO24__FUNC_DBPI_D11 (MTK_PIN_NO(24) | 1) -#define PINMUX_GPIO24__FUNC_SPI3_CLK (MTK_PIN_NO(24) | 2) -#define PINMUX_GPIO24__FUNC_SRCLKENAI0 (MTK_PIN_NO(24) | 3) -#define PINMUX_GPIO24__FUNC_URTS1 (MTK_PIN_NO(24) | 4) -#define PINMUX_GPIO24__FUNC_IO_JTAG_TCK (MTK_PIN_NO(24) | 5) -#define PINMUX_GPIO24__FUNC_I2S2_DI (MTK_PIN_NO(24) | 6) -#define PINMUX_GPIO24__FUNC_DBG_MON_B31 (MTK_PIN_NO(24) | 7) - -#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) -#define PINMUX_GPIO25__FUNC_DBPI_HSYNC (MTK_PIN_NO(25) | 1) -#define PINMUX_GPIO25__FUNC_ANT_SEL0 (MTK_PIN_NO(25) | 2) -#define PINMUX_GPIO25__FUNC_SCL6 (MTK_PIN_NO(25) | 3) -#define PINMUX_GPIO25__FUNC_KPCOL2 (MTK_PIN_NO(25) | 4) -#define PINMUX_GPIO25__FUNC_IO_JTAG_TMS (MTK_PIN_NO(25) | 5) -#define PINMUX_GPIO25__FUNC_I2S1_MCK (MTK_PIN_NO(25) | 6) -#define PINMUX_GPIO25__FUNC_DBG_MON_B0 (MTK_PIN_NO(25) | 7) - -#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) -#define PINMUX_GPIO26__FUNC_DBPI_VSYNC (MTK_PIN_NO(26) | 1) -#define PINMUX_GPIO26__FUNC_ANT_SEL1 (MTK_PIN_NO(26) | 2) -#define PINMUX_GPIO26__FUNC_SDA6 (MTK_PIN_NO(26) | 3) -#define PINMUX_GPIO26__FUNC_KPROW2 (MTK_PIN_NO(26) | 4) -#define PINMUX_GPIO26__FUNC_IO_JTAG_TDI (MTK_PIN_NO(26) | 5) -#define PINMUX_GPIO26__FUNC_I2S1_BCK (MTK_PIN_NO(26) | 6) -#define PINMUX_GPIO26__FUNC_DBG_MON_B1 (MTK_PIN_NO(26) | 7) - -#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) -#define PINMUX_GPIO27__FUNC_DBPI_DE (MTK_PIN_NO(27) | 1) -#define PINMUX_GPIO27__FUNC_ANT_SEL2 (MTK_PIN_NO(27) | 2) -#define PINMUX_GPIO27__FUNC_SCL7 (MTK_PIN_NO(27) | 3) -#define PINMUX_GPIO27__FUNC_DMIC_CLK (MTK_PIN_NO(27) | 4) -#define PINMUX_GPIO27__FUNC_IO_JTAG_TDO (MTK_PIN_NO(27) | 5) -#define PINMUX_GPIO27__FUNC_I2S1_LRCK (MTK_PIN_NO(27) | 6) -#define PINMUX_GPIO27__FUNC_DBG_MON_B9 (MTK_PIN_NO(27) | 7) - -#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) -#define PINMUX_GPIO28__FUNC_DBPI_CK (MTK_PIN_NO(28) | 1) -#define PINMUX_GPIO28__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(28) | 2) -#define PINMUX_GPIO28__FUNC_SDA7 (MTK_PIN_NO(28) | 3) -#define PINMUX_GPIO28__FUNC_DMIC_DAT (MTK_PIN_NO(28) | 4) -#define PINMUX_GPIO28__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(28) | 5) -#define PINMUX_GPIO28__FUNC_I2S1_DO (MTK_PIN_NO(28) | 6) -#define PINMUX_GPIO28__FUNC_DBG_MON_B32 (MTK_PIN_NO(28) | 7) - -#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) -#define PINMUX_GPIO29__FUNC_MSDC1_CLK (MTK_PIN_NO(29) | 1) -#define PINMUX_GPIO29__FUNC_IO_JTAG_TCK (MTK_PIN_NO(29) | 2) -#define PINMUX_GPIO29__FUNC_UDI_TCK (MTK_PIN_NO(29) | 3) -#define PINMUX_GPIO29__FUNC_CONN_DSP_JCK (MTK_PIN_NO(29) | 4) -#define PINMUX_GPIO29__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(29) | 5) -#define PINMUX_GPIO29__FUNC_PCM1_CLK (MTK_PIN_NO(29) | 6) -#define PINMUX_GPIO29__FUNC_DBG_MON_A6 (MTK_PIN_NO(29) | 7) - -#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) -#define PINMUX_GPIO30__FUNC_MSDC1_DAT3 (MTK_PIN_NO(30) | 1) -#define PINMUX_GPIO30__FUNC_DAP_MD32_SWD (MTK_PIN_NO(30) | 2) -#define PINMUX_GPIO30__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(30) | 3) -#define PINMUX_GPIO30__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(30) | 4) -#define PINMUX_GPIO30__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(30) | 5) -#define PINMUX_GPIO30__FUNC_PCM1_DI (MTK_PIN_NO(30) | 6) -#define PINMUX_GPIO30__FUNC_DBG_MON_A7 (MTK_PIN_NO(30) | 7) - -#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) -#define PINMUX_GPIO31__FUNC_MSDC1_CMD (MTK_PIN_NO(31) | 1) -#define PINMUX_GPIO31__FUNC_IO_JTAG_TMS (MTK_PIN_NO(31) | 2) -#define PINMUX_GPIO31__FUNC_UDI_TMS (MTK_PIN_NO(31) | 3) -#define PINMUX_GPIO31__FUNC_CONN_DSP_JMS (MTK_PIN_NO(31) | 4) -#define PINMUX_GPIO31__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(31) | 5) -#define PINMUX_GPIO31__FUNC_PCM1_SYNC (MTK_PIN_NO(31) | 6) -#define PINMUX_GPIO31__FUNC_DBG_MON_A8 (MTK_PIN_NO(31) | 7) - -#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) -#define PINMUX_GPIO32__FUNC_MSDC1_DAT0 (MTK_PIN_NO(32) | 1) -#define PINMUX_GPIO32__FUNC_IO_JTAG_TDI (MTK_PIN_NO(32) | 2) -#define PINMUX_GPIO32__FUNC_UDI_TDI (MTK_PIN_NO(32) | 3) -#define PINMUX_GPIO32__FUNC_CONN_DSP_JDI (MTK_PIN_NO(32) | 4) -#define PINMUX_GPIO32__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(32) | 5) -#define PINMUX_GPIO32__FUNC_PCM1_DO0 (MTK_PIN_NO(32) | 6) -#define PINMUX_GPIO32__FUNC_DBG_MON_A9 (MTK_PIN_NO(32) | 7) - -#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) -#define PINMUX_GPIO33__FUNC_MSDC1_DAT2 (MTK_PIN_NO(33) | 1) -#define PINMUX_GPIO33__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(33) | 2) -#define PINMUX_GPIO33__FUNC_UDI_NTRST (MTK_PIN_NO(33) | 3) -#define PINMUX_GPIO33__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(33) | 4) -#define PINMUX_GPIO33__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(33) | 5) -#define PINMUX_GPIO33__FUNC_PCM1_DO2 (MTK_PIN_NO(33) | 6) -#define PINMUX_GPIO33__FUNC_DBG_MON_A10 (MTK_PIN_NO(33) | 7) - -#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) -#define PINMUX_GPIO34__FUNC_MSDC1_DAT1 (MTK_PIN_NO(34) | 1) -#define PINMUX_GPIO34__FUNC_IO_JTAG_TDO (MTK_PIN_NO(34) | 2) -#define PINMUX_GPIO34__FUNC_UDI_TDO (MTK_PIN_NO(34) | 3) -#define PINMUX_GPIO34__FUNC_CONN_DSP_JDO (MTK_PIN_NO(34) | 4) -#define PINMUX_GPIO34__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(34) | 5) -#define PINMUX_GPIO34__FUNC_PCM1_DO1 (MTK_PIN_NO(34) | 6) -#define PINMUX_GPIO34__FUNC_DBG_MON_A11 (MTK_PIN_NO(34) | 7) - -#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) -#define PINMUX_GPIO35__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(35) | 1) -#define PINMUX_GPIO35__FUNC_CCU_JTAG_TDO (MTK_PIN_NO(35) | 2) -#define PINMUX_GPIO35__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(35) | 3) -#define PINMUX_GPIO35__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(35) | 5) -#define PINMUX_GPIO35__FUNC_CONN_DSP_JMS (MTK_PIN_NO(35) | 6) -#define PINMUX_GPIO35__FUNC_DBG_MON_A28 (MTK_PIN_NO(35) | 7) - -#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) -#define PINMUX_GPIO36__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(36) | 1) -#define PINMUX_GPIO36__FUNC_CCU_JTAG_TMS (MTK_PIN_NO(36) | 2) -#define PINMUX_GPIO36__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(36) | 3) -#define PINMUX_GPIO36__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(36) | 4) -#define PINMUX_GPIO36__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(36) | 5) -#define PINMUX_GPIO36__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(36) | 6) -#define PINMUX_GPIO36__FUNC_DBG_MON_A29 (MTK_PIN_NO(36) | 7) - -#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) -#define PINMUX_GPIO37__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(37) | 1) -#define PINMUX_GPIO37__FUNC_CCU_JTAG_TDI (MTK_PIN_NO(37) | 2) -#define PINMUX_GPIO37__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(37) | 3) -#define PINMUX_GPIO37__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(37) | 5) -#define PINMUX_GPIO37__FUNC_CONN_DSP_JDO (MTK_PIN_NO(37) | 6) -#define PINMUX_GPIO37__FUNC_DBG_MON_A30 (MTK_PIN_NO(37) | 7) - -#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) -#define PINMUX_GPIO38__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(38) | 1) -#define PINMUX_GPIO38__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(38) | 3) -#define PINMUX_GPIO38__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(38) | 4) -#define PINMUX_GPIO38__FUNC_DBG_MON_A20 (MTK_PIN_NO(38) | 7) - -#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) -#define PINMUX_GPIO39__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(39) | 1) -#define PINMUX_GPIO39__FUNC_CCU_JTAG_TCK (MTK_PIN_NO(39) | 2) -#define PINMUX_GPIO39__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(39) | 3) -#define PINMUX_GPIO39__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(39) | 5) -#define PINMUX_GPIO39__FUNC_CONN_DSP_JCK (MTK_PIN_NO(39) | 6) -#define PINMUX_GPIO39__FUNC_DBG_MON_A31 (MTK_PIN_NO(39) | 7) - -#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) -#define PINMUX_GPIO40__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(40) | 1) -#define PINMUX_GPIO40__FUNC_CCU_JTAG_TRST (MTK_PIN_NO(40) | 2) -#define PINMUX_GPIO40__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(40) | 3) -#define PINMUX_GPIO40__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(40) | 5) -#define PINMUX_GPIO40__FUNC_CONN_DSP_JDI (MTK_PIN_NO(40) | 6) -#define PINMUX_GPIO40__FUNC_DBG_MON_A32 (MTK_PIN_NO(40) | 7) - -#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) -#define PINMUX_GPIO41__FUNC_IDDIG (MTK_PIN_NO(41) | 1) -#define PINMUX_GPIO41__FUNC_URXD1 (MTK_PIN_NO(41) | 2) -#define PINMUX_GPIO41__FUNC_UCTS0 (MTK_PIN_NO(41) | 3) -#define PINMUX_GPIO41__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(41) | 4) -#define PINMUX_GPIO41__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(41) | 5) -#define PINMUX_GPIO41__FUNC_DMIC_CLK (MTK_PIN_NO(41) | 6) - -#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) -#define PINMUX_GPIO42__FUNC_USB_DRVVBUS (MTK_PIN_NO(42) | 1) -#define PINMUX_GPIO42__FUNC_UTXD1 (MTK_PIN_NO(42) | 2) -#define PINMUX_GPIO42__FUNC_URTS0 (MTK_PIN_NO(42) | 3) -#define PINMUX_GPIO42__FUNC_SSPM_URXD_AO (MTK_PIN_NO(42) | 4) -#define PINMUX_GPIO42__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(42) | 5) -#define PINMUX_GPIO42__FUNC_DMIC_DAT (MTK_PIN_NO(42) | 6) - -#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) -#define PINMUX_GPIO43__FUNC_DISP_PWM (MTK_PIN_NO(43) | 1) - -#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) -#define PINMUX_GPIO44__FUNC_DSI_TE (MTK_PIN_NO(44) | 1) - -#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) -#define PINMUX_GPIO45__FUNC_LCM_RST (MTK_PIN_NO(45) | 1) - -#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) -#define PINMUX_GPIO46__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(46) | 1) -#define PINMUX_GPIO46__FUNC_URXD1 (MTK_PIN_NO(46) | 2) -#define PINMUX_GPIO46__FUNC_UCTS1 (MTK_PIN_NO(46) | 3) -#define PINMUX_GPIO46__FUNC_CCU_UTXD_AO (MTK_PIN_NO(46) | 4) -#define PINMUX_GPIO46__FUNC_TP_UCTS1_AO (MTK_PIN_NO(46) | 5) -#define PINMUX_GPIO46__FUNC_IDDIG (MTK_PIN_NO(46) | 6) -#define PINMUX_GPIO46__FUNC_I2S5_LRCK (MTK_PIN_NO(46) | 7) - -#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) -#define PINMUX_GPIO47__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(47) | 1) -#define PINMUX_GPIO47__FUNC_UTXD1 (MTK_PIN_NO(47) | 2) -#define PINMUX_GPIO47__FUNC_URTS1 (MTK_PIN_NO(47) | 3) -#define PINMUX_GPIO47__FUNC_CCU_URXD_AO (MTK_PIN_NO(47) | 4) -#define PINMUX_GPIO47__FUNC_TP_URTS1_AO (MTK_PIN_NO(47) | 5) -#define PINMUX_GPIO47__FUNC_USB_DRVVBUS (MTK_PIN_NO(47) | 6) -#define PINMUX_GPIO47__FUNC_I2S5_DO (MTK_PIN_NO(47) | 7) - -#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) -#define PINMUX_GPIO48__FUNC_SCL5 (MTK_PIN_NO(48) | 1) - -#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) -#define PINMUX_GPIO49__FUNC_SDA5 (MTK_PIN_NO(49) | 1) - -#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) -#define PINMUX_GPIO50__FUNC_SCL3 (MTK_PIN_NO(50) | 1) - -#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) -#define PINMUX_GPIO51__FUNC_SDA3 (MTK_PIN_NO(51) | 1) - -#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) -#define PINMUX_GPIO52__FUNC_BPI_ANT2 (MTK_PIN_NO(52) | 1) - -#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) -#define PINMUX_GPIO53__FUNC_BPI_ANT0 (MTK_PIN_NO(53) | 1) - -#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) -#define PINMUX_GPIO54__FUNC_BPI_OLAT1 (MTK_PIN_NO(54) | 1) - -#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) -#define PINMUX_GPIO55__FUNC_BPI_BUS8 (MTK_PIN_NO(55) | 1) - -#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) -#define PINMUX_GPIO56__FUNC_BPI_BUS9 (MTK_PIN_NO(56) | 1) -#define PINMUX_GPIO56__FUNC_SCL_6306 (MTK_PIN_NO(56) | 2) - -#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) -#define PINMUX_GPIO57__FUNC_BPI_BUS10 (MTK_PIN_NO(57) | 1) -#define PINMUX_GPIO57__FUNC_SDA_6306 (MTK_PIN_NO(57) | 2) - -#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) -#define PINMUX_GPIO58__FUNC_RFIC0_BSI_D2 (MTK_PIN_NO(58) | 1) -#define PINMUX_GPIO58__FUNC_SPM_BSI_D2 (MTK_PIN_NO(58) | 2) -#define PINMUX_GPIO58__FUNC_PWM_B (MTK_PIN_NO(58) | 3) - -#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) -#define PINMUX_GPIO59__FUNC_RFIC0_BSI_D1 (MTK_PIN_NO(59) | 1) -#define PINMUX_GPIO59__FUNC_SPM_BSI_D1 (MTK_PIN_NO(59) | 2) - -#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) -#define PINMUX_GPIO60__FUNC_RFIC0_BSI_D0 (MTK_PIN_NO(60) | 1) -#define PINMUX_GPIO60__FUNC_SPM_BSI_D0 (MTK_PIN_NO(60) | 2) - -#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) -#define PINMUX_GPIO61__FUNC_MIPI1_SDATA (MTK_PIN_NO(61) | 1) - -#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) -#define PINMUX_GPIO62__FUNC_MIPI1_SCLK (MTK_PIN_NO(62) | 1) - -#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) -#define PINMUX_GPIO63__FUNC_MIPI0_SDATA (MTK_PIN_NO(63) | 1) - -#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) -#define PINMUX_GPIO64__FUNC_MIPI0_SCLK (MTK_PIN_NO(64) | 1) - -#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) -#define PINMUX_GPIO65__FUNC_MIPI3_SDATA (MTK_PIN_NO(65) | 1) -#define PINMUX_GPIO65__FUNC_BPI_OLAT2 (MTK_PIN_NO(65) | 2) - -#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) -#define PINMUX_GPIO66__FUNC_MIPI3_SCLK (MTK_PIN_NO(66) | 1) -#define PINMUX_GPIO66__FUNC_BPI_OLAT3 (MTK_PIN_NO(66) | 2) - -#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) -#define PINMUX_GPIO67__FUNC_MIPI2_SDATA (MTK_PIN_NO(67) | 1) - -#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) -#define PINMUX_GPIO68__FUNC_MIPI2_SCLK (MTK_PIN_NO(68) | 1) - -#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) -#define PINMUX_GPIO69__FUNC_BPI_BUS7 (MTK_PIN_NO(69) | 1) - -#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) -#define PINMUX_GPIO70__FUNC_BPI_BUS6 (MTK_PIN_NO(70) | 1) - -#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) -#define PINMUX_GPIO71__FUNC_BPI_BUS5 (MTK_PIN_NO(71) | 1) - -#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) -#define PINMUX_GPIO72__FUNC_BPI_BUS4 (MTK_PIN_NO(72) | 1) - -#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) -#define PINMUX_GPIO73__FUNC_BPI_BUS3 (MTK_PIN_NO(73) | 1) - -#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) -#define PINMUX_GPIO74__FUNC_BPI_BUS2 (MTK_PIN_NO(74) | 1) - -#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) -#define PINMUX_GPIO75__FUNC_BPI_BUS1 (MTK_PIN_NO(75) | 1) - -#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) -#define PINMUX_GPIO76__FUNC_BPI_BUS0 (MTK_PIN_NO(76) | 1) - -#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) -#define PINMUX_GPIO77__FUNC_BPI_ANT1 (MTK_PIN_NO(77) | 1) - -#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) -#define PINMUX_GPIO78__FUNC_BPI_OLAT0 (MTK_PIN_NO(78) | 1) - -#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) -#define PINMUX_GPIO79__FUNC_BPI_PA_VM1 (MTK_PIN_NO(79) | 1) -#define PINMUX_GPIO79__FUNC_MIPI4_SDATA (MTK_PIN_NO(79) | 2) - -#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) -#define PINMUX_GPIO80__FUNC_BPI_PA_VM0 (MTK_PIN_NO(80) | 1) -#define PINMUX_GPIO80__FUNC_MIPI4_SCLK (MTK_PIN_NO(80) | 2) - -#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) -#define PINMUX_GPIO81__FUNC_SDA1 (MTK_PIN_NO(81) | 1) - -#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) -#define PINMUX_GPIO82__FUNC_SDA0 (MTK_PIN_NO(82) | 1) - -#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) -#define PINMUX_GPIO83__FUNC_SCL0 (MTK_PIN_NO(83) | 1) - -#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) -#define PINMUX_GPIO84__FUNC_SCL1 (MTK_PIN_NO(84) | 1) - -#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) -#define PINMUX_GPIO85__FUNC_SPI0_MI (MTK_PIN_NO(85) | 1) -#define PINMUX_GPIO85__FUNC_SCP_SPI0_MI (MTK_PIN_NO(85) | 2) -#define PINMUX_GPIO85__FUNC_CLKM3 (MTK_PIN_NO(85) | 3) -#define PINMUX_GPIO85__FUNC_I2S1_BCK (MTK_PIN_NO(85) | 4) -#define PINMUX_GPIO85__FUNC_MFG_DFD_JTAG_TDO (MTK_PIN_NO(85) | 5) -#define PINMUX_GPIO85__FUNC_DFD_TDO (MTK_PIN_NO(85) | 6) -#define PINMUX_GPIO85__FUNC_JTDO_SEL1 (MTK_PIN_NO(85) | 7) - -#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) -#define PINMUX_GPIO86__FUNC_SPI0_CSB (MTK_PIN_NO(86) | 1) -#define PINMUX_GPIO86__FUNC_SCP_SPI0_CS (MTK_PIN_NO(86) | 2) -#define PINMUX_GPIO86__FUNC_CLKM0 (MTK_PIN_NO(86) | 3) -#define PINMUX_GPIO86__FUNC_I2S1_LRCK (MTK_PIN_NO(86) | 4) -#define PINMUX_GPIO86__FUNC_MFG_DFD_JTAG_TMS (MTK_PIN_NO(86) | 5) -#define PINMUX_GPIO86__FUNC_DFD_TMS (MTK_PIN_NO(86) | 6) -#define PINMUX_GPIO86__FUNC_JTMS_SEL1 (MTK_PIN_NO(86) | 7) - -#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) -#define PINMUX_GPIO87__FUNC_SPI0_MO (MTK_PIN_NO(87) | 1) -#define PINMUX_GPIO87__FUNC_SCP_SPI0_MO (MTK_PIN_NO(87) | 2) -#define PINMUX_GPIO87__FUNC_SDA1 (MTK_PIN_NO(87) | 3) -#define PINMUX_GPIO87__FUNC_I2S1_DO (MTK_PIN_NO(87) | 4) -#define PINMUX_GPIO87__FUNC_MFG_DFD_JTAG_TDI (MTK_PIN_NO(87) | 5) -#define PINMUX_GPIO87__FUNC_DFD_TDI (MTK_PIN_NO(87) | 6) -#define PINMUX_GPIO87__FUNC_JTDI_SEL1 (MTK_PIN_NO(87) | 7) - -#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) -#define PINMUX_GPIO88__FUNC_SPI0_CLK (MTK_PIN_NO(88) | 1) -#define PINMUX_GPIO88__FUNC_SCP_SPI0_CK (MTK_PIN_NO(88) | 2) -#define PINMUX_GPIO88__FUNC_SCL1 (MTK_PIN_NO(88) | 3) -#define PINMUX_GPIO88__FUNC_I2S1_MCK (MTK_PIN_NO(88) | 4) -#define PINMUX_GPIO88__FUNC_MFG_DFD_JTAG_TCK (MTK_PIN_NO(88) | 5) -#define PINMUX_GPIO88__FUNC_DFD_TCK_XI (MTK_PIN_NO(88) | 6) -#define PINMUX_GPIO88__FUNC_JTCK_SEL1 (MTK_PIN_NO(88) | 7) - -#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) -#define PINMUX_GPIO89__FUNC_SRCLKENAI0 (MTK_PIN_NO(89) | 1) -#define PINMUX_GPIO89__FUNC_PWM_C (MTK_PIN_NO(89) | 2) -#define PINMUX_GPIO89__FUNC_I2S5_BCK (MTK_PIN_NO(89) | 3) -#define PINMUX_GPIO89__FUNC_ANT_SEL6 (MTK_PIN_NO(89) | 4) -#define PINMUX_GPIO89__FUNC_SDA8 (MTK_PIN_NO(89) | 5) -#define PINMUX_GPIO89__FUNC_CMVREF0 (MTK_PIN_NO(89) | 6) -#define PINMUX_GPIO89__FUNC_DBG_MON_A21 (MTK_PIN_NO(89) | 7) - -#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) -#define PINMUX_GPIO90__FUNC_PWM_A (MTK_PIN_NO(90) | 1) -#define PINMUX_GPIO90__FUNC_CMMCLK2 (MTK_PIN_NO(90) | 2) -#define PINMUX_GPIO90__FUNC_I2S5_LRCK (MTK_PIN_NO(90) | 3) -#define PINMUX_GPIO90__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(90) | 4) -#define PINMUX_GPIO90__FUNC_SCL8 (MTK_PIN_NO(90) | 5) -#define PINMUX_GPIO90__FUNC_PTA_RXD (MTK_PIN_NO(90) | 6) -#define PINMUX_GPIO90__FUNC_DBG_MON_A22 (MTK_PIN_NO(90) | 7) - -#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) -#define PINMUX_GPIO91__FUNC_KPROW1 (MTK_PIN_NO(91) | 1) -#define PINMUX_GPIO91__FUNC_PWM_B (MTK_PIN_NO(91) | 2) -#define PINMUX_GPIO91__FUNC_I2S5_DO (MTK_PIN_NO(91) | 3) -#define PINMUX_GPIO91__FUNC_ANT_SEL7 (MTK_PIN_NO(91) | 4) -#define PINMUX_GPIO91__FUNC_CMMCLK3 (MTK_PIN_NO(91) | 5) -#define PINMUX_GPIO91__FUNC_PTA_TXD (MTK_PIN_NO(91) | 6) - -#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) -#define PINMUX_GPIO92__FUNC_KPROW0 (MTK_PIN_NO(92) | 1) - -#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) -#define PINMUX_GPIO93__FUNC_KPCOL0 (MTK_PIN_NO(93) | 1) -#define PINMUX_GPIO93__FUNC_DBG_MON_B27 (MTK_PIN_NO(93) | 7) - -#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) -#define PINMUX_GPIO94__FUNC_KPCOL1 (MTK_PIN_NO(94) | 1) -#define PINMUX_GPIO94__FUNC_I2S2_DI2 (MTK_PIN_NO(94) | 2) -#define PINMUX_GPIO94__FUNC_I2S5_MCK (MTK_PIN_NO(94) | 3) -#define PINMUX_GPIO94__FUNC_CMMCLK2 (MTK_PIN_NO(94) | 4) -#define PINMUX_GPIO94__FUNC_SCP_SPI2_MI (MTK_PIN_NO(94) | 5) -#define PINMUX_GPIO94__FUNC_SRCLKENAI1 (MTK_PIN_NO(94) | 6) -#define PINMUX_GPIO94__FUNC_SPI2_MI (MTK_PIN_NO(94) | 7) - -#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) -#define PINMUX_GPIO95__FUNC_URXD0 (MTK_PIN_NO(95) | 1) -#define PINMUX_GPIO95__FUNC_UTXD0 (MTK_PIN_NO(95) | 2) -#define PINMUX_GPIO95__FUNC_MD_URXD0 (MTK_PIN_NO(95) | 3) -#define PINMUX_GPIO95__FUNC_MD_URXD1 (MTK_PIN_NO(95) | 4) -#define PINMUX_GPIO95__FUNC_SSPM_URXD_AO (MTK_PIN_NO(95) | 5) -#define PINMUX_GPIO95__FUNC_CCU_URXD_AO (MTK_PIN_NO(95) | 6) - -#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) -#define PINMUX_GPIO96__FUNC_UTXD0 (MTK_PIN_NO(96) | 1) -#define PINMUX_GPIO96__FUNC_URXD0 (MTK_PIN_NO(96) | 2) -#define PINMUX_GPIO96__FUNC_MD_UTXD0 (MTK_PIN_NO(96) | 3) -#define PINMUX_GPIO96__FUNC_MD_UTXD1 (MTK_PIN_NO(96) | 4) -#define PINMUX_GPIO96__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(96) | 5) -#define PINMUX_GPIO96__FUNC_CCU_UTXD_AO (MTK_PIN_NO(96) | 6) -#define PINMUX_GPIO96__FUNC_DBG_MON_B2 (MTK_PIN_NO(96) | 7) - -#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) -#define PINMUX_GPIO97__FUNC_UCTS0 (MTK_PIN_NO(97) | 1) -#define PINMUX_GPIO97__FUNC_I2S2_MCK (MTK_PIN_NO(97) | 2) -#define PINMUX_GPIO97__FUNC_IDDIG (MTK_PIN_NO(97) | 3) -#define PINMUX_GPIO97__FUNC_CONN_MCU_TDO (MTK_PIN_NO(97) | 4) -#define PINMUX_GPIO97__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(97) | 5) -#define PINMUX_GPIO97__FUNC_IO_JTAG_TDO (MTK_PIN_NO(97) | 6) -#define PINMUX_GPIO97__FUNC_DBG_MON_B3 (MTK_PIN_NO(97) | 7) - -#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) -#define PINMUX_GPIO98__FUNC_URTS0 (MTK_PIN_NO(98) | 1) -#define PINMUX_GPIO98__FUNC_I2S2_BCK (MTK_PIN_NO(98) | 2) -#define PINMUX_GPIO98__FUNC_USB_DRVVBUS (MTK_PIN_NO(98) | 3) -#define PINMUX_GPIO98__FUNC_CONN_MCU_TMS (MTK_PIN_NO(98) | 4) -#define PINMUX_GPIO98__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(98) | 5) -#define PINMUX_GPIO98__FUNC_IO_JTAG_TMS (MTK_PIN_NO(98) | 6) -#define PINMUX_GPIO98__FUNC_DBG_MON_B4 (MTK_PIN_NO(98) | 7) - -#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) -#define PINMUX_GPIO99__FUNC_CMMCLK0 (MTK_PIN_NO(99) | 1) -#define PINMUX_GPIO99__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(99) | 4) -#define PINMUX_GPIO99__FUNC_DBG_MON_B28 (MTK_PIN_NO(99) | 7) - -#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) -#define PINMUX_GPIO100__FUNC_CMMCLK1 (MTK_PIN_NO(100) | 1) -#define PINMUX_GPIO100__FUNC_PWM_C (MTK_PIN_NO(100) | 2) -#define PINMUX_GPIO100__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(100) | 3) -#define PINMUX_GPIO100__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(100) | 4) -#define PINMUX_GPIO100__FUNC_DBG_MON_B29 (MTK_PIN_NO(100) | 7) - -#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) -#define PINMUX_GPIO101__FUNC_CLKM2 (MTK_PIN_NO(101) | 1) -#define PINMUX_GPIO101__FUNC_I2S2_LRCK (MTK_PIN_NO(101) | 2) -#define PINMUX_GPIO101__FUNC_CMVREF1 (MTK_PIN_NO(101) | 3) -#define PINMUX_GPIO101__FUNC_CONN_MCU_TCK (MTK_PIN_NO(101) | 4) -#define PINMUX_GPIO101__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(101) | 5) -#define PINMUX_GPIO101__FUNC_IO_JTAG_TCK (MTK_PIN_NO(101) | 6) - -#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) -#define PINMUX_GPIO102__FUNC_CLKM1 (MTK_PIN_NO(102) | 1) -#define PINMUX_GPIO102__FUNC_I2S2_DI (MTK_PIN_NO(102) | 2) -#define PINMUX_GPIO102__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(102) | 3) -#define PINMUX_GPIO102__FUNC_CONN_MCU_TDI (MTK_PIN_NO(102) | 4) -#define PINMUX_GPIO102__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(102) | 5) -#define PINMUX_GPIO102__FUNC_IO_JTAG_TDI (MTK_PIN_NO(102) | 6) -#define PINMUX_GPIO102__FUNC_DBG_MON_B8 (MTK_PIN_NO(102) | 7) - -#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) -#define PINMUX_GPIO103__FUNC_SCL2 (MTK_PIN_NO(103) | 1) - -#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) -#define PINMUX_GPIO104__FUNC_SDA2 (MTK_PIN_NO(104) | 1) - -#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) -#define PINMUX_GPIO105__FUNC_SCL4 (MTK_PIN_NO(105) | 1) - -#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) -#define PINMUX_GPIO106__FUNC_SDA4 (MTK_PIN_NO(106) | 1) - -#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) -#define PINMUX_GPIO107__FUNC_DMIC_CLK (MTK_PIN_NO(107) | 1) -#define PINMUX_GPIO107__FUNC_ANT_SEL0 (MTK_PIN_NO(107) | 2) -#define PINMUX_GPIO107__FUNC_CLKM0 (MTK_PIN_NO(107) | 3) -#define PINMUX_GPIO107__FUNC_SDA7 (MTK_PIN_NO(107) | 4) -#define PINMUX_GPIO107__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(107) | 5) -#define PINMUX_GPIO107__FUNC_PWM_A (MTK_PIN_NO(107) | 6) -#define PINMUX_GPIO107__FUNC_DBG_MON_B12 (MTK_PIN_NO(107) | 7) - -#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) -#define PINMUX_GPIO108__FUNC_CMMCLK2 (MTK_PIN_NO(108) | 1) -#define PINMUX_GPIO108__FUNC_ANT_SEL1 (MTK_PIN_NO(108) | 2) -#define PINMUX_GPIO108__FUNC_CLKM1 (MTK_PIN_NO(108) | 3) -#define PINMUX_GPIO108__FUNC_SCL8 (MTK_PIN_NO(108) | 4) -#define PINMUX_GPIO108__FUNC_DAP_MD32_SWD (MTK_PIN_NO(108) | 5) -#define PINMUX_GPIO108__FUNC_PWM_B (MTK_PIN_NO(108) | 6) -#define PINMUX_GPIO108__FUNC_DBG_MON_B13 (MTK_PIN_NO(108) | 7) - -#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) -#define PINMUX_GPIO109__FUNC_DMIC_DAT (MTK_PIN_NO(109) | 1) -#define PINMUX_GPIO109__FUNC_ANT_SEL2 (MTK_PIN_NO(109) | 2) -#define PINMUX_GPIO109__FUNC_CLKM2 (MTK_PIN_NO(109) | 3) -#define PINMUX_GPIO109__FUNC_SDA8 (MTK_PIN_NO(109) | 4) -#define PINMUX_GPIO109__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(109) | 5) -#define PINMUX_GPIO109__FUNC_PWM_C (MTK_PIN_NO(109) | 6) -#define PINMUX_GPIO109__FUNC_DBG_MON_B14 (MTK_PIN_NO(109) | 7) - -#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) -#define PINMUX_GPIO110__FUNC_SCL7 (MTK_PIN_NO(110) | 1) -#define PINMUX_GPIO110__FUNC_ANT_SEL0 (MTK_PIN_NO(110) | 2) -#define PINMUX_GPIO110__FUNC_TP_URXD1_AO (MTK_PIN_NO(110) | 3) -#define PINMUX_GPIO110__FUNC_USB_DRVVBUS (MTK_PIN_NO(110) | 4) -#define PINMUX_GPIO110__FUNC_SRCLKENAI1 (MTK_PIN_NO(110) | 5) -#define PINMUX_GPIO110__FUNC_KPCOL2 (MTK_PIN_NO(110) | 6) -#define PINMUX_GPIO110__FUNC_URXD1 (MTK_PIN_NO(110) | 7) - -#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) -#define PINMUX_GPIO111__FUNC_CMMCLK3 (MTK_PIN_NO(111) | 1) -#define PINMUX_GPIO111__FUNC_ANT_SEL1 (MTK_PIN_NO(111) | 2) -#define PINMUX_GPIO111__FUNC_SRCLKENAI0 (MTK_PIN_NO(111) | 3) -#define PINMUX_GPIO111__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(111) | 4) -#define PINMUX_GPIO111__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(111) | 5) -#define PINMUX_GPIO111__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(111) | 7) - -#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) -#define PINMUX_GPIO112__FUNC_SDA7 (MTK_PIN_NO(112) | 1) -#define PINMUX_GPIO112__FUNC_ANT_SEL2 (MTK_PIN_NO(112) | 2) -#define PINMUX_GPIO112__FUNC_TP_UTXD1_AO (MTK_PIN_NO(112) | 3) -#define PINMUX_GPIO112__FUNC_IDDIG (MTK_PIN_NO(112) | 4) -#define PINMUX_GPIO112__FUNC_AGPS_SYNC (MTK_PIN_NO(112) | 5) -#define PINMUX_GPIO112__FUNC_KPROW2 (MTK_PIN_NO(112) | 6) -#define PINMUX_GPIO112__FUNC_UTXD1 (MTK_PIN_NO(112) | 7) - -#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) -#define PINMUX_GPIO113__FUNC_CONN_TOP_CLK (MTK_PIN_NO(113) | 1) -#define PINMUX_GPIO113__FUNC_SCL6 (MTK_PIN_NO(113) | 3) -#define PINMUX_GPIO113__FUNC_AUXIF_CLK0 (MTK_PIN_NO(113) | 4) -#define PINMUX_GPIO113__FUNC_TP_UCTS1_AO (MTK_PIN_NO(113) | 6) - -#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) -#define PINMUX_GPIO114__FUNC_CONN_TOP_DATA (MTK_PIN_NO(114) | 1) -#define PINMUX_GPIO114__FUNC_SDA6 (MTK_PIN_NO(114) | 3) -#define PINMUX_GPIO114__FUNC_AUXIF_ST0 (MTK_PIN_NO(114) | 4) -#define PINMUX_GPIO114__FUNC_TP_URTS1_AO (MTK_PIN_NO(114) | 6) - -#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) -#define PINMUX_GPIO115__FUNC_CONN_BT_CLK (MTK_PIN_NO(115) | 1) -#define PINMUX_GPIO115__FUNC_UTXD1 (MTK_PIN_NO(115) | 2) -#define PINMUX_GPIO115__FUNC_PTA_TXD (MTK_PIN_NO(115) | 3) -#define PINMUX_GPIO115__FUNC_AUXIF_CLK1 (MTK_PIN_NO(115) | 4) -#define PINMUX_GPIO115__FUNC_DAP_MD32_SWD (MTK_PIN_NO(115) | 5) -#define PINMUX_GPIO115__FUNC_TP_UTXD1_AO (MTK_PIN_NO(115) | 6) - -#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) -#define PINMUX_GPIO116__FUNC_CONN_BT_DATA (MTK_PIN_NO(116) | 1) -#define PINMUX_GPIO116__FUNC_IPU_JTAG_TRST (MTK_PIN_NO(116) | 2) -#define PINMUX_GPIO116__FUNC_AUXIF_ST1 (MTK_PIN_NO(116) | 4) -#define PINMUX_GPIO116__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(116) | 5) -#define PINMUX_GPIO116__FUNC_TP_URXD2_AO (MTK_PIN_NO(116) | 6) -#define PINMUX_GPIO116__FUNC_DBG_MON_A0 (MTK_PIN_NO(116) | 7) - -#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) -#define PINMUX_GPIO117__FUNC_CONN_WF_HB0 (MTK_PIN_NO(117) | 1) -#define PINMUX_GPIO117__FUNC_IPU_JTAG_TDO (MTK_PIN_NO(117) | 2) -#define PINMUX_GPIO117__FUNC_TP_UTXD2_AO (MTK_PIN_NO(117) | 6) -#define PINMUX_GPIO117__FUNC_DBG_MON_A4 (MTK_PIN_NO(117) | 7) - -#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) -#define PINMUX_GPIO118__FUNC_CONN_WF_HB1 (MTK_PIN_NO(118) | 1) -#define PINMUX_GPIO118__FUNC_IPU_JTAG_TDI (MTK_PIN_NO(118) | 2) -#define PINMUX_GPIO118__FUNC_SSPM_URXD_AO (MTK_PIN_NO(118) | 5) -#define PINMUX_GPIO118__FUNC_TP_UCTS2_AO (MTK_PIN_NO(118) | 6) -#define PINMUX_GPIO118__FUNC_DBG_MON_A5 (MTK_PIN_NO(118) | 7) - -#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) -#define PINMUX_GPIO119__FUNC_CONN_WF_HB2 (MTK_PIN_NO(119) | 1) -#define PINMUX_GPIO119__FUNC_IPU_JTAG_TCK (MTK_PIN_NO(119) | 2) -#define PINMUX_GPIO119__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(119) | 5) -#define PINMUX_GPIO119__FUNC_TP_URTS2_AO (MTK_PIN_NO(119) | 6) - -#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) -#define PINMUX_GPIO120__FUNC_CONN_WB_PTA (MTK_PIN_NO(120) | 1) -#define PINMUX_GPIO120__FUNC_IPU_JTAG_TMS (MTK_PIN_NO(120) | 2) -#define PINMUX_GPIO120__FUNC_CCU_URXD_AO (MTK_PIN_NO(120) | 5) - -#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) -#define PINMUX_GPIO121__FUNC_CONN_HRST_B (MTK_PIN_NO(121) | 1) -#define PINMUX_GPIO121__FUNC_URXD1 (MTK_PIN_NO(121) | 2) -#define PINMUX_GPIO121__FUNC_PTA_RXD (MTK_PIN_NO(121) | 3) -#define PINMUX_GPIO121__FUNC_CCU_UTXD_AO (MTK_PIN_NO(121) | 5) -#define PINMUX_GPIO121__FUNC_TP_URXD1_AO (MTK_PIN_NO(121) | 6) - -#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) -#define PINMUX_GPIO122__FUNC_MSDC0_CMD (MTK_PIN_NO(122) | 1) -#define PINMUX_GPIO122__FUNC_SSPM_URXD2_AO (MTK_PIN_NO(122) | 2) -#define PINMUX_GPIO122__FUNC_ANT_SEL1 (MTK_PIN_NO(122) | 3) -#define PINMUX_GPIO122__FUNC_DBG_MON_A12 (MTK_PIN_NO(122) | 7) - -#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) -#define PINMUX_GPIO123__FUNC_MSDC0_DAT0 (MTK_PIN_NO(123) | 1) -#define PINMUX_GPIO123__FUNC_ANT_SEL0 (MTK_PIN_NO(123) | 3) -#define PINMUX_GPIO123__FUNC_DBG_MON_A13 (MTK_PIN_NO(123) | 7) - -#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) -#define PINMUX_GPIO124__FUNC_MSDC0_CLK (MTK_PIN_NO(124) | 1) -#define PINMUX_GPIO124__FUNC_DBG_MON_A14 (MTK_PIN_NO(124) | 7) - -#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) -#define PINMUX_GPIO125__FUNC_MSDC0_DAT2 (MTK_PIN_NO(125) | 1) -#define PINMUX_GPIO125__FUNC_MRG_CLK (MTK_PIN_NO(125) | 3) -#define PINMUX_GPIO125__FUNC_DBG_MON_A15 (MTK_PIN_NO(125) | 7) - -#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) -#define PINMUX_GPIO126__FUNC_MSDC0_DAT4 (MTK_PIN_NO(126) | 1) -#define PINMUX_GPIO126__FUNC_ANT_SEL5 (MTK_PIN_NO(126) | 3) -#define PINMUX_GPIO126__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(126) | 6) -#define PINMUX_GPIO126__FUNC_DBG_MON_A16 (MTK_PIN_NO(126) | 7) - -#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) -#define PINMUX_GPIO127__FUNC_MSDC0_DAT6 (MTK_PIN_NO(127) | 1) -#define PINMUX_GPIO127__FUNC_ANT_SEL4 (MTK_PIN_NO(127) | 3) -#define PINMUX_GPIO127__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(127) | 6) -#define PINMUX_GPIO127__FUNC_DBG_MON_A17 (MTK_PIN_NO(127) | 7) - -#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) -#define PINMUX_GPIO128__FUNC_MSDC0_DAT1 (MTK_PIN_NO(128) | 1) -#define PINMUX_GPIO128__FUNC_ANT_SEL2 (MTK_PIN_NO(128) | 3) -#define PINMUX_GPIO128__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(128) | 6) -#define PINMUX_GPIO128__FUNC_DBG_MON_A18 (MTK_PIN_NO(128) | 7) - -#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) -#define PINMUX_GPIO129__FUNC_MSDC0_DAT5 (MTK_PIN_NO(129) | 1) -#define PINMUX_GPIO129__FUNC_ANT_SEL3 (MTK_PIN_NO(129) | 3) -#define PINMUX_GPIO129__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(129) | 6) -#define PINMUX_GPIO129__FUNC_DBG_MON_A23 (MTK_PIN_NO(129) | 7) - -#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) -#define PINMUX_GPIO130__FUNC_MSDC0_DAT7 (MTK_PIN_NO(130) | 1) -#define PINMUX_GPIO130__FUNC_MRG_DO (MTK_PIN_NO(130) | 3) -#define PINMUX_GPIO130__FUNC_DBG_MON_A24 (MTK_PIN_NO(130) | 7) - -#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) -#define PINMUX_GPIO131__FUNC_MSDC0_DSL (MTK_PIN_NO(131) | 1) -#define PINMUX_GPIO131__FUNC_MRG_SYNC (MTK_PIN_NO(131) | 3) -#define PINMUX_GPIO131__FUNC_DBG_MON_A25 (MTK_PIN_NO(131) | 7) - -#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) -#define PINMUX_GPIO132__FUNC_MSDC0_DAT3 (MTK_PIN_NO(132) | 1) -#define PINMUX_GPIO132__FUNC_MRG_DI (MTK_PIN_NO(132) | 3) -#define PINMUX_GPIO132__FUNC_DBG_MON_A26 (MTK_PIN_NO(132) | 7) - -#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) -#define PINMUX_GPIO133__FUNC_MSDC0_RSTB (MTK_PIN_NO(133) | 1) -#define PINMUX_GPIO133__FUNC_AGPS_SYNC (MTK_PIN_NO(133) | 3) -#define PINMUX_GPIO133__FUNC_DBG_MON_A27 (MTK_PIN_NO(133) | 7) - -#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) -#define PINMUX_GPIO134__FUNC_RTC32K_CK (MTK_PIN_NO(134) | 1) - -#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) -#define PINMUX_GPIO135__FUNC_WATCHDOG (MTK_PIN_NO(135) | 1) - -#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) -#define PINMUX_GPIO136__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(136) | 1) -#define PINMUX_GPIO136__FUNC_AUD_CLK_MISO (MTK_PIN_NO(136) | 2) -#define PINMUX_GPIO136__FUNC_I2S1_MCK (MTK_PIN_NO(136) | 3) -#define PINMUX_GPIO136__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(136) | 6) - -#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) -#define PINMUX_GPIO137__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(137) | 1) -#define PINMUX_GPIO137__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(137) | 2) -#define PINMUX_GPIO137__FUNC_I2S1_BCK (MTK_PIN_NO(137) | 3) - -#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) -#define PINMUX_GPIO138__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(138) | 1) -#define PINMUX_GPIO138__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(138) | 2) -#define PINMUX_GPIO138__FUNC_I2S1_LRCK (MTK_PIN_NO(138) | 3) -#define PINMUX_GPIO138__FUNC_DBG_MON_B24 (MTK_PIN_NO(138) | 7) - -#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) -#define PINMUX_GPIO139__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(139) | 1) -#define PINMUX_GPIO139__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(139) | 2) -#define PINMUX_GPIO139__FUNC_I2S1_DO (MTK_PIN_NO(139) | 3) -#define PINMUX_GPIO139__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(139) | 6) - -#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) -#define PINMUX_GPIO140__FUNC_AUD_CLK_MISO (MTK_PIN_NO(140) | 1) -#define PINMUX_GPIO140__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(140) | 2) -#define PINMUX_GPIO140__FUNC_I2S0_MCK (MTK_PIN_NO(140) | 3) -#define PINMUX_GPIO140__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(140) | 6) - -#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) -#define PINMUX_GPIO141__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(141) | 1) -#define PINMUX_GPIO141__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(141) | 2) -#define PINMUX_GPIO141__FUNC_I2S0_BCK (MTK_PIN_NO(141) | 3) - -#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) -#define PINMUX_GPIO142__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(142) | 1) -#define PINMUX_GPIO142__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(142) | 2) -#define PINMUX_GPIO142__FUNC_I2S0_LRCK (MTK_PIN_NO(142) | 3) -#define PINMUX_GPIO142__FUNC_VOW_DAT_MISO (MTK_PIN_NO(142) | 4) -#define PINMUX_GPIO142__FUNC_DBG_MON_B25 (MTK_PIN_NO(142) | 7) - -#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) -#define PINMUX_GPIO143__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(143) | 1) -#define PINMUX_GPIO143__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(143) | 2) -#define PINMUX_GPIO143__FUNC_I2S0_DI (MTK_PIN_NO(143) | 3) -#define PINMUX_GPIO143__FUNC_VOW_CLK_MISO (MTK_PIN_NO(143) | 4) -#define PINMUX_GPIO143__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(143) | 6) -#define PINMUX_GPIO143__FUNC_DBG_MON_B26 (MTK_PIN_NO(143) | 7) - -#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) -#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(144) | 1) -#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(144) | 2) - -#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) -#define PINMUX_GPIO145__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(145) | 1) - -#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) -#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(146) | 1) -#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(146) | 2) - -#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) -#define PINMUX_GPIO147__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(147) | 1) - -#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) -#define PINMUX_GPIO148__FUNC_SRCLKENA0 (MTK_PIN_NO(148) | 1) - -#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) -#define PINMUX_GPIO149__FUNC_SRCLKENA1 (MTK_PIN_NO(149) | 1) - -#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) -#define PINMUX_GPIO150__FUNC_PWM_A (MTK_PIN_NO(150) | 1) -#define PINMUX_GPIO150__FUNC_CMFLASH (MTK_PIN_NO(150) | 2) -#define PINMUX_GPIO150__FUNC_CLKM0 (MTK_PIN_NO(150) | 3) -#define PINMUX_GPIO150__FUNC_DBG_MON_B30 (MTK_PIN_NO(150) | 7) - -#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) -#define PINMUX_GPIO151__FUNC_PWM_B (MTK_PIN_NO(151) | 1) -#define PINMUX_GPIO151__FUNC_CMVREF0 (MTK_PIN_NO(151) | 2) -#define PINMUX_GPIO151__FUNC_CLKM1 (MTK_PIN_NO(151) | 3) -#define PINMUX_GPIO151__FUNC_DBG_MON_B20 (MTK_PIN_NO(151) | 7) - -#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) -#define PINMUX_GPIO152__FUNC_PWM_C (MTK_PIN_NO(152) | 1) -#define PINMUX_GPIO152__FUNC_CMFLASH (MTK_PIN_NO(152) | 2) -#define PINMUX_GPIO152__FUNC_CLKM2 (MTK_PIN_NO(152) | 3) -#define PINMUX_GPIO152__FUNC_DBG_MON_B21 (MTK_PIN_NO(152) | 7) - -#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) -#define PINMUX_GPIO153__FUNC_PWM_A (MTK_PIN_NO(153) | 1) -#define PINMUX_GPIO153__FUNC_CMVREF0 (MTK_PIN_NO(153) | 2) -#define PINMUX_GPIO153__FUNC_CLKM3 (MTK_PIN_NO(153) | 3) -#define PINMUX_GPIO153__FUNC_DBG_MON_B22 (MTK_PIN_NO(153) | 7) - -#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) -#define PINMUX_GPIO154__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(154) | 1) -#define PINMUX_GPIO154__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(154) | 2) -#define PINMUX_GPIO154__FUNC_DBG_MON_B18 (MTK_PIN_NO(154) | 7) - -#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) -#define PINMUX_GPIO155__FUNC_ANT_SEL0 (MTK_PIN_NO(155) | 1) -#define PINMUX_GPIO155__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(155) | 2) -#define PINMUX_GPIO155__FUNC_CMVREF1 (MTK_PIN_NO(155) | 3) -#define PINMUX_GPIO155__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(155) | 7) - -#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) -#define PINMUX_GPIO156__FUNC_ANT_SEL1 (MTK_PIN_NO(156) | 1) -#define PINMUX_GPIO156__FUNC_SRCLKENAI0 (MTK_PIN_NO(156) | 2) -#define PINMUX_GPIO156__FUNC_SCL6 (MTK_PIN_NO(156) | 3) -#define PINMUX_GPIO156__FUNC_KPCOL2 (MTK_PIN_NO(156) | 4) -#define PINMUX_GPIO156__FUNC_IDDIG (MTK_PIN_NO(156) | 5) -#define PINMUX_GPIO156__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(156) | 7) - -#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) -#define PINMUX_GPIO157__FUNC_ANT_SEL2 (MTK_PIN_NO(157) | 1) -#define PINMUX_GPIO157__FUNC_SRCLKENAI1 (MTK_PIN_NO(157) | 2) -#define PINMUX_GPIO157__FUNC_SDA6 (MTK_PIN_NO(157) | 3) -#define PINMUX_GPIO157__FUNC_KPROW2 (MTK_PIN_NO(157) | 4) -#define PINMUX_GPIO157__FUNC_USB_DRVVBUS (MTK_PIN_NO(157) | 5) -#define PINMUX_GPIO157__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(157) | 7) - -#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) -#define PINMUX_GPIO158__FUNC_ANT_SEL3 (MTK_PIN_NO(158) | 1) - -#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) -#define PINMUX_GPIO159__FUNC_ANT_SEL4 (MTK_PIN_NO(159) | 1) - -#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) -#define PINMUX_GPIO160__FUNC_ANT_SEL5 (MTK_PIN_NO(160) | 1) - -#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) -#define PINMUX_GPIO161__FUNC_SPI1_A_MI (MTK_PIN_NO(161) | 1) -#define PINMUX_GPIO161__FUNC_SCP_SPI1_MI (MTK_PIN_NO(161) | 2) -#define PINMUX_GPIO161__FUNC_IDDIG (MTK_PIN_NO(161) | 3) -#define PINMUX_GPIO161__FUNC_ANT_SEL6 (MTK_PIN_NO(161) | 4) -#define PINMUX_GPIO161__FUNC_KPCOL2 (MTK_PIN_NO(161) | 5) -#define PINMUX_GPIO161__FUNC_PTA_RXD (MTK_PIN_NO(161) | 6) -#define PINMUX_GPIO161__FUNC_DBG_MON_B19 (MTK_PIN_NO(161) | 7) - -#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) -#define PINMUX_GPIO162__FUNC_SPI1_A_CSB (MTK_PIN_NO(162) | 1) -#define PINMUX_GPIO162__FUNC_SCP_SPI1_CS (MTK_PIN_NO(162) | 2) -#define PINMUX_GPIO162__FUNC_USB_DRVVBUS (MTK_PIN_NO(162) | 3) -#define PINMUX_GPIO162__FUNC_ANT_SEL5 (MTK_PIN_NO(162) | 4) -#define PINMUX_GPIO162__FUNC_KPROW2 (MTK_PIN_NO(162) | 5) -#define PINMUX_GPIO162__FUNC_PTA_TXD (MTK_PIN_NO(162) | 6) - -#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) -#define PINMUX_GPIO163__FUNC_SPI1_A_MO (MTK_PIN_NO(163) | 1) -#define PINMUX_GPIO163__FUNC_SCP_SPI1_MO (MTK_PIN_NO(163) | 2) -#define PINMUX_GPIO163__FUNC_SDA1 (MTK_PIN_NO(163) | 3) -#define PINMUX_GPIO163__FUNC_ANT_SEL4 (MTK_PIN_NO(163) | 4) -#define PINMUX_GPIO163__FUNC_CMMCLK2 (MTK_PIN_NO(163) | 5) -#define PINMUX_GPIO163__FUNC_DMIC_CLK (MTK_PIN_NO(163) | 6) - -#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) -#define PINMUX_GPIO164__FUNC_SPI1_A_CLK (MTK_PIN_NO(164) | 1) -#define PINMUX_GPIO164__FUNC_SCP_SPI1_CK (MTK_PIN_NO(164) | 2) -#define PINMUX_GPIO164__FUNC_SCL1 (MTK_PIN_NO(164) | 3) -#define PINMUX_GPIO164__FUNC_ANT_SEL3 (MTK_PIN_NO(164) | 4) -#define PINMUX_GPIO164__FUNC_CMMCLK3 (MTK_PIN_NO(164) | 5) -#define PINMUX_GPIO164__FUNC_DMIC_DAT (MTK_PIN_NO(164) | 6) - -#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) -#define PINMUX_GPIO165__FUNC_PWM_B (MTK_PIN_NO(165) | 1) -#define PINMUX_GPIO165__FUNC_CMMCLK2 (MTK_PIN_NO(165) | 2) -#define PINMUX_GPIO165__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(165) | 3) -#define PINMUX_GPIO165__FUNC_TDM_MCK_2ND (MTK_PIN_NO(165) | 6) -#define PINMUX_GPIO165__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(165) | 7) - -#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) -#define PINMUX_GPIO166__FUNC_ANT_SEL6 (MTK_PIN_NO(166) | 1) - -#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) -#define PINMUX_GPIO167__FUNC_RFIC0_BSI_EN (MTK_PIN_NO(167) | 1) -#define PINMUX_GPIO167__FUNC_SPM_BSI_EN (MTK_PIN_NO(167) | 2) - -#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) -#define PINMUX_GPIO168__FUNC_RFIC0_BSI_CK (MTK_PIN_NO(168) | 1) -#define PINMUX_GPIO168__FUNC_SPM_BSI_CK (MTK_PIN_NO(168) | 2) - -#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) -#define PINMUX_GPIO169__FUNC_PWM_C (MTK_PIN_NO(169) | 1) -#define PINMUX_GPIO169__FUNC_CMMCLK3 (MTK_PIN_NO(169) | 2) -#define PINMUX_GPIO169__FUNC_CMVREF1 (MTK_PIN_NO(169) | 3) -#define PINMUX_GPIO169__FUNC_ANT_SEL7 (MTK_PIN_NO(169) | 4) -#define PINMUX_GPIO169__FUNC_AGPS_SYNC (MTK_PIN_NO(169) | 5) -#define PINMUX_GPIO169__FUNC_TDM_BCK_2ND (MTK_PIN_NO(169) | 6) -#define PINMUX_GPIO169__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(169) | 7) - -#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) -#define PINMUX_GPIO170__FUNC_I2S1_BCK (MTK_PIN_NO(170) | 1) -#define PINMUX_GPIO170__FUNC_I2S3_BCK (MTK_PIN_NO(170) | 2) -#define PINMUX_GPIO170__FUNC_SCL7 (MTK_PIN_NO(170) | 3) -#define PINMUX_GPIO170__FUNC_I2S5_BCK (MTK_PIN_NO(170) | 4) -#define PINMUX_GPIO170__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(170) | 5) -#define PINMUX_GPIO170__FUNC_TDM_LRCK_2ND (MTK_PIN_NO(170) | 6) -#define PINMUX_GPIO170__FUNC_ANT_SEL3 (MTK_PIN_NO(170) | 7) - -#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) -#define PINMUX_GPIO171__FUNC_I2S1_LRCK (MTK_PIN_NO(171) | 1) -#define PINMUX_GPIO171__FUNC_I2S3_LRCK (MTK_PIN_NO(171) | 2) -#define PINMUX_GPIO171__FUNC_SDA7 (MTK_PIN_NO(171) | 3) -#define PINMUX_GPIO171__FUNC_I2S5_LRCK (MTK_PIN_NO(171) | 4) -#define PINMUX_GPIO171__FUNC_URXD1 (MTK_PIN_NO(171) | 5) -#define PINMUX_GPIO171__FUNC_TDM_DATA0_2ND (MTK_PIN_NO(171) | 6) -#define PINMUX_GPIO171__FUNC_ANT_SEL4 (MTK_PIN_NO(171) | 7) - -#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) -#define PINMUX_GPIO172__FUNC_I2S1_DO (MTK_PIN_NO(172) | 1) -#define PINMUX_GPIO172__FUNC_I2S3_DO (MTK_PIN_NO(172) | 2) -#define PINMUX_GPIO172__FUNC_SCL8 (MTK_PIN_NO(172) | 3) -#define PINMUX_GPIO172__FUNC_I2S5_DO (MTK_PIN_NO(172) | 4) -#define PINMUX_GPIO172__FUNC_UTXD1 (MTK_PIN_NO(172) | 5) -#define PINMUX_GPIO172__FUNC_TDM_DATA1_2ND (MTK_PIN_NO(172) | 6) -#define PINMUX_GPIO172__FUNC_ANT_SEL5 (MTK_PIN_NO(172) | 7) - -#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) -#define PINMUX_GPIO173__FUNC_I2S1_MCK (MTK_PIN_NO(173) | 1) -#define PINMUX_GPIO173__FUNC_I2S3_MCK (MTK_PIN_NO(173) | 2) -#define PINMUX_GPIO173__FUNC_SDA8 (MTK_PIN_NO(173) | 3) -#define PINMUX_GPIO173__FUNC_I2S5_MCK (MTK_PIN_NO(173) | 4) -#define PINMUX_GPIO173__FUNC_UCTS0 (MTK_PIN_NO(173) | 5) -#define PINMUX_GPIO173__FUNC_TDM_DATA2_2ND (MTK_PIN_NO(173) | 6) -#define PINMUX_GPIO173__FUNC_ANT_SEL6 (MTK_PIN_NO(173) | 7) - -#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) -#define PINMUX_GPIO174__FUNC_I2S2_DI (MTK_PIN_NO(174) | 1) -#define PINMUX_GPIO174__FUNC_I2S0_DI (MTK_PIN_NO(174) | 2) -#define PINMUX_GPIO174__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(174) | 3) -#define PINMUX_GPIO174__FUNC_I2S2_DI2 (MTK_PIN_NO(174) | 4) -#define PINMUX_GPIO174__FUNC_URTS0 (MTK_PIN_NO(174) | 5) -#define PINMUX_GPIO174__FUNC_TDM_DATA3_2ND (MTK_PIN_NO(174) | 6) -#define PINMUX_GPIO174__FUNC_ANT_SEL7 (MTK_PIN_NO(174) | 7) - -#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) -#define PINMUX_GPIO175__FUNC_ANT_SEL7 (MTK_PIN_NO(175) | 1) - -#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) - -#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) - -#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) - -#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) - -#endif /* __MT8183-PINFUNC_H */ diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index f90df6439c08..1933045da95d 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -14,7 +14,7 @@ #include #include #include -#include "mt8183-pinfunc.h" +#include / { compatible = "mediatek,mt8183"; diff --git a/include/dt-bindings/pinctrl/mt8183-pinfunc.h b/include/dt-bindings/pinctrl/mt8183-pinfunc.h new file mode 100644 index 000000000000..6221cd712718 --- /dev/null +++ b/include/dt-bindings/pinctrl/mt8183-pinfunc.h @@ -0,0 +1,1120 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Zhiyong Tao + * + */ + +#ifndef __MT8183_PINFUNC_H +#define __MT8183_PINFUNC_H + +#include + +#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) +#define PINMUX_GPIO0__FUNC_MRG_SYNC (MTK_PIN_NO(0) | 1) +#define PINMUX_GPIO0__FUNC_PCM0_SYNC (MTK_PIN_NO(0) | 2) +#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 3) +#define PINMUX_GPIO0__FUNC_SRCLKENAI0 (MTK_PIN_NO(0) | 4) +#define PINMUX_GPIO0__FUNC_SCP_SPI2_CS (MTK_PIN_NO(0) | 5) +#define PINMUX_GPIO0__FUNC_I2S3_MCK (MTK_PIN_NO(0) | 6) +#define PINMUX_GPIO0__FUNC_SPI2_CSB (MTK_PIN_NO(0) | 7) + +#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) +#define PINMUX_GPIO1__FUNC_MRG_CLK (MTK_PIN_NO(1) | 1) +#define PINMUX_GPIO1__FUNC_PCM0_CLK (MTK_PIN_NO(1) | 2) +#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 3) +#define PINMUX_GPIO1__FUNC_CLKM3 (MTK_PIN_NO(1) | 4) +#define PINMUX_GPIO1__FUNC_SCP_SPI2_MO (MTK_PIN_NO(1) | 5) +#define PINMUX_GPIO1__FUNC_I2S3_BCK (MTK_PIN_NO(1) | 6) +#define PINMUX_GPIO1__FUNC_SPI2_MO (MTK_PIN_NO(1) | 7) + +#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) +#define PINMUX_GPIO2__FUNC_MRG_DO (MTK_PIN_NO(2) | 1) +#define PINMUX_GPIO2__FUNC_PCM0_DO (MTK_PIN_NO(2) | 2) +#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 3) +#define PINMUX_GPIO2__FUNC_SCL6 (MTK_PIN_NO(2) | 4) +#define PINMUX_GPIO2__FUNC_SCP_SPI2_CK (MTK_PIN_NO(2) | 5) +#define PINMUX_GPIO2__FUNC_I2S3_LRCK (MTK_PIN_NO(2) | 6) +#define PINMUX_GPIO2__FUNC_SPI2_CLK (MTK_PIN_NO(2) | 7) + +#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) +#define PINMUX_GPIO3__FUNC_MRG_DI (MTK_PIN_NO(3) | 1) +#define PINMUX_GPIO3__FUNC_PCM0_DI (MTK_PIN_NO(3) | 2) +#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 3) +#define PINMUX_GPIO3__FUNC_SDA6 (MTK_PIN_NO(3) | 4) +#define PINMUX_GPIO3__FUNC_TDM_MCK (MTK_PIN_NO(3) | 5) +#define PINMUX_GPIO3__FUNC_I2S3_DO (MTK_PIN_NO(3) | 6) +#define PINMUX_GPIO3__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(3) | 7) + +#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) +#define PINMUX_GPIO4__FUNC_PWM_B (MTK_PIN_NO(4) | 1) +#define PINMUX_GPIO4__FUNC_I2S0_MCK (MTK_PIN_NO(4) | 2) +#define PINMUX_GPIO4__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(4) | 3) +#define PINMUX_GPIO4__FUNC_MD_URXD1 (MTK_PIN_NO(4) | 4) +#define PINMUX_GPIO4__FUNC_TDM_BCK (MTK_PIN_NO(4) | 5) +#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6) +#define PINMUX_GPIO4__FUNC_DAP_MD32_SWD (MTK_PIN_NO(4) | 7) + +#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) +#define PINMUX_GPIO5__FUNC_PWM_C (MTK_PIN_NO(5) | 1) +#define PINMUX_GPIO5__FUNC_I2S0_BCK (MTK_PIN_NO(5) | 2) +#define PINMUX_GPIO5__FUNC_SSPM_URXD_AO (MTK_PIN_NO(5) | 3) +#define PINMUX_GPIO5__FUNC_MD_UTXD1 (MTK_PIN_NO(5) | 4) +#define PINMUX_GPIO5__FUNC_TDM_LRCK (MTK_PIN_NO(5) | 5) +#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6) +#define PINMUX_GPIO5__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(5) | 7) + +#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) +#define PINMUX_GPIO6__FUNC_PWM_A (MTK_PIN_NO(6) | 1) +#define PINMUX_GPIO6__FUNC_I2S0_LRCK (MTK_PIN_NO(6) | 2) +#define PINMUX_GPIO6__FUNC_IDDIG (MTK_PIN_NO(6) | 3) +#define PINMUX_GPIO6__FUNC_MD_URXD0 (MTK_PIN_NO(6) | 4) +#define PINMUX_GPIO6__FUNC_TDM_DATA0 (MTK_PIN_NO(6) | 5) +#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6) +#define PINMUX_GPIO6__FUNC_CMFLASH (MTK_PIN_NO(6) | 7) + +#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) +#define PINMUX_GPIO7__FUNC_SPI1_B_MI (MTK_PIN_NO(7) | 1) +#define PINMUX_GPIO7__FUNC_I2S0_DI (MTK_PIN_NO(7) | 2) +#define PINMUX_GPIO7__FUNC_USB_DRVVBUS (MTK_PIN_NO(7) | 3) +#define PINMUX_GPIO7__FUNC_MD_UTXD0 (MTK_PIN_NO(7) | 4) +#define PINMUX_GPIO7__FUNC_TDM_DATA1 (MTK_PIN_NO(7) | 5) +#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6) +#define PINMUX_GPIO7__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(7) | 7) + +#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) +#define PINMUX_GPIO8__FUNC_SPI1_B_CSB (MTK_PIN_NO(8) | 1) +#define PINMUX_GPIO8__FUNC_ANT_SEL3 (MTK_PIN_NO(8) | 2) +#define PINMUX_GPIO8__FUNC_SCL7 (MTK_PIN_NO(8) | 3) +#define PINMUX_GPIO8__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(8) | 4) +#define PINMUX_GPIO8__FUNC_TDM_DATA2 (MTK_PIN_NO(8) | 5) +#define PINMUX_GPIO8__FUNC_MD_INT0 (MTK_PIN_NO(8) | 6) +#define PINMUX_GPIO8__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(8) | 7) + +#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) +#define PINMUX_GPIO9__FUNC_SPI1_B_MO (MTK_PIN_NO(9) | 1) +#define PINMUX_GPIO9__FUNC_ANT_SEL4 (MTK_PIN_NO(9) | 2) +#define PINMUX_GPIO9__FUNC_CMMCLK2 (MTK_PIN_NO(9) | 3) +#define PINMUX_GPIO9__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(9) | 4) +#define PINMUX_GPIO9__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(9) | 5) +#define PINMUX_GPIO9__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(9) | 6) +#define PINMUX_GPIO9__FUNC_DBG_MON_B10 (MTK_PIN_NO(9) | 7) + +#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) +#define PINMUX_GPIO10__FUNC_SPI1_B_CLK (MTK_PIN_NO(10) | 1) +#define PINMUX_GPIO10__FUNC_ANT_SEL5 (MTK_PIN_NO(10) | 2) +#define PINMUX_GPIO10__FUNC_CMMCLK3 (MTK_PIN_NO(10) | 3) +#define PINMUX_GPIO10__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(10) | 4) +#define PINMUX_GPIO10__FUNC_TDM_DATA3 (MTK_PIN_NO(10) | 5) +#define PINMUX_GPIO10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(10) | 6) +#define PINMUX_GPIO10__FUNC_DBG_MON_B11 (MTK_PIN_NO(10) | 7) + +#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) +#define PINMUX_GPIO11__FUNC_TP_URXD1_AO (MTK_PIN_NO(11) | 1) +#define PINMUX_GPIO11__FUNC_IDDIG (MTK_PIN_NO(11) | 2) +#define PINMUX_GPIO11__FUNC_SCL6 (MTK_PIN_NO(11) | 3) +#define PINMUX_GPIO11__FUNC_UCTS1 (MTK_PIN_NO(11) | 4) +#define PINMUX_GPIO11__FUNC_UCTS0 (MTK_PIN_NO(11) | 5) +#define PINMUX_GPIO11__FUNC_SRCLKENAI1 (MTK_PIN_NO(11) | 6) +#define PINMUX_GPIO11__FUNC_I2S5_MCK (MTK_PIN_NO(11) | 7) + +#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) +#define PINMUX_GPIO12__FUNC_TP_UTXD1_AO (MTK_PIN_NO(12) | 1) +#define PINMUX_GPIO12__FUNC_USB_DRVVBUS (MTK_PIN_NO(12) | 2) +#define PINMUX_GPIO12__FUNC_SDA6 (MTK_PIN_NO(12) | 3) +#define PINMUX_GPIO12__FUNC_URTS1 (MTK_PIN_NO(12) | 4) +#define PINMUX_GPIO12__FUNC_URTS0 (MTK_PIN_NO(12) | 5) +#define PINMUX_GPIO12__FUNC_I2S2_DI2 (MTK_PIN_NO(12) | 6) +#define PINMUX_GPIO12__FUNC_I2S5_BCK (MTK_PIN_NO(12) | 7) + +#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) +#define PINMUX_GPIO13__FUNC_DBPI_D0 (MTK_PIN_NO(13) | 1) +#define PINMUX_GPIO13__FUNC_SPI5_MI (MTK_PIN_NO(13) | 2) +#define PINMUX_GPIO13__FUNC_PCM0_SYNC (MTK_PIN_NO(13) | 3) +#define PINMUX_GPIO13__FUNC_MD_URXD0 (MTK_PIN_NO(13) | 4) +#define PINMUX_GPIO13__FUNC_ANT_SEL3 (MTK_PIN_NO(13) | 5) +#define PINMUX_GPIO13__FUNC_I2S0_MCK (MTK_PIN_NO(13) | 6) +#define PINMUX_GPIO13__FUNC_DBG_MON_B15 (MTK_PIN_NO(13) | 7) + +#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) +#define PINMUX_GPIO14__FUNC_DBPI_D1 (MTK_PIN_NO(14) | 1) +#define PINMUX_GPIO14__FUNC_SPI5_CSB (MTK_PIN_NO(14) | 2) +#define PINMUX_GPIO14__FUNC_PCM0_CLK (MTK_PIN_NO(14) | 3) +#define PINMUX_GPIO14__FUNC_MD_UTXD0 (MTK_PIN_NO(14) | 4) +#define PINMUX_GPIO14__FUNC_ANT_SEL4 (MTK_PIN_NO(14) | 5) +#define PINMUX_GPIO14__FUNC_I2S0_BCK (MTK_PIN_NO(14) | 6) +#define PINMUX_GPIO14__FUNC_DBG_MON_B16 (MTK_PIN_NO(14) | 7) + +#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) +#define PINMUX_GPIO15__FUNC_DBPI_D2 (MTK_PIN_NO(15) | 1) +#define PINMUX_GPIO15__FUNC_SPI5_MO (MTK_PIN_NO(15) | 2) +#define PINMUX_GPIO15__FUNC_PCM0_DO (MTK_PIN_NO(15) | 3) +#define PINMUX_GPIO15__FUNC_MD_URXD1 (MTK_PIN_NO(15) | 4) +#define PINMUX_GPIO15__FUNC_ANT_SEL5 (MTK_PIN_NO(15) | 5) +#define PINMUX_GPIO15__FUNC_I2S0_LRCK (MTK_PIN_NO(15) | 6) +#define PINMUX_GPIO15__FUNC_DBG_MON_B17 (MTK_PIN_NO(15) | 7) + +#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) +#define PINMUX_GPIO16__FUNC_DBPI_D3 (MTK_PIN_NO(16) | 1) +#define PINMUX_GPIO16__FUNC_SPI5_CLK (MTK_PIN_NO(16) | 2) +#define PINMUX_GPIO16__FUNC_PCM0_DI (MTK_PIN_NO(16) | 3) +#define PINMUX_GPIO16__FUNC_MD_UTXD1 (MTK_PIN_NO(16) | 4) +#define PINMUX_GPIO16__FUNC_ANT_SEL6 (MTK_PIN_NO(16) | 5) +#define PINMUX_GPIO16__FUNC_I2S0_DI (MTK_PIN_NO(16) | 6) +#define PINMUX_GPIO16__FUNC_DBG_MON_B23 (MTK_PIN_NO(16) | 7) + +#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) +#define PINMUX_GPIO17__FUNC_DBPI_D4 (MTK_PIN_NO(17) | 1) +#define PINMUX_GPIO17__FUNC_SPI4_MI (MTK_PIN_NO(17) | 2) +#define PINMUX_GPIO17__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(17) | 3) +#define PINMUX_GPIO17__FUNC_MD_INT0 (MTK_PIN_NO(17) | 4) +#define PINMUX_GPIO17__FUNC_ANT_SEL7 (MTK_PIN_NO(17) | 5) +#define PINMUX_GPIO17__FUNC_I2S3_MCK (MTK_PIN_NO(17) | 6) +#define PINMUX_GPIO17__FUNC_DBG_MON_A1 (MTK_PIN_NO(17) | 7) + +#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) +#define PINMUX_GPIO18__FUNC_DBPI_D5 (MTK_PIN_NO(18) | 1) +#define PINMUX_GPIO18__FUNC_SPI4_CSB (MTK_PIN_NO(18) | 2) +#define PINMUX_GPIO18__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(18) | 3) +#define PINMUX_GPIO18__FUNC_MD_INT0 (MTK_PIN_NO(18) | 4) +#define PINMUX_GPIO18__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(18) | 5) +#define PINMUX_GPIO18__FUNC_I2S3_BCK (MTK_PIN_NO(18) | 6) +#define PINMUX_GPIO18__FUNC_DBG_MON_A2 (MTK_PIN_NO(18) | 7) + +#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) +#define PINMUX_GPIO19__FUNC_DBPI_D6 (MTK_PIN_NO(19) | 1) +#define PINMUX_GPIO19__FUNC_SPI4_MO (MTK_PIN_NO(19) | 2) +#define PINMUX_GPIO19__FUNC_CONN_MCU_TDO (MTK_PIN_NO(19) | 3) +#define PINMUX_GPIO19__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(19) | 4) +#define PINMUX_GPIO19__FUNC_URXD1 (MTK_PIN_NO(19) | 5) +#define PINMUX_GPIO19__FUNC_I2S3_LRCK (MTK_PIN_NO(19) | 6) +#define PINMUX_GPIO19__FUNC_DBG_MON_A3 (MTK_PIN_NO(19) | 7) + +#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) +#define PINMUX_GPIO20__FUNC_DBPI_D7 (MTK_PIN_NO(20) | 1) +#define PINMUX_GPIO20__FUNC_SPI4_CLK (MTK_PIN_NO(20) | 2) +#define PINMUX_GPIO20__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(20) | 3) +#define PINMUX_GPIO20__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(20) | 4) +#define PINMUX_GPIO20__FUNC_UTXD1 (MTK_PIN_NO(20) | 5) +#define PINMUX_GPIO20__FUNC_I2S3_DO (MTK_PIN_NO(20) | 6) +#define PINMUX_GPIO20__FUNC_DBG_MON_A19 (MTK_PIN_NO(20) | 7) + +#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) +#define PINMUX_GPIO21__FUNC_DBPI_D8 (MTK_PIN_NO(21) | 1) +#define PINMUX_GPIO21__FUNC_SPI3_MI (MTK_PIN_NO(21) | 2) +#define PINMUX_GPIO21__FUNC_CONN_MCU_TMS (MTK_PIN_NO(21) | 3) +#define PINMUX_GPIO21__FUNC_DAP_MD32_SWD (MTK_PIN_NO(21) | 4) +#define PINMUX_GPIO21__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(21) | 5) +#define PINMUX_GPIO21__FUNC_I2S2_MCK (MTK_PIN_NO(21) | 6) +#define PINMUX_GPIO21__FUNC_DBG_MON_B5 (MTK_PIN_NO(21) | 7) + +#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) +#define PINMUX_GPIO22__FUNC_DBPI_D9 (MTK_PIN_NO(22) | 1) +#define PINMUX_GPIO22__FUNC_SPI3_CSB (MTK_PIN_NO(22) | 2) +#define PINMUX_GPIO22__FUNC_CONN_MCU_TCK (MTK_PIN_NO(22) | 3) +#define PINMUX_GPIO22__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(22) | 4) +#define PINMUX_GPIO22__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(22) | 5) +#define PINMUX_GPIO22__FUNC_I2S2_BCK (MTK_PIN_NO(22) | 6) +#define PINMUX_GPIO22__FUNC_DBG_MON_B6 (MTK_PIN_NO(22) | 7) + +#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) +#define PINMUX_GPIO23__FUNC_DBPI_D10 (MTK_PIN_NO(23) | 1) +#define PINMUX_GPIO23__FUNC_SPI3_MO (MTK_PIN_NO(23) | 2) +#define PINMUX_GPIO23__FUNC_CONN_MCU_TDI (MTK_PIN_NO(23) | 3) +#define PINMUX_GPIO23__FUNC_UCTS1 (MTK_PIN_NO(23) | 4) +#define PINMUX_GPIO23__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(23) | 5) +#define PINMUX_GPIO23__FUNC_I2S2_LRCK (MTK_PIN_NO(23) | 6) +#define PINMUX_GPIO23__FUNC_DBG_MON_B7 (MTK_PIN_NO(23) | 7) + +#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) +#define PINMUX_GPIO24__FUNC_DBPI_D11 (MTK_PIN_NO(24) | 1) +#define PINMUX_GPIO24__FUNC_SPI3_CLK (MTK_PIN_NO(24) | 2) +#define PINMUX_GPIO24__FUNC_SRCLKENAI0 (MTK_PIN_NO(24) | 3) +#define PINMUX_GPIO24__FUNC_URTS1 (MTK_PIN_NO(24) | 4) +#define PINMUX_GPIO24__FUNC_IO_JTAG_TCK (MTK_PIN_NO(24) | 5) +#define PINMUX_GPIO24__FUNC_I2S2_DI (MTK_PIN_NO(24) | 6) +#define PINMUX_GPIO24__FUNC_DBG_MON_B31 (MTK_PIN_NO(24) | 7) + +#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) +#define PINMUX_GPIO25__FUNC_DBPI_HSYNC (MTK_PIN_NO(25) | 1) +#define PINMUX_GPIO25__FUNC_ANT_SEL0 (MTK_PIN_NO(25) | 2) +#define PINMUX_GPIO25__FUNC_SCL6 (MTK_PIN_NO(25) | 3) +#define PINMUX_GPIO25__FUNC_KPCOL2 (MTK_PIN_NO(25) | 4) +#define PINMUX_GPIO25__FUNC_IO_JTAG_TMS (MTK_PIN_NO(25) | 5) +#define PINMUX_GPIO25__FUNC_I2S1_MCK (MTK_PIN_NO(25) | 6) +#define PINMUX_GPIO25__FUNC_DBG_MON_B0 (MTK_PIN_NO(25) | 7) + +#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) +#define PINMUX_GPIO26__FUNC_DBPI_VSYNC (MTK_PIN_NO(26) | 1) +#define PINMUX_GPIO26__FUNC_ANT_SEL1 (MTK_PIN_NO(26) | 2) +#define PINMUX_GPIO26__FUNC_SDA6 (MTK_PIN_NO(26) | 3) +#define PINMUX_GPIO26__FUNC_KPROW2 (MTK_PIN_NO(26) | 4) +#define PINMUX_GPIO26__FUNC_IO_JTAG_TDI (MTK_PIN_NO(26) | 5) +#define PINMUX_GPIO26__FUNC_I2S1_BCK (MTK_PIN_NO(26) | 6) +#define PINMUX_GPIO26__FUNC_DBG_MON_B1 (MTK_PIN_NO(26) | 7) + +#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) +#define PINMUX_GPIO27__FUNC_DBPI_DE (MTK_PIN_NO(27) | 1) +#define PINMUX_GPIO27__FUNC_ANT_SEL2 (MTK_PIN_NO(27) | 2) +#define PINMUX_GPIO27__FUNC_SCL7 (MTK_PIN_NO(27) | 3) +#define PINMUX_GPIO27__FUNC_DMIC_CLK (MTK_PIN_NO(27) | 4) +#define PINMUX_GPIO27__FUNC_IO_JTAG_TDO (MTK_PIN_NO(27) | 5) +#define PINMUX_GPIO27__FUNC_I2S1_LRCK (MTK_PIN_NO(27) | 6) +#define PINMUX_GPIO27__FUNC_DBG_MON_B9 (MTK_PIN_NO(27) | 7) + +#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) +#define PINMUX_GPIO28__FUNC_DBPI_CK (MTK_PIN_NO(28) | 1) +#define PINMUX_GPIO28__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(28) | 2) +#define PINMUX_GPIO28__FUNC_SDA7 (MTK_PIN_NO(28) | 3) +#define PINMUX_GPIO28__FUNC_DMIC_DAT (MTK_PIN_NO(28) | 4) +#define PINMUX_GPIO28__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(28) | 5) +#define PINMUX_GPIO28__FUNC_I2S1_DO (MTK_PIN_NO(28) | 6) +#define PINMUX_GPIO28__FUNC_DBG_MON_B32 (MTK_PIN_NO(28) | 7) + +#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) +#define PINMUX_GPIO29__FUNC_MSDC1_CLK (MTK_PIN_NO(29) | 1) +#define PINMUX_GPIO29__FUNC_IO_JTAG_TCK (MTK_PIN_NO(29) | 2) +#define PINMUX_GPIO29__FUNC_UDI_TCK (MTK_PIN_NO(29) | 3) +#define PINMUX_GPIO29__FUNC_CONN_DSP_JCK (MTK_PIN_NO(29) | 4) +#define PINMUX_GPIO29__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(29) | 5) +#define PINMUX_GPIO29__FUNC_PCM1_CLK (MTK_PIN_NO(29) | 6) +#define PINMUX_GPIO29__FUNC_DBG_MON_A6 (MTK_PIN_NO(29) | 7) + +#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) +#define PINMUX_GPIO30__FUNC_MSDC1_DAT3 (MTK_PIN_NO(30) | 1) +#define PINMUX_GPIO30__FUNC_DAP_MD32_SWD (MTK_PIN_NO(30) | 2) +#define PINMUX_GPIO30__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(30) | 3) +#define PINMUX_GPIO30__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(30) | 4) +#define PINMUX_GPIO30__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(30) | 5) +#define PINMUX_GPIO30__FUNC_PCM1_DI (MTK_PIN_NO(30) | 6) +#define PINMUX_GPIO30__FUNC_DBG_MON_A7 (MTK_PIN_NO(30) | 7) + +#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) +#define PINMUX_GPIO31__FUNC_MSDC1_CMD (MTK_PIN_NO(31) | 1) +#define PINMUX_GPIO31__FUNC_IO_JTAG_TMS (MTK_PIN_NO(31) | 2) +#define PINMUX_GPIO31__FUNC_UDI_TMS (MTK_PIN_NO(31) | 3) +#define PINMUX_GPIO31__FUNC_CONN_DSP_JMS (MTK_PIN_NO(31) | 4) +#define PINMUX_GPIO31__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(31) | 5) +#define PINMUX_GPIO31__FUNC_PCM1_SYNC (MTK_PIN_NO(31) | 6) +#define PINMUX_GPIO31__FUNC_DBG_MON_A8 (MTK_PIN_NO(31) | 7) + +#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) +#define PINMUX_GPIO32__FUNC_MSDC1_DAT0 (MTK_PIN_NO(32) | 1) +#define PINMUX_GPIO32__FUNC_IO_JTAG_TDI (MTK_PIN_NO(32) | 2) +#define PINMUX_GPIO32__FUNC_UDI_TDI (MTK_PIN_NO(32) | 3) +#define PINMUX_GPIO32__FUNC_CONN_DSP_JDI (MTK_PIN_NO(32) | 4) +#define PINMUX_GPIO32__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(32) | 5) +#define PINMUX_GPIO32__FUNC_PCM1_DO0 (MTK_PIN_NO(32) | 6) +#define PINMUX_GPIO32__FUNC_DBG_MON_A9 (MTK_PIN_NO(32) | 7) + +#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) +#define PINMUX_GPIO33__FUNC_MSDC1_DAT2 (MTK_PIN_NO(33) | 1) +#define PINMUX_GPIO33__FUNC_IO_JTAG_TRSTN (MTK_PIN_NO(33) | 2) +#define PINMUX_GPIO33__FUNC_UDI_NTRST (MTK_PIN_NO(33) | 3) +#define PINMUX_GPIO33__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(33) | 4) +#define PINMUX_GPIO33__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(33) | 5) +#define PINMUX_GPIO33__FUNC_PCM1_DO2 (MTK_PIN_NO(33) | 6) +#define PINMUX_GPIO33__FUNC_DBG_MON_A10 (MTK_PIN_NO(33) | 7) + +#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) +#define PINMUX_GPIO34__FUNC_MSDC1_DAT1 (MTK_PIN_NO(34) | 1) +#define PINMUX_GPIO34__FUNC_IO_JTAG_TDO (MTK_PIN_NO(34) | 2) +#define PINMUX_GPIO34__FUNC_UDI_TDO (MTK_PIN_NO(34) | 3) +#define PINMUX_GPIO34__FUNC_CONN_DSP_JDO (MTK_PIN_NO(34) | 4) +#define PINMUX_GPIO34__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(34) | 5) +#define PINMUX_GPIO34__FUNC_PCM1_DO1 (MTK_PIN_NO(34) | 6) +#define PINMUX_GPIO34__FUNC_DBG_MON_A11 (MTK_PIN_NO(34) | 7) + +#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) +#define PINMUX_GPIO35__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(35) | 1) +#define PINMUX_GPIO35__FUNC_CCU_JTAG_TDO (MTK_PIN_NO(35) | 2) +#define PINMUX_GPIO35__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(35) | 3) +#define PINMUX_GPIO35__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(35) | 5) +#define PINMUX_GPIO35__FUNC_CONN_DSP_JMS (MTK_PIN_NO(35) | 6) +#define PINMUX_GPIO35__FUNC_DBG_MON_A28 (MTK_PIN_NO(35) | 7) + +#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) +#define PINMUX_GPIO36__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(36) | 1) +#define PINMUX_GPIO36__FUNC_CCU_JTAG_TMS (MTK_PIN_NO(36) | 2) +#define PINMUX_GPIO36__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(36) | 3) +#define PINMUX_GPIO36__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(36) | 4) +#define PINMUX_GPIO36__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(36) | 5) +#define PINMUX_GPIO36__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(36) | 6) +#define PINMUX_GPIO36__FUNC_DBG_MON_A29 (MTK_PIN_NO(36) | 7) + +#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) +#define PINMUX_GPIO37__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(37) | 1) +#define PINMUX_GPIO37__FUNC_CCU_JTAG_TDI (MTK_PIN_NO(37) | 2) +#define PINMUX_GPIO37__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(37) | 3) +#define PINMUX_GPIO37__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(37) | 5) +#define PINMUX_GPIO37__FUNC_CONN_DSP_JDO (MTK_PIN_NO(37) | 6) +#define PINMUX_GPIO37__FUNC_DBG_MON_A30 (MTK_PIN_NO(37) | 7) + +#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) +#define PINMUX_GPIO38__FUNC_MD1_SIM1_SCLK (MTK_PIN_NO(38) | 1) +#define PINMUX_GPIO38__FUNC_MD1_SIM2_SCLK (MTK_PIN_NO(38) | 3) +#define PINMUX_GPIO38__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(38) | 4) +#define PINMUX_GPIO38__FUNC_DBG_MON_A20 (MTK_PIN_NO(38) | 7) + +#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) +#define PINMUX_GPIO39__FUNC_MD1_SIM1_SRST (MTK_PIN_NO(39) | 1) +#define PINMUX_GPIO39__FUNC_CCU_JTAG_TCK (MTK_PIN_NO(39) | 2) +#define PINMUX_GPIO39__FUNC_MD1_SIM2_SRST (MTK_PIN_NO(39) | 3) +#define PINMUX_GPIO39__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(39) | 5) +#define PINMUX_GPIO39__FUNC_CONN_DSP_JCK (MTK_PIN_NO(39) | 6) +#define PINMUX_GPIO39__FUNC_DBG_MON_A31 (MTK_PIN_NO(39) | 7) + +#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) +#define PINMUX_GPIO40__FUNC_MD1_SIM1_SIO (MTK_PIN_NO(40) | 1) +#define PINMUX_GPIO40__FUNC_CCU_JTAG_TRST (MTK_PIN_NO(40) | 2) +#define PINMUX_GPIO40__FUNC_MD1_SIM2_SIO (MTK_PIN_NO(40) | 3) +#define PINMUX_GPIO40__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(40) | 5) +#define PINMUX_GPIO40__FUNC_CONN_DSP_JDI (MTK_PIN_NO(40) | 6) +#define PINMUX_GPIO40__FUNC_DBG_MON_A32 (MTK_PIN_NO(40) | 7) + +#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) +#define PINMUX_GPIO41__FUNC_IDDIG (MTK_PIN_NO(41) | 1) +#define PINMUX_GPIO41__FUNC_URXD1 (MTK_PIN_NO(41) | 2) +#define PINMUX_GPIO41__FUNC_UCTS0 (MTK_PIN_NO(41) | 3) +#define PINMUX_GPIO41__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(41) | 4) +#define PINMUX_GPIO41__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(41) | 5) +#define PINMUX_GPIO41__FUNC_DMIC_CLK (MTK_PIN_NO(41) | 6) + +#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) +#define PINMUX_GPIO42__FUNC_USB_DRVVBUS (MTK_PIN_NO(42) | 1) +#define PINMUX_GPIO42__FUNC_UTXD1 (MTK_PIN_NO(42) | 2) +#define PINMUX_GPIO42__FUNC_URTS0 (MTK_PIN_NO(42) | 3) +#define PINMUX_GPIO42__FUNC_SSPM_URXD_AO (MTK_PIN_NO(42) | 4) +#define PINMUX_GPIO42__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(42) | 5) +#define PINMUX_GPIO42__FUNC_DMIC_DAT (MTK_PIN_NO(42) | 6) + +#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) +#define PINMUX_GPIO43__FUNC_DISP_PWM (MTK_PIN_NO(43) | 1) + +#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) +#define PINMUX_GPIO44__FUNC_DSI_TE (MTK_PIN_NO(44) | 1) + +#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) +#define PINMUX_GPIO45__FUNC_LCM_RST (MTK_PIN_NO(45) | 1) + +#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) +#define PINMUX_GPIO46__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(46) | 1) +#define PINMUX_GPIO46__FUNC_URXD1 (MTK_PIN_NO(46) | 2) +#define PINMUX_GPIO46__FUNC_UCTS1 (MTK_PIN_NO(46) | 3) +#define PINMUX_GPIO46__FUNC_CCU_UTXD_AO (MTK_PIN_NO(46) | 4) +#define PINMUX_GPIO46__FUNC_TP_UCTS1_AO (MTK_PIN_NO(46) | 5) +#define PINMUX_GPIO46__FUNC_IDDIG (MTK_PIN_NO(46) | 6) +#define PINMUX_GPIO46__FUNC_I2S5_LRCK (MTK_PIN_NO(46) | 7) + +#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) +#define PINMUX_GPIO47__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(47) | 1) +#define PINMUX_GPIO47__FUNC_UTXD1 (MTK_PIN_NO(47) | 2) +#define PINMUX_GPIO47__FUNC_URTS1 (MTK_PIN_NO(47) | 3) +#define PINMUX_GPIO47__FUNC_CCU_URXD_AO (MTK_PIN_NO(47) | 4) +#define PINMUX_GPIO47__FUNC_TP_URTS1_AO (MTK_PIN_NO(47) | 5) +#define PINMUX_GPIO47__FUNC_USB_DRVVBUS (MTK_PIN_NO(47) | 6) +#define PINMUX_GPIO47__FUNC_I2S5_DO (MTK_PIN_NO(47) | 7) + +#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) +#define PINMUX_GPIO48__FUNC_SCL5 (MTK_PIN_NO(48) | 1) + +#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) +#define PINMUX_GPIO49__FUNC_SDA5 (MTK_PIN_NO(49) | 1) + +#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) +#define PINMUX_GPIO50__FUNC_SCL3 (MTK_PIN_NO(50) | 1) + +#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) +#define PINMUX_GPIO51__FUNC_SDA3 (MTK_PIN_NO(51) | 1) + +#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) +#define PINMUX_GPIO52__FUNC_BPI_ANT2 (MTK_PIN_NO(52) | 1) + +#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) +#define PINMUX_GPIO53__FUNC_BPI_ANT0 (MTK_PIN_NO(53) | 1) + +#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) +#define PINMUX_GPIO54__FUNC_BPI_OLAT1 (MTK_PIN_NO(54) | 1) + +#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) +#define PINMUX_GPIO55__FUNC_BPI_BUS8 (MTK_PIN_NO(55) | 1) + +#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) +#define PINMUX_GPIO56__FUNC_BPI_BUS9 (MTK_PIN_NO(56) | 1) +#define PINMUX_GPIO56__FUNC_SCL_6306 (MTK_PIN_NO(56) | 2) + +#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) +#define PINMUX_GPIO57__FUNC_BPI_BUS10 (MTK_PIN_NO(57) | 1) +#define PINMUX_GPIO57__FUNC_SDA_6306 (MTK_PIN_NO(57) | 2) + +#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) +#define PINMUX_GPIO58__FUNC_RFIC0_BSI_D2 (MTK_PIN_NO(58) | 1) +#define PINMUX_GPIO58__FUNC_SPM_BSI_D2 (MTK_PIN_NO(58) | 2) +#define PINMUX_GPIO58__FUNC_PWM_B (MTK_PIN_NO(58) | 3) + +#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) +#define PINMUX_GPIO59__FUNC_RFIC0_BSI_D1 (MTK_PIN_NO(59) | 1) +#define PINMUX_GPIO59__FUNC_SPM_BSI_D1 (MTK_PIN_NO(59) | 2) + +#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) +#define PINMUX_GPIO60__FUNC_RFIC0_BSI_D0 (MTK_PIN_NO(60) | 1) +#define PINMUX_GPIO60__FUNC_SPM_BSI_D0 (MTK_PIN_NO(60) | 2) + +#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) +#define PINMUX_GPIO61__FUNC_MIPI1_SDATA (MTK_PIN_NO(61) | 1) + +#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) +#define PINMUX_GPIO62__FUNC_MIPI1_SCLK (MTK_PIN_NO(62) | 1) + +#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) +#define PINMUX_GPIO63__FUNC_MIPI0_SDATA (MTK_PIN_NO(63) | 1) + +#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) +#define PINMUX_GPIO64__FUNC_MIPI0_SCLK (MTK_PIN_NO(64) | 1) + +#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) +#define PINMUX_GPIO65__FUNC_MIPI3_SDATA (MTK_PIN_NO(65) | 1) +#define PINMUX_GPIO65__FUNC_BPI_OLAT2 (MTK_PIN_NO(65) | 2) + +#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) +#define PINMUX_GPIO66__FUNC_MIPI3_SCLK (MTK_PIN_NO(66) | 1) +#define PINMUX_GPIO66__FUNC_BPI_OLAT3 (MTK_PIN_NO(66) | 2) + +#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) +#define PINMUX_GPIO67__FUNC_MIPI2_SDATA (MTK_PIN_NO(67) | 1) + +#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) +#define PINMUX_GPIO68__FUNC_MIPI2_SCLK (MTK_PIN_NO(68) | 1) + +#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) +#define PINMUX_GPIO69__FUNC_BPI_BUS7 (MTK_PIN_NO(69) | 1) + +#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) +#define PINMUX_GPIO70__FUNC_BPI_BUS6 (MTK_PIN_NO(70) | 1) + +#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) +#define PINMUX_GPIO71__FUNC_BPI_BUS5 (MTK_PIN_NO(71) | 1) + +#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) +#define PINMUX_GPIO72__FUNC_BPI_BUS4 (MTK_PIN_NO(72) | 1) + +#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) +#define PINMUX_GPIO73__FUNC_BPI_BUS3 (MTK_PIN_NO(73) | 1) + +#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) +#define PINMUX_GPIO74__FUNC_BPI_BUS2 (MTK_PIN_NO(74) | 1) + +#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) +#define PINMUX_GPIO75__FUNC_BPI_BUS1 (MTK_PIN_NO(75) | 1) + +#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) +#define PINMUX_GPIO76__FUNC_BPI_BUS0 (MTK_PIN_NO(76) | 1) + +#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) +#define PINMUX_GPIO77__FUNC_BPI_ANT1 (MTK_PIN_NO(77) | 1) + +#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) +#define PINMUX_GPIO78__FUNC_BPI_OLAT0 (MTK_PIN_NO(78) | 1) + +#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) +#define PINMUX_GPIO79__FUNC_BPI_PA_VM1 (MTK_PIN_NO(79) | 1) +#define PINMUX_GPIO79__FUNC_MIPI4_SDATA (MTK_PIN_NO(79) | 2) + +#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) +#define PINMUX_GPIO80__FUNC_BPI_PA_VM0 (MTK_PIN_NO(80) | 1) +#define PINMUX_GPIO80__FUNC_MIPI4_SCLK (MTK_PIN_NO(80) | 2) + +#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) +#define PINMUX_GPIO81__FUNC_SDA1 (MTK_PIN_NO(81) | 1) + +#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) +#define PINMUX_GPIO82__FUNC_SDA0 (MTK_PIN_NO(82) | 1) + +#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) +#define PINMUX_GPIO83__FUNC_SCL0 (MTK_PIN_NO(83) | 1) + +#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) +#define PINMUX_GPIO84__FUNC_SCL1 (MTK_PIN_NO(84) | 1) + +#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) +#define PINMUX_GPIO85__FUNC_SPI0_MI (MTK_PIN_NO(85) | 1) +#define PINMUX_GPIO85__FUNC_SCP_SPI0_MI (MTK_PIN_NO(85) | 2) +#define PINMUX_GPIO85__FUNC_CLKM3 (MTK_PIN_NO(85) | 3) +#define PINMUX_GPIO85__FUNC_I2S1_BCK (MTK_PIN_NO(85) | 4) +#define PINMUX_GPIO85__FUNC_MFG_DFD_JTAG_TDO (MTK_PIN_NO(85) | 5) +#define PINMUX_GPIO85__FUNC_DFD_TDO (MTK_PIN_NO(85) | 6) +#define PINMUX_GPIO85__FUNC_JTDO_SEL1 (MTK_PIN_NO(85) | 7) + +#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) +#define PINMUX_GPIO86__FUNC_SPI0_CSB (MTK_PIN_NO(86) | 1) +#define PINMUX_GPIO86__FUNC_SCP_SPI0_CS (MTK_PIN_NO(86) | 2) +#define PINMUX_GPIO86__FUNC_CLKM0 (MTK_PIN_NO(86) | 3) +#define PINMUX_GPIO86__FUNC_I2S1_LRCK (MTK_PIN_NO(86) | 4) +#define PINMUX_GPIO86__FUNC_MFG_DFD_JTAG_TMS (MTK_PIN_NO(86) | 5) +#define PINMUX_GPIO86__FUNC_DFD_TMS (MTK_PIN_NO(86) | 6) +#define PINMUX_GPIO86__FUNC_JTMS_SEL1 (MTK_PIN_NO(86) | 7) + +#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) +#define PINMUX_GPIO87__FUNC_SPI0_MO (MTK_PIN_NO(87) | 1) +#define PINMUX_GPIO87__FUNC_SCP_SPI0_MO (MTK_PIN_NO(87) | 2) +#define PINMUX_GPIO87__FUNC_SDA1 (MTK_PIN_NO(87) | 3) +#define PINMUX_GPIO87__FUNC_I2S1_DO (MTK_PIN_NO(87) | 4) +#define PINMUX_GPIO87__FUNC_MFG_DFD_JTAG_TDI (MTK_PIN_NO(87) | 5) +#define PINMUX_GPIO87__FUNC_DFD_TDI (MTK_PIN_NO(87) | 6) +#define PINMUX_GPIO87__FUNC_JTDI_SEL1 (MTK_PIN_NO(87) | 7) + +#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) +#define PINMUX_GPIO88__FUNC_SPI0_CLK (MTK_PIN_NO(88) | 1) +#define PINMUX_GPIO88__FUNC_SCP_SPI0_CK (MTK_PIN_NO(88) | 2) +#define PINMUX_GPIO88__FUNC_SCL1 (MTK_PIN_NO(88) | 3) +#define PINMUX_GPIO88__FUNC_I2S1_MCK (MTK_PIN_NO(88) | 4) +#define PINMUX_GPIO88__FUNC_MFG_DFD_JTAG_TCK (MTK_PIN_NO(88) | 5) +#define PINMUX_GPIO88__FUNC_DFD_TCK_XI (MTK_PIN_NO(88) | 6) +#define PINMUX_GPIO88__FUNC_JTCK_SEL1 (MTK_PIN_NO(88) | 7) + +#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) +#define PINMUX_GPIO89__FUNC_SRCLKENAI0 (MTK_PIN_NO(89) | 1) +#define PINMUX_GPIO89__FUNC_PWM_C (MTK_PIN_NO(89) | 2) +#define PINMUX_GPIO89__FUNC_I2S5_BCK (MTK_PIN_NO(89) | 3) +#define PINMUX_GPIO89__FUNC_ANT_SEL6 (MTK_PIN_NO(89) | 4) +#define PINMUX_GPIO89__FUNC_SDA8 (MTK_PIN_NO(89) | 5) +#define PINMUX_GPIO89__FUNC_CMVREF0 (MTK_PIN_NO(89) | 6) +#define PINMUX_GPIO89__FUNC_DBG_MON_A21 (MTK_PIN_NO(89) | 7) + +#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) +#define PINMUX_GPIO90__FUNC_PWM_A (MTK_PIN_NO(90) | 1) +#define PINMUX_GPIO90__FUNC_CMMCLK2 (MTK_PIN_NO(90) | 2) +#define PINMUX_GPIO90__FUNC_I2S5_LRCK (MTK_PIN_NO(90) | 3) +#define PINMUX_GPIO90__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(90) | 4) +#define PINMUX_GPIO90__FUNC_SCL8 (MTK_PIN_NO(90) | 5) +#define PINMUX_GPIO90__FUNC_PTA_RXD (MTK_PIN_NO(90) | 6) +#define PINMUX_GPIO90__FUNC_DBG_MON_A22 (MTK_PIN_NO(90) | 7) + +#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0) +#define PINMUX_GPIO91__FUNC_KPROW1 (MTK_PIN_NO(91) | 1) +#define PINMUX_GPIO91__FUNC_PWM_B (MTK_PIN_NO(91) | 2) +#define PINMUX_GPIO91__FUNC_I2S5_DO (MTK_PIN_NO(91) | 3) +#define PINMUX_GPIO91__FUNC_ANT_SEL7 (MTK_PIN_NO(91) | 4) +#define PINMUX_GPIO91__FUNC_CMMCLK3 (MTK_PIN_NO(91) | 5) +#define PINMUX_GPIO91__FUNC_PTA_TXD (MTK_PIN_NO(91) | 6) + +#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0) +#define PINMUX_GPIO92__FUNC_KPROW0 (MTK_PIN_NO(92) | 1) + +#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0) +#define PINMUX_GPIO93__FUNC_KPCOL0 (MTK_PIN_NO(93) | 1) +#define PINMUX_GPIO93__FUNC_DBG_MON_B27 (MTK_PIN_NO(93) | 7) + +#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0) +#define PINMUX_GPIO94__FUNC_KPCOL1 (MTK_PIN_NO(94) | 1) +#define PINMUX_GPIO94__FUNC_I2S2_DI2 (MTK_PIN_NO(94) | 2) +#define PINMUX_GPIO94__FUNC_I2S5_MCK (MTK_PIN_NO(94) | 3) +#define PINMUX_GPIO94__FUNC_CMMCLK2 (MTK_PIN_NO(94) | 4) +#define PINMUX_GPIO94__FUNC_SCP_SPI2_MI (MTK_PIN_NO(94) | 5) +#define PINMUX_GPIO94__FUNC_SRCLKENAI1 (MTK_PIN_NO(94) | 6) +#define PINMUX_GPIO94__FUNC_SPI2_MI (MTK_PIN_NO(94) | 7) + +#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0) +#define PINMUX_GPIO95__FUNC_URXD0 (MTK_PIN_NO(95) | 1) +#define PINMUX_GPIO95__FUNC_UTXD0 (MTK_PIN_NO(95) | 2) +#define PINMUX_GPIO95__FUNC_MD_URXD0 (MTK_PIN_NO(95) | 3) +#define PINMUX_GPIO95__FUNC_MD_URXD1 (MTK_PIN_NO(95) | 4) +#define PINMUX_GPIO95__FUNC_SSPM_URXD_AO (MTK_PIN_NO(95) | 5) +#define PINMUX_GPIO95__FUNC_CCU_URXD_AO (MTK_PIN_NO(95) | 6) + +#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0) +#define PINMUX_GPIO96__FUNC_UTXD0 (MTK_PIN_NO(96) | 1) +#define PINMUX_GPIO96__FUNC_URXD0 (MTK_PIN_NO(96) | 2) +#define PINMUX_GPIO96__FUNC_MD_UTXD0 (MTK_PIN_NO(96) | 3) +#define PINMUX_GPIO96__FUNC_MD_UTXD1 (MTK_PIN_NO(96) | 4) +#define PINMUX_GPIO96__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(96) | 5) +#define PINMUX_GPIO96__FUNC_CCU_UTXD_AO (MTK_PIN_NO(96) | 6) +#define PINMUX_GPIO96__FUNC_DBG_MON_B2 (MTK_PIN_NO(96) | 7) + +#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0) +#define PINMUX_GPIO97__FUNC_UCTS0 (MTK_PIN_NO(97) | 1) +#define PINMUX_GPIO97__FUNC_I2S2_MCK (MTK_PIN_NO(97) | 2) +#define PINMUX_GPIO97__FUNC_IDDIG (MTK_PIN_NO(97) | 3) +#define PINMUX_GPIO97__FUNC_CONN_MCU_TDO (MTK_PIN_NO(97) | 4) +#define PINMUX_GPIO97__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(97) | 5) +#define PINMUX_GPIO97__FUNC_IO_JTAG_TDO (MTK_PIN_NO(97) | 6) +#define PINMUX_GPIO97__FUNC_DBG_MON_B3 (MTK_PIN_NO(97) | 7) + +#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0) +#define PINMUX_GPIO98__FUNC_URTS0 (MTK_PIN_NO(98) | 1) +#define PINMUX_GPIO98__FUNC_I2S2_BCK (MTK_PIN_NO(98) | 2) +#define PINMUX_GPIO98__FUNC_USB_DRVVBUS (MTK_PIN_NO(98) | 3) +#define PINMUX_GPIO98__FUNC_CONN_MCU_TMS (MTK_PIN_NO(98) | 4) +#define PINMUX_GPIO98__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(98) | 5) +#define PINMUX_GPIO98__FUNC_IO_JTAG_TMS (MTK_PIN_NO(98) | 6) +#define PINMUX_GPIO98__FUNC_DBG_MON_B4 (MTK_PIN_NO(98) | 7) + +#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0) +#define PINMUX_GPIO99__FUNC_CMMCLK0 (MTK_PIN_NO(99) | 1) +#define PINMUX_GPIO99__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(99) | 4) +#define PINMUX_GPIO99__FUNC_DBG_MON_B28 (MTK_PIN_NO(99) | 7) + +#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0) +#define PINMUX_GPIO100__FUNC_CMMCLK1 (MTK_PIN_NO(100) | 1) +#define PINMUX_GPIO100__FUNC_PWM_C (MTK_PIN_NO(100) | 2) +#define PINMUX_GPIO100__FUNC_MD_INT1_C2K_UIM0_HOT_PLUG (MTK_PIN_NO(100) | 3) +#define PINMUX_GPIO100__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(100) | 4) +#define PINMUX_GPIO100__FUNC_DBG_MON_B29 (MTK_PIN_NO(100) | 7) + +#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0) +#define PINMUX_GPIO101__FUNC_CLKM2 (MTK_PIN_NO(101) | 1) +#define PINMUX_GPIO101__FUNC_I2S2_LRCK (MTK_PIN_NO(101) | 2) +#define PINMUX_GPIO101__FUNC_CMVREF1 (MTK_PIN_NO(101) | 3) +#define PINMUX_GPIO101__FUNC_CONN_MCU_TCK (MTK_PIN_NO(101) | 4) +#define PINMUX_GPIO101__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(101) | 5) +#define PINMUX_GPIO101__FUNC_IO_JTAG_TCK (MTK_PIN_NO(101) | 6) + +#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0) +#define PINMUX_GPIO102__FUNC_CLKM1 (MTK_PIN_NO(102) | 1) +#define PINMUX_GPIO102__FUNC_I2S2_DI (MTK_PIN_NO(102) | 2) +#define PINMUX_GPIO102__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(102) | 3) +#define PINMUX_GPIO102__FUNC_CONN_MCU_TDI (MTK_PIN_NO(102) | 4) +#define PINMUX_GPIO102__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(102) | 5) +#define PINMUX_GPIO102__FUNC_IO_JTAG_TDI (MTK_PIN_NO(102) | 6) +#define PINMUX_GPIO102__FUNC_DBG_MON_B8 (MTK_PIN_NO(102) | 7) + +#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0) +#define PINMUX_GPIO103__FUNC_SCL2 (MTK_PIN_NO(103) | 1) + +#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0) +#define PINMUX_GPIO104__FUNC_SDA2 (MTK_PIN_NO(104) | 1) + +#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0) +#define PINMUX_GPIO105__FUNC_SCL4 (MTK_PIN_NO(105) | 1) + +#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0) +#define PINMUX_GPIO106__FUNC_SDA4 (MTK_PIN_NO(106) | 1) + +#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0) +#define PINMUX_GPIO107__FUNC_DMIC_CLK (MTK_PIN_NO(107) | 1) +#define PINMUX_GPIO107__FUNC_ANT_SEL0 (MTK_PIN_NO(107) | 2) +#define PINMUX_GPIO107__FUNC_CLKM0 (MTK_PIN_NO(107) | 3) +#define PINMUX_GPIO107__FUNC_SDA7 (MTK_PIN_NO(107) | 4) +#define PINMUX_GPIO107__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(107) | 5) +#define PINMUX_GPIO107__FUNC_PWM_A (MTK_PIN_NO(107) | 6) +#define PINMUX_GPIO107__FUNC_DBG_MON_B12 (MTK_PIN_NO(107) | 7) + +#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0) +#define PINMUX_GPIO108__FUNC_CMMCLK2 (MTK_PIN_NO(108) | 1) +#define PINMUX_GPIO108__FUNC_ANT_SEL1 (MTK_PIN_NO(108) | 2) +#define PINMUX_GPIO108__FUNC_CLKM1 (MTK_PIN_NO(108) | 3) +#define PINMUX_GPIO108__FUNC_SCL8 (MTK_PIN_NO(108) | 4) +#define PINMUX_GPIO108__FUNC_DAP_MD32_SWD (MTK_PIN_NO(108) | 5) +#define PINMUX_GPIO108__FUNC_PWM_B (MTK_PIN_NO(108) | 6) +#define PINMUX_GPIO108__FUNC_DBG_MON_B13 (MTK_PIN_NO(108) | 7) + +#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0) +#define PINMUX_GPIO109__FUNC_DMIC_DAT (MTK_PIN_NO(109) | 1) +#define PINMUX_GPIO109__FUNC_ANT_SEL2 (MTK_PIN_NO(109) | 2) +#define PINMUX_GPIO109__FUNC_CLKM2 (MTK_PIN_NO(109) | 3) +#define PINMUX_GPIO109__FUNC_SDA8 (MTK_PIN_NO(109) | 4) +#define PINMUX_GPIO109__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(109) | 5) +#define PINMUX_GPIO109__FUNC_PWM_C (MTK_PIN_NO(109) | 6) +#define PINMUX_GPIO109__FUNC_DBG_MON_B14 (MTK_PIN_NO(109) | 7) + +#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0) +#define PINMUX_GPIO110__FUNC_SCL7 (MTK_PIN_NO(110) | 1) +#define PINMUX_GPIO110__FUNC_ANT_SEL0 (MTK_PIN_NO(110) | 2) +#define PINMUX_GPIO110__FUNC_TP_URXD1_AO (MTK_PIN_NO(110) | 3) +#define PINMUX_GPIO110__FUNC_USB_DRVVBUS (MTK_PIN_NO(110) | 4) +#define PINMUX_GPIO110__FUNC_SRCLKENAI1 (MTK_PIN_NO(110) | 5) +#define PINMUX_GPIO110__FUNC_KPCOL2 (MTK_PIN_NO(110) | 6) +#define PINMUX_GPIO110__FUNC_URXD1 (MTK_PIN_NO(110) | 7) + +#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0) +#define PINMUX_GPIO111__FUNC_CMMCLK3 (MTK_PIN_NO(111) | 1) +#define PINMUX_GPIO111__FUNC_ANT_SEL1 (MTK_PIN_NO(111) | 2) +#define PINMUX_GPIO111__FUNC_SRCLKENAI0 (MTK_PIN_NO(111) | 3) +#define PINMUX_GPIO111__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(111) | 4) +#define PINMUX_GPIO111__FUNC_MD_INT2_C2K_UIM1_HOT_PLUG (MTK_PIN_NO(111) | 5) +#define PINMUX_GPIO111__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(111) | 7) + +#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0) +#define PINMUX_GPIO112__FUNC_SDA7 (MTK_PIN_NO(112) | 1) +#define PINMUX_GPIO112__FUNC_ANT_SEL2 (MTK_PIN_NO(112) | 2) +#define PINMUX_GPIO112__FUNC_TP_UTXD1_AO (MTK_PIN_NO(112) | 3) +#define PINMUX_GPIO112__FUNC_IDDIG (MTK_PIN_NO(112) | 4) +#define PINMUX_GPIO112__FUNC_AGPS_SYNC (MTK_PIN_NO(112) | 5) +#define PINMUX_GPIO112__FUNC_KPROW2 (MTK_PIN_NO(112) | 6) +#define PINMUX_GPIO112__FUNC_UTXD1 (MTK_PIN_NO(112) | 7) + +#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0) +#define PINMUX_GPIO113__FUNC_CONN_TOP_CLK (MTK_PIN_NO(113) | 1) +#define PINMUX_GPIO113__FUNC_SCL6 (MTK_PIN_NO(113) | 3) +#define PINMUX_GPIO113__FUNC_AUXIF_CLK0 (MTK_PIN_NO(113) | 4) +#define PINMUX_GPIO113__FUNC_TP_UCTS1_AO (MTK_PIN_NO(113) | 6) + +#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0) +#define PINMUX_GPIO114__FUNC_CONN_TOP_DATA (MTK_PIN_NO(114) | 1) +#define PINMUX_GPIO114__FUNC_SDA6 (MTK_PIN_NO(114) | 3) +#define PINMUX_GPIO114__FUNC_AUXIF_ST0 (MTK_PIN_NO(114) | 4) +#define PINMUX_GPIO114__FUNC_TP_URTS1_AO (MTK_PIN_NO(114) | 6) + +#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0) +#define PINMUX_GPIO115__FUNC_CONN_BT_CLK (MTK_PIN_NO(115) | 1) +#define PINMUX_GPIO115__FUNC_UTXD1 (MTK_PIN_NO(115) | 2) +#define PINMUX_GPIO115__FUNC_PTA_TXD (MTK_PIN_NO(115) | 3) +#define PINMUX_GPIO115__FUNC_AUXIF_CLK1 (MTK_PIN_NO(115) | 4) +#define PINMUX_GPIO115__FUNC_DAP_MD32_SWD (MTK_PIN_NO(115) | 5) +#define PINMUX_GPIO115__FUNC_TP_UTXD1_AO (MTK_PIN_NO(115) | 6) + +#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0) +#define PINMUX_GPIO116__FUNC_CONN_BT_DATA (MTK_PIN_NO(116) | 1) +#define PINMUX_GPIO116__FUNC_IPU_JTAG_TRST (MTK_PIN_NO(116) | 2) +#define PINMUX_GPIO116__FUNC_AUXIF_ST1 (MTK_PIN_NO(116) | 4) +#define PINMUX_GPIO116__FUNC_DAP_MD32_SWCK (MTK_PIN_NO(116) | 5) +#define PINMUX_GPIO116__FUNC_TP_URXD2_AO (MTK_PIN_NO(116) | 6) +#define PINMUX_GPIO116__FUNC_DBG_MON_A0 (MTK_PIN_NO(116) | 7) + +#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) +#define PINMUX_GPIO117__FUNC_CONN_WF_HB0 (MTK_PIN_NO(117) | 1) +#define PINMUX_GPIO117__FUNC_IPU_JTAG_TDO (MTK_PIN_NO(117) | 2) +#define PINMUX_GPIO117__FUNC_TP_UTXD2_AO (MTK_PIN_NO(117) | 6) +#define PINMUX_GPIO117__FUNC_DBG_MON_A4 (MTK_PIN_NO(117) | 7) + +#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) +#define PINMUX_GPIO118__FUNC_CONN_WF_HB1 (MTK_PIN_NO(118) | 1) +#define PINMUX_GPIO118__FUNC_IPU_JTAG_TDI (MTK_PIN_NO(118) | 2) +#define PINMUX_GPIO118__FUNC_SSPM_URXD_AO (MTK_PIN_NO(118) | 5) +#define PINMUX_GPIO118__FUNC_TP_UCTS2_AO (MTK_PIN_NO(118) | 6) +#define PINMUX_GPIO118__FUNC_DBG_MON_A5 (MTK_PIN_NO(118) | 7) + +#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) +#define PINMUX_GPIO119__FUNC_CONN_WF_HB2 (MTK_PIN_NO(119) | 1) +#define PINMUX_GPIO119__FUNC_IPU_JTAG_TCK (MTK_PIN_NO(119) | 2) +#define PINMUX_GPIO119__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(119) | 5) +#define PINMUX_GPIO119__FUNC_TP_URTS2_AO (MTK_PIN_NO(119) | 6) + +#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) +#define PINMUX_GPIO120__FUNC_CONN_WB_PTA (MTK_PIN_NO(120) | 1) +#define PINMUX_GPIO120__FUNC_IPU_JTAG_TMS (MTK_PIN_NO(120) | 2) +#define PINMUX_GPIO120__FUNC_CCU_URXD_AO (MTK_PIN_NO(120) | 5) + +#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) +#define PINMUX_GPIO121__FUNC_CONN_HRST_B (MTK_PIN_NO(121) | 1) +#define PINMUX_GPIO121__FUNC_URXD1 (MTK_PIN_NO(121) | 2) +#define PINMUX_GPIO121__FUNC_PTA_RXD (MTK_PIN_NO(121) | 3) +#define PINMUX_GPIO121__FUNC_CCU_UTXD_AO (MTK_PIN_NO(121) | 5) +#define PINMUX_GPIO121__FUNC_TP_URXD1_AO (MTK_PIN_NO(121) | 6) + +#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) +#define PINMUX_GPIO122__FUNC_MSDC0_CMD (MTK_PIN_NO(122) | 1) +#define PINMUX_GPIO122__FUNC_SSPM_URXD2_AO (MTK_PIN_NO(122) | 2) +#define PINMUX_GPIO122__FUNC_ANT_SEL1 (MTK_PIN_NO(122) | 3) +#define PINMUX_GPIO122__FUNC_DBG_MON_A12 (MTK_PIN_NO(122) | 7) + +#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) +#define PINMUX_GPIO123__FUNC_MSDC0_DAT0 (MTK_PIN_NO(123) | 1) +#define PINMUX_GPIO123__FUNC_ANT_SEL0 (MTK_PIN_NO(123) | 3) +#define PINMUX_GPIO123__FUNC_DBG_MON_A13 (MTK_PIN_NO(123) | 7) + +#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) +#define PINMUX_GPIO124__FUNC_MSDC0_CLK (MTK_PIN_NO(124) | 1) +#define PINMUX_GPIO124__FUNC_DBG_MON_A14 (MTK_PIN_NO(124) | 7) + +#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) +#define PINMUX_GPIO125__FUNC_MSDC0_DAT2 (MTK_PIN_NO(125) | 1) +#define PINMUX_GPIO125__FUNC_MRG_CLK (MTK_PIN_NO(125) | 3) +#define PINMUX_GPIO125__FUNC_DBG_MON_A15 (MTK_PIN_NO(125) | 7) + +#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) +#define PINMUX_GPIO126__FUNC_MSDC0_DAT4 (MTK_PIN_NO(126) | 1) +#define PINMUX_GPIO126__FUNC_ANT_SEL5 (MTK_PIN_NO(126) | 3) +#define PINMUX_GPIO126__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(126) | 6) +#define PINMUX_GPIO126__FUNC_DBG_MON_A16 (MTK_PIN_NO(126) | 7) + +#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) +#define PINMUX_GPIO127__FUNC_MSDC0_DAT6 (MTK_PIN_NO(127) | 1) +#define PINMUX_GPIO127__FUNC_ANT_SEL4 (MTK_PIN_NO(127) | 3) +#define PINMUX_GPIO127__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(127) | 6) +#define PINMUX_GPIO127__FUNC_DBG_MON_A17 (MTK_PIN_NO(127) | 7) + +#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) +#define PINMUX_GPIO128__FUNC_MSDC0_DAT1 (MTK_PIN_NO(128) | 1) +#define PINMUX_GPIO128__FUNC_ANT_SEL2 (MTK_PIN_NO(128) | 3) +#define PINMUX_GPIO128__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(128) | 6) +#define PINMUX_GPIO128__FUNC_DBG_MON_A18 (MTK_PIN_NO(128) | 7) + +#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) +#define PINMUX_GPIO129__FUNC_MSDC0_DAT5 (MTK_PIN_NO(129) | 1) +#define PINMUX_GPIO129__FUNC_ANT_SEL3 (MTK_PIN_NO(129) | 3) +#define PINMUX_GPIO129__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(129) | 6) +#define PINMUX_GPIO129__FUNC_DBG_MON_A23 (MTK_PIN_NO(129) | 7) + +#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) +#define PINMUX_GPIO130__FUNC_MSDC0_DAT7 (MTK_PIN_NO(130) | 1) +#define PINMUX_GPIO130__FUNC_MRG_DO (MTK_PIN_NO(130) | 3) +#define PINMUX_GPIO130__FUNC_DBG_MON_A24 (MTK_PIN_NO(130) | 7) + +#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) +#define PINMUX_GPIO131__FUNC_MSDC0_DSL (MTK_PIN_NO(131) | 1) +#define PINMUX_GPIO131__FUNC_MRG_SYNC (MTK_PIN_NO(131) | 3) +#define PINMUX_GPIO131__FUNC_DBG_MON_A25 (MTK_PIN_NO(131) | 7) + +#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) +#define PINMUX_GPIO132__FUNC_MSDC0_DAT3 (MTK_PIN_NO(132) | 1) +#define PINMUX_GPIO132__FUNC_MRG_DI (MTK_PIN_NO(132) | 3) +#define PINMUX_GPIO132__FUNC_DBG_MON_A26 (MTK_PIN_NO(132) | 7) + +#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) +#define PINMUX_GPIO133__FUNC_MSDC0_RSTB (MTK_PIN_NO(133) | 1) +#define PINMUX_GPIO133__FUNC_AGPS_SYNC (MTK_PIN_NO(133) | 3) +#define PINMUX_GPIO133__FUNC_DBG_MON_A27 (MTK_PIN_NO(133) | 7) + +#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) +#define PINMUX_GPIO134__FUNC_RTC32K_CK (MTK_PIN_NO(134) | 1) + +#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) +#define PINMUX_GPIO135__FUNC_WATCHDOG (MTK_PIN_NO(135) | 1) + +#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) +#define PINMUX_GPIO136__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(136) | 1) +#define PINMUX_GPIO136__FUNC_AUD_CLK_MISO (MTK_PIN_NO(136) | 2) +#define PINMUX_GPIO136__FUNC_I2S1_MCK (MTK_PIN_NO(136) | 3) +#define PINMUX_GPIO136__FUNC_UFS_UNIPRO_SCL (MTK_PIN_NO(136) | 6) + +#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) +#define PINMUX_GPIO137__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(137) | 1) +#define PINMUX_GPIO137__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(137) | 2) +#define PINMUX_GPIO137__FUNC_I2S1_BCK (MTK_PIN_NO(137) | 3) + +#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) +#define PINMUX_GPIO138__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(138) | 1) +#define PINMUX_GPIO138__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(138) | 2) +#define PINMUX_GPIO138__FUNC_I2S1_LRCK (MTK_PIN_NO(138) | 3) +#define PINMUX_GPIO138__FUNC_DBG_MON_B24 (MTK_PIN_NO(138) | 7) + +#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) +#define PINMUX_GPIO139__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(139) | 1) +#define PINMUX_GPIO139__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(139) | 2) +#define PINMUX_GPIO139__FUNC_I2S1_DO (MTK_PIN_NO(139) | 3) +#define PINMUX_GPIO139__FUNC_UFS_MPHY_SDA (MTK_PIN_NO(139) | 6) + +#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) +#define PINMUX_GPIO140__FUNC_AUD_CLK_MISO (MTK_PIN_NO(140) | 1) +#define PINMUX_GPIO140__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(140) | 2) +#define PINMUX_GPIO140__FUNC_I2S0_MCK (MTK_PIN_NO(140) | 3) +#define PINMUX_GPIO140__FUNC_UFS_UNIPRO_SDA (MTK_PIN_NO(140) | 6) + +#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) +#define PINMUX_GPIO141__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(141) | 1) +#define PINMUX_GPIO141__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(141) | 2) +#define PINMUX_GPIO141__FUNC_I2S0_BCK (MTK_PIN_NO(141) | 3) + +#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) +#define PINMUX_GPIO142__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(142) | 1) +#define PINMUX_GPIO142__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(142) | 2) +#define PINMUX_GPIO142__FUNC_I2S0_LRCK (MTK_PIN_NO(142) | 3) +#define PINMUX_GPIO142__FUNC_VOW_DAT_MISO (MTK_PIN_NO(142) | 4) +#define PINMUX_GPIO142__FUNC_DBG_MON_B25 (MTK_PIN_NO(142) | 7) + +#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0) +#define PINMUX_GPIO143__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(143) | 1) +#define PINMUX_GPIO143__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(143) | 2) +#define PINMUX_GPIO143__FUNC_I2S0_DI (MTK_PIN_NO(143) | 3) +#define PINMUX_GPIO143__FUNC_VOW_CLK_MISO (MTK_PIN_NO(143) | 4) +#define PINMUX_GPIO143__FUNC_UFS_MPHY_SCL (MTK_PIN_NO(143) | 6) +#define PINMUX_GPIO143__FUNC_DBG_MON_B26 (MTK_PIN_NO(143) | 7) + +#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0) +#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(144) | 1) +#define PINMUX_GPIO144__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(144) | 2) + +#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0) +#define PINMUX_GPIO145__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(145) | 1) + +#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0) +#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(146) | 1) +#define PINMUX_GPIO146__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(146) | 2) + +#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0) +#define PINMUX_GPIO147__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(147) | 1) + +#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0) +#define PINMUX_GPIO148__FUNC_SRCLKENA0 (MTK_PIN_NO(148) | 1) + +#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0) +#define PINMUX_GPIO149__FUNC_SRCLKENA1 (MTK_PIN_NO(149) | 1) + +#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0) +#define PINMUX_GPIO150__FUNC_PWM_A (MTK_PIN_NO(150) | 1) +#define PINMUX_GPIO150__FUNC_CMFLASH (MTK_PIN_NO(150) | 2) +#define PINMUX_GPIO150__FUNC_CLKM0 (MTK_PIN_NO(150) | 3) +#define PINMUX_GPIO150__FUNC_DBG_MON_B30 (MTK_PIN_NO(150) | 7) + +#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0) +#define PINMUX_GPIO151__FUNC_PWM_B (MTK_PIN_NO(151) | 1) +#define PINMUX_GPIO151__FUNC_CMVREF0 (MTK_PIN_NO(151) | 2) +#define PINMUX_GPIO151__FUNC_CLKM1 (MTK_PIN_NO(151) | 3) +#define PINMUX_GPIO151__FUNC_DBG_MON_B20 (MTK_PIN_NO(151) | 7) + +#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0) +#define PINMUX_GPIO152__FUNC_PWM_C (MTK_PIN_NO(152) | 1) +#define PINMUX_GPIO152__FUNC_CMFLASH (MTK_PIN_NO(152) | 2) +#define PINMUX_GPIO152__FUNC_CLKM2 (MTK_PIN_NO(152) | 3) +#define PINMUX_GPIO152__FUNC_DBG_MON_B21 (MTK_PIN_NO(152) | 7) + +#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0) +#define PINMUX_GPIO153__FUNC_PWM_A (MTK_PIN_NO(153) | 1) +#define PINMUX_GPIO153__FUNC_CMVREF0 (MTK_PIN_NO(153) | 2) +#define PINMUX_GPIO153__FUNC_CLKM3 (MTK_PIN_NO(153) | 3) +#define PINMUX_GPIO153__FUNC_DBG_MON_B22 (MTK_PIN_NO(153) | 7) + +#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0) +#define PINMUX_GPIO154__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(154) | 1) +#define PINMUX_GPIO154__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(154) | 2) +#define PINMUX_GPIO154__FUNC_DBG_MON_B18 (MTK_PIN_NO(154) | 7) + +#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0) +#define PINMUX_GPIO155__FUNC_ANT_SEL0 (MTK_PIN_NO(155) | 1) +#define PINMUX_GPIO155__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(155) | 2) +#define PINMUX_GPIO155__FUNC_CMVREF1 (MTK_PIN_NO(155) | 3) +#define PINMUX_GPIO155__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(155) | 7) + +#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0) +#define PINMUX_GPIO156__FUNC_ANT_SEL1 (MTK_PIN_NO(156) | 1) +#define PINMUX_GPIO156__FUNC_SRCLKENAI0 (MTK_PIN_NO(156) | 2) +#define PINMUX_GPIO156__FUNC_SCL6 (MTK_PIN_NO(156) | 3) +#define PINMUX_GPIO156__FUNC_KPCOL2 (MTK_PIN_NO(156) | 4) +#define PINMUX_GPIO156__FUNC_IDDIG (MTK_PIN_NO(156) | 5) +#define PINMUX_GPIO156__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(156) | 7) + +#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0) +#define PINMUX_GPIO157__FUNC_ANT_SEL2 (MTK_PIN_NO(157) | 1) +#define PINMUX_GPIO157__FUNC_SRCLKENAI1 (MTK_PIN_NO(157) | 2) +#define PINMUX_GPIO157__FUNC_SDA6 (MTK_PIN_NO(157) | 3) +#define PINMUX_GPIO157__FUNC_KPROW2 (MTK_PIN_NO(157) | 4) +#define PINMUX_GPIO157__FUNC_USB_DRVVBUS (MTK_PIN_NO(157) | 5) +#define PINMUX_GPIO157__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(157) | 7) + +#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0) +#define PINMUX_GPIO158__FUNC_ANT_SEL3 (MTK_PIN_NO(158) | 1) + +#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0) +#define PINMUX_GPIO159__FUNC_ANT_SEL4 (MTK_PIN_NO(159) | 1) + +#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0) +#define PINMUX_GPIO160__FUNC_ANT_SEL5 (MTK_PIN_NO(160) | 1) + +#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0) +#define PINMUX_GPIO161__FUNC_SPI1_A_MI (MTK_PIN_NO(161) | 1) +#define PINMUX_GPIO161__FUNC_SCP_SPI1_MI (MTK_PIN_NO(161) | 2) +#define PINMUX_GPIO161__FUNC_IDDIG (MTK_PIN_NO(161) | 3) +#define PINMUX_GPIO161__FUNC_ANT_SEL6 (MTK_PIN_NO(161) | 4) +#define PINMUX_GPIO161__FUNC_KPCOL2 (MTK_PIN_NO(161) | 5) +#define PINMUX_GPIO161__FUNC_PTA_RXD (MTK_PIN_NO(161) | 6) +#define PINMUX_GPIO161__FUNC_DBG_MON_B19 (MTK_PIN_NO(161) | 7) + +#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0) +#define PINMUX_GPIO162__FUNC_SPI1_A_CSB (MTK_PIN_NO(162) | 1) +#define PINMUX_GPIO162__FUNC_SCP_SPI1_CS (MTK_PIN_NO(162) | 2) +#define PINMUX_GPIO162__FUNC_USB_DRVVBUS (MTK_PIN_NO(162) | 3) +#define PINMUX_GPIO162__FUNC_ANT_SEL5 (MTK_PIN_NO(162) | 4) +#define PINMUX_GPIO162__FUNC_KPROW2 (MTK_PIN_NO(162) | 5) +#define PINMUX_GPIO162__FUNC_PTA_TXD (MTK_PIN_NO(162) | 6) + +#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0) +#define PINMUX_GPIO163__FUNC_SPI1_A_MO (MTK_PIN_NO(163) | 1) +#define PINMUX_GPIO163__FUNC_SCP_SPI1_MO (MTK_PIN_NO(163) | 2) +#define PINMUX_GPIO163__FUNC_SDA1 (MTK_PIN_NO(163) | 3) +#define PINMUX_GPIO163__FUNC_ANT_SEL4 (MTK_PIN_NO(163) | 4) +#define PINMUX_GPIO163__FUNC_CMMCLK2 (MTK_PIN_NO(163) | 5) +#define PINMUX_GPIO163__FUNC_DMIC_CLK (MTK_PIN_NO(163) | 6) + +#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0) +#define PINMUX_GPIO164__FUNC_SPI1_A_CLK (MTK_PIN_NO(164) | 1) +#define PINMUX_GPIO164__FUNC_SCP_SPI1_CK (MTK_PIN_NO(164) | 2) +#define PINMUX_GPIO164__FUNC_SCL1 (MTK_PIN_NO(164) | 3) +#define PINMUX_GPIO164__FUNC_ANT_SEL3 (MTK_PIN_NO(164) | 4) +#define PINMUX_GPIO164__FUNC_CMMCLK3 (MTK_PIN_NO(164) | 5) +#define PINMUX_GPIO164__FUNC_DMIC_DAT (MTK_PIN_NO(164) | 6) + +#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0) +#define PINMUX_GPIO165__FUNC_PWM_B (MTK_PIN_NO(165) | 1) +#define PINMUX_GPIO165__FUNC_CMMCLK2 (MTK_PIN_NO(165) | 2) +#define PINMUX_GPIO165__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(165) | 3) +#define PINMUX_GPIO165__FUNC_TDM_MCK_2ND (MTK_PIN_NO(165) | 6) +#define PINMUX_GPIO165__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(165) | 7) + +#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0) +#define PINMUX_GPIO166__FUNC_ANT_SEL6 (MTK_PIN_NO(166) | 1) + +#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0) +#define PINMUX_GPIO167__FUNC_RFIC0_BSI_EN (MTK_PIN_NO(167) | 1) +#define PINMUX_GPIO167__FUNC_SPM_BSI_EN (MTK_PIN_NO(167) | 2) + +#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0) +#define PINMUX_GPIO168__FUNC_RFIC0_BSI_CK (MTK_PIN_NO(168) | 1) +#define PINMUX_GPIO168__FUNC_SPM_BSI_CK (MTK_PIN_NO(168) | 2) + +#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0) +#define PINMUX_GPIO169__FUNC_PWM_C (MTK_PIN_NO(169) | 1) +#define PINMUX_GPIO169__FUNC_CMMCLK3 (MTK_PIN_NO(169) | 2) +#define PINMUX_GPIO169__FUNC_CMVREF1 (MTK_PIN_NO(169) | 3) +#define PINMUX_GPIO169__FUNC_ANT_SEL7 (MTK_PIN_NO(169) | 4) +#define PINMUX_GPIO169__FUNC_AGPS_SYNC (MTK_PIN_NO(169) | 5) +#define PINMUX_GPIO169__FUNC_TDM_BCK_2ND (MTK_PIN_NO(169) | 6) +#define PINMUX_GPIO169__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(169) | 7) + +#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0) +#define PINMUX_GPIO170__FUNC_I2S1_BCK (MTK_PIN_NO(170) | 1) +#define PINMUX_GPIO170__FUNC_I2S3_BCK (MTK_PIN_NO(170) | 2) +#define PINMUX_GPIO170__FUNC_SCL7 (MTK_PIN_NO(170) | 3) +#define PINMUX_GPIO170__FUNC_I2S5_BCK (MTK_PIN_NO(170) | 4) +#define PINMUX_GPIO170__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(170) | 5) +#define PINMUX_GPIO170__FUNC_TDM_LRCK_2ND (MTK_PIN_NO(170) | 6) +#define PINMUX_GPIO170__FUNC_ANT_SEL3 (MTK_PIN_NO(170) | 7) + +#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0) +#define PINMUX_GPIO171__FUNC_I2S1_LRCK (MTK_PIN_NO(171) | 1) +#define PINMUX_GPIO171__FUNC_I2S3_LRCK (MTK_PIN_NO(171) | 2) +#define PINMUX_GPIO171__FUNC_SDA7 (MTK_PIN_NO(171) | 3) +#define PINMUX_GPIO171__FUNC_I2S5_LRCK (MTK_PIN_NO(171) | 4) +#define PINMUX_GPIO171__FUNC_URXD1 (MTK_PIN_NO(171) | 5) +#define PINMUX_GPIO171__FUNC_TDM_DATA0_2ND (MTK_PIN_NO(171) | 6) +#define PINMUX_GPIO171__FUNC_ANT_SEL4 (MTK_PIN_NO(171) | 7) + +#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0) +#define PINMUX_GPIO172__FUNC_I2S1_DO (MTK_PIN_NO(172) | 1) +#define PINMUX_GPIO172__FUNC_I2S3_DO (MTK_PIN_NO(172) | 2) +#define PINMUX_GPIO172__FUNC_SCL8 (MTK_PIN_NO(172) | 3) +#define PINMUX_GPIO172__FUNC_I2S5_DO (MTK_PIN_NO(172) | 4) +#define PINMUX_GPIO172__FUNC_UTXD1 (MTK_PIN_NO(172) | 5) +#define PINMUX_GPIO172__FUNC_TDM_DATA1_2ND (MTK_PIN_NO(172) | 6) +#define PINMUX_GPIO172__FUNC_ANT_SEL5 (MTK_PIN_NO(172) | 7) + +#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0) +#define PINMUX_GPIO173__FUNC_I2S1_MCK (MTK_PIN_NO(173) | 1) +#define PINMUX_GPIO173__FUNC_I2S3_MCK (MTK_PIN_NO(173) | 2) +#define PINMUX_GPIO173__FUNC_SDA8 (MTK_PIN_NO(173) | 3) +#define PINMUX_GPIO173__FUNC_I2S5_MCK (MTK_PIN_NO(173) | 4) +#define PINMUX_GPIO173__FUNC_UCTS0 (MTK_PIN_NO(173) | 5) +#define PINMUX_GPIO173__FUNC_TDM_DATA2_2ND (MTK_PIN_NO(173) | 6) +#define PINMUX_GPIO173__FUNC_ANT_SEL6 (MTK_PIN_NO(173) | 7) + +#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0) +#define PINMUX_GPIO174__FUNC_I2S2_DI (MTK_PIN_NO(174) | 1) +#define PINMUX_GPIO174__FUNC_I2S0_DI (MTK_PIN_NO(174) | 2) +#define PINMUX_GPIO174__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(174) | 3) +#define PINMUX_GPIO174__FUNC_I2S2_DI2 (MTK_PIN_NO(174) | 4) +#define PINMUX_GPIO174__FUNC_URTS0 (MTK_PIN_NO(174) | 5) +#define PINMUX_GPIO174__FUNC_TDM_DATA3_2ND (MTK_PIN_NO(174) | 6) +#define PINMUX_GPIO174__FUNC_ANT_SEL7 (MTK_PIN_NO(174) | 7) + +#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0) +#define PINMUX_GPIO175__FUNC_ANT_SEL7 (MTK_PIN_NO(175) | 1) + +#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0) + +#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0) + +#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0) + +#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0) + +#endif /* __MT8183-PINFUNC_H */ -- cgit v1.2.3-70-g09d2 From b9ffc18c6388c0c62dbcfb486525825c0ca504f8 Mon Sep 17 00:00:00 2001 From: Hsin-Yi Wang Date: Wed, 4 Aug 2021 12:40:34 +0800 Subject: dt-bindings: mediatek: convert pinctrl to yaml Convert mt65xx, mt6796, mt7622, mt8183 bindings to yaml. Signed-off-by: Hsin-Yi Wang Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20210804044033.3047296-3-hsinyi@chromium.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml | 206 +++++++++ .../bindings/pinctrl/mediatek,mt6797-pinctrl.yaml | 173 ++++++++ .../bindings/pinctrl/mediatek,mt7622-pinctrl.yaml | 373 ++++++++++++++++ .../bindings/pinctrl/mediatek,mt8183-pinctrl.yaml | 228 ++++++++++ .../devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 156 ------- .../devicetree/bindings/pinctrl/pinctrl-mt6797.txt | 83 ---- .../devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 490 --------------------- .../devicetree/bindings/pinctrl/pinctrl-mt8183.txt | 132 ------ MAINTAINERS | 6 +- 9 files changed, 984 insertions(+), 863 deletions(-) create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml create mode 100644 Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt delete mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml new file mode 100644 index 000000000000..f8e6e138dc13 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml @@ -0,0 +1,206 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt65xx-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT65xx Pin Controller Device Tree Bindings + +maintainers: + - Sean Wang + +description: |+ + The Mediatek's Pin controller is used to control SoC pins. + +properties: + compatible: + enum: + - mediatek,mt2701-pinctrl + - mediatek,mt2712-pinctrl + - mediatek,mt6397-pinctrl + - mediatek,mt7623-pinctrl + - mediatek,mt8127-pinctrl + - mediatek,mt8135-pinctrl + - mediatek,mt8167-pinctrl + - mediatek,mt8173-pinctrl + - mediatek,mt8516-pinctrl + + reg: + maxItems: 1 + + pins-are-numbered: + $ref: /schemas/types.yaml#/definitions/flag + description: | + Specify the subnodes are using numbered pinmux to specify pins. + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + + mediatek,pctl-regmap: + $ref: /schemas/types.yaml#/definitions/phandle-array + minItems: 1 + maxItems: 2 + description: | + Should be phandles of the syscfg node. + + interrupt-controller: true + + interrupts: + minItems: 1 + maxItems: 3 + + "#interrupt-cells": + const: 2 + +required: + - compatible + - pins-are-numbered + - gpio-controller + - "#gpio-cells" + +patternProperties: + '-[0-9]+$': + type: object + additionalProperties: false + patternProperties: + 'pins': + type: object + additionalProperties: false + description: | + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and input + schmitt. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pinmux: + description: + integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are + defined as macros in -pinfunc.h directly. + + bias-disable: true + + bias-pull-up: + description: | + Besides generic pinconfig options, it can be used as the pull up + settings for 2 pull resistors, R0 and R1. User can configure those + special pins. Some macros have been defined for this usage, such + as MTK_PUPD_SET_R1R0_00. See dt-bindings/pinctrl/mt65xx.h for + valid arguments. + + bias-pull-down: true + + input-enable: true + + input-disable: true + + output-low: true + + output-high: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + drive-strength: + description: | + Can support some arguments, such as MTK_DRIVE_4mA, MTK_DRIVE_6mA, + etc. See dt-bindings/pinctrl/mt65xx.h for valid arguments. + + required: + - pinmux + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + syscfg_pctl_a: syscfg-pctl-a@10005000 { + compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon"; + reg = <0 0x10005000 0 0x1000>; + }; + + syscfg_pctl_b: syscfg-pctl-b@1020c020 { + compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon"; + reg = <0 0x1020C020 0 0x1000>; + }; + + pinctrl@1c20800 { + compatible = "mediatek,mt8135-pinctrl"; + reg = <0 0x1000B000 0 0x1000>; + mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>; + pins-are-numbered; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = , + , + ; + + i2c0_pins_a: i2c0-0 { + pins1 { + pinmux = , + ; + bias-disable; + }; + }; + + i2c1_pins_a: i2c1-0 { + pins { + pinmux = , + ; + bias-pull-up = ; + }; + }; + + i2c2_pins_a: i2c2-0 { + pins1 { + pinmux = ; + bias-pull-down; + }; + + pins2 { + pinmux = ; + bias-pull-up; + }; + }; + + i2c3_pins_a: i2c3-0 { + pins1 { + pinmux = , + ; + bias-pull-up = ; + }; + + pins2 { + pinmux = , + ; + output-low; + bias-pull-up = ; + }; + + pins3 { + pinmux = , + ; + drive-strength = <32>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml new file mode 100644 index 000000000000..76a6df75ed9c --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml @@ -0,0 +1,173 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt6797-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT6797 Pin Controller Device Tree Bindings + +maintainers: + - Sean Wang + +description: |+ + The MediaTek's MT6797 Pin controller is used to control SoC pins. + +properties: + compatible: + const: mediatek,mt6797-pinctrl + + reg: + minItems: 5 + maxItems: 5 + + reg-names: + items: + - const: gpio + - const: iocfgl + - const: iocfgb + - const: iocfgr + - const: iocfgt + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + + interrupt-controller: true + + interrupts: + maxItems: 1 + + "#interrupt-cells": + const: 2 + +required: + - compatible + - reg + - reg-names + - gpio-controller + - "#gpio-cells" + +patternProperties: + '-[0-9]+$': + type: object + additionalProperties: false + patternProperties: + 'pins': + type: object + additionalProperties: false + description: | + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and input + schmitt. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pinmux: + description: + integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are + defined as macros in -pinfunc.h directly. + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + input-enable: true + + input-disable: true + + output-enable: true + + output-low: true + + output-high: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + drive-strength: + enum: [2, 4, 8, 12, 16] + + slew-rate: + enum: [0, 1] + + mediatek,pull-up-adv: + description: | + Pull up setings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + mediatek,pull-down-adv: + description: | + Pull down settings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + mediatek,tdsel: + description: | + An integer describing the steps for output level shifter duty + cycle when asserted (high pulse width adjustment). Valid arguments + are from 0 to 15. + $ref: /schemas/types.yaml#/definitions/uint32 + + mediatek,rdsel: + description: | + An integer describing the steps for input level shifter duty cycle + when asserted (high pulse width adjustment). Valid arguments are + from 0 to 63. + $ref: /schemas/types.yaml#/definitions/uint32 + + required: + - pinmux + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt6797-pinctrl"; + reg = <0 0x10005000 0 0x1000>, + <0 0x10002000 0 0x400>, + <0 0x10002400 0 0x400>, + <0 0x10002800 0 0x400>, + <0 0x10002C00 0 0x400>; + reg-names = "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt"; + gpio-controller; + #gpio-cells = <2>; + + uart_pins_a: uart-0 { + pins1 { + pinmux = , + ; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml new file mode 100644 index 000000000000..0feecd376c69 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml @@ -0,0 +1,373 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt7622-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT7622 Pin Controller Device Tree Bindings + +maintainers: + - Sean Wang + +description: |+ + The MediaTek's MT7622 Pin controller is used to control SoC pins. + +properties: + compatible: + enum: + - mediatek,mt7622-pinctrl + - mediatek,mt7629-pinctrl + + reg: + maxItems: 1 + + reg-names: + items: + - const: eint + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + + interrupt-controller: true + + interrupts: + maxItems: 1 + + "#interrupt-cells": + const: 2 + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + +if: + required: + - interrupt-controller +then: + required: + - reg-names + - interrupts + - "#interrupt-cells" + +patternProperties: + '-[0-9]+$': + type: object + additionalProperties: false + patternProperties: + 'mux': + type: object + additionalProperties: false + description: | + pinmux configuration nodes. + $ref: "/schemas/pinctrl/pinmux-node.yaml" + properties: + function: + description: | + A string containing the name of the function to mux to the group. + enum: [emmc, eth, i2c, i2s, ir, led, flash, pcie, pmic, pwm, sd, + spi, tdm, uart, watchdog, wifi] + + groups: + description: | + An array of strings. Each string contains the name of a group. + + drive-strength: + enum: [4, 8, 12, 16] + + required: + - groups + - function + + allOf: + - if: + properties: + function: + const: emmc + then: + properties: + groups: + enum: [emmc, emmc_rst] + - if: + properties: + function: + const: eth + then: + properties: + groups: + enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw, + rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio] + - if: + properties: + function: + const: i2c + then: + properties: + groups: + enum: [i2c0, i2c_0, i2c_1, i2c1_0, i2c1_1, i2c1_2, i2c2_0, + i2c2_1, i2c2_2] + - if: + properties: + function: + const: i2s + then: + properties: + groups: + enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data, + i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws, + i2s1_out_data, i2s2_out_data, i2s3_out_data, + i2s4_out_data] + - if: + properties: + function: + const: ir + then: + properties: + groups: + enum: [ir_0_tx, ir_1_tx, ir_2_tx, ir_0_rx, ir_1_rx, ir_2_rx] + - if: + properties: + function: + const: led + then: + properties: + groups: + enum: [ephy_leds, ephy0_led, ephy1_led, ephy2_led, ephy3_led, + ephy4_led, wled, wf2g_led, wf5g_led] + - if: + properties: + function: + const: flash + then: + properties: + groups: + enum: [par_nand, snfi, spi_nor] + - if: + properties: + function: + const: pcie + then: + properties: + groups: + enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken, + pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq, + pcie0_pad_perst, pcie1_pad_perst, pcie_pereset, + pcie_wake, pcie_clkreq] + - if: + properties: + function: + const: pmic + then: + properties: + groups: + enum: [pmic_bus] + - if: + properties: + function: + const: pwm + then: + properties: + groups: + enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1, + pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0, + pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1, + pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3, + pwm_ch7_0, pwm_0, pwm_1] + - if: + properties: + function: + const: sd + then: + properties: + groups: + enum: [sd_0, sd_1] + - if: + properties: + function: + const: spi + then: + properties: + groups: + enum: [spic0_0, spic0_1, spic1_0, spic1_1, spic2_0_wp_hold, + spic2_0, spi_0, spi_1, spi_wp, spi_hold] + - if: + properties: + function: + const: tdm + then: + properties: + groups: + enum: [tdm_0_out_mclk_bclk_ws, tdm_0_in_mclk_bclk_ws, + tdm_0_out_data, tdm_0_in_data, tdm_1_out_mclk_bclk_ws, + tdm_1_in_mclk_bclk_ws, tdm_1_out_data, tdm_1_in_data] + - if: + properties: + function: + const: uart + then: + properties: + groups: + enum: [uart0_0_tx_rx, uart1_0_tx_rx, uart1_0_rts_cts, + uart1_1_tx_rx, uart1_1_rts_cts, uart2_0_tx_rx, + uart2_0_rts_cts, uart2_1_tx_rx, uart2_1_rts_cts, + uart2_2_tx_rx, uart2_2_rts_cts, uart2_3_tx_rx, + uart3_0_tx_rx, uart3_1_tx_rx, uart3_1_rts_cts, + uart4_0_tx_rx, uart4_1_tx_rx, uart4_1_rts_cts, + uart4_2_tx_rx, uart4_2_rts_cts, uart0_txd_rxd, + uart1_0_txd_rxd, uart1_0_cts_rts, uart1_1_txd_rxd, + uart1_1_cts_rts, uart2_0_txd_rxd, uart2_0_cts_rts, + uart2_1_txd_rxd, uart2_1_cts_rts] + - if: + properties: + function: + const: watchdog + then: + properties: + groups: + enum: [watchdog] + - if: + properties: + function: + const: wifi + then: + properties: + groups: + enum: [wf0_2g, wf0_5g] + + 'conf': + type: object + additionalProperties: false + description: | + pinconf configuration nodes. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + groups: + description: | + An array of strings. Each string contains the name of a group. + Valid values are the same as the pinmux node. + + pins: + description: | + An array of strings. Each string contains the name of a pin. + enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0, + RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS, + I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT, + I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1, + G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2, + G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6, + NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0, + MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1, + MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2, + MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3, + MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL, + PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS, + GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N, + PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2, + AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4, + PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA, + WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4, + WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG, + EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS, + EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N, + WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD, + UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD, + UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N, + PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5, + GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK, + TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3, + WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6] + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + input-enable: true + + input-disable: true + + output-enable: true + + output-low: true + + output-high: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + drive-strength: + enum: [4, 8, 12, 16] + + slew-rate: + enum: [0, 1] + + mediatek,tdsel: + description: | + An integer describing the steps for output level shifter duty + cycle when asserted (high pulse width adjustment). Valid arguments + are from 0 to 15. + $ref: /schemas/types.yaml#/definitions/uint32 + + mediatek,rdsel: + description: | + An integer describing the steps for input level shifter duty cycle + when asserted (high pulse width adjustment). Valid arguments are + from 0 to 63. + $ref: /schemas/types.yaml#/definitions/uint32 + + required: + - pins + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pio: pinctrl@10211000 { + compatible = "mediatek,mt7622-pinctrl"; + reg = <0 0x10211000 0 0x1000>; + gpio-controller; + #gpio-cells = <2>; + + pinctrl_eth_default: eth-0 { + mux-mdio { + groups = "mdc_mdio"; + function = "eth"; + drive-strength = <12>; + }; + + mux-gmac2 { + groups = "rgmii_via_gmac2"; + function = "eth"; + drive-strength = <12>; + }; + + mux-esw { + groups = "esw"; + function = "eth"; + drive-strength = <8>; + }; + + conf-mdio { + pins = "MDC"; + bias-pull-up; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml new file mode 100644 index 000000000000..cc1509e9b981 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml @@ -0,0 +1,228 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/mediatek,mt8183-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT8183 Pin Controller Device Tree Bindings + +maintainers: + - Sean Wang + +description: |+ + The MediaTek's MT8183 Pin controller is used to control SoC pins. + +properties: + compatible: + const: mediatek,mt8183-pinctrl + + reg: + minItems: 10 + maxItems: 10 + + reg-names: + items: + - const: iocfg0 + - const: iocfg1 + - const: iocfg2 + - const: iocfg3 + - const: iocfg4 + - const: iocfg5 + - const: iocfg6 + - const: iocfg7 + - const: iocfg8 + - const: eint + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + Number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See the below + mentioned gpio binding representation for description of particular cells. + + gpio-ranges: + minItems: 1 + maxItems: 5 + description: | + GPIO valid number range. + + interrupt-controller: true + + interrupts: + maxItems: 1 + + "#interrupt-cells": + const: 2 + +required: + - compatible + - reg + - gpio-controller + - "#gpio-cells" + - gpio-ranges + +patternProperties: + '-[0-9]+$': + type: object + additionalProperties: false + patternProperties: + 'pins': + type: object + additionalProperties: false + description: | + A pinctrl node should contain at least one subnodes representing the + pinctrl groups available on the machine. Each subnode will list the + pins it needs, and how they should be configured, with regard to muxer + configuration, pullups, drive strength, input enable/disable and input + schmitt. + $ref: "/schemas/pinctrl/pincfg-node.yaml" + + properties: + pinmux: + description: + integer array, represents gpio pin number and mux setting. + Supported pin number and mux varies for different SoCs, and are + defined as macros in -pinfunc.h directly. + + bias-disable: true + + bias-pull-up: true + + bias-pull-down: true + + input-enable: true + + input-disable: true + + output-low: true + + output-high: true + + input-schmitt-enable: true + + input-schmitt-disable: true + + drive-strength: + enum: [2, 4, 6, 8, 10, 12, 14, 16] + + mediatek,drive-strength-adv: + description: | + Describe the specific driving setup property. + For I2C pins, the existing generic driving setup can only support + 2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they + can support 0.125/0.25/0.5/1mA adjustment. If we enable specific + driving setup, the existing generic setup will be disabled. + The specific driving setup is controlled by E1E0EN. + When E1=0/E0=0, the strength is 0.125mA. + When E1=0/E0=1, the strength is 0.25mA. + When E1=1/E0=0, the strength is 0.5mA. + When E1=1/E0=1, the strength is 1mA. + EN is used to enable or disable the specific driving setup. + Valid arguments are described as below: + 0: (E1, E0, EN) = (0, 0, 0) + 1: (E1, E0, EN) = (0, 0, 1) + 2: (E1, E0, EN) = (0, 1, 0) + 3: (E1, E0, EN) = (0, 1, 1) + 4: (E1, E0, EN) = (1, 0, 0) + 5: (E1, E0, EN) = (1, 0, 1) + 6: (E1, E0, EN) = (1, 1, 0) + 7: (E1, E0, EN) = (1, 1, 1) + So the valid arguments are from 0 to 7. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6, 7] + + mediatek,pull-up-adv: + description: | + Pull up setings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + mediatek,pull-down-adv: + description: | + Pull down settings for 2 pull resistors, R0 and R1. User can + configure those special pins. Valid arguments are described as below: + 0: (R1, R0) = (0, 0) which means R1 disabled and R0 disabled. + 1: (R1, R0) = (0, 1) which means R1 disabled and R0 enabled. + 2: (R1, R0) = (1, 0) which means R1 enabled and R0 disabled. + 3: (R1, R0) = (1, 1) which means R1 enabled and R0 enabled. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + + mediatek,tdsel: + description: | + An integer describing the steps for output level shifter duty + cycle when asserted (high pulse width adjustment). Valid arguments + are from 0 to 15. + $ref: /schemas/types.yaml#/definitions/uint32 + + mediatek,rdsel: + description: | + An integer describing the steps for input level shifter duty cycle + when asserted (high pulse width adjustment). Valid arguments are + from 0 to 63. + $ref: /schemas/types.yaml#/definitions/uint32 + + required: + - pinmux + +additionalProperties: false + +examples: + - | + #include + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + pio: pinctrl@10005000 { + compatible = "mediatek,mt8183-pinctrl"; + reg = <0 0x10005000 0 0x1000>, + <0 0x11f20000 0 0x1000>, + <0 0x11e80000 0 0x1000>, + <0 0x11e70000 0 0x1000>, + <0 0x11e90000 0 0x1000>, + <0 0x11d30000 0 0x1000>, + <0 0x11d20000 0 0x1000>, + <0 0x11c50000 0 0x1000>, + <0 0x11f30000 0 0x1000>, + <0 0x1000b000 0 0x1000>; + reg-names = "iocfg0", "iocfg1", "iocfg2", + "iocfg3", "iocfg4", "iocfg5", + "iocfg6", "iocfg7", "iocfg8", + "eint"; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pio 0 0 192>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <2>; + + i2c0_pins_a: i2c-0 { + pins1 { + pinmux = , + ; + mediatek,pull-up-adv = <3>; + mediatek,drive-strength-adv = <7>; + }; + }; + + i2c1_pins_a: i2c-1 { + pins { + pinmux = , + ; + mediatek,pull-down-adv = <2>; + mediatek,drive-strength-adv = <4>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt deleted file mode 100644 index 5fe2c26c28bf..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +++ /dev/null @@ -1,156 +0,0 @@ -* Mediatek MT65XX Pin Controller - -The Mediatek's Pin controller is used to control SoC pins. - -Required properties: -- compatible: value should be one of the following. - "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl. - "mediatek,mt2712-pinctrl", compatible with mt2712 pinctrl. - "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl. - "mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl. - "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl. - "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl. - "mediatek,mt8167-pinctrl", compatible with mt8167 pinctrl. - "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl. - "mediatek,mt8365-pinctrl", compatible with mt8365 pinctrl. - "mediatek,mt8516-pinctrl", compatible with mt8516 pinctrl. -- pins-are-numbered: Specify the subnodes are using numbered pinmux to - specify pins. -- gpio-controller : Marks the device node as a gpio controller. -- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO - binding is used, the amount of cells must be specified as 2. See the below - mentioned gpio binding representation for description of particular cells. - - Eg: <&pio 6 0> - <[phandle of the gpio controller node] - [line number within the gpio controller] - [flags]> - - Values for gpio specifier: - - Line number: is a value between 0 to 202. - - Flags: bit field of flags, as defined in . - Only the following flags are supported: - 0 - GPIO_ACTIVE_HIGH - 1 - GPIO_ACTIVE_LOW - -Optional properties: -- mediatek,pctl-regmap: Should be a phandle of the syscfg node. -- reg: physicall address base for EINT registers -- interrupt-controller: Marks the device node as an interrupt controller -- #interrupt-cells: Should be two. -- interrupts : The interrupt outputs from the controller. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices. - -Subnode format -A pinctrl node should contain at least one subnodes representing the -pinctrl groups available on the machine. Each subnode will list the -pins it needs, and how they should be configured, with regard to muxer -configuration, pullups, drive strength, input enable/disable and input schmitt. - - node { - pinmux = ; - GENERIC_PINCONFIG; - }; - -Required properties: -- pinmux: integer array, represents gpio pin number and mux setting. - Supported pin number and mux varies for different SoCs, and are defined - as macros in boot/dts/-pinfunc.h directly. - -Optional properties: -- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable, - bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, output-high, - input-schmitt-enable, input-schmitt-disable and drive-strength are valid. - - Some special pins have extra pull up strength, there are R0 and R1 pull-up - resistors available, but for user, it's only need to set R1R0 as 00, 01, 10 or 11. - So when config bias-pull-up, it support arguments for those special pins. - Some macros have been defined for this usage, such as MTK_PUPD_SET_R1R0_00. - See dt-bindings/pinctrl/mt65xx.h. - - When config drive-strength, it can support some arguments, such as - MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h. - -Examples: - -#include "mt8135-pinfunc.h" - -... -{ - syscfg_pctl_a: syscfg-pctl-a@10005000 { - compatible = "mediatek,mt8135-pctl-a-syscfg", "syscon"; - reg = <0 0x10005000 0 0x1000>; - }; - - syscfg_pctl_b: syscfg-pctl-b@1020c020 { - compatible = "mediatek,mt8135-pctl-b-syscfg", "syscon"; - reg = <0 0x1020C020 0 0x1000>; - }; - - pinctrl@1c20800 { - compatible = "mediatek,mt8135-pinctrl"; - reg = <0 0x1000B000 0 0x1000>; - mediatek,pctl-regmap = <&syscfg_pctl_a>, <&syscfg_pctl_b>; - pins-are-numbered; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - interrupts = , - , - ; - - i2c0_pins_a: i2c0@0 { - pins1 { - pinmux = , - ; - bias-disable; - }; - }; - - i2c1_pins_a: i2c1@0 { - pins { - pinmux = , - ; - bias-pull-up = <55>; - }; - }; - - i2c2_pins_a: i2c2@0 { - pins1 { - pinmux = ; - bias-pull-down; - }; - - pins2 { - pinmux = ; - bias-pull-up; - }; - }; - - i2c3_pins_a: i2c3@0 { - pins1 { - pinmux = , - ; - bias-pull-up = <55>; - }; - - pins2 { - pinmux = , - ; - output-low; - bias-pull-up = <55>; - }; - - pins3 { - pinmux = , - ; - drive-strength = <32>; - }; - }; - - ... - } -}; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt deleted file mode 100644 index bd83401e6179..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt6797.txt +++ /dev/null @@ -1,83 +0,0 @@ -* MediaTek MT6797 Pin Controller - -The MediaTek's MT6797 Pin controller is used to control SoC pins. - -Required properties: -- compatible: Value should be one of the following. - "mediatek,mt6797-pinctrl", compatible with mt6797 pinctrl. -- reg: Should contain address and size for gpio, iocfgl, iocfgb, - iocfgr and iocfgt register bases. -- reg-names: An array of strings describing the "reg" entries. Must - contain "gpio", "iocfgl", "iocfgb", "iocfgr", "iocfgt". -- gpio-controller: Marks the device node as a gpio controller. -- #gpio-cells: Should be two. The first cell is the gpio pin number - and the second cell is used for optional parameters. - -Optional properties: -- interrupt-controller: Marks the device node as an interrupt controller. -- #interrupt-cells: Should be two. -- interrupts : The interrupt outputs from the controller. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices. - -Subnode format -A pinctrl node should contain at least one subnodes representing the -pinctrl groups available on the machine. Each subnode will list the -pins it needs, and how they should be configured, with regard to muxer -configuration, pullups, drive strength, input enable/disable and input schmitt. - - node { - pinmux = ; - GENERIC_PINCONFIG; - }; - -Required properties: -- pinmux: Integer array, represents gpio pin number and mux setting. - Supported pin number and mux varies for different SoCs, and are defined - as macros in dt-bindings/pinctrl/-pinfunc.h directly. - -Optional properties: -- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable, - bias-pull, bias-pull-down, input-enable, input-schmitt-enable, - input-schmitt-disable, output-enable output-low, output-high, - drive-strength, and slew-rate are valid. - - Valid arguments for 'slew-rate' are '0' for no slew rate controlled and - '1' for slower slew rate respectively. Valid arguments for 'drive-strength' - is limited, such as 2, 4, 8, 12, or 16 in mA. - - Some optional vendor properties as defined are valid to specify in a - pinconf subnode: - - mediatek,tdsel: An integer describing the steps for output level shifter - duty cycle when asserted (high pulse width adjustment). Valid arguments - are from 0 to 15. - - mediatek,rdsel: An integer describing the steps for input level shifter - duty cycle when asserted (high pulse width adjustment). Valid arguments - are from 0 to 63. - - mediatek,pull-up-adv: An integer describing the code R1R0 as 0, 1, 2 - or 3 for the advanced pull-up resistors. - - mediatek,pull-down-adv: An integer describing the code R1R0 as 0, 1, 2, - or 3 for the advanced pull-down resistors. - -Examples: - - pio: pinctrl@10005000 { - compatible = "mediatek,mt6797-pinctrl"; - reg = <0 0x10005000 0 0x1000>, - <0 0x10002000 0 0x400>, - <0 0x10002400 0 0x400>, - <0 0x10002800 0 0x400>, - <0 0x10002C00 0 0x400>; - reg-names = "gpio", "iocfgl", "iocfgb", - "iocfgr", "iocfgt"; - gpio-controller; - #gpio-cells = <2>; - - uart1_pins_a: uart1 { - pins1 { - pinmux = , - ; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt deleted file mode 100644 index 7a7aca1ed705..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt +++ /dev/null @@ -1,490 +0,0 @@ -== MediaTek MT7622 pinctrl controller == - -Required properties for the root node: - - compatible: Should be one of the following - "mediatek,mt7622-pinctrl" for MT7622 SoC - "mediatek,mt7629-pinctrl" for MT7629 SoC - - reg: offset and length of the pinctrl space - - - gpio-controller: Marks the device node as a GPIO controller. - - #gpio-cells: Should be two. The first cell is the pin number and the - second is the GPIO flags. - -Optional properties: -- interrupt-controller : Marks the device node as an interrupt controller - -If the property interrupt-controller is defined, following property is required -- reg-names: A string describing the "reg" entries. Must contain "eint". -- interrupts : The interrupt output from the controller. -- #interrupt-cells: Should be two. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -MT7622 pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin, a group, or a list of pins or groups. This configuration can include the -mux function to select on those pin(s)/group(s), and various pin configuration -parameters, such as pull-up, slew rate, etc. - -We support 2 types of configuration nodes. Those nodes can be either pinmux -nodes or pinconf nodes. Each configuration node can consist of multiple nodes -describing the pinmux and pinconf options. - -The name of each subnode doesn't matter as long as it is unique; all subnodes -should be enumerated and processed purely based on their content. - -== pinmux nodes content == - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pinmux subnode: - -Required properties are: - - groups: An array of strings. Each string contains the name of a group. - Valid values for these names are listed below. - - function: A string containing the name of the function to mux to the - group. Valid values for function names are listed below. - -== pinconf nodes content == - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pinconf subnode: - -Required properties are: - - pins: An array of strings. Each string contains the name of a pin. - Valid values for these names are listed below. - - groups: An array of strings. Each string contains the name of a group. - Valid values for these names are listed below. - -Optional properies are: - bias-disable, bias-pull, bias-pull-down, input-enable, - input-schmitt-enable, input-schmitt-disable, output-enable - output-low, output-high, drive-strength, slew-rate - - Valid arguments for 'slew-rate' are '0' for no slew rate controlled and '1' for - slower slew rate respectively. - Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA. - -The following specific properties as defined are valid to specify in a pinconf -subnode: - -Optional properties are: - - mediatek,tdsel: An integer describing the steps for output level shifter duty - cycle when asserted (high pulse width adjustment). Valid arguments are from 0 - to 15. - - mediatek,rdsel: An integer describing the steps for input level shifter duty - cycle when asserted (high pulse width adjustment). Valid arguments are from 0 - to 63. - -== Valid values for pins, function and groups on MT7622 == - -Valid values for pins are: -pins can be referenced via the pin names as the below table shown and the -related physical number is also put ahead of those names which helps cross -references to pins between groups to know whether pins assignment conflict -happens among devices try to acquire those available pins. - - Pin #: Valid values for pins - ----------------------------- - PIN 0: "GPIO_A" - PIN 1: "I2S1_IN" - PIN 2: "I2S1_OUT" - PIN 3: "I2S_BCLK" - PIN 4: "I2S_WS" - PIN 5: "I2S_MCLK" - PIN 6: "TXD0" - PIN 7: "RXD0" - PIN 8: "SPI_WP" - PIN 9: "SPI_HOLD" - PIN 10: "SPI_CLK" - PIN 11: "SPI_MOSI" - PIN 12: "SPI_MISO" - PIN 13: "SPI_CS" - PIN 14: "I2C_SDA" - PIN 15: "I2C_SCL" - PIN 16: "I2S2_IN" - PIN 17: "I2S3_IN" - PIN 18: "I2S4_IN" - PIN 19: "I2S2_OUT" - PIN 20: "I2S3_OUT" - PIN 21: "I2S4_OUT" - PIN 22: "GPIO_B" - PIN 23: "MDC" - PIN 24: "MDIO" - PIN 25: "G2_TXD0" - PIN 26: "G2_TXD1" - PIN 27: "G2_TXD2" - PIN 28: "G2_TXD3" - PIN 29: "G2_TXEN" - PIN 30: "G2_TXC" - PIN 31: "G2_RXD0" - PIN 32: "G2_RXD1" - PIN 33: "G2_RXD2" - PIN 34: "G2_RXD3" - PIN 35: "G2_RXDV" - PIN 36: "G2_RXC" - PIN 37: "NCEB" - PIN 38: "NWEB" - PIN 39: "NREB" - PIN 40: "NDL4" - PIN 41: "NDL5" - PIN 42: "NDL6" - PIN 43: "NDL7" - PIN 44: "NRB" - PIN 45: "NCLE" - PIN 46: "NALE" - PIN 47: "NDL0" - PIN 48: "NDL1" - PIN 49: "NDL2" - PIN 50: "NDL3" - PIN 51: "MDI_TP_P0" - PIN 52: "MDI_TN_P0" - PIN 53: "MDI_RP_P0" - PIN 54: "MDI_RN_P0" - PIN 55: "MDI_TP_P1" - PIN 56: "MDI_TN_P1" - PIN 57: "MDI_RP_P1" - PIN 58: "MDI_RN_P1" - PIN 59: "MDI_RP_P2" - PIN 60: "MDI_RN_P2" - PIN 61: "MDI_TP_P2" - PIN 62: "MDI_TN_P2" - PIN 63: "MDI_TP_P3" - PIN 64: "MDI_TN_P3" - PIN 65: "MDI_RP_P3" - PIN 66: "MDI_RN_P3" - PIN 67: "MDI_RP_P4" - PIN 68: "MDI_RN_P4" - PIN 69: "MDI_TP_P4" - PIN 70: "MDI_TN_P4" - PIN 71: "PMIC_SCL" - PIN 72: "PMIC_SDA" - PIN 73: "SPIC1_CLK" - PIN 74: "SPIC1_MOSI" - PIN 75: "SPIC1_MISO" - PIN 76: "SPIC1_CS" - PIN 77: "GPIO_D" - PIN 78: "WATCHDOG" - PIN 79: "RTS3_N" - PIN 80: "CTS3_N" - PIN 81: "TXD3" - PIN 82: "RXD3" - PIN 83: "PERST0_N" - PIN 84: "PERST1_N" - PIN 85: "WLED_N" - PIN 86: "EPHY_LED0_N" - PIN 87: "AUXIN0" - PIN 88: "AUXIN1" - PIN 89: "AUXIN2" - PIN 90: "AUXIN3" - PIN 91: "TXD4" - PIN 92: "RXD4" - PIN 93: "RTS4_N" - PIN 94: "CST4_N" - PIN 95: "PWM1" - PIN 96: "PWM2" - PIN 97: "PWM3" - PIN 98: "PWM4" - PIN 99: "PWM5" - PIN 100: "PWM6" - PIN 101: "PWM7" - PIN 102: "GPIO_E" - -Valid values for function are: - "emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie", - "pmic", "pwm", "sd", "spi", "tdm", "uart", "watchdog" - -Valid values for groups are: -additional data is put followingly with valid value allowing us to know which -applicable function and which relevant pins (in pin#) are able applied for that -group. - - Valid value function pins (in pin#) - ------------------------------------------------------------------------- - "emmc" "emmc" 40, 41, 42, 43, 44, 45, - 47, 48, 49, 50 - "emmc_rst" "emmc" 37 - "esw" "eth" 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, - 69, 70 - "esw_p0_p1" "eth" 51, 52, 53, 54, 55, 56, - 57, 58 - "esw_p2_p3_p4" "eth" 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70 - "rgmii_via_esw" "eth" 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70 - "rgmii_via_gmac1" "eth" 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70 - "rgmii_via_gmac2" "eth" 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36 - "mdc_mdio" "eth" 23, 24 - "i2c0" "i2c" 14, 15 - "i2c1_0" "i2c" 55, 56 - "i2c1_1" "i2c" 73, 74 - "i2c1_2" "i2c" 87, 88 - "i2c2_0" "i2c" 57, 58 - "i2c2_1" "i2c" 75, 76 - "i2c2_2" "i2c" 89, 90 - "i2s_in_mclk_bclk_ws" "i2s" 3, 4, 5 - "i2s1_in_data" "i2s" 1 - "i2s2_in_data" "i2s" 16 - "i2s3_in_data" "i2s" 17 - "i2s4_in_data" "i2s" 18 - "i2s_out_mclk_bclk_ws" "i2s" 3, 4, 5 - "i2s1_out_data" "i2s" 2 - "i2s2_out_data" "i2s" 19 - "i2s3_out_data" "i2s" 20 - "i2s4_out_data" "i2s" 21 - "ir_0_tx" "ir" 16 - "ir_1_tx" "ir" 59 - "ir_2_tx" "ir" 99 - "ir_0_rx" "ir" 17 - "ir_1_rx" "ir" 60 - "ir_2_rx" "ir" 100 - "ephy_leds" "led" 86, 91, 92, 93, 94 - "ephy0_led" "led" 86 - "ephy1_led" "led" 91 - "ephy2_led" "led" 92 - "ephy3_led" "led" 93 - "ephy4_led" "led" 94 - "wled" "led" 85 - "par_nand" "flash" 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, - 49, 50 - "snfi" "flash" 8, 9, 10, 11, 12, 13 - "spi_nor" "flash" 8, 9, 10, 11, 12, 13 - "pcie0_0_waken" "pcie" 14 - "pcie0_1_waken" "pcie" 79 - "pcie1_0_waken" "pcie" 14 - "pcie0_0_clkreq" "pcie" 15 - "pcie0_1_clkreq" "pcie" 80 - "pcie1_0_clkreq" "pcie" 15 - "pcie0_pad_perst" "pcie" 83 - "pcie1_pad_perst" "pcie" 84 - "pmic_bus" "pmic" 71, 72 - "pwm_ch1_0" "pwm" 51 - "pwm_ch1_1" "pwm" 73 - "pwm_ch1_2" "pwm" 95 - "pwm_ch2_0" "pwm" 52 - "pwm_ch2_1" "pwm" 74 - "pwm_ch2_2" "pwm" 96 - "pwm_ch3_0" "pwm" 53 - "pwm_ch3_1" "pwm" 75 - "pwm_ch3_2" "pwm" 97 - "pwm_ch4_0" "pwm" 54 - "pwm_ch4_1" "pwm" 67 - "pwm_ch4_2" "pwm" 76 - "pwm_ch4_3" "pwm" 98 - "pwm_ch5_0" "pwm" 68 - "pwm_ch5_1" "pwm" 77 - "pwm_ch5_2" "pwm" 99 - "pwm_ch6_0" "pwm" 69 - "pwm_ch6_1" "pwm" 78 - "pwm_ch6_2" "pwm" 81 - "pwm_ch6_3" "pwm" 100 - "pwm_ch7_0" "pwm" 70 - "pwm_ch7_1" "pwm" 82 - "pwm_ch7_2" "pwm" 101 - "sd_0" "sd" 16, 17, 18, 19, 20, 21 - "sd_1" "sd" 25, 26, 27, 28, 29, 30 - "spic0_0" "spi" 63, 64, 65, 66 - "spic0_1" "spi" 79, 80, 81, 82 - "spic1_0" "spi" 67, 68, 69, 70 - "spic1_1" "spi" 73, 74, 75, 76 - "spic2_0_wp_hold" "spi" 8, 9 - "spic2_0" "spi" 10, 11, 12, 13 - "tdm_0_out_mclk_bclk_ws" "tdm" 8, 9, 10 - "tdm_0_in_mclk_bclk_ws" "tdm" 11, 12, 13 - "tdm_0_out_data" "tdm" 20 - "tdm_0_in_data" "tdm" 21 - "tdm_1_out_mclk_bclk_ws" "tdm" 57, 58, 59 - "tdm_1_in_mclk_bclk_ws" "tdm" 60, 61, 62 - "tdm_1_out_data" "tdm" 55 - "tdm_1_in_data" "tdm" 56 - "uart0_0_tx_rx" "uart" 6, 7 - "uart1_0_tx_rx" "uart" 55, 56 - "uart1_0_rts_cts" "uart" 57, 58 - "uart1_1_tx_rx" "uart" 73, 74 - "uart1_1_rts_cts" "uart" 75, 76 - "uart2_0_tx_rx" "uart" 3, 4 - "uart2_0_rts_cts" "uart" 1, 2 - "uart2_1_tx_rx" "uart" 51, 52 - "uart2_1_rts_cts" "uart" 53, 54 - "uart2_2_tx_rx" "uart" 59, 60 - "uart2_2_rts_cts" "uart" 61, 62 - "uart2_3_tx_rx" "uart" 95, 96 - "uart3_0_tx_rx" "uart" 57, 58 - "uart3_1_tx_rx" "uart" 81, 82 - "uart3_1_rts_cts" "uart" 79, 80 - "uart4_0_tx_rx" "uart" 61, 62 - "uart4_1_tx_rx" "uart" 91, 92 - "uart4_1_rts_cts" "uart" 93, 94 - "uart4_2_tx_rx" "uart" 97, 98 - "uart4_2_rts_cts" "uart" 95, 96 - "watchdog" "watchdog" 78 - - -== Valid values for pins, function and groups on MT7629 == - - Pin #: Valid values for pins - ----------------------------- - PIN 0: "TOP_5G_CLK" - PIN 1: "TOP_5G_DATA" - PIN 2: "WF0_5G_HB0" - PIN 3: "WF0_5G_HB1" - PIN 4: "WF0_5G_HB2" - PIN 5: "WF0_5G_HB3" - PIN 6: "WF0_5G_HB4" - PIN 7: "WF0_5G_HB5" - PIN 8: "WF0_5G_HB6" - PIN 9: "XO_REQ" - PIN 10: "TOP_RST_N" - PIN 11: "SYS_WATCHDOG" - PIN 12: "EPHY_LED0_N_JTDO" - PIN 13: "EPHY_LED1_N_JTDI" - PIN 14: "EPHY_LED2_N_JTMS" - PIN 15: "EPHY_LED3_N_JTCLK" - PIN 16: "EPHY_LED4_N_JTRST_N" - PIN 17: "WF2G_LED_N" - PIN 18: "WF5G_LED_N" - PIN 19: "I2C_SDA" - PIN 20: "I2C_SCL" - PIN 21: "GPIO_9" - PIN 22: "GPIO_10" - PIN 23: "GPIO_11" - PIN 24: "GPIO_12" - PIN 25: "UART1_TXD" - PIN 26: "UART1_RXD" - PIN 27: "UART1_CTS" - PIN 28: "UART1_RTS" - PIN 29: "UART2_TXD" - PIN 30: "UART2_RXD" - PIN 31: "UART2_CTS" - PIN 32: "UART2_RTS" - PIN 33: "MDI_TP_P1" - PIN 34: "MDI_TN_P1" - PIN 35: "MDI_RP_P1" - PIN 36: "MDI_RN_P1" - PIN 37: "MDI_RP_P2" - PIN 38: "MDI_RN_P2" - PIN 39: "MDI_TP_P2" - PIN 40: "MDI_TN_P2" - PIN 41: "MDI_TP_P3" - PIN 42: "MDI_TN_P3" - PIN 43: "MDI_RP_P3" - PIN 44: "MDI_RN_P3" - PIN 45: "MDI_RP_P4" - PIN 46: "MDI_RN_P4" - PIN 47: "MDI_TP_P4" - PIN 48: "MDI_TN_P4" - PIN 49: "SMI_MDC" - PIN 50: "SMI_MDIO" - PIN 51: "PCIE_PERESET_N" - PIN 52: "PWM_0" - PIN 53: "GPIO_0" - PIN 54: "GPIO_1" - PIN 55: "GPIO_2" - PIN 56: "GPIO_3" - PIN 57: "GPIO_4" - PIN 58: "GPIO_5" - PIN 59: "GPIO_6" - PIN 60: "GPIO_7" - PIN 61: "GPIO_8" - PIN 62: "SPI_CLK" - PIN 63: "SPI_CS" - PIN 64: "SPI_MOSI" - PIN 65: "SPI_MISO" - PIN 66: "SPI_WP" - PIN 67: "SPI_HOLD" - PIN 68: "UART0_TXD" - PIN 69: "UART0_RXD" - PIN 70: "TOP_2G_CLK" - PIN 71: "TOP_2G_DATA" - PIN 72: "WF0_2G_HB0" - PIN 73: "WF0_2G_HB1" - PIN 74: "WF0_2G_HB2" - PIN 75: "WF0_2G_HB3" - PIN 76: "WF0_2G_HB4" - PIN 77: "WF0_2G_HB5" - PIN 78: "WF0_2G_HB6" - -Valid values for function are: - "eth", "i2c", "led", "flash", "pcie", "pwm", "spi", "uart", - "watchdog", "wifi" - -Valid values for groups are: - Valid value function pins (in pin#) - ---------------------------------------------------------------- - "mdc_mdio" "eth" 23, 24 - "i2c_0" "i2c" 19, 20 - "i2c_1" "i2c" 53, 54 - "ephy_leds" "led" 12, 13, 14, 15, 16, - 17, 18 - "ephy0_led" "led" 12 - "ephy1_led" "led" 13 - "ephy2_led" "led" 14 - "ephy3_led" "led" 15 - "ephy4_led" "led" 16 - "wf2g_led" "led" 17 - "wf5g_led" "led" 18 - "snfi" "flash" 62, 63, 64, 65, 66, 67 - "spi_nor" "flash" 62, 63, 64, 65, 66, 67 - "pcie_pereset" "pcie" 51 - "pcie_wake" "pcie" 55 - "pcie_clkreq" "pcie" 56 - "pwm_0" "pwm" 52 - "pwm_1" "pwm" 61 - "spi_0" "spi" 21, 22, 23, 24 - "spi_1" "spi" 62, 63, 64, 65 - "spi_wp" "spi" 66 - "spi_hold" "spi" 67 - "uart0_txd_rxd" "uart" 68, 69 - "uart1_0_txd_rxd" "uart" 25, 26 - "uart1_0_cts_rts" "uart" 27, 28 - "uart1_1_txd_rxd" "uart" 53, 54 - "uart1_1_cts_rts" "uart" 55, 56 - "uart2_0_txd_rxd" "uart" 29, 30 - "uart2_0_cts_rts" "uart" 31, 32 - "uart2_1_txd_rxd" "uart" 57, 58 - "uart2_1_cts_rts" "uart" 59, 60 - "watchdog" "watchdog" 11 - "wf0_2g" "wifi" 70, 71, 72, 73, 74, - 75, 76, 77, 78 - "wf0_5g" "wifi" 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10 - -Example: - - pio: pinctrl@10211000 { - compatible = "mediatek,mt7622-pinctrl"; - reg = <0 0x10211000 0 0x1000>; - gpio-controller; - #gpio-cells = <2>; - - pinctrl_eth_default: eth-default { - mux-mdio { - groups = "mdc_mdio"; - function = "eth"; - drive-strength = <12>; - }; - - mux-gmac2 { - groups = "gmac2"; - function = "eth"; - drive-strength = <12>; - }; - - mux-esw { - groups = "esw"; - function = "eth"; - drive-strength = <8>; - }; - - conf-mdio { - pins = "MDC"; - bias-pull-up; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt deleted file mode 100644 index eccbe3f55d3f..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8183.txt +++ /dev/null @@ -1,132 +0,0 @@ -* Mediatek MT8183 Pin Controller - -The Mediatek's Pin controller is used to control SoC pins. - -Required properties: -- compatible: value should be one of the following. - "mediatek,mt8183-pinctrl", compatible with mt8183 pinctrl. -- gpio-controller : Marks the device node as a gpio controller. -- #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO - binding is used, the amount of cells must be specified as 2. See the below - mentioned gpio binding representation for description of particular cells. -- gpio-ranges : gpio valid number range. -- reg: physical address base for gpio base registers. There are 10 GPIO - physical address base in mt8183. - -Optional properties: -- reg-names: gpio base register names. There are 10 gpio base register - names in mt8183. They are "iocfg0", "iocfg1", "iocfg2", "iocfg3", "iocfg4", - "iocfg5", "iocfg6", "iocfg7", "iocfg8", "eint". -- interrupt-controller: Marks the device node as an interrupt controller -- #interrupt-cells: Should be two. -- interrupts : The interrupt outputs to sysirq. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices. - -Subnode format -A pinctrl node should contain at least one subnodes representing the -pinctrl groups available on the machine. Each subnode will list the -pins it needs, and how they should be configured, with regard to muxer -configuration, pullups, drive strength, input enable/disable and input schmitt. - - node { - pinmux = ; - GENERIC_PINCONFIG; - }; - -Required properties: -- pinmux: integer array, represents gpio pin number and mux setting. - Supported pin number and mux varies for different SoCs, and are defined - as macros in boot/dts/-pinfunc.h directly. - -Optional properties: -- GENERIC_PINCONFIG: is the generic pinconfig options to use, bias-disable, - bias-pull-down, bias-pull-up, input-enable, input-disable, output-low, - output-high, input-schmitt-enable, input-schmitt-disable - and drive-strength are valid. - - Some special pins have extra pull up strength, there are R0 and R1 pull-up - resistors available, but for user, it's only need to set R1R0 as 00, 01, - 10 or 11. So It needs config "mediatek,pull-up-adv" or - "mediatek,pull-down-adv" to support arguments for those special pins. - Valid arguments are from 0 to 3. - - mediatek,tdsel: An integer describing the steps for output level shifter - duty cycle when asserted (high pulse width adjustment). Valid arguments - are from 0 to 15. - mediatek,rdsel: An integer describing the steps for input level shifter - duty cycle when asserted (high pulse width adjustment). Valid arguments - are from 0 to 63. - - When config drive-strength, it can support some arguments, such as - MTK_DRIVE_4mA, MTK_DRIVE_6mA, etc. See dt-bindings/pinctrl/mt65xx.h. - It can only support 2/4/6/8/10/12/14/16mA in mt8183. - For I2C pins, there are existing generic driving setup and the specific - driving setup. I2C pins can only support 2/4/6/8/10/12/14/16mA driving - adjustment in generic driving setup. But in specific driving setup, - they can support 0.125/0.25/0.5/1mA adjustment. If we enable specific - driving setup for I2C pins, the existing generic driving setup will be - disabled. For some special features, we need the I2C pins specific - driving setup. The specific driving setup is controlled by E1E0EN. - So we need add extra vendor driving preperty instead of - the generic driving property. - We can add "mediatek,drive-strength-adv = ;" to describe the specific - driving setup property. "XXX" means the value of E1E0EN. EN is 0 or 1. - It is used to enable or disable the specific driving setup. - E1E0 is used to describe the detail strength specification of the I2C pin. - When E1=0/E0=0, the strength is 0.125mA. - When E1=0/E0=1, the strength is 0.25mA. - When E1=1/E0=0, the strength is 0.5mA. - When E1=1/E0=1, the strength is 1mA. - So the valid arguments of "mediatek,drive-strength-adv" are from 0 to 7. - -Examples: - -#include "mt8183-pinfunc.h" - -... -{ - pio: pinctrl@10005000 { - compatible = "mediatek,mt8183-pinctrl"; - reg = <0 0x10005000 0 0x1000>, - <0 0x11f20000 0 0x1000>, - <0 0x11e80000 0 0x1000>, - <0 0x11e70000 0 0x1000>, - <0 0x11e90000 0 0x1000>, - <0 0x11d30000 0 0x1000>, - <0 0x11d20000 0 0x1000>, - <0 0x11c50000 0 0x1000>, - <0 0x11f30000 0 0x1000>, - <0 0x1000b000 0 0x1000>; - reg-names = "iocfg0", "iocfg1", "iocfg2", - "iocfg3", "iocfg4", "iocfg5", - "iocfg6", "iocfg7", "iocfg8", - "eint"; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pio 0 0 192>; - interrupt-controller; - interrupts = ; - #interrupt-cells = <2>; - - i2c0_pins_a: i2c0 { - pins1 { - pinmux = , - ; - mediatek,pull-up-adv = <3>; - mediatek,drive-strength-adv = <7>; - }; - }; - - i2c1_pins_a: i2c1 { - pins { - pinmux = , - ; - mediatek,pull-down-adv = <2>; - mediatek,drive-strength-adv = <4>; - }; - }; - ... - }; -}; diff --git a/MAINTAINERS b/MAINTAINERS index a61f4f3b78a9..669b3f546e00 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14639,8 +14639,10 @@ PIN CONTROLLER - MEDIATEK M: Sean Wang L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt -F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt +F: Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml +F: Documentation/devicetree/bindings/pinctrl/mediatek,mt6797-pinctrl.yaml +F: Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml +F: Documentation/devicetree/bindings/pinctrl/mediatek,mt8183-pinctrl.yaml F: drivers/pinctrl/mediatek/ PIN CONTROLLER - MICROCHIP AT91 -- cgit v1.2.3-70-g09d2 From 936c985478716b228f42f47c075d4ea10dfa98bb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 26 Jul 2021 19:19:41 +0800 Subject: dt-bindings: pinctrl: mt8195: Use real world values for drive-strength arguments The original binding submission for MT8195 pinctrl described the possible drive strength values in micro-amps in its description, but then proceeded to list register values in its device tree binding constraints. However, the macros used with the Mediatek pinctrl bindings directly specify the drive strength in micro-amps, instead of hardware register values. The current driver implementation in Linux does convert the value from micro-amps to hardware register values. This implementation is also used with MT7622 and MT8183, which use real world values in their device trees. Given the above, it was likely an oversight to use the raw register values in the binding. Correct the values in the binding. Also drop the description since the binding combined with its parent, pinctrl/pincfg.yaml, the binding is now self-describing. Fixes: 7f7663899d94 ("dt-bindings: pinctrl: mt8195: add pinctrl file and binding document") Signed-off-by: Chen-Yu Tsai Acked-by: Rob Herring Link: https://lore.kernel.org/r/20210726111941.1447057-1-wenst@chromium.org Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml index 2f12ec59eee5..e17a399e0904 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml @@ -80,10 +80,7 @@ patternProperties: as macros in dt-bindings/pinctrl/-pinfunc.h directly. drive-strength: - description: | - It can support some arguments which is from 0 to 7. It can only support - 2/4/6/8/10/12/14/16mA in mt8195. - enum: [0, 1, 2, 3, 4, 5, 6, 7] + enum: [2, 4, 6, 8, 10, 12, 14, 16] bias-pull-down: true -- cgit v1.2.3-70-g09d2 From e3245a7b7b34bd2e97f744fd79463add6e9d41f4 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Tue, 10 Aug 2021 15:59:20 +0300 Subject: netfilter: nft_ct: protect nft_ct_pcpu_template_refcnt with mutex Syzbot hit use-after-free in nf_tables_dump_sets. The problem was in missing lock protection for nft_ct_pcpu_template_refcnt. Before commit f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") all transactions were serialized by global mutex, but then global mutex was changed to local per netnamespace commit_mutex. This change causes use-after-free bug, when 2 netnamespaces concurently changing nft_ct_pcpu_template_refcnt without proper locking. Fix it by adding nft_ct_pcpu_mutex and protect all nft_ct_pcpu_template_refcnt changes with it. Fixes: f102d66b335a ("netfilter: nf_tables: use dedicated mutex to guard transactions") Reported-and-tested-by: syzbot+649e339fa6658ee623d3@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin Acked-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_ct.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 337e22d8b40b..99b1de14ff7e 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -41,6 +41,7 @@ struct nft_ct_helper_obj { #ifdef CONFIG_NF_CONNTRACK_ZONES static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template); static unsigned int nft_ct_pcpu_template_refcnt __read_mostly; +static DEFINE_MUTEX(nft_ct_pcpu_mutex); #endif static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c, @@ -525,8 +526,10 @@ static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv) #endif #ifdef CONFIG_NF_CONNTRACK_ZONES case NFT_CT_ZONE: + mutex_lock(&nft_ct_pcpu_mutex); if (--nft_ct_pcpu_template_refcnt == 0) nft_ct_tmpl_put_pcpu(); + mutex_unlock(&nft_ct_pcpu_mutex); break; #endif default: @@ -564,9 +567,13 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, #endif #ifdef CONFIG_NF_CONNTRACK_ZONES case NFT_CT_ZONE: - if (!nft_ct_tmpl_alloc_pcpu()) + mutex_lock(&nft_ct_pcpu_mutex); + if (!nft_ct_tmpl_alloc_pcpu()) { + mutex_unlock(&nft_ct_pcpu_mutex); return -ENOMEM; + } nft_ct_pcpu_template_refcnt++; + mutex_unlock(&nft_ct_pcpu_mutex); len = sizeof(u16); break; #endif -- cgit v1.2.3-70-g09d2 From faa8605f9f92e36c724ecaf03b466cfe31b04b06 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Tue, 3 Aug 2021 01:13:36 +0300 Subject: clk: tegra: Remove CLK_IS_CRITICAL flag from fuse clock FUSE driver now takes care of keeping the clock enabled when necessary. Remove the CLK_IS_CRITICAL flag from the clock. Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/clk/tegra/clk-tegra-periph.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 292d6269daf1..4dcf7f7cb8a0 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -777,11 +777,7 @@ static struct tegra_periph_init_data gate_clks[] = { GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0), GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0), GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), - /* - * Critical for RAM re-repair operation, which must occur on resume - * from LP1 system suspend and as part of CCPLEX cluster switching. - */ - GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL), + GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0), -- cgit v1.2.3-70-g09d2 From d21292f13f1f0721d60e8122e2db46bea8cf6950 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 9 Aug 2021 16:24:28 +0100 Subject: KVM: arm64: Add hyp_spin_is_locked() for basic locking assertions at EL2 Introduce hyp_spin_is_locked() so that functions can easily assert that a given lock is held (albeit possibly by another CPU!) without having to drag full lockdep support up to EL2. Signed-off-by: Will Deacon Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-2-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/spinlock.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h index 76b537f8d1c6..04f65b655fcf 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h +++ b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h @@ -15,6 +15,7 @@ #include #include +#include typedef union hyp_spinlock { u32 __val; @@ -89,4 +90,11 @@ static inline void hyp_spin_unlock(hyp_spinlock_t *lock) : "memory"); } +static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock) +{ + hyp_spinlock_t lockval = READ_ONCE(*lock); + + return lockval.owner != lockval.next; +} + #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */ -- cgit v1.2.3-70-g09d2 From 8e049e0daf23aa380c264e5e15e4c64ea5497ed7 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:29 +0100 Subject: KVM: arm64: Introduce hyp_assert_lock_held() Introduce a poor man's lockdep implementation at EL2 which allows to BUG() whenever a hyp spinlock is not held when it should. Hide this feature behind a new Kconfig option that targets the EL2 object specifically, instead of piggy backing on the existing CONFIG_LOCKDEP. EL2 cannot WARN() cleanly to report locking issues, hence BUG() is the only option and it is not clear whether we want this widely enabled. This is most likely going to be useful for local testing until the EL2 WARN() situation has improved. Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-3-qperret@google.com --- arch/arm64/kvm/Kconfig | 9 +++++++++ arch/arm64/kvm/hyp/include/nvhe/spinlock.h | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index a4eba0908bfa..9b9721895e5c 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -46,6 +46,15 @@ if KVM source "virt/kvm/Kconfig" +config NVHE_EL2_DEBUG + bool "Debug mode for non-VHE EL2 object" + help + Say Y here to enable the debug mode for the non-VHE KVM EL2 object. + Failure reports will BUG() in the hypervisor. This is intended for + local EL2 hypervisor development. + + If unsure, say N. + endif # KVM endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h index 04f65b655fcf..4652fd04bdbe 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/spinlock.h +++ b/arch/arm64/kvm/hyp/include/nvhe/spinlock.h @@ -97,4 +97,21 @@ static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock) return lockval.owner != lockval.next; } +#ifdef CONFIG_NVHE_EL2_DEBUG +static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) +{ + /* + * The __pkvm_init() path accesses protected data-structures without + * holding locks as the other CPUs are guaranteed to not enter EL2 + * concurrently at this point in time. The point by which EL2 is + * initialized on all CPUs is reflected in the pkvm static key, so + * wait until it is set before checking the lock state. + */ + if (static_branch_likely(&kvm_protected_mode_initialized)) + BUG_ON(!hyp_spin_is_locked(lock)); +} +#else +static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) { } +#endif + #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */ -- cgit v1.2.3-70-g09d2 From 1bac49d490cbc813f407a5c9806e464bf4a300c9 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:30 +0100 Subject: KVM: arm64: Provide the host_stage2_try() helper macro We currently unmap all MMIO mappings from the host stage-2 to recycle the pages whenever we run out. In order to make this pattern easy to re-use from other places, factor the logic out into a dedicated macro. While at it, apply the macro for the kvm_pgtable_stage2_set_owner() calls. They're currently only called early on and are guaranteed to succeed, but making them robust to the -ENOMEM case doesn't hurt and will avoid painful debugging sessions later on. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-4-qperret@google.com --- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 40 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index d938ce95d3bd..74280a753efb 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -208,6 +208,25 @@ static inline int __host_stage2_idmap(u64 start, u64 end, prot, &host_s2_pool); } +/* + * The pool has been provided with enough pages to cover all of memory with + * page granularity, but it is difficult to know how much of the MMIO range + * we will need to cover upfront, so we may need to 'recycle' the pages if we + * run out. + */ +#define host_stage2_try(fn, ...) \ + ({ \ + int __ret; \ + hyp_assert_lock_held(&host_kvm.lock); \ + __ret = fn(__VA_ARGS__); \ + if (__ret == -ENOMEM) { \ + __ret = host_stage2_unmap_dev_all(); \ + if (!__ret) \ + __ret = fn(__VA_ARGS__); \ + } \ + __ret; \ + }) + static int host_stage2_idmap(u64 addr) { enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W; @@ -223,22 +242,7 @@ static int host_stage2_idmap(u64 addr) if (ret) goto unlock; - ret = __host_stage2_idmap(range.start, range.end, prot); - if (ret != -ENOMEM) - goto unlock; - - /* - * The pool has been provided with enough pages to cover all of memory - * with page granularity, but it is difficult to know how much of the - * MMIO range we will need to cover upfront, so we may need to 'recycle' - * the pages if we run out. - */ - ret = host_stage2_unmap_dev_all(); - if (ret) - goto unlock; - - ret = __host_stage2_idmap(range.start, range.end, prot); - + ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot); unlock: hyp_spin_unlock(&host_kvm.lock); @@ -257,8 +261,8 @@ int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) return -EINVAL; hyp_spin_lock(&host_kvm.lock); - ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start, - &host_s2_pool, pkvm_hyp_id); + ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, + start, end - start, &host_s2_pool, pkvm_hyp_id); hyp_spin_unlock(&host_kvm.lock); return ret != -EAGAIN ? ret : 0; -- cgit v1.2.3-70-g09d2 From 51add457733bbc4a442fc280d73d14bfe262e4a0 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:32 +0100 Subject: KVM: arm64: Expose page-table helpers The KVM pgtable API exposes the kvm_pgtable_walk() function to allow the definition of walkers outside of pgtable.c. However, it is not easy to implement any of those walkers without some of the low-level helpers. Move some of them to the header file to allow re-use from other places. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-6-qperret@google.com --- arch/arm64/include/asm/kvm_pgtable.h | 40 ++++++++++++++++++++++++++++++++++++ arch/arm64/kvm/hyp/pgtable.c | 39 ----------------------------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index e42b55bd50a2..83c21d35be10 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -25,6 +25,46 @@ static inline u64 kvm_get_parange(u64 mmfr0) typedef u64 kvm_pte_t; +#define KVM_PTE_VALID BIT(0) + +#define KVM_PTE_ADDR_MASK GENMASK(47, PAGE_SHIFT) +#define KVM_PTE_ADDR_51_48 GENMASK(15, 12) + +static inline bool kvm_pte_valid(kvm_pte_t pte) +{ + return pte & KVM_PTE_VALID; +} + +static inline u64 kvm_pte_to_phys(kvm_pte_t pte) +{ + u64 pa = pte & KVM_PTE_ADDR_MASK; + + if (PAGE_SHIFT == 16) + pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48; + + return pa; +} + +static inline u64 kvm_granule_shift(u32 level) +{ + /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */ + return ARM64_HW_PGTABLE_LEVEL_SHIFT(level); +} + +static inline u64 kvm_granule_size(u32 level) +{ + return BIT(kvm_granule_shift(level)); +} + +static inline bool kvm_level_supports_block_mapping(u32 level) +{ + /* + * Reject invalid block mappings and don't bother with 4TB mappings for + * 52-bit PAs. + */ + return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1)); +} + /** * struct kvm_pgtable_mm_ops - Memory management callbacks. * @zalloc_page: Allocate a single zeroed memory page. diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 78f36bd5df6c..49d768b92997 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -11,16 +11,12 @@ #include #include -#define KVM_PTE_VALID BIT(0) #define KVM_PTE_TYPE BIT(1) #define KVM_PTE_TYPE_BLOCK 0 #define KVM_PTE_TYPE_PAGE 1 #define KVM_PTE_TYPE_TABLE 1 -#define KVM_PTE_ADDR_MASK GENMASK(47, PAGE_SHIFT) -#define KVM_PTE_ADDR_51_48 GENMASK(15, 12) - #define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2) #define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2) @@ -61,17 +57,6 @@ struct kvm_pgtable_walk_data { u64 end; }; -static u64 kvm_granule_shift(u32 level) -{ - /* Assumes KVM_PGTABLE_MAX_LEVELS is 4 */ - return ARM64_HW_PGTABLE_LEVEL_SHIFT(level); -} - -static u64 kvm_granule_size(u32 level) -{ - return BIT(kvm_granule_shift(level)); -} - #define KVM_PHYS_INVALID (-1ULL) static bool kvm_phys_is_valid(u64 phys) @@ -79,15 +64,6 @@ static bool kvm_phys_is_valid(u64 phys) return phys < BIT(id_aa64mmfr0_parange_to_phys_shift(ID_AA64MMFR0_PARANGE_MAX)); } -static bool kvm_level_supports_block_mapping(u32 level) -{ - /* - * Reject invalid block mappings and don't bother with 4TB mappings for - * 52-bit PAs. - */ - return !(level == 0 || (PAGE_SIZE != SZ_4K && level == 1)); -} - static bool kvm_block_mapping_supported(u64 addr, u64 end, u64 phys, u32 level) { u64 granule = kvm_granule_size(level); @@ -135,11 +111,6 @@ static u32 kvm_pgd_pages(u32 ia_bits, u32 start_level) return __kvm_pgd_page_idx(&pgt, -1ULL) + 1; } -static bool kvm_pte_valid(kvm_pte_t pte) -{ - return pte & KVM_PTE_VALID; -} - static bool kvm_pte_table(kvm_pte_t pte, u32 level) { if (level == KVM_PGTABLE_MAX_LEVELS - 1) @@ -151,16 +122,6 @@ static bool kvm_pte_table(kvm_pte_t pte, u32 level) return FIELD_GET(KVM_PTE_TYPE, pte) == KVM_PTE_TYPE_TABLE; } -static u64 kvm_pte_to_phys(kvm_pte_t pte) -{ - u64 pa = pte & KVM_PTE_ADDR_MASK; - - if (PAGE_SHIFT == 16) - pa |= FIELD_GET(KVM_PTE_ADDR_51_48, pte) << 48; - - return pa; -} - static kvm_pte_t kvm_phys_to_pte(u64 pa) { kvm_pte_t pte = pa & KVM_PTE_ADDR_MASK; -- cgit v1.2.3-70-g09d2 From c4f0935e4d957bfcea25ad76860445660a60f3fd Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:33 +0100 Subject: KVM: arm64: Optimize host memory aborts The kvm_pgtable_stage2_find_range() function is used in the host memory abort path to try and look for the largest block mapping that can be used to map the faulting address. In order to do so, the function currently walks the stage-2 page-table and looks for existing incompatible mappings within the range of the largest possible block. If incompatible mappings are found, it tries the same procedure again, but using a smaller block range, and repeats until a matching range is found (potentially up to page granularity). While this approach has benefits (mostly in the fact that it proactively coalesces host stage-2 mappings), it can be slow if the ranges are fragmented, and it isn't optimized to deal with CPUs faulting on the same IPA as all of them will do all the work every time. To avoid these issues, remove kvm_pgtable_stage2_find_range(), and walk the page-table only once in the host_mem_abort() path to find the closest leaf to the input address. With this, use the corresponding range if it is invalid and not owned by another entity. If a valid leaf is found, return -EAGAIN similar to what is done in the kvm_pgtable_stage2_map() path to optimize concurrent faults. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-7-qperret@google.com --- arch/arm64/include/asm/kvm_pgtable.h | 30 -------------- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 45 ++++++++++++++++++++- arch/arm64/kvm/hyp/pgtable.c | 74 ----------------------------------- 3 files changed, 44 insertions(+), 105 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 83c21d35be10..8d6c710c1996 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -154,16 +154,6 @@ enum kvm_pgtable_prot { #define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) #define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE) -/** - * struct kvm_mem_range - Range of Intermediate Physical Addresses - * @start: Start of the range. - * @end: End of the range. - */ -struct kvm_mem_range { - u64 start; - u64 end; -}; - /** * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk. * @KVM_PGTABLE_WALK_LEAF: Visit leaf entries, including invalid @@ -491,24 +481,4 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, */ int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, kvm_pte_t *ptep, u32 *level); - -/** - * kvm_pgtable_stage2_find_range() - Find a range of Intermediate Physical - * Addresses with compatible permission - * attributes. - * @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*(). - * @addr: Address that must be covered by the range. - * @prot: Protection attributes that the range must be compatible with. - * @range: Range structure used to limit the search space at call time and - * that will hold the result. - * - * The offset of @addr within a page is ignored. An IPA is compatible with @prot - * iff its corresponding stage-2 page-table entry has default ownership and, if - * valid, is mapped with protection attributes identical to @prot. - * - * Return: 0 on success, negative error code on failure. - */ -int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr, - enum kvm_pgtable_prot prot, - struct kvm_mem_range *range); #endif /* __ARM64_KVM_PGTABLE_H__ */ diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 74280a753efb..2148d3968aa5 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -159,6 +159,11 @@ static int host_stage2_unmap_dev_all(void) return kvm_pgtable_stage2_unmap(pgt, addr, BIT(pgt->ia_bits) - addr); } +struct kvm_mem_range { + u64 start; + u64 end; +}; + static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) { int cur, left = 0, right = hyp_memblock_nr; @@ -227,6 +232,44 @@ static inline int __host_stage2_idmap(u64 start, u64 end, __ret; \ }) +static inline bool range_included(struct kvm_mem_range *child, + struct kvm_mem_range *parent) +{ + return parent->start <= child->start && child->end <= parent->end; +} + +static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) +{ + struct kvm_mem_range cur; + kvm_pte_t pte; + u32 level; + int ret; + + hyp_assert_lock_held(&host_kvm.lock); + ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, &level); + if (ret) + return ret; + + if (kvm_pte_valid(pte)) + return -EAGAIN; + + if (pte) + return -EPERM; + + do { + u64 granule = kvm_granule_size(level); + cur.start = ALIGN_DOWN(addr, granule); + cur.end = cur.start + granule; + level++; + } while ((level < KVM_PGTABLE_MAX_LEVELS) && + !(kvm_level_supports_block_mapping(level) && + range_included(&cur, range))); + + *range = cur; + + return 0; +} + static int host_stage2_idmap(u64 addr) { enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W; @@ -238,7 +281,7 @@ static int host_stage2_idmap(u64 addr) prot |= KVM_PGTABLE_PROT_X; hyp_spin_lock(&host_kvm.lock); - ret = kvm_pgtable_stage2_find_range(&host_kvm.pgt, addr, prot, &range); + ret = host_stage2_adjust_range(addr, &range); if (ret) goto unlock; diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 49d768b92997..4dff2ad39ee4 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -1102,77 +1102,3 @@ void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt) pgt->mm_ops->free_pages_exact(pgt->pgd, pgd_sz); pgt->pgd = NULL; } - -#define KVM_PTE_LEAF_S2_COMPAT_MASK (KVM_PTE_LEAF_ATTR_S2_PERMS | \ - KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR | \ - KVM_PTE_LEAF_ATTR_S2_IGNORED) - -static int stage2_check_permission_walker(u64 addr, u64 end, u32 level, - kvm_pte_t *ptep, - enum kvm_pgtable_walk_flags flag, - void * const arg) -{ - kvm_pte_t old_attr, pte = *ptep, *new_attr = arg; - - /* - * Compatible mappings are either invalid and owned by the page-table - * owner (whose id is 0), or valid with matching permission attributes. - */ - if (kvm_pte_valid(pte)) { - old_attr = pte & KVM_PTE_LEAF_S2_COMPAT_MASK; - if (old_attr != *new_attr) - return -EEXIST; - } else if (pte) { - return -EEXIST; - } - - return 0; -} - -int kvm_pgtable_stage2_find_range(struct kvm_pgtable *pgt, u64 addr, - enum kvm_pgtable_prot prot, - struct kvm_mem_range *range) -{ - kvm_pte_t attr; - struct kvm_pgtable_walker check_perm_walker = { - .cb = stage2_check_permission_walker, - .flags = KVM_PGTABLE_WALK_LEAF, - .arg = &attr, - }; - u64 granule, start, end; - u32 level; - int ret; - - ret = stage2_set_prot_attr(pgt, prot, &attr); - if (ret) - return ret; - attr &= KVM_PTE_LEAF_S2_COMPAT_MASK; - - for (level = pgt->start_level; level < KVM_PGTABLE_MAX_LEVELS; level++) { - granule = kvm_granule_size(level); - start = ALIGN_DOWN(addr, granule); - end = start + granule; - - if (!kvm_level_supports_block_mapping(level)) - continue; - - if (start < range->start || range->end < end) - continue; - - /* - * Check the presence of existing mappings with incompatible - * permissions within the current block range, and try one level - * deeper if one is found. - */ - ret = kvm_pgtable_walk(pgt, start, granule, &check_perm_walker); - if (ret != -EEXIST) - break; - } - - if (!ret) { - range->start = start; - range->end = end; - } - - return ret; -} -- cgit v1.2.3-70-g09d2 From 178cac08d588e7406a09351a992f57892d8d9cc9 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:34 +0100 Subject: KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED The ignored bits for both stage-1 and stage-2 page and block descriptors are in [55:58], so rename KVM_PTE_LEAF_ATTR_S2_IGNORED to make it applicable to both. And while at it, since these bits are more commonly known as 'software' bits, rename accordingly. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-8-qperret@google.com --- arch/arm64/kvm/hyp/pgtable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 4dff2ad39ee4..59a394d82de3 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -36,6 +36,8 @@ #define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 51) +#define KVM_PTE_LEAF_ATTR_HI_SW GENMASK(58, 55) + #define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54) #define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54) @@ -44,8 +46,6 @@ KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ KVM_PTE_LEAF_ATTR_HI_S2_XN) -#define KVM_PTE_LEAF_ATTR_S2_IGNORED GENMASK(58, 55) - #define KVM_INVALID_PTE_OWNER_MASK GENMASK(63, 56) #define KVM_MAX_OWNER_ID 1 -- cgit v1.2.3-70-g09d2 From 8a0282c68121e53ab17413283cfed408a47e1a2a Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:35 +0100 Subject: KVM: arm64: Don't overwrite software bits with owner id We will soon start annotating page-tables with new flags to track shared pages and such, and we will do so in valid mappings using software bits in the PTEs, as provided by the architecture. However, it is possible that we will need to use those flags to annotate invalid mappings as well in the future, similar to what we do to track page ownership in the host stage-2. In order to facilitate the annotation of invalid mappings with such flags, it would be preferable to re-use the same bits as for valid mappings (bits [58-55]), but these are currently used for ownership encoding. Since we have plenty of bits left to use in invalid mappings, move the ownership bits further down the PTE to avoid the conflict. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-9-qperret@google.com --- arch/arm64/kvm/hyp/pgtable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 59a394d82de3..1ee1168ac32d 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -46,7 +46,7 @@ KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \ KVM_PTE_LEAF_ATTR_HI_S2_XN) -#define KVM_INVALID_PTE_OWNER_MASK GENMASK(63, 56) +#define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2) #define KVM_MAX_OWNER_ID 1 struct kvm_pgtable_walk_data { -- cgit v1.2.3-70-g09d2 From b53846c5f279cb5329b82f19a7d313f02cb9d21c Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:36 +0100 Subject: KVM: arm64: Tolerate re-creating hyp mappings to set software bits The current hypervisor stage-1 mapping code doesn't allow changing an existing valid mapping. Relax this condition by allowing changes that only target software bits, as that will soon be needed to annotate shared pages. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-10-qperret@google.com --- arch/arm64/kvm/hyp/pgtable.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 1ee1168ac32d..2689fcb7901d 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -362,6 +362,21 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep) return 0; } +static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new) +{ + /* + * Tolerate KVM recreating the exact same mapping, or changing software + * bits if the existing mapping was valid. + */ + if (old == new) + return false; + + if (!kvm_pte_valid(old)) + return true; + + return !WARN_ON((old ^ new) & ~KVM_PTE_LEAF_ATTR_HI_SW); +} + static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, struct hyp_map_data *data) { @@ -371,9 +386,8 @@ static bool hyp_map_walker_try_leaf(u64 addr, u64 end, u32 level, if (!kvm_block_mapping_supported(addr, end, phys, level)) return false; - /* Tolerate KVM recreating the exact same mapping */ new = kvm_init_valid_leaf_pte(phys, data->attr, level); - if (old != new && !WARN_ON(kvm_pte_valid(old))) + if (hyp_pte_needs_update(old, new)) smp_store_release(ptep, new); data->phys += granule; -- cgit v1.2.3-70-g09d2 From 5651311941105ca077d3ab74dd4a92e646ecf7fb Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:37 +0100 Subject: KVM: arm64: Enable forcing page-level stage-2 mappings Much of the stage-2 manipulation logic relies on being able to destroy block mappings if e.g. installing a smaller mapping in the range. The rationale for this behaviour is that stage-2 mappings can always be re-created lazily. However, this gets more complicated when the stage-2 page-table is used to store metadata about the underlying pages. In such cases, destroying a block mapping may lead to losing part of the state, and confuse the user of those metadata (such as the hypervisor in nVHE protected mode). To avoid this, introduce a callback function in the pgtable struct which is called during all map operations to determine whether the mappings can use blocks, or should be forced to page granularity. This is used by the hypervisor when creating the host stage-2 to force page-level mappings when using non-default protection attributes. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-11-qperret@google.com --- arch/arm64/include/asm/kvm_pgtable.h | 66 ++++++++++++++++++++++------------- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 34 +++++++++++++++--- arch/arm64/kvm/hyp/pgtable.c | 29 ++++++++++++--- 3 files changed, 94 insertions(+), 35 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index 8d6c710c1996..ca0c039547b5 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -115,25 +115,6 @@ enum kvm_pgtable_stage2_flags { KVM_PGTABLE_S2_IDMAP = BIT(1), }; -/** - * struct kvm_pgtable - KVM page-table. - * @ia_bits: Maximum input address size, in bits. - * @start_level: Level at which the page-table walk starts. - * @pgd: Pointer to the first top-level entry of the page-table. - * @mm_ops: Memory management callbacks. - * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables. - */ -struct kvm_pgtable { - u32 ia_bits; - u32 start_level; - kvm_pte_t *pgd; - struct kvm_pgtable_mm_ops *mm_ops; - - /* Stage-2 only */ - struct kvm_s2_mmu *mmu; - enum kvm_pgtable_stage2_flags flags; -}; - /** * enum kvm_pgtable_prot - Page-table permissions and attributes. * @KVM_PGTABLE_PROT_X: Execute permission. @@ -149,11 +130,43 @@ enum kvm_pgtable_prot { KVM_PGTABLE_PROT_DEVICE = BIT(3), }; -#define PAGE_HYP (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) +#define KVM_PGTABLE_PROT_RW (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) +#define KVM_PGTABLE_PROT_RWX (KVM_PGTABLE_PROT_RW | KVM_PGTABLE_PROT_X) + +#define PKVM_HOST_MEM_PROT KVM_PGTABLE_PROT_RWX +#define PKVM_HOST_MMIO_PROT KVM_PGTABLE_PROT_RW + +#define PAGE_HYP KVM_PGTABLE_PROT_RW #define PAGE_HYP_EXEC (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_X) #define PAGE_HYP_RO (KVM_PGTABLE_PROT_R) #define PAGE_HYP_DEVICE (PAGE_HYP | KVM_PGTABLE_PROT_DEVICE) +typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end, + enum kvm_pgtable_prot prot); + +/** + * struct kvm_pgtable - KVM page-table. + * @ia_bits: Maximum input address size, in bits. + * @start_level: Level at which the page-table walk starts. + * @pgd: Pointer to the first top-level entry of the page-table. + * @mm_ops: Memory management callbacks. + * @mmu: Stage-2 KVM MMU struct. Unused for stage-1 page-tables. + * @flags: Stage-2 page-table flags. + * @force_pte_cb: Function that returns true if page level mappings must + * be used instead of block mappings. + */ +struct kvm_pgtable { + u32 ia_bits; + u32 start_level; + kvm_pte_t *pgd; + struct kvm_pgtable_mm_ops *mm_ops; + + /* Stage-2 only */ + struct kvm_s2_mmu *mmu; + enum kvm_pgtable_stage2_flags flags; + kvm_pgtable_force_pte_cb_t force_pte_cb; +}; + /** * enum kvm_pgtable_walk_flags - Flags to control a depth-first page-table walk. * @KVM_PGTABLE_WALK_LEAF: Visit leaf entries, including invalid @@ -246,21 +259,24 @@ int kvm_pgtable_hyp_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys, u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift); /** - * kvm_pgtable_stage2_init_flags() - Initialise a guest stage-2 page-table. + * __kvm_pgtable_stage2_init() - Initialise a guest stage-2 page-table. * @pgt: Uninitialised page-table structure to initialise. * @arch: Arch-specific KVM structure representing the guest virtual * machine. * @mm_ops: Memory management callbacks. * @flags: Stage-2 configuration flags. + * @force_pte_cb: Function that returns true if page level mappings must + * be used instead of block mappings. * * Return: 0 on success, negative error code on failure. */ -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch, - struct kvm_pgtable_mm_ops *mm_ops, - enum kvm_pgtable_stage2_flags flags); +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, + struct kvm_pgtable_mm_ops *mm_ops, + enum kvm_pgtable_stage2_flags flags, + kvm_pgtable_force_pte_cb_t force_pte_cb); #define kvm_pgtable_stage2_init(pgt, arch, mm_ops) \ - kvm_pgtable_stage2_init_flags(pgt, arch, mm_ops, 0) + __kvm_pgtable_stage2_init(pgt, arch, mm_ops, 0, NULL) /** * kvm_pgtable_stage2_destroy() - Destroy an unused guest stage-2 page-table. diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 2148d3968aa5..6fed6772c673 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -89,6 +89,8 @@ static void prepare_host_vtcr(void) id_aa64mmfr1_el1_sys_val, phys_shift); } +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot); + int kvm_host_prepare_stage2(void *pgt_pool_base) { struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu; @@ -101,8 +103,9 @@ int kvm_host_prepare_stage2(void *pgt_pool_base) if (ret) return ret; - ret = kvm_pgtable_stage2_init_flags(&host_kvm.pgt, &host_kvm.arch, - &host_kvm.mm_ops, KVM_HOST_S2_FLAGS); + ret = __kvm_pgtable_stage2_init(&host_kvm.pgt, &host_kvm.arch, + &host_kvm.mm_ops, KVM_HOST_S2_FLAGS, + host_stage2_force_pte_cb); if (ret) return ret; @@ -270,15 +273,36 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) return 0; } +static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot) +{ + /* + * Block mappings must be used with care in the host stage-2 as a + * kvm_pgtable_stage2_map() operation targeting a page in the range of + * an existing block will delete the block under the assumption that + * mappings in the rest of the block range can always be rebuilt lazily. + * That assumption is correct for the host stage-2 with RWX mappings + * targeting memory or RW mappings targeting MMIO ranges (see + * host_stage2_idmap() below which implements some of the host memory + * abort logic). However, this is not safe for any other mappings where + * the host stage-2 page-table is in fact the only place where this + * state is stored. In all those cases, it is safer to use page-level + * mappings, hence avoiding to lose the state because of side-effects in + * kvm_pgtable_stage2_map(). + */ + if (range_is_memory(addr, end)) + return prot != PKVM_HOST_MEM_PROT; + else + return prot != PKVM_HOST_MMIO_PROT; +} + static int host_stage2_idmap(u64 addr) { - enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W; struct kvm_mem_range range; bool is_memory = find_mem_range(addr, &range); + enum kvm_pgtable_prot prot; int ret; - if (is_memory) - prot |= KVM_PGTABLE_PROT_X; + prot = is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; hyp_spin_lock(&host_kvm.lock); ret = host_stage2_adjust_range(addr, &range); diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 2689fcb7901d..e25d829587b9 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -452,6 +452,8 @@ int kvm_pgtable_hyp_init(struct kvm_pgtable *pgt, u32 va_bits, pgt->start_level = KVM_PGTABLE_MAX_LEVELS - levels; pgt->mm_ops = mm_ops; pgt->mmu = NULL; + pgt->force_pte_cb = NULL; + return 0; } @@ -489,6 +491,9 @@ struct stage2_map_data { void *memcache; struct kvm_pgtable_mm_ops *mm_ops; + + /* Force mappings to page granularity */ + bool force_pte; }; u64 kvm_get_vtcr(u64 mmfr0, u64 mmfr1, u32 phys_shift) @@ -602,6 +607,15 @@ static bool stage2_pte_executable(kvm_pte_t pte) return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN); } +static bool stage2_leaf_mapping_allowed(u64 addr, u64 end, u32 level, + struct stage2_map_data *data) +{ + if (data->force_pte && (level < (KVM_PGTABLE_MAX_LEVELS - 1))) + return false; + + return kvm_block_mapping_supported(addr, end, data->phys, level); +} + static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, struct stage2_map_data *data) @@ -611,7 +625,7 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, struct kvm_pgtable *pgt = data->mmu->pgt; struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; - if (!kvm_block_mapping_supported(addr, end, phys, level)) + if (!stage2_leaf_mapping_allowed(addr, end, level, data)) return -E2BIG; if (kvm_phys_is_valid(phys)) @@ -655,7 +669,7 @@ static int stage2_map_walk_table_pre(u64 addr, u64 end, u32 level, if (data->anchor) return 0; - if (!kvm_block_mapping_supported(addr, end, data->phys, level)) + if (!stage2_leaf_mapping_allowed(addr, end, level, data)) return 0; data->childp = kvm_pte_follow(*ptep, data->mm_ops); @@ -785,6 +799,7 @@ int kvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, .mmu = pgt->mmu, .memcache = mc, .mm_ops = pgt->mm_ops, + .force_pte = pgt->force_pte_cb && pgt->force_pte_cb(addr, addr + size, prot), }; struct kvm_pgtable_walker walker = { .cb = stage2_map_walker, @@ -816,6 +831,7 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size, .memcache = mc, .mm_ops = pgt->mm_ops, .owner_id = owner_id, + .force_pte = true, }; struct kvm_pgtable_walker walker = { .cb = stage2_map_walker, @@ -1057,9 +1073,11 @@ int kvm_pgtable_stage2_flush(struct kvm_pgtable *pgt, u64 addr, u64 size) return kvm_pgtable_walk(pgt, addr, size, &walker); } -int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch, - struct kvm_pgtable_mm_ops *mm_ops, - enum kvm_pgtable_stage2_flags flags) + +int __kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_arch *arch, + struct kvm_pgtable_mm_ops *mm_ops, + enum kvm_pgtable_stage2_flags flags, + kvm_pgtable_force_pte_cb_t force_pte_cb) { size_t pgd_sz; u64 vtcr = arch->vtcr; @@ -1077,6 +1095,7 @@ int kvm_pgtable_stage2_init_flags(struct kvm_pgtable *pgt, struct kvm_arch *arch pgt->mm_ops = mm_ops; pgt->mmu = &arch->mmu; pgt->flags = flags; + pgt->force_pte_cb = force_pte_cb; /* Ensure zeroed PGD pages are visible to the hardware walker */ dsb(ishst); -- cgit v1.2.3-70-g09d2 From 4505e9b624cefafa4b75d8a28e72f32076c33375 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:38 +0100 Subject: KVM: arm64: Allow populating software bits Introduce infrastructure allowing to manipulate software bits in stage-1 and stage-2 page-tables using additional entries in the kvm_pgtable_prot enum. This is heavily inspired by Marc's implementation of a similar feature in the NV patch series, but adapted to allow stage-1 changes as well: https://lore.kernel.org/kvmarm/20210510165920.1913477-56-maz@kernel.org/ Suggested-by: Marc Zyngier Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-12-qperret@google.com --- arch/arm64/include/asm/kvm_pgtable.h | 12 +++++++++++- arch/arm64/kvm/hyp/pgtable.c | 5 +++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index ca0c039547b5..bfea573703d7 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -121,6 +121,10 @@ enum kvm_pgtable_stage2_flags { * @KVM_PGTABLE_PROT_W: Write permission. * @KVM_PGTABLE_PROT_R: Read permission. * @KVM_PGTABLE_PROT_DEVICE: Device attributes. + * @KVM_PGTABLE_PROT_SW0: Software bit 0. + * @KVM_PGTABLE_PROT_SW1: Software bit 1. + * @KVM_PGTABLE_PROT_SW2: Software bit 2. + * @KVM_PGTABLE_PROT_SW3: Software bit 3. */ enum kvm_pgtable_prot { KVM_PGTABLE_PROT_X = BIT(0), @@ -128,6 +132,11 @@ enum kvm_pgtable_prot { KVM_PGTABLE_PROT_R = BIT(2), KVM_PGTABLE_PROT_DEVICE = BIT(3), + + KVM_PGTABLE_PROT_SW0 = BIT(55), + KVM_PGTABLE_PROT_SW1 = BIT(56), + KVM_PGTABLE_PROT_SW2 = BIT(57), + KVM_PGTABLE_PROT_SW3 = BIT(58), }; #define KVM_PGTABLE_PROT_RW (KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W) @@ -420,7 +429,8 @@ kvm_pte_t kvm_pgtable_stage2_mkold(struct kvm_pgtable *pgt, u64 addr); * If there is a valid, leaf page-table entry used to translate @addr, then * relax the permissions in that entry according to the read, write and * execute permissions specified by @prot. No permissions are removed, and - * TLB invalidation is performed after updating the entry. + * TLB invalidation is performed after updating the entry. Software bits cannot + * be set or cleared using kvm_pgtable_stage2_relax_perms(). * * Return: 0 on success, negative error code on failure. */ diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index e25d829587b9..cff744136044 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -357,6 +357,7 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep) attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_AP, ap); attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S1_SH, sh); attr |= KVM_PTE_LEAF_ATTR_LO_S1_AF; + attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; *ptep = attr; return 0; @@ -558,6 +559,7 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p attr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_LO_S2_SH, sh); attr |= KVM_PTE_LEAF_ATTR_LO_S2_AF; + attr |= prot & KVM_PTE_LEAF_ATTR_HI_SW; *ptep = attr; return 0; @@ -1025,6 +1027,9 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr, u32 level; kvm_pte_t set = 0, clr = 0; + if (prot & KVM_PTE_LEAF_ATTR_HI_SW) + return -EINVAL; + if (prot & KVM_PGTABLE_PROT_R) set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R; -- cgit v1.2.3-70-g09d2 From ec250a67ea8db6209918a389554cf3aec0395b1f Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:39 +0100 Subject: KVM: arm64: Add helpers to tag shared pages in SW bits We will soon start annotating shared pages in page-tables in nVHE protected mode. Define all the states in which a page can be (owned, shared and owned, shared and borrowed), and provide helpers allowing to convert this into SW bits annotations using the matching prot attributes. Reviewed-by: Fuad Tabba Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-13-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 9c227d87c36d..87b1690c439f 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -12,6 +12,32 @@ #include #include +/* + * SW bits 0-1 are reserved to track the memory ownership state of each page: + * 00: The page is owned exclusively by the page-table owner. + * 01: The page is owned by the page-table owner, but is shared + * with another entity. + * 10: The page is shared with, but not owned by the page-table owner. + * 11: Reserved for future use (lending). + */ +enum pkvm_page_state { + PKVM_PAGE_OWNED = 0ULL, + PKVM_PAGE_SHARED_OWNED = KVM_PGTABLE_PROT_SW0, + PKVM_PAGE_SHARED_BORROWED = KVM_PGTABLE_PROT_SW1, +}; + +#define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1) +static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot, + enum pkvm_page_state state) +{ + return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state; +} + +static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot) +{ + return prot & PKVM_PAGE_STATE_PROT_MASK; +} + struct host_kvm { struct kvm_arch arch; struct kvm_pgtable pgt; -- cgit v1.2.3-70-g09d2 From 39257da0e04e5cdb1e4a3ca715dc3d949fe8b059 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:40 +0100 Subject: KVM: arm64: Expose host stage-2 manipulation helpers We will need to manipulate the host stage-2 page-table from outside mem_protect.c soon. Introduce two functions allowing this, and make them usable to users of mem_protect.h. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-14-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 2 ++ arch/arm64/kvm/hyp/nvhe/mem_protect.c | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 87b1690c439f..0849ee8fa260 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -49,6 +49,8 @@ extern struct host_kvm host_kvm; int __pkvm_prot_finalize(void); int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); +int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); +int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id); int kvm_host_prepare_stage2(void *pgt_pool_base); void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 6fed6772c673..f95a5a4aa09c 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -273,6 +273,22 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) return 0; } +int host_stage2_idmap_locked(phys_addr_t addr, u64 size, + enum kvm_pgtable_prot prot) +{ + hyp_assert_lock_held(&host_kvm.lock); + + return host_stage2_try(__host_stage2_idmap, addr, addr + size, prot); +} + +int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id) +{ + hyp_assert_lock_held(&host_kvm.lock); + + return host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, + addr, size, &host_s2_pool, owner_id); +} + static bool host_stage2_force_pte_cb(u64 addr, u64 end, enum kvm_pgtable_prot prot) { /* @@ -309,7 +325,7 @@ static int host_stage2_idmap(u64 addr) if (ret) goto unlock; - ret = host_stage2_try(__host_stage2_idmap, range.start, range.end, prot); + ret = host_stage2_idmap_locked(range.start, range.end - range.start, prot); unlock: hyp_spin_unlock(&host_kvm.lock); -- cgit v1.2.3-70-g09d2 From 2d77e238badb022adb364332b7d6a1d627f77145 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:41 +0100 Subject: KVM: arm64: Expose pkvm_hyp_id Allow references to the hypervisor's owner id from outside mem_protect.c. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-15-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 2 ++ arch/arm64/kvm/hyp/nvhe/mem_protect.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 0849ee8fa260..23316a021880 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -46,6 +46,8 @@ struct host_kvm { }; extern struct host_kvm host_kvm; +extern const u8 pkvm_hyp_id; + int __pkvm_prot_finalize(void); int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index f95a5a4aa09c..ee255171945c 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -31,7 +31,7 @@ static struct hyp_pool host_s2_pool; u64 id_aa64mmfr0_el1_sys_val; u64 id_aa64mmfr1_el1_sys_val; -static const u8 pkvm_hyp_id = 1; +const u8 pkvm_hyp_id = 1; static void *host_s2_zalloc_pages_exact(size_t size) { -- cgit v1.2.3-70-g09d2 From e009dce1292c37cf8ee7c33e0887ad3c642f980f Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:42 +0100 Subject: KVM: arm64: Introduce addr_is_memory() Introduce a helper usable in nVHE protected mode to check whether a physical address is in a RAM region or not. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-16-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/nvhe/mem_protect.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 23316a021880..49db0ec5a606 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -51,6 +51,7 @@ extern const u8 pkvm_hyp_id; int __pkvm_prot_finalize(void); int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); +bool addr_is_memory(phys_addr_t phys); int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); int host_stage2_set_owner_locked(phys_addr_t addr, u64 size, u8 owner_id); int kvm_host_prepare_stage2(void *pgt_pool_base); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index ee255171945c..cb023d31666e 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -197,6 +197,13 @@ static bool find_mem_range(phys_addr_t addr, struct kvm_mem_range *range) return false; } +bool addr_is_memory(phys_addr_t phys) +{ + struct kvm_mem_range range; + + return find_mem_range(phys, &range); +} + static bool range_is_memory(u64 start, u64 end) { struct kvm_mem_range r1, r2; -- cgit v1.2.3-70-g09d2 From 9024b3d0069ab4b8ef70cf55f0ee09e61f3a0747 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:43 +0100 Subject: KVM: arm64: Enable retrieving protections attributes of PTEs Introduce helper functions in the KVM stage-2 and stage-1 page-table manipulation library allowing to retrieve the enum kvm_pgtable_prot of a PTE. This will be useful to implement custom walkers outside of pgtable.c. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-17-qperret@google.com --- arch/arm64/include/asm/kvm_pgtable.h | 20 +++++++++++++++++++ arch/arm64/kvm/hyp/pgtable.c | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index bfea573703d7..027783829584 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -507,4 +507,24 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size, */ int kvm_pgtable_get_leaf(struct kvm_pgtable *pgt, u64 addr, kvm_pte_t *ptep, u32 *level); + +/** + * kvm_pgtable_stage2_pte_prot() - Retrieve the protection attributes of a + * stage-2 Page-Table Entry. + * @pte: Page-table entry + * + * Return: protection attributes of the page-table entry in the enum + * kvm_pgtable_prot format. + */ +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte); + +/** + * kvm_pgtable_hyp_pte_prot() - Retrieve the protection attributes of a stage-1 + * Page-Table Entry. + * @pte: Page-table entry + * + * Return: protection attributes of the page-table entry in the enum + * kvm_pgtable_prot format. + */ +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte); #endif /* __ARM64_KVM_PGTABLE_H__ */ diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index cff744136044..f8ceebe4982e 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -363,6 +363,26 @@ static int hyp_set_prot_attr(enum kvm_pgtable_prot prot, kvm_pte_t *ptep) return 0; } +enum kvm_pgtable_prot kvm_pgtable_hyp_pte_prot(kvm_pte_t pte) +{ + enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; + u32 ap; + + if (!kvm_pte_valid(pte)) + return prot; + + if (!(pte & KVM_PTE_LEAF_ATTR_HI_S1_XN)) + prot |= KVM_PGTABLE_PROT_X; + + ap = FIELD_GET(KVM_PTE_LEAF_ATTR_LO_S1_AP, pte); + if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RO) + prot |= KVM_PGTABLE_PROT_R; + else if (ap == KVM_PTE_LEAF_ATTR_LO_S1_AP_RW) + prot |= KVM_PGTABLE_PROT_RW; + + return prot; +} + static bool hyp_pte_needs_update(kvm_pte_t old, kvm_pte_t new) { /* @@ -565,6 +585,23 @@ static int stage2_set_prot_attr(struct kvm_pgtable *pgt, enum kvm_pgtable_prot p return 0; } +enum kvm_pgtable_prot kvm_pgtable_stage2_pte_prot(kvm_pte_t pte) +{ + enum kvm_pgtable_prot prot = pte & KVM_PTE_LEAF_ATTR_HI_SW; + + if (!kvm_pte_valid(pte)) + return prot; + + if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R) + prot |= KVM_PGTABLE_PROT_R; + if (pte & KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W) + prot |= KVM_PGTABLE_PROT_W; + if (!(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN)) + prot |= KVM_PGTABLE_PROT_X; + + return prot; +} + static bool stage2_pte_needs_update(kvm_pte_t old, kvm_pte_t new) { if (!kvm_pte_valid(old) || !kvm_pte_valid(new)) -- cgit v1.2.3-70-g09d2 From 2c50166c62ba7f3c23c1bbdbb9324db462ddc97b Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:44 +0100 Subject: KVM: arm64: Mark host bss and rodata section as shared As the hypervisor maps the host's .bss and .rodata sections in its stage-1, make sure to tag them as shared in hyp and host page-tables. But since the hypervisor relies on the presence of these mappings, we cannot let the host in complete control of the memory regions -- it must not unshare or donate them to another entity for example. To prevent this, let's transfer the ownership of those ranges to the hypervisor itself, and share the pages back with the host. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-18-qperret@google.com --- arch/arm64/kvm/hyp/nvhe/setup.c | 82 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 0b574d106519..57c27846320f 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -58,6 +58,7 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, { void *start, *end, *virt = hyp_phys_to_virt(phys); unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT; + enum kvm_pgtable_prot prot; int ret, i; /* Recreate the hyp page-table using the early page allocator */ @@ -83,10 +84,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, if (ret) return ret; - ret = pkvm_create_mappings(__start_rodata, __end_rodata, PAGE_HYP_RO); - if (ret) - return ret; - ret = pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_HYP_RO); if (ret) return ret; @@ -95,10 +92,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, if (ret) return ret; - ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, PAGE_HYP_RO); - if (ret) - return ret; - ret = pkvm_create_mappings(virt, virt + size, PAGE_HYP); if (ret) return ret; @@ -117,6 +110,24 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, return ret; } + /* + * Map the host's .bss and .rodata sections RO in the hypervisor, but + * transfer the ownership from the host to the hypervisor itself to + * make sure it can't be donated or shared with another entity. + * + * The ownership transition requires matching changes in the host + * stage-2. This will be done later (see finalize_host_mappings()) once + * the hyp_vmemmap is addressable. + */ + prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED); + ret = pkvm_create_mappings(__start_rodata, __end_rodata, prot); + if (ret) + return ret; + + ret = pkvm_create_mappings(__hyp_bss_end, __bss_stop, prot); + if (ret) + return ret; + return 0; } @@ -148,6 +159,57 @@ static void hpool_put_page(void *addr) hyp_put_page(&hpool, addr); } +static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level, + kvm_pte_t *ptep, + enum kvm_pgtable_walk_flags flag, + void * const arg) +{ + enum kvm_pgtable_prot prot; + enum pkvm_page_state state; + kvm_pte_t pte = *ptep; + phys_addr_t phys; + + if (!kvm_pte_valid(pte)) + return 0; + + if (level != (KVM_PGTABLE_MAX_LEVELS - 1)) + return -EINVAL; + + phys = kvm_pte_to_phys(pte); + if (!addr_is_memory(phys)) + return 0; + + /* + * Adjust the host stage-2 mappings to match the ownership attributes + * configured in the hypervisor stage-1. + */ + state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte)); + switch (state) { + case PKVM_PAGE_OWNED: + return host_stage2_set_owner_locked(phys, PAGE_SIZE, pkvm_hyp_id); + case PKVM_PAGE_SHARED_OWNED: + prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_BORROWED); + break; + case PKVM_PAGE_SHARED_BORROWED: + prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED); + break; + default: + return -EINVAL; + } + + return host_stage2_idmap_locked(phys, PAGE_SIZE, prot); +} + +static int finalize_host_mappings(void) +{ + struct kvm_pgtable_walker walker = { + .cb = finalize_host_mappings_walker, + .flags = KVM_PGTABLE_WALK_LEAF, + }; + + return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker); +} + void __noreturn __pkvm_init_finalise(void) { struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data); @@ -167,6 +229,10 @@ void __noreturn __pkvm_init_finalise(void) if (ret) goto out; + ret = finalize_host_mappings(); + if (ret) + goto out; + pkvm_pgtable_mm_ops = (struct kvm_pgtable_mm_ops) { .zalloc_page = hyp_zalloc_hyp_page, .phys_to_virt = hyp_phys_to_virt, -- cgit v1.2.3-70-g09d2 From ad0e0139a8e163245d8f44ab4f6ec3bc9b08034d Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:45 +0100 Subject: KVM: arm64: Remove __pkvm_mark_hyp Now that we mark memory owned by the hypervisor in the host stage-2 during __pkvm_init(), we no longer need to rely on the host to explicitly mark the hyp sections later on. Remove the __pkvm_mark_hyp() hypercall altogether. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-19-qperret@google.com --- arch/arm64/include/asm/kvm_asm.h | 3 +- arch/arm64/kvm/arm.c | 46 --------------------------- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 - arch/arm64/kvm/hyp/nvhe/hyp-main.c | 9 ------ arch/arm64/kvm/hyp/nvhe/mem_protect.c | 19 ----------- 5 files changed, 1 insertion(+), 77 deletions(-) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 9f0bf2109be7..432a9ea1f02e 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -63,8 +63,7 @@ #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping 17 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 -#define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp 20 -#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 21 +#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 20 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e9a2b8f27792..2f378482471b 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1954,57 +1954,11 @@ static void _kvm_host_prot_finalize(void *discard) WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); } -static inline int pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) -{ - return kvm_call_hyp_nvhe(__pkvm_mark_hyp, start, end); -} - -#define pkvm_mark_hyp_section(__section) \ - pkvm_mark_hyp(__pa_symbol(__section##_start), \ - __pa_symbol(__section##_end)) - static int finalize_hyp_mode(void) { - int cpu, ret; - if (!is_protected_kvm_enabled()) return 0; - ret = pkvm_mark_hyp_section(__hyp_idmap_text); - if (ret) - return ret; - - ret = pkvm_mark_hyp_section(__hyp_text); - if (ret) - return ret; - - ret = pkvm_mark_hyp_section(__hyp_rodata); - if (ret) - return ret; - - ret = pkvm_mark_hyp_section(__hyp_bss); - if (ret) - return ret; - - ret = pkvm_mark_hyp(hyp_mem_base, hyp_mem_base + hyp_mem_size); - if (ret) - return ret; - - for_each_possible_cpu(cpu) { - phys_addr_t start = virt_to_phys((void *)kvm_arm_hyp_percpu_base[cpu]); - phys_addr_t end = start + (PAGE_SIZE << nvhe_percpu_order()); - - ret = pkvm_mark_hyp(start, end); - if (ret) - return ret; - - start = virt_to_phys((void *)per_cpu(kvm_arm_hyp_stack_page, cpu)); - end = start + PAGE_SIZE; - ret = pkvm_mark_hyp(start, end); - if (ret) - return ret; - } - /* * Flip the static key upfront as that may no longer be possible * once the host stage 2 is installed. diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 49db0ec5a606..0118527b07b0 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -49,7 +49,6 @@ extern struct host_kvm host_kvm; extern const u8 pkvm_hyp_id; int __pkvm_prot_finalize(void); -int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); bool addr_is_memory(phys_addr_t phys); int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 1632f001f4ed..7900d5b66ba3 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -163,14 +163,6 @@ static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt) { cpu_reg(host_ctxt, 1) = __pkvm_prot_finalize(); } - -static void handle___pkvm_mark_hyp(struct kvm_cpu_context *host_ctxt) -{ - DECLARE_REG(phys_addr_t, start, host_ctxt, 1); - DECLARE_REG(phys_addr_t, end, host_ctxt, 2); - - cpu_reg(host_ctxt, 1) = __pkvm_mark_hyp(start, end); -} typedef void (*hcall_t)(struct kvm_cpu_context *); #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] = (hcall_t)handle_##x @@ -196,7 +188,6 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__pkvm_create_mappings), HANDLE_FUNC(__pkvm_create_private_mapping), HANDLE_FUNC(__pkvm_prot_finalize), - HANDLE_FUNC(__pkvm_mark_hyp), }; static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index cb023d31666e..2991dc6996b9 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -339,25 +339,6 @@ unlock: return ret; } -int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) -{ - int ret; - - /* - * host_stage2_unmap_dev_all() currently relies on MMIO mappings being - * non-persistent, so don't allow changing page ownership in MMIO range. - */ - if (!range_is_memory(start, end)) - return -EINVAL; - - hyp_spin_lock(&host_kvm.lock); - ret = host_stage2_try(kvm_pgtable_stage2_set_owner, &host_kvm.pgt, - start, end - start, &host_s2_pool, pkvm_hyp_id); - hyp_spin_unlock(&host_kvm.lock); - - return ret != -EAGAIN ? ret : 0; -} - void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) { struct kvm_vcpu_fault_info fault; -- cgit v1.2.3-70-g09d2 From f9370010e92638f66473baf342e19de940403362 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:46 +0100 Subject: KVM: arm64: Refactor protected nVHE stage-1 locking Refactor the hypervisor stage-1 locking in nVHE protected mode to expose a new pkvm_create_mappings_locked() function. This will be used in later patches to allow walking and changing the hypervisor stage-1 without releasing the lock. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-20-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mm.h | 1 + arch/arm64/kvm/hyp/nvhe/mm.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h index 8ec3a5a7744b..c76d7136ed9b 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h @@ -23,6 +23,7 @@ int hyp_map_vectors(void); int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back); int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot); int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot); +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot); int __pkvm_create_mappings(unsigned long start, unsigned long size, unsigned long phys, enum kvm_pgtable_prot prot); unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size, diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index a8efdf0f9003..6fbe8e8030f6 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -67,13 +67,15 @@ out: return addr; } -int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) +int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot) { unsigned long start = (unsigned long)from; unsigned long end = (unsigned long)to; unsigned long virt_addr; phys_addr_t phys; + hyp_assert_lock_held(&pkvm_pgd_lock); + start = start & PAGE_MASK; end = PAGE_ALIGN(end); @@ -81,7 +83,8 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) int err; phys = hyp_virt_to_phys((void *)virt_addr); - err = __pkvm_create_mappings(virt_addr, PAGE_SIZE, phys, prot); + err = kvm_pgtable_hyp_map(&pkvm_pgtable, virt_addr, PAGE_SIZE, + phys, prot); if (err) return err; } @@ -89,6 +92,17 @@ int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) return 0; } +int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot) +{ + int ret; + + hyp_spin_lock(&pkvm_pgd_lock); + ret = pkvm_create_mappings_locked(from, to, prot); + hyp_spin_unlock(&pkvm_pgd_lock); + + return ret; +} + int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back) { unsigned long start, end; -- cgit v1.2.3-70-g09d2 From 66c57edd3bc79e3527daaae8123f72ecd1e3fa25 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:47 +0100 Subject: KVM: arm64: Restrict EL2 stage-1 changes in protected mode The host kernel is currently able to change EL2 stage-1 mappings without restrictions thanks to the __pkvm_create_mappings() hypercall. But in a world where the host is no longer part of the TCB, this clearly poses a problem. To fix this, introduce a new hypercall to allow the host to share a physical memory page with the hypervisor, and remove the __pkvm_create_mappings() variant. The new hypercall implements ownership and permission checks before allowing the sharing operation, and it annotates the shared page in the hypervisor stage-1 and host stage-2 page-tables. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-21-qperret@google.com --- arch/arm64/include/asm/kvm_asm.h | 2 +- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/nvhe/hyp-main.c | 11 ++-- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 88 +++++++++++++++++++++++++++ arch/arm64/kvm/mmu.c | 28 +++++++-- 5 files changed, 118 insertions(+), 12 deletions(-) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 432a9ea1f02e..aed2aa61766a 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -59,7 +59,7 @@ #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs 13 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs 14 #define __KVM_HOST_SMCCC_FUNC___pkvm_init 15 -#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings 16 +#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp 16 #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping 17 #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 0118527b07b0..03e604f842e2 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -49,6 +49,7 @@ extern struct host_kvm host_kvm; extern const u8 pkvm_hyp_id; int __pkvm_prot_finalize(void); +int __pkvm_host_share_hyp(u64 pfn); bool addr_is_memory(phys_addr_t phys); int host_stage2_idmap_locked(phys_addr_t addr, u64 size, enum kvm_pgtable_prot prot); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 7900d5b66ba3..2da6aa8da868 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -140,14 +140,11 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot); } -static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt) +static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt) { - DECLARE_REG(unsigned long, start, host_ctxt, 1); - DECLARE_REG(unsigned long, size, host_ctxt, 2); - DECLARE_REG(unsigned long, phys, host_ctxt, 3); - DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4); + DECLARE_REG(u64, pfn, host_ctxt, 1); - cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot); + cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(pfn); } static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt) @@ -185,7 +182,7 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__vgic_v3_restore_aprs), HANDLE_FUNC(__pkvm_init), HANDLE_FUNC(__pkvm_cpu_set_vector), - HANDLE_FUNC(__pkvm_create_mappings), + HANDLE_FUNC(__pkvm_host_share_hyp), HANDLE_FUNC(__pkvm_create_private_mapping), HANDLE_FUNC(__pkvm_prot_finalize), }; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 2991dc6996b9..8165390d3ec9 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -339,6 +339,94 @@ unlock: return ret; } +static inline bool check_prot(enum kvm_pgtable_prot prot, + enum kvm_pgtable_prot required, + enum kvm_pgtable_prot denied) +{ + return (prot & (required | denied)) == required; +} + +int __pkvm_host_share_hyp(u64 pfn) +{ + phys_addr_t addr = hyp_pfn_to_phys(pfn); + enum kvm_pgtable_prot prot, cur; + void *virt = __hyp_va(addr); + enum pkvm_page_state state; + kvm_pte_t pte; + int ret; + + if (!addr_is_memory(addr)) + return -EINVAL; + + hyp_spin_lock(&host_kvm.lock); + hyp_spin_lock(&pkvm_pgd_lock); + + ret = kvm_pgtable_get_leaf(&host_kvm.pgt, addr, &pte, NULL); + if (ret) + goto unlock; + if (!pte) + goto map_shared; + + /* + * Check attributes in the host stage-2 PTE. We need the page to be: + * - mapped RWX as we're sharing memory; + * - not borrowed, as that implies absence of ownership. + * Otherwise, we can't let it got through + */ + cur = kvm_pgtable_stage2_pte_prot(pte); + prot = pkvm_mkstate(0, PKVM_PAGE_SHARED_BORROWED); + if (!check_prot(cur, PKVM_HOST_MEM_PROT, prot)) { + ret = -EPERM; + goto unlock; + } + + state = pkvm_getstate(cur); + if (state == PKVM_PAGE_OWNED) + goto map_shared; + + /* + * Tolerate double-sharing the same page, but this requires + * cross-checking the hypervisor stage-1. + */ + if (state != PKVM_PAGE_SHARED_OWNED) { + ret = -EPERM; + goto unlock; + } + + ret = kvm_pgtable_get_leaf(&pkvm_pgtable, (u64)virt, &pte, NULL); + if (ret) + goto unlock; + + /* + * If the page has been shared with the hypervisor, it must be + * already mapped as SHARED_BORROWED in its stage-1. + */ + cur = kvm_pgtable_hyp_pte_prot(pte); + prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); + if (!check_prot(cur, prot, ~prot)) + ret = EPERM; + goto unlock; + +map_shared: + /* + * If the page is not yet shared, adjust mappings in both page-tables + * while both locks are held. + */ + prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); + ret = pkvm_create_mappings_locked(virt, virt + PAGE_SIZE, prot); + BUG_ON(ret); + + prot = pkvm_mkstate(PKVM_HOST_MEM_PROT, PKVM_PAGE_SHARED_OWNED); + ret = host_stage2_idmap_locked(addr, PAGE_SIZE, prot); + BUG_ON(ret); + +unlock: + hyp_spin_unlock(&pkvm_pgd_lock); + hyp_spin_unlock(&host_kvm.lock); + + return ret; +} + void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) { struct kvm_vcpu_fault_info fault; diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 0625bf2353c2..cbab146cda6a 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size, { int err; - if (!kvm_host_owns_hyp_mappings()) { - return kvm_call_hyp_nvhe(__pkvm_create_mappings, - start, size, phys, prot); - } + if (WARN_ON(!kvm_host_owns_hyp_mappings())) + return -EINVAL; mutex_lock(&kvm_hyp_pgd_mutex); err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot); @@ -282,6 +280,21 @@ static phys_addr_t kvm_kaddr_to_phys(void *kaddr) } } +static int pkvm_share_hyp(phys_addr_t start, phys_addr_t end) +{ + phys_addr_t addr; + int ret; + + for (addr = ALIGN_DOWN(start, PAGE_SIZE); addr < end; addr += PAGE_SIZE) { + ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, + __phys_to_pfn(addr)); + if (ret) + return ret; + } + + return 0; +} + /** * create_hyp_mappings - duplicate a kernel virtual address range in Hyp mode * @from: The virtual kernel start address of the range @@ -302,6 +315,13 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot) if (is_kernel_in_hyp_mode()) return 0; + if (!kvm_host_owns_hyp_mappings()) { + if (WARN_ON(prot != PAGE_HYP)) + return -EPERM; + return pkvm_share_hyp(kvm_kaddr_to_phys(from), + kvm_kaddr_to_phys(to)); + } + start = start & PAGE_MASK; end = PAGE_ALIGN(end); -- cgit v1.2.3-70-g09d2 From 64a80fb766f9a91e26930bfc56d8e7c12425df12 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 9 Aug 2021 16:24:48 +0100 Subject: KVM: arm64: Make __pkvm_create_mappings static The __pkvm_create_mappings() function is no longer used outside of nvhe/mm.c, make it static. Signed-off-by: Quentin Perret Reviewed-by: Fuad Tabba Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210809152448.1810400-22-qperret@google.com --- arch/arm64/kvm/hyp/include/nvhe/mm.h | 2 -- arch/arm64/kvm/hyp/nvhe/mm.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h index c76d7136ed9b..c9a8f535212e 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h @@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back); int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot); int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot); int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot); -int __pkvm_create_mappings(unsigned long start, unsigned long size, - unsigned long phys, enum kvm_pgtable_prot prot); unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size, enum kvm_pgtable_prot prot); diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index 6fbe8e8030f6..2fabeceb889a 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -23,8 +23,8 @@ u64 __io_map_base; struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS]; unsigned int hyp_memblock_nr; -int __pkvm_create_mappings(unsigned long start, unsigned long size, - unsigned long phys, enum kvm_pgtable_prot prot) +static int __pkvm_create_mappings(unsigned long start, unsigned long size, + unsigned long phys, enum kvm_pgtable_prot prot) { int err; -- cgit v1.2.3-70-g09d2 From 00974b9a83cb233d9c8f9758f541d9aa2a80c5cd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Aug 2021 10:54:36 +0200 Subject: memblock: Add missing debug code to memblock_add_node() All other memblock APIs built on top of memblock_add_range() contain debug code to print their parameters. Signed-off-by: Geert Uytterhoeven Reviewed-by: David Hildenbrand Signed-off-by: Mike Rapoport Link: https://lore.kernel.org/r/c45e5218b6fcf0e3aeb63d9a9d9792addae0bb7a.1628672041.git.geert+renesas@glider.be --- mm/memblock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/memblock.c b/mm/memblock.c index de7b553baa50..57a9849a5d82 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -665,6 +665,11 @@ repeat: int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size, int nid) { + phys_addr_t end = base + size - 1; + + memblock_dbg("%s: [%pa-%pa] nid=%d %pS\n", __func__, + &base, &end, nid, (void *)_RET_IP_); + return memblock_add_range(&memblock.memory, base, size, nid, 0); } -- cgit v1.2.3-70-g09d2 From e888fa7bb882a1f305526d8f49d7016a7bc5f5ca Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Aug 2021 10:55:18 +0200 Subject: memblock: Check memory add/cap ordering For memblock_cap_memory_range() to work properly, it should be called after memory is detected and added to memblock with memblock_add() or memblock_add_node(). If memblock_cap_memory_range() would be called before memory is registered, we may silently corrupt memory later because the crash kernel will see all memory as available. Print a warning and bail out if ordering is not satisfied. Suggested-by: Mike Rapoport Signed-off-by: Geert Uytterhoeven Reviewed-by: David Hildenbrand Signed-off-by: Mike Rapoport Link: https://lore.kernel.org/r/aabc5bad008d49f07d542815c6c8d28ec90bb09e.1628672091.git.geert+renesas@glider.be --- mm/memblock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/memblock.c b/mm/memblock.c index 57a9849a5d82..e2ca8ddc8ebe 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1685,6 +1685,11 @@ void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size) if (!size) return; + if (memblock.memory.cnt <= 1) { + pr_warn("%s: No memory registered yet\n", __func__); + return; + } + ret = memblock_isolate_range(&memblock.memory, base, size, &start_rgn, &end_rgn); if (ret) -- cgit v1.2.3-70-g09d2 From 328fb93a84686d8884b9b7ce1107ae0a46c194f7 Mon Sep 17 00:00:00 2001 From: satya priya Date: Mon, 2 Aug 2021 18:51:03 +0530 Subject: dt-bindings: pinctrl: qcom-pmic-gpio: Convert qcom pmic gpio bindings to YAML Convert Qualcomm PMIC GPIO bindings from .txt to .yaml format. Signed-off-by: satya priya Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1627910464-19363-3-git-send-email-skakit@codeaurora.org Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/qcom,pmic-gpio.txt | 294 --------------------- .../bindings/pinctrl/qcom,pmic-gpio.yaml | 259 ++++++++++++++++++ 2 files changed, 259 insertions(+), 294 deletions(-) delete mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt create mode 100644 Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt deleted file mode 100644 index 48cc82d075e2..000000000000 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ /dev/null @@ -1,294 +0,0 @@ -Qualcomm PMIC GPIO block - -This binding describes the GPIO block(s) found in the 8xxx series of -PMIC's from Qualcomm. - -- compatible: - Usage: required - Value type: - Definition: must be one of: - "qcom,pm660-gpio" - "qcom,pm660l-gpio" - "qcom,pm6150-gpio" - "qcom,pm6150l-gpio" - "qcom,pm7325-gpio" - "qcom,pm8005-gpio" - "qcom,pm8008-gpio" - "qcom,pm8018-gpio" - "qcom,pm8038-gpio" - "qcom,pm8058-gpio" - "qcom,pm8150-gpio" - "qcom,pm8150b-gpio" - "qcom,pm8350-gpio" - "qcom,pm8350b-gpio" - "qcom,pm8350c-gpio" - "qcom,pm8916-gpio" - "qcom,pm8917-gpio" - "qcom,pm8921-gpio" - "qcom,pm8941-gpio" - "qcom,pm8950-gpio" - "qcom,pm8994-gpio" - "qcom,pm8998-gpio" - "qcom,pma8084-gpio" - "qcom,pmc8180-gpio" - "qcom,pmc8180c-gpio" - "qcom,pmi8950-gpio" - "qcom,pmi8994-gpio" - "qcom,pmi8998-gpio" - "qcom,pmk8350-gpio" - "qcom,pmm8155au-gpio" - "qcom,pmr735a-gpio" - "qcom,pmr735b-gpio" - "qcom,pms405-gpio" - "qcom,pmx55-gpio" - - And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio" - if the device is on an spmi bus or an ssbi bus respectively - -- reg: - Usage: required - Value type: - Definition: Register base of the GPIO block and length. - -- interrupts: - Usage: required - Value type: - Definition: Must contain an array of encoded interrupt specifiers for - each available GPIO - -- gpio-controller: - Usage: required - Value type: - Definition: Mark the device node as a GPIO controller - -- #gpio-cells: - Usage: required - Value type: - Definition: Must be 2; - the first cell will be used to define gpio number and the - second denotes the flags for this gpio - -Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for -a general description of GPIO and interrupt bindings. - -Please refer to pinctrl-bindings.txt in this directory for details of the -common pinctrl bindings used by client devices, including the meaning of the -phrase "pin configuration node". - -The pin configuration nodes act as a container for an arbitrary number of -subnodes. Each of these subnodes represents some desired configuration for a -pin or a list of pins. This configuration can include the -mux function to select on those pin(s), and various pin configuration -parameters, as listed below. - - -SUBNODES: - -The name of each subnode is not important; all subnodes should be enumerated -and processed purely based on their content. - -Each subnode only affects those parameters that are explicitly listed. In -other words, a subnode that lists a mux function but no pin configuration -parameters implies no information about any pin configuration parameters. -Similarly, a pin subnode that describes a pullup parameter implies no -information about e.g. the mux function. - -The following generic properties as defined in pinctrl-bindings.txt are valid -to specify in a pin configuration subnode: - -- pins: - Usage: required - Value type: - Definition: List of gpio pins affected by the properties specified in - this subnode. Valid pins are: - gpio1-gpio10 for pm6150 - gpio1-gpio12 for pm6150l - gpio1-gpio10 for pm7325 - gpio1-gpio4 for pm8005 - gpio1-gpio2 for pm8008 - gpio1-gpio6 for pm8018 - gpio1-gpio12 for pm8038 - gpio1-gpio40 for pm8058 - gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, gpio7 - and gpio8) - gpio1-gpio12 for pm8150b (holes on gpio3, gpio4, gpio7) - gpio1-gpio12 for pm8150l (hole on gpio7) - gpio1-gpio10 for pm8350 - gpio1-gpio8 for pm8350b - gpio1-gpio9 for pm8350c - gpio1-gpio4 for pm8916 - gpio1-gpio38 for pm8917 - gpio1-gpio44 for pm8921 - gpio1-gpio36 for pm8941 - gpio1-gpio8 for pm8950 (hole on gpio3) - gpio1-gpio22 for pm8994 - gpio1-gpio26 for pm8998 - gpio1-gpio22 for pma8084 - gpio1-gpio10 for pmc8180 - gpio1-gpio12 for pmc8180c - gpio1-gpio2 for pmi8950 - gpio1-gpio10 for pmi8994 - gpio1-gpio4 for pmk8350 - gpio1-gpio10 for pmm8155au - gpio1-gpio4 for pmr735a - gpio1-gpio4 for pmr735b - gpio1-gpio12 for pms405 (holes on gpio1, gpio9 and gpio10) - gpio1-gpio11 for pmx55 (holes on gpio3, gpio7, gpio10 - and gpio11) - -- function: - Usage: required - Value type: - Definition: Specify the alternative function to be configured for the - specified pins. Valid values are: - "normal", - "paired", - "func1", - "func2", - "dtest1", - "dtest2", - "dtest3", - "dtest4", - And following values are supported by LV/MV GPIO subtypes: - "func3", - "func4" - -- bias-disable: - Usage: optional - Value type: - Definition: The specified pins should be configured as no pull. - -- bias-pull-down: - Usage: optional - Value type: - Definition: The specified pins should be configured as pull down. - -- bias-pull-up: - Usage: optional - Value type: - Definition: The specified pins should be configured as pull up. - -- qcom,pull-up-strength: - Usage: optional - Value type: - Definition: Specifies the strength to use for pull up, if selected. - Valid values are; as defined in - : - 1: 30uA (PMIC_GPIO_PULL_UP_30) - 2: 1.5uA (PMIC_GPIO_PULL_UP_1P5) - 3: 31.5uA (PMIC_GPIO_PULL_UP_31P5) - 4: 1.5uA + 30uA boost (PMIC_GPIO_PULL_UP_1P5_30) - If this property is omitted 30uA strength will be used if - pull up is selected - -- bias-high-impedance: - Usage: optional - Value type: - Definition: The specified pins will put in high-Z mode and disabled. - -- input-enable: - Usage: optional - Value type: - Definition: The specified pins are put in input mode. - -- output-high: - Usage: optional - Value type: - Definition: The specified pins are configured in output mode, driven - high. - -- output-low: - Usage: optional - Value type: - Definition: The specified pins are configured in output mode, driven - low. - -- power-source: - Usage: optional - Value type: - Definition: Selects the power source for the specified pins. Valid - power sources are defined per chip in - - -- qcom,drive-strength: - Usage: optional - Value type: - Definition: Selects the drive strength for the specified pins. Value - drive strengths are: - 0: no (PMIC_GPIO_STRENGTH_NO) - 1: high (PMIC_GPIO_STRENGTH_HIGH) 0.9mA @ 1.8V - 1.9mA @ 2.6V - 2: medium (PMIC_GPIO_STRENGTH_MED) 0.6mA @ 1.8V - 1.25mA @ 2.6V - 3: low (PMIC_GPIO_STRENGTH_LOW) 0.15mA @ 1.8V - 0.3mA @ 2.6V - as defined in - -- drive-push-pull: - Usage: optional - Value type: - Definition: The specified pins are configured in push-pull mode. - -- drive-open-drain: - Usage: optional - Value type: - Definition: The specified pins are configured in open-drain mode. - -- drive-open-source: - Usage: optional - Value type: - Definition: The specified pins are configured in open-source mode. - -- qcom,analog-pass: - Usage: optional - Value type: - Definition: The specified pins are configured in analog-pass-through mode. - -- qcom,atest: - Usage: optional - Value type: - Definition: Selects ATEST rail to route to GPIO when it's configured - in analog-pass-through mode. - Valid values are 1-4 corresponding to ATEST1 to ATEST4. - -- qcom,dtest-buffer: - Usage: optional - Value type: - Definition: Selects DTEST rail to route to GPIO when it's configured - as digital input. - Valid values are 1-4 corresponding to DTEST1 to DTEST4. - -Example: - - pm8921_gpio: gpio@150 { - compatible = "qcom,pm8921-gpio", "qcom,ssbi-gpio"; - reg = <0x150 0x160>; - interrupts = <192 1>, <193 1>, <194 1>, - <195 1>, <196 1>, <197 1>, - <198 1>, <199 1>, <200 1>, - <201 1>, <202 1>, <203 1>, - <204 1>, <205 1>, <206 1>, - <207 1>, <208 1>, <209 1>, - <210 1>, <211 1>, <212 1>, - <213 1>, <214 1>, <215 1>, - <216 1>, <217 1>, <218 1>, - <219 1>, <220 1>, <221 1>, - <222 1>, <223 1>, <224 1>, - <225 1>, <226 1>, <227 1>, - <228 1>, <229 1>, <230 1>, - <231 1>, <232 1>, <233 1>, - <234 1>, <235 1>; - - gpio-controller; - #gpio-cells = <2>; - - pm8921_gpio_keys: gpio-keys { - volume-keys { - pins = "gpio20", "gpio21"; - function = "normal"; - - input-enable; - bias-pull-up; - drive-push-pull; - qcom,drive-strength = ; - power-source = ; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml new file mode 100644 index 000000000000..7a0d2d8e1c86 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -0,0 +1,259 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/qcom,pmic-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm PMIC GPIO block + +maintainers: + - Bjorn Andersson + +description: + This binding describes the GPIO block(s) found in the 8xxx series of + PMIC's from Qualcomm. + +properties: + compatible: + items: + - enum: + - qcom,pm660-gpio + - qcom,pm660l-gpio + - qcom,pm6150-gpio + - qcom,pm6150l-gpio + - qcom,pm7325-gpio + - qcom,pm8005-gpio + - qcom,pm8008-gpio + - qcom,pm8018-gpio + - qcom,pm8038-gpio + - qcom,pm8058-gpio + - qcom,pm8150-gpio + - qcom,pm8150b-gpio + - qcom,pm8350-gpio + - qcom,pm8350b-gpio + - qcom,pm8350c-gpio + - qcom,pm8916-gpio + - qcom,pm8917-gpio + - qcom,pm8921-gpio + - qcom,pm8941-gpio + - qcom,pm8950-gpio + - qcom,pm8994-gpio + - qcom,pm8998-gpio + - qcom,pma8084-gpio + - qcom,pmi8950-gpio + - qcom,pmi8994-gpio + - qcom,pmi8998-gpio + - qcom,pmk8350-gpio + - qcom,pmr735a-gpio + - qcom,pmr735b-gpio + - qcom,pms405-gpio + - qcom,pmx55-gpio + + - enum: + - qcom,spmi-gpio + - qcom,ssbi-gpio + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 44 + description: + Must contain an array of encoded interrupt specifiers for + each available GPIO + + '#interrupt-cells': + const: 2 + + interrupt-controller: true + + gpio-controller: true + + gpio-ranges: + maxItems: 1 + + '#gpio-cells': + const: 2 + description: + The first cell will be used to define gpio number and the + second denotes the flags for this gpio + +additionalProperties: false + +required: + - compatible + - reg + - gpio-controller + - '#gpio-cells' + - gpio-ranges + +patternProperties: + '-state$': + oneOf: + - $ref: "#/$defs/qcom-pmic-gpio-state" + - patternProperties: + ".*": + $ref: "#/$defs/qcom-pmic-gpio-state" + +$defs: + qcom-pmic-gpio-state: + type: object + allOf: + - $ref: "pinmux-node.yaml" + - $ref: "pincfg-node.yaml" + properties: + pins: + description: + List of gpio pins affected by the properties specified in + this subnode. Valid pins are + - gpio1-gpio10 for pm6150 + - gpio1-gpio12 for pm6150l + - gpio1-gpio10 for pm7325 + - gpio1-gpio4 for pm8005 + - gpio1-gpio2 for pm8008 + - gpio1-gpio6 for pm8018 + - gpio1-gpio12 for pm8038 + - gpio1-gpio40 for pm8058 + - gpio1-gpio10 for pm8150 (holes on gpio2, gpio5, + gpio7 and gpio8) + - gpio1-gpio12 for pm8150b (holes on gpio3, gpio4 + and gpio7) + - gpio1-gpio12 for pm8150l (hole on gpio7) + - gpio1-gpio4 for pm8916 + - gpio1-gpio10 for pm8350 + - gpio1-gpio8 for pm8350b + - gpio1-gpio9 for pm8350c + - gpio1-gpio38 for pm8917 + - gpio1-gpio44 for pm8921 + - gpio1-gpio36 for pm8941 + - gpio1-gpio8 for pm8950 (hole on gpio3) + - gpio1-gpio22 for pm8994 + - gpio1-gpio26 for pm8998 + - gpio1-gpio22 for pma8084 + - gpio1-gpio2 for pmi8950 + - gpio1-gpio10 for pmi8994 + - gpio1-gpio4 for pmk8350 + - gpio1-gpio4 for pmr735a + - gpio1-gpio4 for pmr735b + - gpio1-gpio12 for pms405 (holes on gpio1, gpio9 + and gpio10) + - gpio1-gpio11 for pmx55 (holes on gpio3, gpio7, gpio10 + and gpio11) + + items: + pattern: "^gpio([0-9]+)$" + + function: + items: + - enum: + - normal + - paired + - func1 + - func2 + - dtest1 + - dtest2 + - dtest3 + - dtest4 + - func3 # supported by LV/MV GPIO subtypes + - func4 # supported by LV/MV GPIO subtypes + + bias-disable: true + bias-pull-down: true + bias-pull-up: true + + qcom,pull-up-strength: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Specifies the strength to use for pull up, if selected. + Valid values are defined in + + If this property is omitted 30uA strength will be used + if pull up is selected + enum: [0, 1, 2, 3] + + bias-high-impedance: true + input-enable: true + output-high: true + output-low: true + power-source: true + + qcom,drive-strength: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Selects the drive strength for the specified pins + Valid drive strength values are defined in + + enum: [0, 1, 2, 3] + + drive-push-pull: true + drive-open-drain: true + drive-open-source: true + + qcom,analog-pass: + $ref: /schemas/types.yaml#/definitions/flag + description: + The specified pins are configured in + analog-pass-through mode. + + qcom,atest: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Selects ATEST rail to route to GPIO when it's + configured in analog-pass-through mode. + enum: [1, 2, 3, 4] + + qcom,dtest-buffer: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Selects DTEST rail to route to GPIO when it's + configured as digital input. + enum: [1, 2, 3, 4] + + required: + - pins + - function + + additionalProperties: false + +examples: + - | + #include + + pm8921_gpio: gpio@150 { + compatible = "qcom,pm8921-gpio", "qcom,ssbi-gpio"; + reg = <0x150 0x160>; + interrupts = <192 1>, <193 1>, <194 1>, + <195 1>, <196 1>, <197 1>, + <198 1>, <199 1>, <200 1>, + <201 1>, <202 1>, <203 1>, + <204 1>, <205 1>, <206 1>, + <207 1>, <208 1>, <209 1>, + <210 1>, <211 1>, <212 1>, + <213 1>, <214 1>, <215 1>, + <216 1>, <217 1>, <218 1>, + <219 1>, <220 1>, <221 1>, + <222 1>, <223 1>, <224 1>, + <225 1>, <226 1>, <227 1>, + <228 1>, <229 1>, <230 1>, + <231 1>, <232 1>, <233 1>, + <234 1>, <235 1>; + + gpio-controller; + gpio-ranges = <&pm8921_gpio 0 0 44>; + #gpio-cells = <2>; + + pm8921_gpio_keys: gpio-keys-state { + volume-keys { + pins = "gpio20", "gpio21"; + function = "normal"; + + input-enable; + bias-pull-up; + drive-push-pull; + qcom,drive-strength = ; + power-source = ; + }; + }; + }; +... -- cgit v1.2.3-70-g09d2 From f03f5c75f5dddda2a615a9640f4385138e0ba43b Mon Sep 17 00:00:00 2001 From: satya priya Date: Mon, 2 Aug 2021 18:51:04 +0530 Subject: dt-bindings: pinctrl: qcom-pmic-gpio: Remove the interrupts property Remove the interrupts property as we no longer specify it. Signed-off-by: satya priya Acked-by: Rob Herring Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/1627910464-19363-4-git-send-email-skakit@codeaurora.org Signed-off-by: Linus Walleij --- .../bindings/pinctrl/qcom,pmic-gpio.yaml | 28 ++++------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml index 7a0d2d8e1c86..9bd01db37dcd 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.yaml @@ -56,18 +56,11 @@ properties: reg: maxItems: 1 - interrupts: - minItems: 1 - maxItems: 44 - description: - Must contain an array of encoded interrupt specifiers for - each available GPIO + interrupt-controller: true '#interrupt-cells': const: 2 - interrupt-controller: true - gpio-controller: true gpio-ranges: @@ -87,6 +80,7 @@ required: - gpio-controller - '#gpio-cells' - gpio-ranges + - interrupt-controller patternProperties: '-state$': @@ -223,22 +217,8 @@ examples: pm8921_gpio: gpio@150 { compatible = "qcom,pm8921-gpio", "qcom,ssbi-gpio"; reg = <0x150 0x160>; - interrupts = <192 1>, <193 1>, <194 1>, - <195 1>, <196 1>, <197 1>, - <198 1>, <199 1>, <200 1>, - <201 1>, <202 1>, <203 1>, - <204 1>, <205 1>, <206 1>, - <207 1>, <208 1>, <209 1>, - <210 1>, <211 1>, <212 1>, - <213 1>, <214 1>, <215 1>, - <216 1>, <217 1>, <218 1>, - <219 1>, <220 1>, <221 1>, - <222 1>, <223 1>, <224 1>, - <225 1>, <226 1>, <227 1>, - <228 1>, <229 1>, <230 1>, - <231 1>, <232 1>, <233 1>, - <234 1>, <235 1>; - + interrupt-controller; + #interrupt-cells = <2>; gpio-controller; gpio-ranges = <&pm8921_gpio 0 0 44>; #gpio-cells = <2>; -- cgit v1.2.3-70-g09d2 From 988db17932a78d201e826af3df7e89494ee0c037 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:31 +0300 Subject: perf script: Fix documented const'ness of perf_dlfilter_fns perf_dlfilter_fns must not be const, because it is not. Declaring it const can result in it being mapped read-only, causing a segfaullt when it is written. Update documentation accordingly. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Fixes: 8defa7147d5572 ("perf script Add API for filtering via dynamically loaded shared object") Link: https //lore.kernel.org/r/20210811101036.17986-2-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-dlfilter.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-dlfilter.txt b/tools/perf/Documentation/perf-dlfilter.txt index 02842cb4cf90..ece07509d1f7 100644 --- a/tools/perf/Documentation/perf-dlfilter.txt +++ b/tools/perf/Documentation/perf-dlfilter.txt @@ -32,7 +32,7 @@ The API for filtering consists of the following: ---- #include -const struct perf_dlfilter_fns perf_dlfilter_fns; +struct perf_dlfilter_fns perf_dlfilter_fns; int start(void **data, void *ctx); int stop(void *data, void *ctx); @@ -214,7 +214,7 @@ Filter out everything except branches from "foo" to "bar": #include #include -const struct perf_dlfilter_fns perf_dlfilter_fns; +struct perf_dlfilter_fns perf_dlfilter_fns; int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx) { -- cgit v1.2.3-70-g09d2 From 29159727aa7ed3341dc560e9983e7284f4279ade Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:32 +0300 Subject: perf script: Fix unnecessary machine_resolve() machine_resolve() may have already been called. Test for that to avoid calling it again unnecessarily. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Link: https //lore.kernel.org/r/20210811101036.17986-3-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e2e165b53499..f469354155f1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2212,7 +2212,7 @@ static int process_sample_event(struct perf_tool *tool, if (filter_cpu(sample)) goto out_put; - if (machine__resolve(machine, &al, sample) < 0) { + if (!al.thread && machine__resolve(machine, &al, sample) < 0) { pr_err("problem processing %d event, skipping it.\n", event->header.type); ret = -1; -- cgit v1.2.3-70-g09d2 From 3e8e226307c19bbab679678b44645e542afa7db8 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:33 +0300 Subject: perf script: Fix --list-dlfilters documentation The option --list-dlfilters does use a string value. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Fixes: 638e2b9984ee1b ("perf script Add option to list dlfilters") Link: https //lore.kernel.org/r/20210811101036.17986-4-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-script.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index aa3a0b2c29a2..c80515243560 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -106,7 +106,7 @@ OPTIONS Pass 'arg' as an argument to the dlfilter. --dlarg may be repeated to add more arguments. ---list-dlfilters=:: +--list-dlfilters:: Display a list of available dlfilters. Use with option -v (must come before option --list-dlfilters) to show long descriptions. -- cgit v1.2.3-70-g09d2 From b29edf35ef7022a6f72695106a6e91f67d00c9e9 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:34 +0300 Subject: perf dlfilter: Amend documentation wrt library dependencies Like all locally-built programs, dlfilters may need to be re-built if shared libraries they use change. Also there may be unexpected results if the dfilter uses different versions of the shared libraries that perf uses. Note those things in the documentation. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Link: https //lore.kernel.org/r/20210811101036.17986-5-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-dlfilter.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/Documentation/perf-dlfilter.txt b/tools/perf/Documentation/perf-dlfilter.txt index ece07509d1f7..594f5a5a0c9e 100644 --- a/tools/perf/Documentation/perf-dlfilter.txt +++ b/tools/perf/Documentation/perf-dlfilter.txt @@ -246,6 +246,14 @@ To use the filter with perf script: perf script --dlfilter dlfilter-example.so +NOTES +----- + +The dlfilter .so file will be dependent on shared libraries. If those change, +it may be necessary to rebuild the .so. Also there may be unexpected results +if the .so uses different versions of the shared libraries that perf uses. +Versions can be checked using the ldd command. + SEE ALSO -------- linkperf:perf-script[1] -- cgit v1.2.3-70-g09d2 From 3af1dfdd51e0669721510dadd6c1d3ebe78e5868 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:35 +0300 Subject: perf build: Move perf_dlfilters.h in the source tree Move perf_dlfilters.h in the source tree so that it will be found when building dlfilters as part of the perf build. Signed-off-by: Adrian Hunter Cc: Jiri Olsa Link: https //lore.kernel.org/r/20210811101036.17986-6-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 2 +- tools/perf/include/perf/perf_dlfilter.h | 150 ++++++++++++++++++++++++++++++++ tools/perf/util/dlfilter.c | 2 +- tools/perf/util/perf_dlfilter.h | 150 -------------------------------- 4 files changed, 152 insertions(+), 152 deletions(-) create mode 100644 tools/perf/include/perf/perf_dlfilter.h delete mode 100644 tools/perf/util/perf_dlfilter.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 77e7f18c0bd0..6dafde69d5e3 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -925,7 +925,7 @@ install-tools: all install-gtk $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \ $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(includedir_SQ)/perf'; \ - $(INSTALL) util/perf_dlfilter.h -t '$(DESTDIR_SQ)$(includedir_SQ)/perf' + $(INSTALL) -m 644 include/perf/perf_dlfilter.h -t '$(DESTDIR_SQ)$(includedir_SQ)/perf' ifndef NO_PERF_READ_VDSO32 $(call QUIET_INSTALL, perf-read-vdso32) \ $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(bindir_SQ)'; diff --git a/tools/perf/include/perf/perf_dlfilter.h b/tools/perf/include/perf/perf_dlfilter.h new file mode 100644 index 000000000000..3eef03d661b4 --- /dev/null +++ b/tools/perf/include/perf/perf_dlfilter.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * perf_dlfilter.h: API for perf --dlfilter shared object + * Copyright (c) 2021, Intel Corporation. + */ +#ifndef _LINUX_PERF_DLFILTER_H +#define _LINUX_PERF_DLFILTER_H + +#include +#include + +/* Definitions for perf_dlfilter_sample flags */ +enum { + PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, + PERF_DLFILTER_FLAG_CALL = 1ULL << 1, + PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, + PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, + PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, + PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, + PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, + PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, + PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, + PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, + PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, + PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, + PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, +}; + +/* + * perf sample event information (as per perf script and ) + */ +struct perf_dlfilter_sample { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u64 ip; + __s32 pid; + __s32 tid; + __u64 time; + __u64 addr; + __u64 id; + __u64 stream_id; + __u64 period; + __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in */ + __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ + __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ + __s32 cpu; + __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ + __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in */ + __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in */ + __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in */ + __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in */ + __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in */ + __u8 cpumode; /* Refer CPUMODE_MASK etc in */ + __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ + __u16 misc; /* Refer perf_event_header in */ + __u32 raw_size; /* Refer PERF_SAMPLE_RAW in */ + const void *raw_data; /* Refer PERF_SAMPLE_RAW in */ + __u64 brstack_nr; /* Number of brstack entries */ + const struct perf_branch_entry *brstack; /* Refer */ + __u64 raw_callchain_nr; /* Number of raw_callchain entries */ + const __u64 *raw_callchain; /* Refer */ + const char *event; +}; + +/* + * Address location (as per perf script) + */ +struct perf_dlfilter_al { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u32 symoff; + const char *sym; + __u64 addr; /* Mapped address (from dso) */ + __u64 sym_start; + __u64 sym_end; + const char *dso; + __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer */ + __u8 is_64_bit; /* Only valid if dso is not NULL */ + __u8 is_kernel_ip; /* True if in kernel space */ + __u32 buildid_size; + __u8 *buildid; + /* Below members are only populated by resolve_ip() */ + __u8 filtered; /* True if this sample event will be filtered out */ + const char *comm; +}; + +struct perf_dlfilter_fns { + /* Return information about ip */ + const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); + /* Return information about addr (if addr_correlates_sym) */ + const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); + /* Return arguments from --dlarg option */ + char **(*args)(void *ctx, int *dlargc); + /* + * Return information about address (al->size must be set before + * calling). Returns 0 on success, -1 otherwise. + */ + __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); + /* Return instruction bytes and length */ + const __u8 *(*insn)(void *ctx, __u32 *length); + /* Return source file name and line number */ + const char *(*srcline)(void *ctx, __u32 *line_number); + /* Return perf_event_attr, refer */ + struct perf_event_attr *(*attr)(void *ctx); + /* Read object code, return numbers of bytes read */ + __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); + /* Reserved */ + void *(*reserved[120])(void *); +}; + +/* + * If implemented, 'start' will be called at the beginning, + * before any calls to 'filter_event'. Return 0 to indicate success, + * or return a negative error code. '*data' can be assigned for use + * by other functions. 'ctx' is needed for calls to perf_dlfilter_fns, + * but most perf_dlfilter_fns are not valid when called from 'start'. + */ +int start(void **data, void *ctx); + +/* + * If implemented, 'stop' will be called at the end, + * after any calls to 'filter_event'. Return 0 to indicate success, or + * return a negative error code. 'data' is set by start(). 'ctx' is + * needed for calls to perf_dlfilter_fns, but most perf_dlfilter_fns + * are not valid when called from 'stop'. + */ +int stop(void *data, void *ctx); + +/* + * If implemented, 'filter_event' will be called for each sample + * event. Return 0 to keep the sample event, 1 to filter it out, or + * return a negative error code. 'data' is set by start(). 'ctx' is + * needed for calls to perf_dlfilter_fns. + */ +int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx); + +/* + * The same as 'filter_event' except it is called before internal + * filtering. + */ +int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx); + +/* + * If implemented, return a one-line description of the filter, and optionally + * a longer description. + */ +const char *filter_description(const char **long_description); + +#endif diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index ca33fbc5efde..7d11ce76157c 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -21,7 +21,7 @@ #include "symbol.h" #include "srcline.h" #include "dlfilter.h" -#include "perf_dlfilter.h" +#include "../include/perf/perf_dlfilter.h" static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al) { diff --git a/tools/perf/util/perf_dlfilter.h b/tools/perf/util/perf_dlfilter.h deleted file mode 100644 index 3eef03d661b4..000000000000 --- a/tools/perf/util/perf_dlfilter.h +++ /dev/null @@ -1,150 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * perf_dlfilter.h: API for perf --dlfilter shared object - * Copyright (c) 2021, Intel Corporation. - */ -#ifndef _LINUX_PERF_DLFILTER_H -#define _LINUX_PERF_DLFILTER_H - -#include -#include - -/* Definitions for perf_dlfilter_sample flags */ -enum { - PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, - PERF_DLFILTER_FLAG_CALL = 1ULL << 1, - PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, - PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, - PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, - PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, - PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, - PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, - PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, - PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, - PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, - PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, - PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, -}; - -/* - * perf sample event information (as per perf script and ) - */ -struct perf_dlfilter_sample { - __u32 size; /* Size of this structure (for compatibility checking) */ - __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ - __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ - __u64 ip; - __s32 pid; - __s32 tid; - __u64 time; - __u64 addr; - __u64 id; - __u64 stream_id; - __u64 period; - __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ - __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in */ - __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ - __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ - __s32 cpu; - __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ - __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in */ - __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in */ - __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in */ - __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in */ - __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in */ - __u8 cpumode; /* Refer CPUMODE_MASK etc in */ - __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ - __u16 misc; /* Refer perf_event_header in */ - __u32 raw_size; /* Refer PERF_SAMPLE_RAW in */ - const void *raw_data; /* Refer PERF_SAMPLE_RAW in */ - __u64 brstack_nr; /* Number of brstack entries */ - const struct perf_branch_entry *brstack; /* Refer */ - __u64 raw_callchain_nr; /* Number of raw_callchain entries */ - const __u64 *raw_callchain; /* Refer */ - const char *event; -}; - -/* - * Address location (as per perf script) - */ -struct perf_dlfilter_al { - __u32 size; /* Size of this structure (for compatibility checking) */ - __u32 symoff; - const char *sym; - __u64 addr; /* Mapped address (from dso) */ - __u64 sym_start; - __u64 sym_end; - const char *dso; - __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer */ - __u8 is_64_bit; /* Only valid if dso is not NULL */ - __u8 is_kernel_ip; /* True if in kernel space */ - __u32 buildid_size; - __u8 *buildid; - /* Below members are only populated by resolve_ip() */ - __u8 filtered; /* True if this sample event will be filtered out */ - const char *comm; -}; - -struct perf_dlfilter_fns { - /* Return information about ip */ - const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); - /* Return information about addr (if addr_correlates_sym) */ - const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); - /* Return arguments from --dlarg option */ - char **(*args)(void *ctx, int *dlargc); - /* - * Return information about address (al->size must be set before - * calling). Returns 0 on success, -1 otherwise. - */ - __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); - /* Return instruction bytes and length */ - const __u8 *(*insn)(void *ctx, __u32 *length); - /* Return source file name and line number */ - const char *(*srcline)(void *ctx, __u32 *line_number); - /* Return perf_event_attr, refer */ - struct perf_event_attr *(*attr)(void *ctx); - /* Read object code, return numbers of bytes read */ - __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); - /* Reserved */ - void *(*reserved[120])(void *); -}; - -/* - * If implemented, 'start' will be called at the beginning, - * before any calls to 'filter_event'. Return 0 to indicate success, - * or return a negative error code. '*data' can be assigned for use - * by other functions. 'ctx' is needed for calls to perf_dlfilter_fns, - * but most perf_dlfilter_fns are not valid when called from 'start'. - */ -int start(void **data, void *ctx); - -/* - * If implemented, 'stop' will be called at the end, - * after any calls to 'filter_event'. Return 0 to indicate success, or - * return a negative error code. 'data' is set by start(). 'ctx' is - * needed for calls to perf_dlfilter_fns, but most perf_dlfilter_fns - * are not valid when called from 'stop'. - */ -int stop(void *data, void *ctx); - -/* - * If implemented, 'filter_event' will be called for each sample - * event. Return 0 to keep the sample event, 1 to filter it out, or - * return a negative error code. 'data' is set by start(). 'ctx' is - * needed for calls to perf_dlfilter_fns. - */ -int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx); - -/* - * The same as 'filter_event' except it is called before internal - * filtering. - */ -int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx); - -/* - * If implemented, return a one-line description of the filter, and optionally - * a longer description. - */ -const char *filter_description(const char **long_description); - -#endif -- cgit v1.2.3-70-g09d2 From 9f9c9a8de2d5e96c045deaf769006ef7b7b7fb1b Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2021 13:10:36 +0300 Subject: perf tests: Add dlfilter test Add a perf test to test the dlfilter C API. A perf.data file is synthesized and then processed by perf script with a dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to provide a dso to match the synthesized perf.data file. Committer testing: [root@five ~]# perf test dlfilter 72: dlfilter C API : Ok [root@five ~]# perf test -v dlfilter 72: dlfilter C API : --- start --- test child forked, pid 3387712 Checking for gcc Command: gcc --version gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dlfilters path: /var/home/acme/libexec/perf-core/dlfilters Command: gcc -g -o /tmp/dlfilter-test-3387712-prog /tmp/dlfilter-test-3387712-prog.c Creating new host machine structure Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3387712-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last start API filter_event_early API filter_event API stop API Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3387712-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 1 --dlarg last start API filter_event_early API filter_event API stop API Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3387712-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 2 --dlarg last start API filter_event_early API stop API test child finished with 0 ---- end ---- dlfilter C API: Ok [root@five ~]# Signed-off-by: Adrian Hunter Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Link: https //lore.kernel.org/r/20210811101036.17986-7-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 15 +- tools/perf/dlfilters/dlfilter-test-api-v0.c | 336 +++++++++++++++++++++++ tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/dlfilter-test.c | 411 ++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/dlfilter.c | 4 +- tools/perf/util/dlfilter.h | 2 + 8 files changed, 771 insertions(+), 3 deletions(-) create mode 100644 tools/perf/dlfilters/dlfilter-test-api-v0.c create mode 100644 tools/perf/tests/dlfilter-test.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6dafde69d5e3..24623599113d 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -360,8 +360,11 @@ ifndef NO_JVMTI PROGRAMS += $(OUTPUT)$(LIBJVMTI) endif +DLFILTERS := dlfilter-test-api-v0.so +DLFILTERS := $(patsubst %,$(OUTPUT)dlfilters/%,$(DLFILTERS)) + # what 'all' will build and 'install' will install, in perfexecdir -ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) +ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) $(DLFILTERS) # what 'all' will build but not install in perfexecdir OTHER_PROGRAMS = $(OUTPUT)perf @@ -780,6 +783,13 @@ $(OUTPUT)perf-read-vdsox32: perf-read-vdso.c util/find-map.c $(QUIET_CC)$(CC) -mx32 $(filter -static,$(LDFLAGS)) -Wall -Werror -o $@ perf-read-vdso.c endif +$(OUTPUT)dlfilters/%.o: dlfilters/%.c include/perf/perf_dlfilter.h + $(Q)$(MKDIR) -p $(OUTPUT)dlfilters + $(QUIET_CC)$(CC) -c -Iinclude -o $@ -fpic $< + +$(OUTPUT)dlfilters/%.so: $(OUTPUT)dlfilters/%.o + $(QUIET_LINK)$(CC) -shared -o $@ $< + ifndef NO_JVMTI LIBJVMTI_IN := $(OUTPUT)jvmti/jvmti-in.o @@ -978,6 +988,9 @@ ifndef NO_LIBPYTHON $(INSTALL) scripts/python/*.py -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \ $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' endif + $(call QUIET_INSTALL, dlfilters) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters'; \ + $(INSTALL) $(DLFILTERS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters'; $(call QUIET_INSTALL, perf_completion-script) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \ $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' diff --git a/tools/perf/dlfilters/dlfilter-test-api-v0.c b/tools/perf/dlfilters/dlfilter-test-api-v0.c new file mode 100644 index 000000000000..7565a1852c74 --- /dev/null +++ b/tools/perf/dlfilters/dlfilter-test-api-v0.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dlfilter-test-api-v0.c: test original (v0) API for perf --dlfilter shared object + * Copyright (c) 2021, Intel Corporation. + */ +#include +#include +#include +#include + +/* + * Copy original (v0) API instead of including current API + */ +#include +#include + +/* Definitions for perf_dlfilter_sample flags */ +enum { + PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, + PERF_DLFILTER_FLAG_CALL = 1ULL << 1, + PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, + PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, + PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, + PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, + PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, + PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, + PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, + PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, + PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, + PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, + PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, +}; + +/* + * perf sample event information (as per perf script and ) + */ +struct perf_dlfilter_sample { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u64 ip; + __s32 pid; + __s32 tid; + __u64 time; + __u64 addr; + __u64 id; + __u64 stream_id; + __u64 period; + __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in */ + __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in */ + __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ + __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ + __s32 cpu; + __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ + __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in */ + __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in */ + __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in */ + __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in */ + __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in */ + __u8 cpumode; /* Refer CPUMODE_MASK etc in */ + __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ + __u16 misc; /* Refer perf_event_header in */ + __u32 raw_size; /* Refer PERF_SAMPLE_RAW in */ + const void *raw_data; /* Refer PERF_SAMPLE_RAW in */ + __u64 brstack_nr; /* Number of brstack entries */ + const struct perf_branch_entry *brstack; /* Refer */ + __u64 raw_callchain_nr; /* Number of raw_callchain entries */ + const __u64 *raw_callchain; /* Refer */ + const char *event; +}; + +/* + * Address location (as per perf script) + */ +struct perf_dlfilter_al { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u32 symoff; + const char *sym; + __u64 addr; /* Mapped address (from dso) */ + __u64 sym_start; + __u64 sym_end; + const char *dso; + __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer */ + __u8 is_64_bit; /* Only valid if dso is not NULL */ + __u8 is_kernel_ip; /* True if in kernel space */ + __u32 buildid_size; + __u8 *buildid; + /* Below members are only populated by resolve_ip() */ + __u8 filtered; /* True if this sample event will be filtered out */ + const char *comm; +}; + +struct perf_dlfilter_fns { + /* Return information about ip */ + const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); + /* Return information about addr (if addr_correlates_sym) */ + const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); + /* Return arguments from --dlarg option */ + char **(*args)(void *ctx, int *dlargc); + /* + * Return information about address (al->size must be set before + * calling). Returns 0 on success, -1 otherwise. + */ + __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); + /* Return instruction bytes and length */ + const __u8 *(*insn)(void *ctx, __u32 *length); + /* Return source file name and line number */ + const char *(*srcline)(void *ctx, __u32 *line_number); + /* Return perf_event_attr, refer */ + struct perf_event_attr *(*attr)(void *ctx); + /* Read object code, return numbers of bytes read */ + __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); + /* Reserved */ + void *(*reserved[120])(void *); +}; + +struct perf_dlfilter_fns perf_dlfilter_fns; + +static int verbose; + +#define pr_debug(fmt, ...) do { \ + if (verbose) \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + } while (0) + +static int test_fail(const char *msg) +{ + pr_debug("%s\n", msg); + return -1; +} + +#define CHECK(x) do { \ + if (!(x)) \ + return test_fail("Check '" #x "' failed\n"); \ + } while (0) + +struct filter_data { + __u64 ip; + __u64 addr; + int do_early; + int early_filter_cnt; + int filter_cnt; +}; + +static struct filter_data *filt_dat; + +int start(void **data, void *ctx) +{ + int dlargc; + char **dlargv; + struct filter_data *d; + static bool called; + + verbose = 1; + + CHECK(!filt_dat && !called); + called = true; + + d = calloc(1, sizeof(*d)); + if (!d) + test_fail("Failed to allocate memory"); + filt_dat = d; + *data = d; + + dlargv = perf_dlfilter_fns.args(ctx, &dlargc); + + CHECK(dlargc == 6); + CHECK(!strcmp(dlargv[0], "first")); + verbose = strtol(dlargv[1], NULL, 0); + d->ip = strtoull(dlargv[2], NULL, 0); + d->addr = strtoull(dlargv[3], NULL, 0); + d->do_early = strtol(dlargv[4], NULL, 0); + CHECK(!strcmp(dlargv[5], "last")); + + pr_debug("%s API\n", __func__); + + return 0; +} + +#define CHECK_SAMPLE(x) do { \ + if (sample->x != expected.x) \ + return test_fail("'" #x "' not expected value\n"); \ + } while (0) + +static int check_sample(struct filter_data *d, const struct perf_dlfilter_sample *sample) +{ + struct perf_dlfilter_sample expected = { + .ip = d->ip, + .pid = 12345, + .tid = 12346, + .time = 1234567890, + .addr = d->addr, + .id = 99, + .stream_id = 101, + .period = 543212345, + .cpu = 31, + .cpumode = PERF_RECORD_MISC_USER, + .addr_correlates_sym = 1, + .misc = PERF_RECORD_MISC_USER, + }; + + CHECK(sample->size >= sizeof(struct perf_dlfilter_sample)); + + CHECK_SAMPLE(ip); + CHECK_SAMPLE(pid); + CHECK_SAMPLE(tid); + CHECK_SAMPLE(time); + CHECK_SAMPLE(addr); + CHECK_SAMPLE(id); + CHECK_SAMPLE(stream_id); + CHECK_SAMPLE(period); + CHECK_SAMPLE(cpu); + CHECK_SAMPLE(cpumode); + CHECK_SAMPLE(addr_correlates_sym); + CHECK_SAMPLE(misc); + + CHECK(!sample->raw_data); + CHECK_SAMPLE(brstack_nr); + CHECK(!sample->brstack); + CHECK_SAMPLE(raw_callchain_nr); + CHECK(!sample->raw_callchain); + +#define EVENT_NAME "branches:" + CHECK(!strncmp(sample->event, EVENT_NAME, strlen(EVENT_NAME))); + + return 0; +} + +static int check_al(void *ctx) +{ + const struct perf_dlfilter_al *al; + + al = perf_dlfilter_fns.resolve_ip(ctx); + if (!al) + return test_fail("resolve_ip() failed"); + + CHECK(al->sym && !strcmp("foo", al->sym)); + CHECK(!al->symoff); + + return 0; +} + +static int check_addr_al(void *ctx) +{ + const struct perf_dlfilter_al *addr_al; + + addr_al = perf_dlfilter_fns.resolve_addr(ctx); + if (!addr_al) + return test_fail("resolve_addr() failed"); + + CHECK(addr_al->sym && !strcmp("bar", addr_al->sym)); + CHECK(!addr_al->symoff); + + return 0; +} + +static int check_attr(void *ctx) +{ + struct perf_event_attr *attr = perf_dlfilter_fns.attr(ctx); + + CHECK(attr); + CHECK(attr->type == PERF_TYPE_HARDWARE); + CHECK(attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS); + + return 0; +} + +static int do_checks(void *data, const struct perf_dlfilter_sample *sample, void *ctx, bool early) +{ + struct filter_data *d = data; + + CHECK(data && filt_dat == data); + + if (early) { + CHECK(!d->early_filter_cnt); + d->early_filter_cnt += 1; + } else { + CHECK(!d->filter_cnt); + CHECK(d->early_filter_cnt); + CHECK(d->do_early != 2); + d->filter_cnt += 1; + } + + if (check_sample(data, sample)) + return -1; + + if (check_attr(ctx)) + return -1; + + if (early && !d->do_early) + return 0; + + if (check_al(ctx) || check_addr_al(ctx)) + return -1; + + if (early) + return d->do_early == 2; + + return 1; +} + +int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx) +{ + pr_debug("%s API\n", __func__); + + return do_checks(data, sample, ctx, true); +} + +int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx) +{ + struct filter_data *d = data; + + pr_debug("%s API\n", __func__); + + return do_checks(data, sample, ctx, false); +} + +int stop(void *data, void *ctx) +{ + static bool called; + + pr_debug("%s API\n", __func__); + + CHECK(data && filt_dat == data && !called); + called = true; + + free(data); + filt_dat = NULL; + return 0; +} + +const char *filter_description(const char **long_description) +{ + *long_description = "Filter used by the 'dlfilter C API' perf test"; + return "dlfilter to test v0 C API"; +} diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 650aec19d490..803ca426f8e6 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -64,6 +64,7 @@ perf-y += parse-metric.o perf-y += pe-file-parsing.o perf-y += expand-cgroup.o perf-y += perf-time-to-tsc.o +perf-y += dlfilter-test.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 5e6242576236..fb5846db02e1 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -360,6 +360,10 @@ static struct test generic_tests[] = { .func = test__perf_time_to_tsc, .is_supported = test__tsc_is_supported, }, + { + .desc = "dlfilter C API", + .func = test__dlfilter, + }, { .func = NULL, }, diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c new file mode 100644 index 000000000000..7eba7955d531 --- /dev/null +++ b/tools/perf/tests/dlfilter-test.c @@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test dlfilter C API. A perf.data file is synthesized and then processed + * by perf script with a dlfilter named dlfilter-test-api-v0.so. Also a C file + * is compiled to provide a dso to match the synthesized perf.data file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" +#include "tool.h" +#include "event.h" +#include "header.h" +#include "machine.h" +#include "dso.h" +#include "map.h" +#include "symbol.h" +#include "synthetic-events.h" +#include "util.h" +#include "archinsn.h" +#include "dlfilter.h" +#include "tests.h" + +#define MAP_START 0x400000 + +struct test_data { + struct perf_tool tool; + struct machine *machine; + int fd; + u64 foo; + u64 bar; + u64 ip; + u64 addr; + char perf[PATH_MAX]; + char perf_data_file_name[PATH_MAX]; + char c_file_name[PATH_MAX]; + char prog_file_name[PATH_MAX]; + char dlfilters[PATH_MAX]; +}; + +static int test_result(const char *msg, int ret) +{ + pr_debug("%s\n", msg); + return ret; +} + +static int process(struct perf_tool *tool, union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct test_data *td = container_of(tool, struct test_data, tool); + int fd = td->fd; + + if (writen(fd, event, event->header.size) != event->header.size) + return -1; + + return 0; +} + +#define MAXCMD 4096 +#define REDIRECT_TO_DEV_NULL " >/dev/null 2>&1" + +static __printf(1, 2) int system_cmd(const char *fmt, ...) +{ + char cmd[MAXCMD + sizeof(REDIRECT_TO_DEV_NULL)]; + int ret; + + va_list args; + + va_start(args, fmt); + ret = vsnprintf(cmd, MAXCMD, fmt, args); + va_end(args); + + if (ret <= 0 || ret >= MAXCMD) + return -1; + + if (!verbose) + strcat(cmd, REDIRECT_TO_DEV_NULL); + + pr_debug("Command: %s\n", cmd); + ret = system(cmd); + if (ret) + pr_debug("Failed with return value %d\n", ret); + + return ret; +} + +static bool have_gcc(void) +{ + pr_debug("Checking for gcc\n"); + return !system_cmd("gcc --version"); +} + +static int write_attr(struct test_data *td, u64 sample_type, u64 *id) +{ + struct perf_event_attr attr = { + .size = sizeof(attr), + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + .sample_type = sample_type, + .sample_period = 1, + }; + + return perf_event__synthesize_attr(&td->tool, &attr, 1, id, process); +} + +static int write_comm(int fd, pid_t pid, pid_t tid, const char *comm_str) +{ + struct perf_record_comm comm; + ssize_t sz = sizeof(comm); + + comm.header.type = PERF_RECORD_COMM; + comm.header.misc = PERF_RECORD_MISC_USER; + comm.header.size = sz; + + comm.pid = pid; + comm.tid = tid; + strncpy(comm.comm, comm_str, 16); + + if (writen(fd, &comm, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_mmap(int fd, pid_t pid, pid_t tid, u64 start, u64 len, u64 pgoff, + const char *filename) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + struct perf_record_mmap *mmap = (struct perf_record_mmap *)buf; + size_t fsz = roundup(strlen(filename) + 1, 8); + ssize_t sz = sizeof(*mmap) - sizeof(mmap->filename) + fsz; + + mmap->header.type = PERF_RECORD_MMAP; + mmap->header.misc = PERF_RECORD_MISC_USER; + mmap->header.size = sz; + + mmap->pid = pid; + mmap->tid = tid; + mmap->start = start; + mmap->len = len; + mmap->pgoff = pgoff; + strncpy(mmap->filename, filename, sizeof(mmap->filename)); + + if (writen(fd, mmap, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid, pid_t tid) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + union perf_event *event = (union perf_event *)buf; + struct perf_sample sample = { + .ip = td->ip, + .addr = td->addr, + .id = id, + .time = 1234567890, + .cpu = 31, + .pid = pid, + .tid = tid, + .period = 543212345, + .stream_id = 101, + }; + int err; + + event->header.type = PERF_RECORD_SAMPLE; + event->header.misc = PERF_RECORD_MISC_USER; + event->header.size = perf_event__sample_event_size(&sample, sample_type, 0); + err = perf_event__synthesize_sample(event, sample_type, 0, &sample); + if (err) + return test_result("perf_event__synthesize_sample() failed", TEST_FAIL); + + err = process(&td->tool, event, &sample, td->machine); + if (err) + return test_result("Failed to write sample", TEST_FAIL); + + return TEST_OK; +} + +static void close_fd(int fd) +{ + if (fd >= 0) + close(fd); +} + +static const char *prog = "int bar(){};int foo(){bar();};int main(){foo();return 0;}"; + +static int write_prog(char *file_name) +{ + int fd = creat(file_name, 0644); + ssize_t n = strlen(prog); + bool err = fd < 0 || writen(fd, prog, n) != n; + + close_fd(fd); + return err ? -1 : 0; +} + +static int get_dlfilters_path(char *buf, size_t sz) +{ + char perf[PATH_MAX]; + char path[PATH_MAX]; + char *perf_path; + char *exec_path; + + perf_exe(perf, sizeof(perf)); + perf_path = dirname(perf); + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", perf_path); + if (access(path, R_OK)) { + exec_path = get_argv_exec_path(); + if (!exec_path) + return -1; + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", exec_path); + free(exec_path); + if (access(path, R_OK)) + return -1; + } + strlcpy(buf, dirname(path), sz); + return 0; +} + +static int check_filter_desc(struct test_data *td) +{ + char *long_desc; + char *desc; + + if (get_filter_desc(td->dlfilters, "dlfilter-test-api-v0.so", &desc, &long_desc) && + long_desc && !strcmp(long_desc, "Filter used by the 'dlfilter C API' perf test") && + desc && !strcmp(desc, "dlfilter to test v0 C API")) + return 0; + + return -1; +} + +static int get_ip_addr(struct test_data *td) +{ + struct map *map; + struct symbol *sym; + + map = dso__new_map(td->prog_file_name); + if (!map) + return -1; + + sym = map__find_symbol_by_name(map, "foo"); + if (sym) + td->foo = sym->start; + + sym = map__find_symbol_by_name(map, "bar"); + if (sym) + td->bar = sym->start; + + map__put(map); + + td->ip = MAP_START + td->foo; + td->addr = MAP_START + td->bar; + + return td->foo && td->bar ? 0 : -1; +} + +static int do_run_perf_script(struct test_data *td, int do_early) +{ + return system_cmd("%s script -i %s " + "--dlfilter %s/dlfilter-test-api-v0.so " + "--dlarg first " + "--dlarg %d " + "--dlarg %" PRIu64 " " + "--dlarg %" PRIu64 " " + "--dlarg %d " + "--dlarg last", + td->perf, td->perf_data_file_name, td->dlfilters, + verbose, td->ip, td->addr, do_early); +} + +static int run_perf_script(struct test_data *td) +{ + int do_early; + int err; + + for (do_early = 0; do_early < 3; do_early++) { + err = do_run_perf_script(td, do_early); + if (err) + return err; + } + return 0; +} + +#define TEST_SAMPLE_TYPE (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ + PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ADDR | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_STREAM_ID) + +static int test__dlfilter_test(struct test_data *td) +{ + u64 sample_type = TEST_SAMPLE_TYPE; + pid_t pid = 12345; + pid_t tid = 12346; + u64 id = 99; + int err; + + if (get_dlfilters_path(td->dlfilters, PATH_MAX)) + return test_result("dlfilters not found", TEST_SKIP); + + if (check_filter_desc(td)) + return test_result("Failed to get expected filter description", TEST_FAIL); + + if (!have_gcc()) + return test_result("gcc not found", TEST_SKIP); + + pr_debug("dlfilters path: %s\n", td->dlfilters); + + if (write_prog(td->c_file_name)) + return test_result("Failed to write test C file", TEST_FAIL); + + if (verbose > 1) + system_cmd("cat %s ; echo", td->c_file_name); + + if (system_cmd("gcc -g -o %s %s", td->prog_file_name, td->c_file_name)) + return TEST_FAIL; + + if (verbose > 2) + system_cmd("objdump -x -dS %s", td->prog_file_name); + + if (get_ip_addr(td)) + return test_result("Failed to find program symbols", TEST_FAIL); + + pr_debug("Creating new host machine structure\n"); + td->machine = machine__new_host(); + td->machine->env = &perf_env; + + td->fd = creat(td->perf_data_file_name, 0644); + if (td->fd < 0) + return test_result("Failed to create test perf.data file", TEST_FAIL); + + err = perf_header__write_pipe(td->fd); + if (err < 0) + return test_result("perf_header__write_pipe() failed", TEST_FAIL); + + err = write_attr(td, sample_type, &id); + if (err) + return test_result("perf_event__synthesize_attr() failed", TEST_FAIL); + + if (write_comm(td->fd, pid, tid, "test-prog")) + return TEST_FAIL; + + if (write_mmap(td->fd, pid, tid, MAP_START, 0x10000, 0, td->prog_file_name)) + return TEST_FAIL; + + if (write_sample(td, sample_type, id, pid, tid) != TEST_OK) + return TEST_FAIL; + + if (verbose > 1) + system_cmd("%s script -i %s -D", td->perf, td->perf_data_file_name); + + err = run_perf_script(td); + if (err) + return TEST_FAIL; + + return TEST_OK; +} + +static void unlink_path(const char *path) +{ + if (*path) + unlink(path); +} + +static void test_data__free(struct test_data *td) +{ + machine__delete(td->machine); + close_fd(td->fd); + if (verbose <= 2) { + unlink_path(td->c_file_name); + unlink_path(td->prog_file_name); + unlink_path(td->perf_data_file_name); + } +} + +int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) +{ + struct test_data td = {.fd = -1}; + int pid = getpid(); + int err; + + perf_exe(td.perf, sizeof(td.perf)); + + snprintf(td.perf_data_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-perf-data", pid); + snprintf(td.c_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog.c", pid); + snprintf(td.prog_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog", pid); + + err = test__dlfilter_test(&td); + test_data__free(&td); + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 1100dd55b657..fe1306f58495 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -127,6 +127,7 @@ int test__parse_metric(struct test *test, int subtest); int test__pe_file_parsing(struct test *test, int subtest); int test__expand_cgroup_events(struct test *test, int subtest); int test__perf_time_to_tsc(struct test *test, int subtest); +int test__dlfilter(struct test *test, int subtest); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 7d11ce76157c..db964d5a52af 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -530,8 +530,8 @@ int dlfilter__do_filter_event(struct dlfilter *d, return ret; } -static bool get_filter_desc(const char *dirname, const char *name, - char **desc, char **long_desc) +bool get_filter_desc(const char *dirname, const char *name, char **desc, + char **long_desc) { char path[PATH_MAX]; void *handle; diff --git a/tools/perf/util/dlfilter.h b/tools/perf/util/dlfilter.h index 505980442360..cc4bb9657d05 100644 --- a/tools/perf/util/dlfilter.h +++ b/tools/perf/util/dlfilter.h @@ -93,5 +93,7 @@ static inline int dlfilter__filter_event_early(struct dlfilter *d, } int list_available_dlfilters(const struct option *opt, const char *s, int unset); +bool get_filter_desc(const char *dirname, const char *name, char **desc, + char **long_desc); #endif -- cgit v1.2.3-70-g09d2 From b390752191a6e09e8fb89625e227db0d5cc0ca33 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Aug 2021 20:39:25 +0300 Subject: gpiolib: Deduplicate forward declaration in the consumer.h header struct acpi_device is repeated in two branches of ifdeffery. Move it out and hence deduplicate. Signed-off-by: Andy Shevchenko Reviewed-by: Linus Walleij --- include/linux/gpio/consumer.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 566feb56601f..414b8f98d70f 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -680,10 +680,10 @@ struct acpi_gpio_mapping { unsigned int quirks; }; -#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_ACPI) - struct acpi_device; +#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_ACPI) + int acpi_dev_add_driver_gpios(struct acpi_device *adev, const struct acpi_gpio_mapping *gpios); void acpi_dev_remove_driver_gpios(struct acpi_device *adev); @@ -696,8 +696,6 @@ struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label); #else /* CONFIG_GPIOLIB && CONFIG_ACPI */ -struct acpi_device; - static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev, const struct acpi_gpio_mapping *gpios) { -- cgit v1.2.3-70-g09d2 From c1b291e96a6d27ac83938596829086945ff8a36e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 4 Aug 2021 19:00:16 +0300 Subject: gpio: dwapb: Unify ACPI enumeration checks in get_irq() and configure_irqs() Shared IRQ is only enabled for ACPI enumeration, there is no need to have a special flag for that, since we simple can test if device has been enumerated by ACPI. This unifies the checks in dwapb_get_irq() and dwapb_configure_irqs(). Signed-off-by: Andy Shevchenko Acked-by: Lee Jones Acked-by: Serge Semin Tested-by: Serge Semin --- drivers/gpio/gpio-dwapb.c | 24 ++++++++++++------------ drivers/mfd/intel_quark_i2c_gpio.c | 1 - include/linux/platform_data/gpio-dwapb.h | 1 - 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 3eb13d6d31ef..4c7153cb646c 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -436,21 +436,17 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, pirq->irqchip.irq_set_wake = dwapb_irq_set_wake; #endif - if (!pp->irq_shared) { - girq->num_parents = pirq->nr_irqs; - girq->parents = pirq->irq; - girq->parent_handler_data = gpio; - girq->parent_handler = dwapb_irq_handler; - } else { - /* This will let us handle the parent IRQ in the driver */ + /* + * Intel ACPI-based platforms mostly have the DesignWare APB GPIO + * IRQ lane shared between several devices. In that case the parental + * IRQ has to be handled in the shared way so to be properly delivered + * to all the connected devices. + */ + if (has_acpi_companion(gpio->dev)) { girq->num_parents = 0; girq->parents = NULL; girq->parent_handler = NULL; - /* - * Request a shared IRQ since where MFD would have devices - * using the same irq pin - */ err = devm_request_irq(gpio->dev, pp->irq[0], dwapb_irq_handler_mfd, IRQF_SHARED, DWAPB_DRIVER_NAME, gpio); @@ -458,6 +454,11 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, dev_err(gpio->dev, "error requesting IRQ\n"); goto err_kfree_pirq; } + } else { + girq->num_parents = pirq->nr_irqs; + girq->parents = pirq->irq; + girq->parent_handler_data = gpio; + girq->parent_handler = dwapb_irq_handler; } girq->chip = &pirq->irqchip; @@ -581,7 +582,6 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) pp->ngpio = DWAPB_MAX_GPIOS; } - pp->irq_shared = false; pp->gpio_base = -1; /* diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c index 01935ae4e9e1..a43993e38b6e 100644 --- a/drivers/mfd/intel_quark_i2c_gpio.c +++ b/drivers/mfd/intel_quark_i2c_gpio.c @@ -227,7 +227,6 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev) pdata->properties->ngpio = INTEL_QUARK_MFD_NGPIO; pdata->properties->gpio_base = INTEL_QUARK_MFD_GPIO_BASE; pdata->properties->irq[0] = pci_irq_vector(pdev, 0); - pdata->properties->irq_shared = true; cell->platform_data = pdata; cell->pdata_size = sizeof(*pdata); diff --git a/include/linux/platform_data/gpio-dwapb.h b/include/linux/platform_data/gpio-dwapb.h index 0aa5c6720259..535e5ed549d9 100644 --- a/include/linux/platform_data/gpio-dwapb.h +++ b/include/linux/platform_data/gpio-dwapb.h @@ -14,7 +14,6 @@ struct dwapb_port_property { unsigned int ngpio; unsigned int gpio_base; int irq[DWAPB_MAX_GPIOS]; - bool irq_shared; }; struct dwapb_platform_data { -- cgit v1.2.3-70-g09d2 From f973be8ad5dfa2ceac19657444ba57abc205218c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 4 Aug 2021 19:00:17 +0300 Subject: gpio: dwapb: Read GPIO base from gpio-base property For backward compatibility with some legacy devices introduce a new (*) property gpio-base to read GPIO base. This will allow further cleaning up of the driver. *) Note, it's not new for the GPIO library since the mockup driver is using it already. Signed-off-by: Andy Shevchenko Tested-by: Serge Semin Acked-by: Serge Semin Reviewed-by: Linus Walleij --- drivers/gpio/gpio-dwapb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 4c7153cb646c..674e91e69cc5 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -584,6 +584,10 @@ static struct dwapb_platform_data *dwapb_gpio_get_pdata(struct device *dev) pp->gpio_base = -1; + /* For internal use only, new platforms mustn't exercise this */ + if (is_software_node(fwnode)) + fwnode_property_read_u32(fwnode, "gpio-base", &pp->gpio_base); + /* * Only port A can provide interrupts in all configurations of * the IP. -- cgit v1.2.3-70-g09d2 From 36edadf5d336df62288658fcbdbb0fbf14554611 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 4 Aug 2021 19:00:18 +0300 Subject: mfd: intel_quark_i2c_gpio: Convert GPIO to use software nodes The driver can provide a software node group instead of passing legacy platform data. This will allow to drop the legacy platform data structures along with unifying a child device driver to use same interface for all property providers, i.e. Device Tree, ACPI, and board files. Signed-off-by: Andy Shevchenko Tested-by: Serge Semin Acked-for-MFD-by: Lee Jones Reviewed-by: Linus Walleij --- drivers/mfd/intel_quark_i2c_gpio.c | 70 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c index a43993e38b6e..9b9c76bd067b 100644 --- a/drivers/mfd/intel_quark_i2c_gpio.c +++ b/drivers/mfd/intel_quark_i2c_gpio.c @@ -17,7 +17,6 @@ #include #include #include -#include #include /* PCI BAR for register base address */ @@ -28,15 +27,6 @@ #define MFD_ACPI_MATCH_GPIO 0ULL #define MFD_ACPI_MATCH_I2C 1ULL -/* The base GPIO number under GPIOLIB framework */ -#define INTEL_QUARK_MFD_GPIO_BASE 8 - -/* The default number of South-Cluster GPIO on Quark. */ -#define INTEL_QUARK_MFD_NGPIO 8 - -/* The DesignWare GPIO ports on Quark. */ -#define INTEL_QUARK_GPIO_NPORTS 1 - #define INTEL_QUARK_IORES_MEM 0 #define INTEL_QUARK_IORES_IRQ 1 @@ -111,12 +101,38 @@ static struct resource intel_quark_gpio_res[] = { [INTEL_QUARK_IORES_MEM] = { .flags = IORESOURCE_MEM, }, + [INTEL_QUARK_IORES_IRQ] = { + .flags = IORESOURCE_IRQ, + }, }; static struct mfd_cell_acpi_match intel_quark_acpi_match_gpio = { .adr = MFD_ACPI_MATCH_GPIO, }; +static const struct software_node intel_quark_gpio_controller_node = { + .name = "intel-quark-gpio-controller", +}; + +static const struct property_entry intel_quark_gpio_portA_properties[] = { + PROPERTY_ENTRY_U32("reg", 0), + PROPERTY_ENTRY_U32("snps,nr-gpios", 8), + PROPERTY_ENTRY_U32("gpio-base", 8), + { } +}; + +static const struct software_node intel_quark_gpio_portA_node = { + .name = "portA", + .parent = &intel_quark_gpio_controller_node, + .properties = intel_quark_gpio_portA_properties, +}; + +static const struct software_node *intel_quark_gpio_node_group[] = { + &intel_quark_gpio_controller_node, + &intel_quark_gpio_portA_node, + NULL +}; + static struct mfd_cell intel_quark_mfd_cells[] = { [MFD_I2C_BAR] = { .id = MFD_I2C_BAR, @@ -203,34 +219,19 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev) { struct mfd_cell *cell = &intel_quark_mfd_cells[MFD_GPIO_BAR]; struct resource *res = intel_quark_gpio_res; - struct dwapb_platform_data *pdata; - struct device *dev = &pdev->dev; + int ret; res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_GPIO_BAR); res[INTEL_QUARK_IORES_MEM].end = pci_resource_end(pdev, MFD_GPIO_BAR); - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - /* For intel quark x1000, it has only one port: portA */ - pdata->nports = INTEL_QUARK_GPIO_NPORTS; - pdata->properties = devm_kcalloc(dev, pdata->nports, - sizeof(*pdata->properties), - GFP_KERNEL); - if (!pdata->properties) - return -ENOMEM; - - /* Set the properties for portA */ - pdata->properties->fwnode = NULL; - pdata->properties->idx = 0; - pdata->properties->ngpio = INTEL_QUARK_MFD_NGPIO; - pdata->properties->gpio_base = INTEL_QUARK_MFD_GPIO_BASE; - pdata->properties->irq[0] = pci_irq_vector(pdev, 0); + res[INTEL_QUARK_IORES_IRQ].start = pci_irq_vector(pdev, 0); + res[INTEL_QUARK_IORES_IRQ].end = pci_irq_vector(pdev, 0); - cell->platform_data = pdata; - cell->pdata_size = sizeof(*pdata); + ret = software_node_register_node_group(intel_quark_gpio_node_group); + if (ret) + return ret; + cell->swnode = &intel_quark_gpio_controller_node; return 0; } @@ -273,10 +274,12 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev, ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0, NULL); if (ret) - goto err_free_irq_vectors; + goto err_unregister_gpio_node_group; return 0; +err_unregister_gpio_node_group: + software_node_unregister_node_group(intel_quark_gpio_node_group); err_free_irq_vectors: pci_free_irq_vectors(pdev); err_unregister_i2c_clk: @@ -287,6 +290,7 @@ err_unregister_i2c_clk: static void intel_quark_mfd_remove(struct pci_dev *pdev) { mfd_remove_devices(&pdev->dev); + software_node_unregister_node_group(intel_quark_gpio_node_group); pci_free_irq_vectors(pdev); intel_quark_unregister_i2c_clk(&pdev->dev); } -- cgit v1.2.3-70-g09d2 From 5111c2b6b0194b509f47e6338c4deeeb4497bda8 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 4 Aug 2021 19:00:19 +0300 Subject: gpio: dwapb: Get rid of legacy platform data Platform data is a legacy interface to supply device properties to the driver. In this case we don't have anymore in-kernel users for it. Just remove it for good. Signed-off-by: Andy Shevchenko Acked-by: Serge Semin Tested-by: Serge Semin --- drivers/gpio/gpio-dwapb.c | 28 ++++++++++++++++++---------- include/linux/platform_data/gpio-dwapb.h | 24 ------------------------ 2 files changed, 18 insertions(+), 34 deletions(-) delete mode 100644 include/linux/platform_data/gpio-dwapb.h diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 674e91e69cc5..f98fa33e1679 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -48,6 +47,7 @@ #define DWAPB_DRIVER_NAME "gpio-dwapb" #define DWAPB_MAX_PORTS 4 +#define DWAPB_MAX_GPIOS 32 #define GPIO_EXT_PORT_STRIDE 0x04 /* register stride 32 bits */ #define GPIO_SWPORT_DR_STRIDE 0x0c /* register stride 3*32 bits */ @@ -65,6 +65,19 @@ struct dwapb_gpio; +struct dwapb_port_property { + struct fwnode_handle *fwnode; + unsigned int idx; + unsigned int ngpio; + unsigned int gpio_base; + int irq[DWAPB_MAX_GPIOS]; +}; + +struct dwapb_platform_data { + struct dwapb_port_property *properties; + unsigned int nports; +}; + #ifdef CONFIG_PM_SLEEP /* Store GPIO context across system-wide suspend/resume transitions */ struct dwapb_context { @@ -674,17 +687,12 @@ static int dwapb_gpio_probe(struct platform_device *pdev) unsigned int i; struct dwapb_gpio *gpio; int err; + struct dwapb_platform_data *pdata; struct device *dev = &pdev->dev; - struct dwapb_platform_data *pdata = dev_get_platdata(dev); - - if (!pdata) { - pdata = dwapb_gpio_get_pdata(dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - } - if (!pdata->nports) - return -ENODEV; + pdata = dwapb_gpio_get_pdata(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) diff --git a/include/linux/platform_data/gpio-dwapb.h b/include/linux/platform_data/gpio-dwapb.h deleted file mode 100644 index 535e5ed549d9..000000000000 --- a/include/linux/platform_data/gpio-dwapb.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright(c) 2014 Intel Corporation. - */ - -#ifndef GPIO_DW_APB_H -#define GPIO_DW_APB_H - -#define DWAPB_MAX_GPIOS 32 - -struct dwapb_port_property { - struct fwnode_handle *fwnode; - unsigned int idx; - unsigned int ngpio; - unsigned int gpio_base; - int irq[DWAPB_MAX_GPIOS]; -}; - -struct dwapb_platform_data { - struct dwapb_port_property *properties; - unsigned int nports; -}; - -#endif -- cgit v1.2.3-70-g09d2 From 3fb5c90452e41d3536106789a532edfa7e7a032f Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 29 Jul 2021 15:19:05 +0800 Subject: pinctrl: zynqmp: Drop pinctrl_unregister for devm_ registered device It's not necessary to unregister pin controller device registered with devm_pinctrl_register() and using pinctrl_unregister() leads to a double free. Fixes: fa99e7013827 ("pinctrl: zynqmp: some code cleanups") Signed-off-by: Yang Yingliang Reviewed-by: Michal Simek Link: https://lore.kernel.org/r/20210729071905.3235953-1-yangyingliang@huawei.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-zynqmp.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c index bbde676b7313..e14012209992 100644 --- a/drivers/pinctrl/pinctrl-zynqmp.c +++ b/drivers/pinctrl/pinctrl-zynqmp.c @@ -866,15 +866,6 @@ static int zynqmp_pinctrl_probe(struct platform_device *pdev) return ret; } -static int zynqmp_pinctrl_remove(struct platform_device *pdev) -{ - struct zynqmp_pinctrl *pctrl = platform_get_drvdata(pdev); - - pinctrl_unregister(pctrl->pctrl); - - return 0; -} - static const struct of_device_id zynqmp_pinctrl_of_match[] = { { .compatible = "xlnx,zynqmp-pinctrl" }, { } @@ -887,7 +878,6 @@ static struct platform_driver zynqmp_pinctrl_driver = { .of_match_table = zynqmp_pinctrl_of_match, }, .probe = zynqmp_pinctrl_probe, - .remove = zynqmp_pinctrl_remove, }; module_platform_driver(zynqmp_pinctrl_driver); -- cgit v1.2.3-70-g09d2 From d2083893e4ade786498ba7f5f6ab77913c67ab83 Mon Sep 17 00:00:00 2001 From: Lakshmi Sowjanya D Date: Fri, 6 Aug 2021 19:55:26 +0530 Subject: dt-bindings: pinctrl: Add bindings for Intel Keembay pinctrl driver Add Device Tree bindings documentation for Intel Keem Bay SoC's pin controller. Add entry for INTEL Keem Bay pinctrl driver in MAINTAINERS file Co-developed-by: Vineetha G. Jaya Kumaran Signed-off-by: Vineetha G. Jaya Kumaran Co-developed-by: Vijayakannan Ayyathurai Signed-off-by: Vijayakannan Ayyathurai Signed-off-by: Lakshmi Sowjanya D Acked-by: Mark Gross Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210806142527.29113-2-lakshmi.sowjanya.d@intel.com Signed-off-by: Linus Walleij --- .../bindings/pinctrl/intel,pinctrl-keembay.yaml | 135 +++++++++++++++++++++ MAINTAINERS | 5 + 2 files changed, 140 insertions(+) create mode 100644 Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml diff --git a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml new file mode 100644 index 000000000000..5e99d79499b4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/intel,pinctrl-keembay.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intel Keem Bay pin controller Device Tree Bindings + +maintainers: + - Lakshmi Sowjanya D + +description: | + Intel Keem Bay SoC integrates a pin controller which enables control + of pin directions, input/output values and configuration + for a total of 80 pins. + +properties: + compatible: + const: intel,keembay-pinctrl + + reg: + maxItems: 2 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + ngpios: + description: The number of GPIOs exposed. + const: 80 + + interrupts: + description: + Specifies the interrupt lines to be used by the controller. + Each interrupt line is shared by upto 4 GPIO lines. + maxItems: 8 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + +patternProperties: + '^gpio@[0-9a-f]*$': + type: object + + description: + Child nodes can be specified to contain pin configuration information, + which can then be utilized by pinctrl client devices. + The following properties are supported. + + properties: + pins: + description: | + The name(s) of the pins to be configured in the child node. + Supported pin names are "GPIO0" up to "GPIO79". + + bias-disable: true + + bias-pull-down: true + + bias-pull-up: true + + drive-strength: + description: IO pads drive strength in milli Ampere. + enum: [2, 4, 8, 12] + + bias-bus-hold: + type: boolean + + input-schmitt-enable: + type: boolean + + slew-rate: + description: GPIO slew rate control. + 0 - Fast(~100MHz) + 1 - Slow(~50MHz) + enum: [0, 1] + +additionalProperties: false + +required: + - compatible + - reg + - gpio-controller + - ngpios + - '#gpio-cells' + - interrupts + - interrupt-controller + - '#interrupt-cells' + +examples: + - | + #include + #include + // Example 1 + gpio@0 { + compatible = "intel,keembay-pinctrl"; + reg = <0x600b0000 0x88>, + <0x600b0190 0x1ac>; + gpio-controller; + ngpios = <0x50>; + #gpio-cells = <0x2>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + }; + + // Example 2 + gpio@1 { + compatible = "intel,keembay-pinctrl"; + reg = <0x600c0000 0x88>, + <0x600c0190 0x1ac>; + gpio-controller; + ngpios = <0x50>; + #gpio-cells = <0x2>; + interrupts = , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 669b3f546e00..0b36fa427d8f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14635,6 +14635,11 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git F: drivers/pinctrl/intel/ +PIN CONTROLLER - KEEMBAY +M: Lakshmi Sowjanya D +S: Supported +F: drivers/pinctrl/pinctrl-keembay* + PIN CONTROLLER - MEDIATEK M: Sean Wang L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) -- cgit v1.2.3-70-g09d2 From ffd4e739358be036377563a0c6c33702c700e3ee Mon Sep 17 00:00:00 2001 From: Lakshmi Sowjanya D Date: Fri, 6 Aug 2021 19:55:27 +0530 Subject: pinctrl: Add Intel Keem Bay pinctrl driver About Intel Keem Bay: ------------------- Intel Keem Bay is a computer vision AI accelerator SoC based on ARM CPU. Documentation of Keem Bay: Documentation/vpu/vpu-stack-overview.rst. Pinctrl IP: ---------- The SoC has a customised pinmux controller IP which controls pin multiplexing and configuration. Keem Bay pinctrl IP is not based on and have nothing in common with the existing pinctrl drivers. The registers used are incompatible with the existing drivers, so it requires a new driver. Add pinctrl driver to enable pin control support in the Intel Keem Bay SoC. Co-developed-by: Vineetha G. Jaya Kumaran Signed-off-by: Vineetha G. Jaya Kumaran Co-developed-by: Vijayakannan Ayyathurai Signed-off-by: Vijayakannan Ayyathurai Signed-off-by: Lakshmi Sowjanya D Reviewed-by: Mark Gross Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20210806142527.29113-3-lakshmi.sowjanya.d@intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 19 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-keembay.c | 1731 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1751 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-keembay.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index eb981713b40d..31921108e456 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -407,6 +407,25 @@ config PINCTRL_K210 Add support for the Canaan Kendryte K210 RISC-V SOC Field Programmable IO Array (FPIOA) controller. +config PINCTRL_KEEMBAY + tristate "Pinctrl driver for Intel Keem Bay SoC" + depends on ARCH_KEEMBAY || (ARM64 && COMPILE_TEST) + depends on HAS_IOMEM + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + select GPIOLIB + select GPIOLIB_IRQCHIP + select GPIO_GENERIC + help + This selects pin control driver for the Intel Keembay SoC. + It provides pin config functions such as pullup, pulldown, + interrupt, drive strength, sec lock, schmitt trigger, slew + rate control and direction control. This module will be + called as pinctrl-keembay. + source "drivers/pinctrl/actions/Kconfig" source "drivers/pinctrl/aspeed/Kconfig" source "drivers/pinctrl/bcm/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 5ef5334a797f..200073bcc2c1 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_MICROCHIP_SGPIO) += pinctrl-microchip-sgpio.o obj-$(CONFIG_PINCTRL_EQUILIBRIUM) += pinctrl-equilibrium.o obj-$(CONFIG_PINCTRL_K210) += pinctrl-k210.o +obj-$(CONFIG_PINCTRL_KEEMBAY) += pinctrl-keembay.o obj-y += actions/ obj-$(CONFIG_ARCH_ASPEED) += aspeed/ diff --git a/drivers/pinctrl/pinctrl-keembay.c b/drivers/pinctrl/pinctrl-keembay.c new file mode 100644 index 000000000000..2bce563d5b8b --- /dev/null +++ b/drivers/pinctrl/pinctrl-keembay.c @@ -0,0 +1,1731 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2020 Intel Corporation */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "core.h" +#include "pinmux.h" + +/* GPIO data registers' offsets */ +#define KEEMBAY_GPIO_DATA_OUT 0x000 +#define KEEMBAY_GPIO_DATA_IN 0x020 +#define KEEMBAY_GPIO_DATA_IN_RAW 0x040 +#define KEEMBAY_GPIO_DATA_HIGH 0x060 +#define KEEMBAY_GPIO_DATA_LOW 0x080 + +/* GPIO Interrupt and mode registers' offsets */ +#define KEEMBAY_GPIO_INT_CFG 0x000 +#define KEEMBAY_GPIO_MODE 0x070 + +/* GPIO mode register bit fields */ +#define KEEMBAY_GPIO_MODE_PULLUP_MASK GENMASK(13, 12) +#define KEEMBAY_GPIO_MODE_DRIVE_MASK GENMASK(8, 7) +#define KEEMBAY_GPIO_MODE_INV_MASK GENMASK(5, 4) +#define KEEMBAY_GPIO_MODE_SELECT_MASK GENMASK(2, 0) +#define KEEMBAY_GPIO_MODE_DIR_OVR BIT(15) +#define KEEMBAY_GPIO_MODE_REN BIT(11) +#define KEEMBAY_GPIO_MODE_SCHMITT_EN BIT(10) +#define KEEMBAY_GPIO_MODE_SLEW_RATE BIT(9) +#define KEEMBAY_GPIO_IRQ_ENABLE BIT(7) +#define KEEMBAY_GPIO_MODE_DIR BIT(3) +#define KEEMBAY_GPIO_MODE_DEFAULT 0x7 +#define KEEMBAY_GPIO_MODE_INV_VAL 0x3 + +#define KEEMBAY_GPIO_DISABLE 0 +#define KEEMBAY_GPIO_PULL_UP 1 +#define KEEMBAY_GPIO_PULL_DOWN 2 +#define KEEMBAY_GPIO_BUS_HOLD 3 +#define KEEMBAY_GPIO_NUM_IRQ 8 +#define KEEMBAY_GPIO_MAX_PER_IRQ 4 +#define KEEMBAY_GPIO_MAX_PER_REG 32 +#define KEEMBAY_GPIO_MIN_STRENGTH 2 +#define KEEMBAY_GPIO_MAX_STRENGTH 12 +#define KEEMBAY_GPIO_SENSE_LOW (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING) + +/* GPIO reg address calculation */ +#define KEEMBAY_GPIO_REG_OFFSET(pin) ((pin) * 4) + +/** + * struct keembay_mux_desc - Mux properties of each GPIO pin + * @mode: Pin mode when operating in this function + * @name: Pin function name + */ +struct keembay_mux_desc { + u8 mode; + const char *name; +}; + +#define KEEMBAY_PIN_DESC(pin_number, pin_name, ...) { \ + .number = pin_number, \ + .name = pin_name, \ + .drv_data = &(struct keembay_mux_desc[]) { \ + __VA_ARGS__, { } }, \ +} \ + +#define KEEMBAY_MUX(pin_mode, pin_function) { \ + .mode = pin_mode, \ + .name = pin_function, \ +} \ + +/** + * struct keembay_gpio_irq - Config of each GPIO Interrupt sources + * @source: Interrupt source number (0 - 7) + * @line: Actual Interrupt line number + * @pins: Array of GPIO pins using this Interrupt line + * @trigger: Interrupt trigger type for this line + * @num_share: Number of pins currently using this Interrupt line + */ +struct keembay_gpio_irq { + unsigned int source; + unsigned int line; + unsigned int pins[KEEMBAY_GPIO_MAX_PER_IRQ]; + unsigned int trigger; + unsigned int num_share; +}; + +/** + * struct keembay_pinctrl - Intel Keembay pinctrl structure + * @pctrl: Pointer to the pin controller device + * @base0: First register base address + * @base1: Second register base address + * @dev: Pointer to the device structure + * @chip: GPIO chip used by this pin controller + * @soc: Pin control configuration data based on SoC + * @lock: Spinlock to protect various gpio config register access + * @ngroups: Number of pin groups available + * @nfuncs: Number of pin functions available + * @npins: Number of GPIO pins available + * @irq: Store Interrupt source + * @max_gpios_level_type: Store max level trigger type + * @max_gpios_edge_type: Store max edge trigger type + */ +struct keembay_pinctrl { + struct pinctrl_dev *pctrl; + void __iomem *base0; + void __iomem *base1; + struct device *dev; + struct gpio_chip chip; + const struct keembay_pin_soc *soc; + raw_spinlock_t lock; + unsigned int ngroups; + unsigned int nfuncs; + unsigned int npins; + struct keembay_gpio_irq irq[KEEMBAY_GPIO_NUM_IRQ]; + int max_gpios_level_type; + int max_gpios_edge_type; +}; + +/** + * struct keembay_pin_soc - Pin control config data based on SoC + * @pins: Pin description structure + */ +struct keembay_pin_soc { + const struct pinctrl_pin_desc *pins; +}; + +static const struct pinctrl_pin_desc keembay_pins[] = { + KEEMBAY_PIN_DESC(0, "GPIO0", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(1, "GPIO1", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(2, "GPIO2", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(3, "GPIO3", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(4, "GPIO4", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C2_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(5, "GPIO5", + KEEMBAY_MUX(0x0, "I2S0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C2_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(6, "GPIO6", + KEEMBAY_MUX(0x0, "I2S1_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C3_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(7, "GPIO7", + KEEMBAY_MUX(0x0, "I2S1_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "I2C3_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(8, "GPIO8", + KEEMBAY_MUX(0x0, "I2S1_M0"), + KEEMBAY_MUX(0x1, "I2S1_M1"), + KEEMBAY_MUX(0x2, "SLVDS0_M2"), + KEEMBAY_MUX(0x3, "UART0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(9, "GPIO9", + KEEMBAY_MUX(0x0, "I2S1_M0"), + KEEMBAY_MUX(0x1, "I2S1_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "UART0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(10, "GPIO10", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "UART0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(11, "GPIO11", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "SD0_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "UART0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(12, "GPIO12", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "I2S2_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "SPI0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(13, "GPIO13", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "I2S2_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "SPI0_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(14, "GPIO14", + KEEMBAY_MUX(0x0, "UART0_M0"), + KEEMBAY_MUX(0x1, "I2S3_M1"), + KEEMBAY_MUX(0x2, "PWM_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "ETH_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(15, "GPIO15", + KEEMBAY_MUX(0x0, "UART0_M0"), + KEEMBAY_MUX(0x1, "I2S3_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(16, "GPIO16", + KEEMBAY_MUX(0x0, "UART0_M0"), + KEEMBAY_MUX(0x1, "I2S3_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(17, "GPIO17", + KEEMBAY_MUX(0x0, "UART0_M0"), + KEEMBAY_MUX(0x1, "I2S3_M1"), + KEEMBAY_MUX(0x2, "I2S3_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(18, "GPIO18", + KEEMBAY_MUX(0x0, "UART1_M0"), + KEEMBAY_MUX(0x1, "SPI0_M1"), + KEEMBAY_MUX(0x2, "I2S3_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(19, "GPIO19", + KEEMBAY_MUX(0x0, "UART1_M0"), + KEEMBAY_MUX(0x1, "LCD_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "SD1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "LCD_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(20, "GPIO20", + KEEMBAY_MUX(0x0, "UART1_M0"), + KEEMBAY_MUX(0x1, "LCD_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "SPI1_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(21, "GPIO21", + KEEMBAY_MUX(0x0, "UART1_M0"), + KEEMBAY_MUX(0x1, "LCD_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C0_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(22, "GPIO22", + KEEMBAY_MUX(0x0, "I2C0_M0"), + KEEMBAY_MUX(0x1, "UART2_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C0_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(23, "GPIO23", + KEEMBAY_MUX(0x0, "I2C0_M0"), + KEEMBAY_MUX(0x1, "UART2_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C1_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(24, "GPIO24", + KEEMBAY_MUX(0x0, "I2C1_M0"), + KEEMBAY_MUX(0x1, "UART2_M1"), + KEEMBAY_MUX(0x2, "DEBUG_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C1_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(25, "GPIO25", + KEEMBAY_MUX(0x0, "I2C1_M0"), + KEEMBAY_MUX(0x1, "UART2_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C2_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(26, "GPIO26", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2C2_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "DSU_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C2_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(27, "GPIO27", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2C2_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "DSU_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C0_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(28, "GPIO28", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2C3_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C1_M5"), + KEEMBAY_MUX(0x6, "SLVDS0_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(29, "GPIO29", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2C3_M1"), + KEEMBAY_MUX(0x2, "UART0_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I3C2_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(30, "GPIO30", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "I2C4_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(31, "GPIO31", + KEEMBAY_MUX(0x0, "SPI0_M0"), + KEEMBAY_MUX(0x1, "I2S0_M1"), + KEEMBAY_MUX(0x2, "I2C4_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "UART1_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(32, "GPIO32", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "SPI0_M1"), + KEEMBAY_MUX(0x2, "UART1_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "PCIE_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(33, "GPIO33", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "SPI0_M1"), + KEEMBAY_MUX(0x2, "UART1_M2"), + KEEMBAY_MUX(0x3, "PWM_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "PCIE_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(34, "GPIO34", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "SPI0_M1"), + KEEMBAY_MUX(0x2, "I2C0_M2"), + KEEMBAY_MUX(0x3, "UART1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I2S0_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(35, "GPIO35", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "PCIE_M1"), + KEEMBAY_MUX(0x2, "I2C0_M2"), + KEEMBAY_MUX(0x3, "UART1_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I2S0_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(36, "GPIO36", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "I2C1_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I2S0_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(37, "GPIO37", + KEEMBAY_MUX(0x0, "SD0_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "I2C1_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "I2S0_M5"), + KEEMBAY_MUX(0x6, "SLVDS1_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(38, "GPIO38", + KEEMBAY_MUX(0x0, "I3C1_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "UART3_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(39, "GPIO39", + KEEMBAY_MUX(0x0, "I3C1_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "UART3_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(40, "GPIO40", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "UART3_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(41, "GPIO41", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI3_M1"), + KEEMBAY_MUX(0x2, "SPI3_M2"), + KEEMBAY_MUX(0x3, "DEBUG_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(42, "GPIO42", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI3_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "CAM_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C4_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(43, "GPIO43", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI3_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2C4_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(44, "GPIO44", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(45, "GPIO45", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "CPR_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(46, "GPIO46", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(47, "GPIO47", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SD1_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(48, "GPIO48", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "UART2_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(49, "GPIO49", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "UART2_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(50, "GPIO50", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "UART2_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(51, "GPIO51", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "UART2_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(52, "GPIO52", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(53, "GPIO53", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(54, "GPIO54", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(55, "GPIO55", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(56, "GPIO56", + KEEMBAY_MUX(0x0, "ETH_M0"), + KEEMBAY_MUX(0x1, "SPI2_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I2S2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(57, "GPIO57", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "I2S1_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(58, "GPIO58", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(59, "GPIO59", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(60, "GPIO60", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "I3C1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(61, "GPIO61", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SD0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(62, "GPIO62", + KEEMBAY_MUX(0x0, "SPI1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(63, "GPIO63", + KEEMBAY_MUX(0x0, "I2S1_M0"), + KEEMBAY_MUX(0x1, "SPI1_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(64, "GPIO64", + KEEMBAY_MUX(0x0, "I2S2_M0"), + KEEMBAY_MUX(0x1, "SPI1_M1"), + KEEMBAY_MUX(0x2, "ETH_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "UART1_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(65, "GPIO65", + KEEMBAY_MUX(0x0, "I3C0_M0"), + KEEMBAY_MUX(0x1, "SPI1_M1"), + KEEMBAY_MUX(0x2, "SD1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SPI0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(66, "GPIO66", + KEEMBAY_MUX(0x0, "I3C0_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "I2C0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SPI0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "CAM_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(67, "GPIO67", + KEEMBAY_MUX(0x0, "I3C1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "I2C0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SPI0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2S3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(68, "GPIO68", + KEEMBAY_MUX(0x0, "I3C1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "I2C1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SPI0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2S3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(69, "GPIO69", + KEEMBAY_MUX(0x0, "I3C2_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "I2C1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SPI0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2S3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(70, "GPIO70", + KEEMBAY_MUX(0x0, "I3C2_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SPI0_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2S3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(71, "GPIO71", + KEEMBAY_MUX(0x0, "I3C0_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "I2S3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(72, "GPIO72", + KEEMBAY_MUX(0x0, "I3C1_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(73, "GPIO73", + KEEMBAY_MUX(0x0, "I3C2_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(74, "GPIO74", + KEEMBAY_MUX(0x0, "I3C0_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(75, "GPIO75", + KEEMBAY_MUX(0x0, "I3C0_M0"), + KEEMBAY_MUX(0x1, "ETH_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "SD0_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART2_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(76, "GPIO76", + KEEMBAY_MUX(0x0, "I2C2_M0"), + KEEMBAY_MUX(0x1, "I3C0_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "ETH_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(77, "GPIO77", + KEEMBAY_MUX(0x0, "PCIE_M0"), + KEEMBAY_MUX(0x1, "I3C1_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I3C2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(78, "GPIO78", + KEEMBAY_MUX(0x0, "PCIE_M0"), + KEEMBAY_MUX(0x1, "I3C2_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I3C2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), + KEEMBAY_PIN_DESC(79, "GPIO79", + KEEMBAY_MUX(0x0, "PCIE_M0"), + KEEMBAY_MUX(0x1, "I2C2_M1"), + KEEMBAY_MUX(0x2, "SLVDS1_M2"), + KEEMBAY_MUX(0x3, "TPIU_M3"), + KEEMBAY_MUX(0x4, "I3C2_M4"), + KEEMBAY_MUX(0x5, "LCD_M5"), + KEEMBAY_MUX(0x6, "UART3_M6"), + KEEMBAY_MUX(0x7, "GPIO_M7")), +}; + +static inline u32 keembay_read_reg(void __iomem *base, unsigned int pin) +{ + return readl(base + KEEMBAY_GPIO_REG_OFFSET(pin)); +} + +static inline u32 keembay_read_gpio_reg(void __iomem *base, unsigned int pin) +{ + return keembay_read_reg(base, pin / KEEMBAY_GPIO_MAX_PER_REG); +} + +static inline u32 keembay_read_pin(void __iomem *base, unsigned int pin) +{ + u32 val = keembay_read_gpio_reg(base, pin); + + return !!(val & BIT(pin % KEEMBAY_GPIO_MAX_PER_REG)); +} + +static inline void keembay_write_reg(u32 val, void __iomem *base, unsigned int pin) +{ + writel(val, base + KEEMBAY_GPIO_REG_OFFSET(pin)); +} + +static inline void keembay_write_gpio_reg(u32 val, void __iomem *base, unsigned int pin) +{ + keembay_write_reg(val, base, pin / KEEMBAY_GPIO_MAX_PER_REG); +} + +static void keembay_gpio_invert(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + /* + * This IP doesn't support the falling edge and low level interrupt + * trigger. Invert API is used to mimic the falling edge and low + * level support + */ + + val |= FIELD_PREP(KEEMBAY_GPIO_MODE_INV_MASK, KEEMBAY_GPIO_MODE_INV_VAL); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); +} + +static void keembay_gpio_restore_default(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + val &= FIELD_PREP(KEEMBAY_GPIO_MODE_INV_MASK, 0); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); +} + +static int keembay_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned int pin) +{ + struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); + unsigned int val; + + if (pin >= kpc->npins) + return -EINVAL; + + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + val = FIELD_GET(KEEMBAY_GPIO_MODE_SELECT_MASK, val); + + /* As per Pin Mux Map, Modes 0 to 6 are for peripherals */ + if (val != KEEMBAY_GPIO_MODE_DEFAULT) + return -EBUSY; + + return 0; +} + +static int keembay_set_mux(struct pinctrl_dev *pctldev, unsigned int fun_sel, + unsigned int grp_sel) +{ + struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); + struct function_desc *func; + struct group_desc *grp; + unsigned int val; + u8 pin_mode; + int pin; + + grp = pinctrl_generic_get_group(pctldev, grp_sel); + if (!grp) + return -EINVAL; + + func = pinmux_generic_get_function(pctldev, fun_sel); + if (!func) + return -EINVAL; + + /* Change modes for pins in the selected group */ + pin = *grp->pins; + pin_mode = *(u8 *)(func->data); + + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + val = u32_replace_bits(val, pin_mode, KEEMBAY_GPIO_MODE_SELECT_MASK); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static u32 keembay_pinconf_get_pull(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return FIELD_GET(KEEMBAY_GPIO_MODE_PULLUP_MASK, val); +} + +static int keembay_pinconf_set_pull(struct keembay_pinctrl *kpc, unsigned int pin, + unsigned int pull) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + val = u32_replace_bits(val, pull, KEEMBAY_GPIO_MODE_PULLUP_MASK); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static int keembay_pinconf_get_drive(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + val = FIELD_GET(KEEMBAY_GPIO_MODE_DRIVE_MASK, val) * 4; + if (val) + return val; + + return KEEMBAY_GPIO_MIN_STRENGTH; +} + +static int keembay_pinconf_set_drive(struct keembay_pinctrl *kpc, unsigned int pin, + unsigned int drive) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + unsigned int strength = clamp_val(drive, KEEMBAY_GPIO_MIN_STRENGTH, + KEEMBAY_GPIO_MAX_STRENGTH) / 4; + + val = u32_replace_bits(val, strength, KEEMBAY_GPIO_MODE_DRIVE_MASK); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static int keembay_pinconf_get_slew_rate(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return !!(val & KEEMBAY_GPIO_MODE_SLEW_RATE); +} + +static int keembay_pinconf_set_slew_rate(struct keembay_pinctrl *kpc, unsigned int pin, + unsigned int slew_rate) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + if (slew_rate) + val |= KEEMBAY_GPIO_MODE_SLEW_RATE; + else + val &= ~KEEMBAY_GPIO_MODE_SLEW_RATE; + + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static int keembay_pinconf_get_schmitt(struct keembay_pinctrl *kpc, unsigned int pin) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return !!(val & KEEMBAY_GPIO_MODE_SCHMITT_EN); +} + +static int keembay_pinconf_set_schmitt(struct keembay_pinctrl *kpc, unsigned int pin, + unsigned int schmitt_en) +{ + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + if (schmitt_en) + val |= KEEMBAY_GPIO_MODE_SCHMITT_EN; + else + val &= ~KEEMBAY_GPIO_MODE_SCHMITT_EN; + + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static int keembay_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *cfg) +{ + struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); + unsigned int param = pinconf_to_config_param(*cfg); + unsigned int val; + + if (pin >= kpc->npins) + return -EINVAL; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_DISABLE) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_PULL_UP) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_PULL_DOWN) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_BUS_HOLD: + if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_BUS_HOLD) + return -EINVAL; + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (!keembay_pinconf_get_schmitt(kpc, pin)) + return -EINVAL; + break; + + case PIN_CONFIG_SLEW_RATE: + val = keembay_pinconf_get_slew_rate(kpc, pin); + *cfg = pinconf_to_config_packed(param, val); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + val = keembay_pinconf_get_drive(kpc, pin); + *cfg = pinconf_to_config_packed(param, val); + break; + + default: + return -ENOTSUPP; + } + + return 0; +} + +static int keembay_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *cfg, unsigned int num_configs) +{ + struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param; + unsigned int arg, i; + int ret = 0; + + if (pin >= kpc->npins) + return -EINVAL; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(cfg[i]); + arg = pinconf_to_config_argument(cfg[i]); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_DISABLE); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_PULL_UP); + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_PULL_DOWN); + break; + + case PIN_CONFIG_BIAS_BUS_HOLD: + ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_BUS_HOLD); + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + ret = keembay_pinconf_set_schmitt(kpc, pin, arg); + break; + + case PIN_CONFIG_SLEW_RATE: + ret = keembay_pinconf_set_slew_rate(kpc, pin, arg); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + ret = keembay_pinconf_set_drive(kpc, pin, arg); + break; + + default: + return -ENOTSUPP; + } + if (ret) + return ret; + } + return ret; +} + +static const struct pinctrl_ops keembay_pctlops = { + .get_groups_count = pinctrl_generic_get_group_count, + .get_group_name = pinctrl_generic_get_group_name, + .get_group_pins = pinctrl_generic_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, + .dt_free_map = pinconf_generic_dt_free_map, +}; + +static const struct pinmux_ops keembay_pmxops = { + .get_functions_count = pinmux_generic_get_function_count, + .get_function_name = pinmux_generic_get_function_name, + .get_function_groups = pinmux_generic_get_function_groups, + .gpio_request_enable = keembay_request_gpio, + .set_mux = keembay_set_mux, +}; + +static const struct pinconf_ops keembay_confops = { + .is_generic = true, + .pin_config_get = keembay_pinconf_get, + .pin_config_set = keembay_pinconf_set, +}; + +static struct pinctrl_desc keembay_pinctrl_desc = { + .name = "keembay-pinmux", + .pctlops = &keembay_pctlops, + .pmxops = &keembay_pmxops, + .confops = &keembay_confops, + .owner = THIS_MODULE, +}; + +static int keembay_gpio_get(struct gpio_chip *gc, unsigned int pin) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int val, offset; + + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + offset = (val & KEEMBAY_GPIO_MODE_DIR) ? KEEMBAY_GPIO_DATA_IN : KEEMBAY_GPIO_DATA_OUT; + + return keembay_read_pin(kpc->base0 + offset, pin); +} + +static void keembay_gpio_set(struct gpio_chip *gc, unsigned int pin, int val) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int reg_val; + + reg_val = keembay_read_gpio_reg(kpc->base0 + KEEMBAY_GPIO_DATA_OUT, pin); + if (val) + keembay_write_gpio_reg(reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), + kpc->base0 + KEEMBAY_GPIO_DATA_HIGH, pin); + else + keembay_write_gpio_reg(~reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), + kpc->base0 + KEEMBAY_GPIO_DATA_LOW, pin); +} + +static int keembay_gpio_get_direction(struct gpio_chip *gc, unsigned int pin) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return !!(val & KEEMBAY_GPIO_MODE_DIR); +} + +static int keembay_gpio_set_direction_in(struct gpio_chip *gc, unsigned int pin) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int val; + + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + val |= KEEMBAY_GPIO_MODE_DIR; + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + + return 0; +} + +static int keembay_gpio_set_direction_out(struct gpio_chip *gc, + unsigned int pin, int value) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int val; + + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); + val &= ~KEEMBAY_GPIO_MODE_DIR; + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); + keembay_gpio_set(gc, pin, value); + + return 0; +} + +static void keembay_gpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + unsigned int kmb_irq = irq_desc_get_irq(desc); + unsigned long reg, clump = 0, bit = 0; + struct irq_chip *parent_chip; + struct keembay_pinctrl *kpc; + unsigned int src, pin, val; + + /* Identify GPIO interrupt number from GIC interrupt number */ + for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { + if (kmb_irq == gc->irq.parents[src]) + break; + } + + if (src == KEEMBAY_GPIO_NUM_IRQ) + return; + + parent_chip = irq_desc_get_chip(desc); + kpc = gpiochip_get_data(gc); + + chained_irq_enter(parent_chip, desc); + reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + + /* + * Each Interrupt line can be shared by up to 4 GPIO pins. Enable bit + * and input values were checked to identify the source of the + * Interrupt. The checked enable bit positions are 7, 15, 23 and 31. + */ + for_each_set_clump8(bit, clump, ®, BITS_PER_TYPE(typeof(reg))) { + pin = clump & ~KEEMBAY_GPIO_IRQ_ENABLE; + val = keembay_read_pin(kpc->base0 + KEEMBAY_GPIO_DATA_IN, pin); + kmb_irq = irq_linear_revmap(gc->irq.domain, pin); + + /* Checks if the interrupt is enabled */ + if (val && (clump & KEEMBAY_GPIO_IRQ_ENABLE)) + generic_handle_irq(kmb_irq); + } + chained_irq_exit(parent_chip, desc); +} + +static void keembay_gpio_clear_irq(struct irq_data *data, unsigned long pos, + u32 src, irq_hw_number_t pin) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned long trig = irqd_get_trigger_type(data); + struct keembay_gpio_irq *irq = &kpc->irq[src]; + unsigned long val; + + /* Check if the value of pos/KEEMBAY_GPIO_NUM_IRQ is in valid range. */ + if ((pos / KEEMBAY_GPIO_NUM_IRQ) >= KEEMBAY_GPIO_MAX_PER_IRQ) + return; + + /* Retains val register as it handles other interrupts as well. */ + val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + + bitmap_set_value8(&val, 0, pos); + keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + + irq->num_share--; + irq->pins[pos / KEEMBAY_GPIO_NUM_IRQ] = 0; + + if (trig & IRQ_TYPE_LEVEL_MASK) + keembay_gpio_restore_default(kpc, pin); + + if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) + kpc->max_gpios_level_type++; + else if (irq->trigger == IRQ_TYPE_EDGE_RISING) + kpc->max_gpios_edge_type++; +} + +static int keembay_find_free_slot(struct keembay_pinctrl *kpc, unsigned int src) +{ + unsigned long val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + + return bitmap_find_free_region(&val, KEEMBAY_GPIO_MAX_PER_REG, 3) / KEEMBAY_GPIO_NUM_IRQ; +} + +static int keembay_find_free_src(struct keembay_pinctrl *kpc, unsigned int trig) +{ + int src, type = 0; + + if (trig & IRQ_TYPE_LEVEL_MASK) + type = IRQ_TYPE_LEVEL_HIGH; + else if (trig & IRQ_TYPE_EDGE_BOTH) + type = IRQ_TYPE_EDGE_RISING; + + for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { + if (kpc->irq[src].trigger != type) + continue; + + if (!keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src) || + kpc->irq[src].num_share < KEEMBAY_GPIO_MAX_PER_IRQ) + return src; + } + + return -EBUSY; +} + +static void keembay_gpio_set_irq(struct keembay_pinctrl *kpc, int src, + int slot, irq_hw_number_t pin) +{ + unsigned long val = pin | KEEMBAY_GPIO_IRQ_ENABLE; + struct keembay_gpio_irq *irq = &kpc->irq[src]; + unsigned long flags, reg; + + raw_spin_lock_irqsave(&kpc->lock, flags); + reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + bitmap_set_value8(®, val, slot * 8); + keembay_write_reg(reg, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + raw_spin_unlock_irqrestore(&kpc->lock, flags); + + if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) + kpc->max_gpios_level_type--; + else if (irq->trigger == IRQ_TYPE_EDGE_RISING) + kpc->max_gpios_edge_type--; + + irq->source = src; + irq->pins[slot] = pin; + irq->num_share++; +} + +static void keembay_gpio_irq_enable(struct irq_data *data) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + unsigned int trig = irqd_get_trigger_type(data); + irq_hw_number_t pin = irqd_to_hwirq(data); + int src, slot; + + /* Check which Interrupt source and slot is available */ + src = keembay_find_free_src(kpc, trig); + slot = keembay_find_free_slot(kpc, src); + + if (src < 0 || slot < 0) + return; + + if (trig & KEEMBAY_GPIO_SENSE_LOW) + keembay_gpio_invert(kpc, pin); + + keembay_gpio_set_irq(kpc, src, slot, pin); +} + +static void keembay_gpio_irq_ack(struct irq_data *data) +{ + /* + * The keembay_gpio_irq_ack function is needed to handle_edge_irq. + * IRQ ack is not possible from the SOC perspective. The IP by itself + * is used for handling interrupts which do not come in short-time and + * not used as protocol or communication interrupts. All the interrupts + * are threaded IRQ interrupts. But this function is expected to be + * present as the gpio IP is registered with irq framework. Otherwise + * handle_edge_irq() fails. + */ +} + +static void keembay_gpio_irq_disable(struct irq_data *data) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + irq_hw_number_t pin = irqd_to_hwirq(data); + unsigned long reg, clump = 0, pos = 0; + unsigned int src; + + for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { + reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); + for_each_set_clump8(pos, clump, ®, BITS_PER_TYPE(typeof(reg))) { + if ((clump & ~KEEMBAY_GPIO_IRQ_ENABLE) == pin) { + keembay_gpio_clear_irq(data, pos, src, pin); + return; + } + } + } +} + +static int keembay_gpio_irq_set_type(struct irq_data *data, unsigned int type) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct keembay_pinctrl *kpc = gpiochip_get_data(gc); + + /* Change EDGE_BOTH as EDGE_RISING in order to claim the IRQ for power button */ + if (!kpc->max_gpios_edge_type && (type & IRQ_TYPE_EDGE_BOTH)) + type = IRQ_TYPE_EDGE_RISING; + + if (!kpc->max_gpios_level_type && (type & IRQ_TYPE_LEVEL_MASK)) + type = IRQ_TYPE_NONE; + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(data, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(data, handle_level_irq); + else + return -EINVAL; + + return 0; +} + +static int keembay_gpio_add_pin_ranges(struct gpio_chip *chip) +{ + struct keembay_pinctrl *kpc = gpiochip_get_data(chip); + int ret; + + ret = gpiochip_add_pin_range(chip, dev_name(kpc->dev), 0, 0, chip->ngpio); + if (ret) + dev_err_probe(kpc->dev, ret, "failed to add GPIO pin range\n"); + return ret; +} + +static struct irq_chip keembay_gpio_irqchip = { + .name = "keembay-gpio", + .irq_enable = keembay_gpio_irq_enable, + .irq_disable = keembay_gpio_irq_disable, + .irq_set_type = keembay_gpio_irq_set_type, + .irq_ack = keembay_gpio_irq_ack, +}; + +static int keembay_gpiochip_probe(struct keembay_pinctrl *kpc, + struct platform_device *pdev) +{ + unsigned int i, level_line = 0, edge_line = 0; + struct gpio_chip *gc = &kpc->chip; + struct gpio_irq_chip *girq; + + /* Setup GPIO IRQ chip */ + girq = &kpc->chip.irq; + girq->chip = &keembay_gpio_irqchip; + girq->parent_handler = keembay_gpio_irq_handler; + girq->num_parents = KEEMBAY_GPIO_NUM_IRQ; + girq->parents = devm_kcalloc(kpc->dev, girq->num_parents, + sizeof(*girq->parents), GFP_KERNEL); + + if (!girq->parents) + return -ENOMEM; + + /* Setup GPIO chip */ + gc->label = dev_name(kpc->dev); + gc->parent = kpc->dev; + gc->request = gpiochip_generic_request; + gc->free = gpiochip_generic_free; + gc->get_direction = keembay_gpio_get_direction; + gc->direction_input = keembay_gpio_set_direction_in; + gc->direction_output = keembay_gpio_set_direction_out; + gc->get = keembay_gpio_get; + gc->set = keembay_gpio_set; + gc->set_config = gpiochip_generic_config; + gc->base = -1; + gc->ngpio = kpc->npins; + gc->add_pin_ranges = keembay_gpio_add_pin_ranges; + + for (i = 0; i < KEEMBAY_GPIO_NUM_IRQ; i++) { + struct keembay_gpio_irq *kmb_irq = &kpc->irq[i]; + int irq; + + irq = platform_get_irq_optional(pdev, i); + if (irq <= 0) + continue; + + girq->parents[i] = irq; + kmb_irq->line = girq->parents[i]; + kmb_irq->source = i; + kmb_irq->trigger = irq_get_trigger_type(girq->parents[i]); + kmb_irq->num_share = 0; + + if (kmb_irq->trigger == IRQ_TYPE_LEVEL_HIGH) + level_line++; + else + edge_line++; + } + + kpc->max_gpios_level_type = level_line * KEEMBAY_GPIO_MAX_PER_IRQ; + kpc->max_gpios_edge_type = edge_line * KEEMBAY_GPIO_MAX_PER_IRQ; + + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_bad_irq; + + return devm_gpiochip_add_data(kpc->dev, gc, kpc); +} + +static int keembay_build_groups(struct keembay_pinctrl *kpc) +{ + struct group_desc *grp; + unsigned int i; + + kpc->ngroups = kpc->npins; + grp = devm_kcalloc(kpc->dev, kpc->ngroups, sizeof(*grp), GFP_KERNEL); + if (!grp) + return -ENOMEM; + + /* Each pin is categorised as one group */ + for (i = 0; i < kpc->ngroups; i++) { + const struct pinctrl_pin_desc *pdesc = keembay_pins + i; + struct group_desc *kmb_grp = grp + i; + + kmb_grp->name = pdesc->name; + kmb_grp->pins = (int *)&pdesc->number; + pinctrl_generic_add_group(kpc->pctrl, kmb_grp->name, + kmb_grp->pins, 1, NULL); + } + + return 0; +} + +static int keembay_pinctrl_reg(struct keembay_pinctrl *kpc, struct device *dev) +{ + int ret; + + keembay_pinctrl_desc.pins = keembay_pins; + ret = of_property_read_u32(dev->of_node, "ngpios", &kpc->npins); + if (ret < 0) + return ret; + keembay_pinctrl_desc.npins = kpc->npins; + + kpc->pctrl = devm_pinctrl_register(kpc->dev, &keembay_pinctrl_desc, kpc); + + return PTR_ERR_OR_ZERO(kpc->pctrl); +} + +static int keembay_add_functions(struct keembay_pinctrl *kpc, + struct function_desc *function) +{ + unsigned int i; + + /* Assign the groups for each function */ + for (i = 0; i < kpc->npins; i++) { + const struct pinctrl_pin_desc *pdesc = keembay_pins + i; + struct keembay_mux_desc *mux = pdesc->drv_data; + + while (mux->name) { + struct function_desc *func; + const char **grp; + size_t grp_size; + u32 j, grp_num; + + for (j = 0; j < kpc->nfuncs; j++) { + if (!strcmp(mux->name, function[j].name)) + break; + } + + if (j == kpc->nfuncs) + return -EINVAL; + + func = function + j; + grp_num = func->num_group_names; + grp_size = sizeof(*func->group_names); + + if (!func->group_names) { + func->group_names = devm_kcalloc(kpc->dev, + grp_num, + grp_size, + GFP_KERNEL); + if (!func->group_names) + return -ENOMEM; + } + + grp = func->group_names; + while (*grp) + grp++; + + *grp = pdesc->name; + mux++; + } + } + + /* Add all functions */ + for (i = 0; i < kpc->nfuncs; i++) { + pinmux_generic_add_function(kpc->pctrl, + function[i].name, + function[i].group_names, + function[i].num_group_names, + function[i].data); + } + + return 0; +} + +static int keembay_build_functions(struct keembay_pinctrl *kpc) +{ + struct function_desc *keembay_funcs, *new_funcs; + int i; + + /* Allocate total number of functions */ + kpc->nfuncs = 0; + keembay_funcs = kcalloc(kpc->npins * 8, sizeof(*keembay_funcs), GFP_KERNEL); + if (!keembay_funcs) + return -ENOMEM; + + /* Find total number of functions and each's properties */ + for (i = 0; i < kpc->npins; i++) { + const struct pinctrl_pin_desc *pdesc = keembay_pins + i; + struct keembay_mux_desc *mux = pdesc->drv_data; + + while (mux->name) { + struct function_desc *fdesc = keembay_funcs; + + while (fdesc->name) { + if (!strcmp(mux->name, fdesc->name)) { + fdesc->num_group_names++; + break; + } + + fdesc++; + } + + if (!fdesc->name) { + fdesc->name = mux->name; + fdesc->num_group_names = 1; + fdesc->data = &mux->mode; + kpc->nfuncs++; + } + + mux++; + } + } + + /* Reallocate memory based on actual number of functions */ + new_funcs = krealloc(keembay_funcs, kpc->nfuncs * sizeof(*new_funcs), GFP_KERNEL); + if (!new_funcs) { + kfree(keembay_funcs); + return -ENOMEM; + } + + return keembay_add_functions(kpc, new_funcs); +} + +static const struct keembay_pin_soc keembay_data = { + .pins = keembay_pins, +}; + +static const struct of_device_id keembay_pinctrl_match[] = { + { .compatible = "intel,keembay-pinctrl", .data = &keembay_data }, + { } +}; +MODULE_DEVICE_TABLE(of, keembay_pinctrl_match); + +static int keembay_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct keembay_pinctrl *kpc; + int ret; + + kpc = devm_kzalloc(dev, sizeof(*kpc), GFP_KERNEL); + if (!kpc) + return -ENOMEM; + + kpc->dev = dev; + kpc->soc = device_get_match_data(dev); + + kpc->base0 = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(kpc->base0)) + return PTR_ERR(kpc->base0); + + kpc->base1 = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(kpc->base1)) + return PTR_ERR(kpc->base1); + + raw_spin_lock_init(&kpc->lock); + + ret = keembay_pinctrl_reg(kpc, dev); + if (ret) + return ret; + + ret = keembay_build_groups(kpc); + if (ret) + return ret; + + ret = keembay_build_functions(kpc); + if (ret) + return ret; + + ret = keembay_gpiochip_probe(kpc, pdev); + if (ret) + return ret; + + platform_set_drvdata(pdev, kpc); + + return 0; +} + +static struct platform_driver keembay_pinctrl_driver = { + .probe = keembay_pinctrl_probe, + .driver = { + .name = "keembay-pinctrl", + .of_match_table = keembay_pinctrl_match, + }, +}; +module_platform_driver(keembay_pinctrl_driver); + +MODULE_AUTHOR("Muhammad Husaini Zulkifli "); +MODULE_AUTHOR("Vijayakannan Ayyathurai "); +MODULE_AUTHOR("Lakshmi Sowjanya D "); +MODULE_DESCRIPTION("Intel Keem Bay SoC pinctrl/GPIO driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 6fadc1241c33fe0228c94bc6a1aa6c1da8872e8b Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Wed, 11 Aug 2021 08:57:06 +0530 Subject: KVM: arm64: perf: Replace '0xf' instances with ID_AA64DFR0_PMUVER_IMP_DEF ID_AA64DFR0_PMUVER_IMP_DEF which indicate implementation defined PMU, never actually gets used although there are '0xf' instances scattered all around. Just do the macro replacement to improve readability. Cc: Catalin Marinas Cc: Will Deacon Cc: Mark Rutland Cc: Peter Zijlstra Cc: Marc Zyngier Cc: linux-perf-users@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: kvmarm@lists.cs.columbia.edu Cc: linux-kernel@vger.kernel.org Signed-off-by: Anshuman Khandual Signed-off-by: Marc Zyngier --- arch/arm64/kvm/perf.c | 2 +- arch/arm64/kvm/pmu-emul.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c index 151c31fb9860..f9bb3b14130e 100644 --- a/arch/arm64/kvm/perf.c +++ b/arch/arm64/kvm/perf.c @@ -50,7 +50,7 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = { int kvm_perf_init(void) { - if (kvm_pmu_probe_pmuver() != 0xf && !is_protected_kvm_enabled()) + if (kvm_pmu_probe_pmuver() != ID_AA64DFR0_PMUVER_IMP_DEF && !is_protected_kvm_enabled()) static_branch_enable(&kvm_arm_pmu_available); return perf_register_guest_info_callbacks(&kvm_guest_cbs); diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index f33825c995cb..60f89bdbeebb 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -745,7 +745,7 @@ int kvm_pmu_probe_pmuver(void) struct perf_event_attr attr = { }; struct perf_event *event; struct arm_pmu *pmu; - int pmuver = 0xf; + int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF; /* * Create a dummy event that only counts user cycles. As we'll never @@ -770,7 +770,7 @@ int kvm_pmu_probe_pmuver(void) if (IS_ERR(event)) { pr_err_once("kvm: pmu event creation failed %ld\n", PTR_ERR(event)); - return 0xf; + return ID_AA64DFR0_PMUVER_IMP_DEF; } if (event->pmu) { @@ -923,7 +923,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) if (!vcpu->kvm->arch.pmuver) vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver(); - if (vcpu->kvm->arch.pmuver == 0xf) + if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF) return -ENODEV; switch (attr->attr) { -- cgit v1.2.3-70-g09d2 From b31578f627177bda5c16894e3170a7a6a1236136 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Tue, 10 Aug 2021 09:59:42 +0530 Subject: arm64/mm: Define ID_AA64MMFR0_TGRAN_2_SHIFT Streamline the Stage-2 TGRAN value extraction from ID_AA64MMFR0 register by adding a page size agnostic ID_AA64MMFR0_TGRAN_2_SHIFT. This is similar to the existing Stage-1 TGRAN shift i.e ID_AA64MMFR0_TGRAN_SHIFT. Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: linux-arm-kernel@lists.infradead.org Cc: kvmarm@lists.cs.columbia.edu Cc: linux-kernel@vger.kernel.org Signed-off-by: Anshuman Khandual Acked-by: Will Deacon Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1628569782-30213-1-git-send-email-anshuman.khandual@arm.com --- arch/arm64/include/asm/sysreg.h | 3 +++ arch/arm64/kvm/reset.c | 17 ++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 7b9c3acba684..943d31d92b5b 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1028,14 +1028,17 @@ #if defined(CONFIG_ARM64_4K_PAGES) #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN4_SHIFT +#define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN4_2_SHIFT #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN4_SUPPORTED #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 #elif defined(CONFIG_ARM64_16K_PAGES) #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN16_SHIFT +#define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN16_2_SHIFT #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN16_SUPPORTED #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0xF #elif defined(CONFIG_ARM64_64K_PAGES) #define ID_AA64MMFR0_TGRAN_SHIFT ID_AA64MMFR0_TGRAN64_SHIFT +#define ID_AA64MMFR0_TGRAN_2_SHIFT ID_AA64MMFR0_TGRAN64_2_SHIFT #define ID_AA64MMFR0_TGRAN_SUPPORTED_MIN ID_AA64MMFR0_TGRAN64_SUPPORTED #define ID_AA64MMFR0_TGRAN_SUPPORTED_MAX 0x7 #endif diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index cba7872d69a8..20588220fe66 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -311,7 +311,7 @@ u32 get_kvm_ipa_limit(void) int kvm_set_ipa_limit(void) { - unsigned int parange, tgran_2; + unsigned int parange; u64 mmfr0; mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); @@ -322,20 +322,7 @@ int kvm_set_ipa_limit(void) * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at * Stage-2. If not, things will stop very quickly. */ - switch (PAGE_SIZE) { - default: - case SZ_4K: - tgran_2 = ID_AA64MMFR0_TGRAN4_2_SHIFT; - break; - case SZ_16K: - tgran_2 = ID_AA64MMFR0_TGRAN16_2_SHIFT; - break; - case SZ_64K: - tgran_2 = ID_AA64MMFR0_TGRAN64_2_SHIFT; - break; - } - - switch (cpuid_feature_extract_unsigned_field(mmfr0, tgran_2)) { + switch (cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_TGRAN_2_SHIFT)) { case ID_AA64MMFR0_TGRAN_2_SUPPORTED_NONE: kvm_err("PAGE_SIZE not supported at Stage-2, giving up\n"); return -EINVAL; -- cgit v1.2.3-70-g09d2 From 5e5df9571c319fb107d7a523cc96fcc99961ee70 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Wed, 11 Aug 2021 16:41:15 +0530 Subject: KVM: arm64: Restrict IPA size to maximum 48 bits on 4K and 16K page size Even though ID_AA64MMFR0.PARANGE reports 52 bit PA size support, it cannot be enabled as guest IPA size on 4K or 16K page size configurations. Hence kvm_ipa_limit must be restricted to 48 bits. This change achieves required IPA capping. Before the commit c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration"), the problem here would have been just latent via PHYS_MASK_SHIFT (which earlier in turn capped kvm_ipa_limit), which remains capped at 48 bits on 4K and 16K configs. Cc: Marc Zyngier Cc: James Morse Cc: Alexandru Elisei Cc: Suzuki K Poulose Cc: Catalin Marinas Cc: Will Deacon Cc: linux-arm-kernel@lists.infradead.org Cc: kvmarm@lists.cs.columbia.edu Cc: linux-kernel@vger.kernel.org Fixes: c9b69a0cf0b4 ("KVM: arm64: Don't constrain maximum IPA size based on host configuration") Signed-off-by: Anshuman Khandual Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1628680275-16578-1-git-send-email-anshuman.khandual@arm.com --- arch/arm64/kvm/reset.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index 20588220fe66..18ffc6ad67b8 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -317,6 +317,14 @@ int kvm_set_ipa_limit(void) mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1); parange = cpuid_feature_extract_unsigned_field(mmfr0, ID_AA64MMFR0_PARANGE_SHIFT); + /* + * IPA size beyond 48 bits could not be supported + * on either 4K or 16K page size. Hence let's cap + * it to 48 bits, in case it's reported as larger + * on the system. + */ + if (PAGE_SIZE != SZ_64K) + parange = min(parange, (unsigned int)ID_AA64MMFR0_PARANGE_48); /* * Check with ARMv8.5-GTG that our PAGE_SIZE is supported at -- cgit v1.2.3-70-g09d2 From e1706f0764f8bea42db8d33df5d7f9e754b89693 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:18:57 -0300 Subject: vfio/samples: Remove module get/put The patch to move the get/put to core and the patch to convert the samples to use vfio_device crossed in a way that this was missed. When both patches are together the samples do not need their own get/put. Fixes: 437e41368c01 ("vfio/mdpy: Convert to use vfio_register_group_dev()") Fixes: 681c1615f891 ("vfio/mbochs: Convert to use vfio_register_group_dev()") Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Max Gurtovoy Link: https://lore.kernel.org/r/1-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- samples/vfio-mdev/mbochs.c | 4 ---- samples/vfio-mdev/mdpy.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 6c0f229db36a..e81b875b4d87 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1274,9 +1274,6 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, static int mbochs_open(struct vfio_device *vdev) { - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - return 0; } @@ -1300,7 +1297,6 @@ static void mbochs_close(struct vfio_device *vdev) mbochs_put_pages(mdev_state); mutex_unlock(&mdev_state->ops_lock); - module_put(THIS_MODULE); } static ssize_t diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 393c9df6f6a0..a7d4ed28d664 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -611,15 +611,11 @@ static long mdpy_ioctl(struct vfio_device *vdev, unsigned int cmd, static int mdpy_open(struct vfio_device *vdev) { - if (!try_module_get(THIS_MODULE)) - return -ENODEV; - return 0; } static void mdpy_close(struct vfio_device *vdev) { - module_put(THIS_MODULE); } static ssize_t -- cgit v1.2.3-70-g09d2 From de5494af4815a4c9328536c72741229b7de88e7f Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:18:58 -0300 Subject: vfio/mbochs: Fix missing error unwind of mbochs_used_mbytes Convert mbochs to use an atomic scheme for this like mtty was changed into. The atomic fixes various race conditions with probing. Add the missing error unwind. Also add the missing kfree of mdev_state->pages. Fixes: 681c1615f891 ("vfio/mbochs: Convert to use vfio_register_group_dev()") Reported-by: Cornelia Huck Co-developed-by: Alex Williamson Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/2-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- samples/vfio-mdev/mbochs.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index e81b875b4d87..3e885be7d076 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -129,7 +129,7 @@ static dev_t mbochs_devt; static struct class *mbochs_class; static struct cdev mbochs_cdev; static struct device mbochs_dev; -static int mbochs_used_mbytes; +static atomic_t mbochs_avail_mbytes; static const struct vfio_device_ops mbochs_dev_ops; struct vfio_region_info_ext { @@ -507,18 +507,22 @@ static int mbochs_reset(struct mdev_state *mdev_state) static int mbochs_probe(struct mdev_device *mdev) { + int avail_mbytes = atomic_read(&mbochs_avail_mbytes); const struct mbochs_type *type = &mbochs_types[mdev_get_type_group_id(mdev)]; struct device *dev = mdev_dev(mdev); struct mdev_state *mdev_state; int ret = -ENOMEM; - if (type->mbytes + mbochs_used_mbytes > max_mbytes) - return -ENOMEM; + do { + if (avail_mbytes < type->mbytes) + return -ENOSPC; + } while (!atomic_try_cmpxchg(&mbochs_avail_mbytes, &avail_mbytes, + avail_mbytes - type->mbytes)); mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL); if (mdev_state == NULL) - return -ENOMEM; + goto err_avail; vfio_init_group_dev(&mdev_state->vdev, &mdev->dev, &mbochs_dev_ops); mdev_state->vconfig = kzalloc(MBOCHS_CONFIG_SPACE_SIZE, GFP_KERNEL); @@ -549,17 +553,17 @@ static int mbochs_probe(struct mdev_device *mdev) mbochs_create_config_space(mdev_state); mbochs_reset(mdev_state); - mbochs_used_mbytes += type->mbytes; - ret = vfio_register_group_dev(&mdev_state->vdev); if (ret) goto err_mem; dev_set_drvdata(&mdev->dev, mdev_state); return 0; - err_mem: + kfree(mdev_state->pages); kfree(mdev_state->vconfig); kfree(mdev_state); +err_avail: + atomic_add(type->mbytes, &mbochs_avail_mbytes); return ret; } @@ -567,8 +571,8 @@ static void mbochs_remove(struct mdev_device *mdev) { struct mdev_state *mdev_state = dev_get_drvdata(&mdev->dev); - mbochs_used_mbytes -= mdev_state->type->mbytes; vfio_unregister_group_dev(&mdev_state->vdev); + atomic_add(mdev_state->type->mbytes, &mbochs_avail_mbytes); kfree(mdev_state->pages); kfree(mdev_state->vconfig); kfree(mdev_state); @@ -1351,7 +1355,7 @@ static ssize_t available_instances_show(struct mdev_type *mtype, { const struct mbochs_type *type = &mbochs_types[mtype_get_type_group_id(mtype)]; - int count = (max_mbytes - mbochs_used_mbytes) / type->mbytes; + int count = atomic_read(&mbochs_avail_mbytes) / type->mbytes; return sprintf(buf, "%d\n", count); } @@ -1433,6 +1437,8 @@ static int __init mbochs_dev_init(void) { int ret = 0; + atomic_set(&mbochs_avail_mbytes, max_mbytes); + ret = alloc_chrdev_region(&mbochs_devt, 0, MINORMASK + 1, MBOCHS_NAME); if (ret < 0) { pr_err("Error: failed to register mbochs_dev, err: %d\n", ret); -- cgit v1.2.3-70-g09d2 From ae03c3771b8cbbed3802ad1153d896c32015c520 Mon Sep 17 00:00:00 2001 From: Max Gurtovoy Date: Thu, 5 Aug 2021 22:18:59 -0300 Subject: vfio: Introduce a vfio_uninit_group_dev() API call This pairs with vfio_init_group_dev() and allows undoing any state that is stored in the vfio_device unrelated to registration. Add appropriately placed calls to all the drivers. The following patch will use this to add pre-registration state for the device set. Signed-off-by: Max Gurtovoy Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/3-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- Documentation/driver-api/vfio.rst | 4 +++- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 7 ++++--- drivers/vfio/mdev/vfio_mdev.c | 13 +++++++++---- drivers/vfio/pci/vfio_pci.c | 6 ++++-- drivers/vfio/platform/vfio_platform_common.c | 7 +++++-- drivers/vfio/vfio.c | 5 +++++ include/linux/vfio.h | 1 + samples/vfio-mdev/mbochs.c | 2 ++ samples/vfio-mdev/mdpy.c | 25 +++++++++++++++---------- samples/vfio-mdev/mtty.c | 27 ++++++++++++++++----------- 10 files changed, 64 insertions(+), 33 deletions(-) diff --git a/Documentation/driver-api/vfio.rst b/Documentation/driver-api/vfio.rst index 606eed8823ce..c663b6f97825 100644 --- a/Documentation/driver-api/vfio.rst +++ b/Documentation/driver-api/vfio.rst @@ -255,11 +255,13 @@ vfio_unregister_group_dev() respectively:: void vfio_init_group_dev(struct vfio_device *device, struct device *dev, const struct vfio_device_ops *ops); + void vfio_uninit_group_dev(struct vfio_device *device); int vfio_register_group_dev(struct vfio_device *device); void vfio_unregister_group_dev(struct vfio_device *device); The driver should embed the vfio_device in its own structure and call -vfio_init_group_dev() to pre-configure it before going to registration. +vfio_init_group_dev() to pre-configure it before going to registration +and call vfio_uninit_group_dev() after completing the un-registration. vfio_register_group_dev() indicates to the core to begin tracking the iommu_group of the specified dev and register the dev as owned by a VFIO bus driver. Once vfio_register_group_dev() returns it is possible for userspace to diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 90cad109583b..122997c61ba4 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -627,7 +627,7 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) ret = vfio_fsl_mc_reflck_attach(vdev); if (ret) - goto out_kfree; + goto out_uninit; ret = vfio_fsl_mc_init_device(vdev); if (ret) @@ -657,7 +657,8 @@ out_device: vfio_fsl_uninit_device(vdev); out_reflck: vfio_fsl_mc_reflck_put(vdev->reflck); -out_kfree: +out_uninit: + vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); out_group_put: vfio_iommu_group_put(group, dev); @@ -675,7 +676,7 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) dprc_remove_devices(mc_dev, NULL, 0); vfio_fsl_uninit_device(vdev); vfio_fsl_mc_reflck_put(vdev->reflck); - + vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); vfio_iommu_group_put(mc_dev->dev.iommu_group, dev); diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index 39ef7489fe47..a5c77ccb24f7 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -120,12 +120,16 @@ static int vfio_mdev_probe(struct mdev_device *mdev) vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops); ret = vfio_register_group_dev(vdev); - if (ret) { - kfree(vdev); - return ret; - } + if (ret) + goto out_uninit; + dev_set_drvdata(&mdev->dev, vdev); return 0; + +out_uninit: + vfio_uninit_group_dev(vdev); + kfree(vdev); + return ret; } static void vfio_mdev_remove(struct mdev_device *mdev) @@ -133,6 +137,7 @@ static void vfio_mdev_remove(struct mdev_device *mdev) struct vfio_device *vdev = dev_get_drvdata(&mdev->dev); vfio_unregister_group_dev(vdev); + vfio_uninit_group_dev(vdev); kfree(vdev); } diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 318864d52837..fab3715d60d4 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -2022,7 +2022,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = vfio_pci_reflck_attach(vdev); if (ret) - goto out_free; + goto out_uninit; ret = vfio_pci_vf_init(vdev); if (ret) goto out_reflck; @@ -2059,7 +2059,8 @@ out_vf: vfio_pci_vf_uninit(vdev); out_reflck: vfio_pci_reflck_put(vdev->reflck); -out_free: +out_uninit: + vfio_uninit_group_dev(&vdev->vdev); kfree(vdev->pm_save); kfree(vdev); out_group_put: @@ -2077,6 +2078,7 @@ static void vfio_pci_remove(struct pci_dev *pdev) vfio_pci_vf_uninit(vdev); vfio_pci_reflck_put(vdev->reflck); + vfio_uninit_group_dev(&vdev->vdev); vfio_pci_vga_uninit(vdev); vfio_iommu_group_put(pdev->dev.iommu_group, &pdev->dev); diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index 703164df7637..bdde8605178c 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -667,7 +667,7 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev, ret = vfio_platform_of_probe(vdev, dev); if (ret) - return ret; + goto out_uninit; vdev->device = dev; @@ -675,7 +675,7 @@ int vfio_platform_probe_common(struct vfio_platform_device *vdev, if (ret && vdev->reset_required) { dev_err(dev, "No reset function found for device %s\n", vdev->name); - return ret; + goto out_uninit; } group = vfio_iommu_group_get(dev); @@ -698,6 +698,8 @@ put_iommu: vfio_iommu_group_put(group, dev); put_reset: vfio_platform_put_reset(vdev); +out_uninit: + vfio_uninit_group_dev(&vdev->vdev); return ret; } EXPORT_SYMBOL_GPL(vfio_platform_probe_common); @@ -708,6 +710,7 @@ void vfio_platform_remove_common(struct vfio_platform_device *vdev) pm_runtime_disable(vdev->device); vfio_platform_put_reset(vdev); + vfio_uninit_group_dev(&vdev->vdev); vfio_iommu_group_put(vdev->vdev.dev->iommu_group, vdev->vdev.dev); } EXPORT_SYMBOL_GPL(vfio_platform_remove_common); diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 02cc51ce6891..cc375df0fd5d 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -749,6 +749,11 @@ void vfio_init_group_dev(struct vfio_device *device, struct device *dev, } EXPORT_SYMBOL_GPL(vfio_init_group_dev); +void vfio_uninit_group_dev(struct vfio_device *device) +{ +} +EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); + int vfio_register_group_dev(struct vfio_device *device) { struct vfio_device *existing_device; diff --git a/include/linux/vfio.h b/include/linux/vfio.h index a2c5b30e1763..b0875cf8e496 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -61,6 +61,7 @@ extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); void vfio_init_group_dev(struct vfio_device *device, struct device *dev, const struct vfio_device_ops *ops); +void vfio_uninit_group_dev(struct vfio_device *device); int vfio_register_group_dev(struct vfio_device *device); void vfio_unregister_group_dev(struct vfio_device *device); extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 3e885be7d076..0f1511849b7c 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -559,6 +559,7 @@ static int mbochs_probe(struct mdev_device *mdev) dev_set_drvdata(&mdev->dev, mdev_state); return 0; err_mem: + vfio_uninit_group_dev(&mdev_state->vdev); kfree(mdev_state->pages); kfree(mdev_state->vconfig); kfree(mdev_state); @@ -572,6 +573,7 @@ static void mbochs_remove(struct mdev_device *mdev) struct mdev_state *mdev_state = dev_get_drvdata(&mdev->dev); vfio_unregister_group_dev(&mdev_state->vdev); + vfio_uninit_group_dev(&mdev_state->vdev); atomic_add(mdev_state->type->mbytes, &mbochs_avail_mbytes); kfree(mdev_state->pages); kfree(mdev_state->vconfig); diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index a7d4ed28d664..57334034cde6 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -235,17 +235,16 @@ static int mdpy_probe(struct mdev_device *mdev) mdev_state->vconfig = kzalloc(MDPY_CONFIG_SPACE_SIZE, GFP_KERNEL); if (mdev_state->vconfig == NULL) { - kfree(mdev_state); - return -ENOMEM; + ret = -ENOMEM; + goto err_state; } fbsize = roundup_pow_of_two(type->width * type->height * type->bytepp); mdev_state->memblk = vmalloc_user(fbsize); if (!mdev_state->memblk) { - kfree(mdev_state->vconfig); - kfree(mdev_state); - return -ENOMEM; + ret = -ENOMEM; + goto err_vconfig; } dev_info(dev, "%s: %s (%dx%d)\n", __func__, type->name, type->width, type->height); @@ -260,13 +259,18 @@ static int mdpy_probe(struct mdev_device *mdev) mdpy_count++; ret = vfio_register_group_dev(&mdev_state->vdev); - if (ret) { - kfree(mdev_state->vconfig); - kfree(mdev_state); - return ret; - } + if (ret) + goto err_mem; dev_set_drvdata(&mdev->dev, mdev_state); return 0; +err_mem: + vfree(mdev_state->memblk); +err_vconfig: + kfree(mdev_state->vconfig); +err_state: + vfio_uninit_group_dev(&mdev_state->vdev); + kfree(mdev_state); + return ret; } static void mdpy_remove(struct mdev_device *mdev) @@ -278,6 +282,7 @@ static void mdpy_remove(struct mdev_device *mdev) vfio_unregister_group_dev(&mdev_state->vdev); vfree(mdev_state->memblk); kfree(mdev_state->vconfig); + vfio_uninit_group_dev(&mdev_state->vdev); kfree(mdev_state); mdpy_count--; diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 8b26fecc4afe..37cc9067e160 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -718,8 +718,8 @@ static int mtty_probe(struct mdev_device *mdev) mdev_state = kzalloc(sizeof(struct mdev_state), GFP_KERNEL); if (mdev_state == NULL) { - atomic_add(nr_ports, &mdev_avail_ports); - return -ENOMEM; + ret = -ENOMEM; + goto err_nr_ports; } vfio_init_group_dev(&mdev_state->vdev, &mdev->dev, &mtty_dev_ops); @@ -732,9 +732,8 @@ static int mtty_probe(struct mdev_device *mdev) mdev_state->vconfig = kzalloc(MTTY_CONFIG_SPACE_SIZE, GFP_KERNEL); if (mdev_state->vconfig == NULL) { - kfree(mdev_state); - atomic_add(nr_ports, &mdev_avail_ports); - return -ENOMEM; + ret = -ENOMEM; + goto err_state; } mutex_init(&mdev_state->ops_lock); @@ -743,14 +742,19 @@ static int mtty_probe(struct mdev_device *mdev) mtty_create_config_space(mdev_state); ret = vfio_register_group_dev(&mdev_state->vdev); - if (ret) { - kfree(mdev_state); - atomic_add(nr_ports, &mdev_avail_ports); - return ret; - } - + if (ret) + goto err_vconfig; dev_set_drvdata(&mdev->dev, mdev_state); return 0; + +err_vconfig: + kfree(mdev_state->vconfig); +err_state: + vfio_uninit_group_dev(&mdev_state->vdev); + kfree(mdev_state); +err_nr_ports: + atomic_add(nr_ports, &mdev_avail_ports); + return ret; } static void mtty_remove(struct mdev_device *mdev) @@ -761,6 +765,7 @@ static void mtty_remove(struct mdev_device *mdev) vfio_unregister_group_dev(&mdev_state->vdev); kfree(mdev_state->vconfig); + vfio_uninit_group_dev(&mdev_state->vdev); kfree(mdev_state); atomic_add(nr_ports, &mdev_avail_ports); } -- cgit v1.2.3-70-g09d2 From 2fd585f4ed9de9b9259e95affdd7d8cde06b48c3 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:00 -0300 Subject: vfio: Provide better generic support for open/release vfio_device_ops Currently the driver ops have an open/release pair that is called once each time a device FD is opened or closed. Add an additional set of open/close_device() ops which are called when the device FD is opened for the first time and closed for the last time. An analysis shows that all of the drivers require this semantic. Some are open coding it as part of their reflck implementation, and some are just buggy and miss it completely. To retain the current semantics PCI and FSL depend on, introduce the idea of a "device set" which is a grouping of vfio_device's that share the same lock around opening. The device set is established by providing a 'set_id' pointer. All vfio_device's that provide the same pointer will be joined to the same singleton memory and lock across the whole set. This effectively replaces the oddly named reflck. After conversion the set_id will be sourced from: - A struct device from a fsl_mc_device (fsl) - A struct pci_slot (pci) - A struct pci_bus (pci) - The struct vfio_device (everything) The design ensures that the above pointers are live as long as the vfio_device is registered, so they form reliable unique keys to group vfio_devices into sets. This implementation uses xarray instead of searching through the driver core structures, which simplifies the somewhat tricky locking in this area. Following patches convert all the drivers. Signed-off-by: Yishai Hadas Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/4-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/mdev/vfio_mdev.c | 26 +++++++- drivers/vfio/vfio.c | 149 +++++++++++++++++++++++++++++++++++------- include/linux/mdev.h | 2 + include/linux/vfio.h | 21 ++++++ 4 files changed, 174 insertions(+), 24 deletions(-) diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index a5c77ccb24f7..e12196ffd487 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -17,13 +17,33 @@ #include "mdev_private.h" +static int vfio_mdev_open_device(struct vfio_device *core_vdev) +{ + struct mdev_device *mdev = to_mdev_device(core_vdev->dev); + struct mdev_parent *parent = mdev->type->parent; + + if (unlikely(!parent->ops->open_device)) + return 0; + + return parent->ops->open_device(mdev); +} + +static void vfio_mdev_close_device(struct vfio_device *core_vdev) +{ + struct mdev_device *mdev = to_mdev_device(core_vdev->dev); + struct mdev_parent *parent = mdev->type->parent; + + if (likely(parent->ops->close_device)) + parent->ops->close_device(mdev); +} + static int vfio_mdev_open(struct vfio_device *core_vdev) { struct mdev_device *mdev = to_mdev_device(core_vdev->dev); struct mdev_parent *parent = mdev->type->parent; if (unlikely(!parent->ops->open)) - return -EINVAL; + return 0; return parent->ops->open(mdev); } @@ -44,7 +64,7 @@ static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev, struct mdev_parent *parent = mdev->type->parent; if (unlikely(!parent->ops->ioctl)) - return -EINVAL; + return 0; return parent->ops->ioctl(mdev, cmd, arg); } @@ -100,6 +120,8 @@ static void vfio_mdev_request(struct vfio_device *core_vdev, unsigned int count) static const struct vfio_device_ops vfio_mdev_dev_ops = { .name = "vfio-mdev", + .open_device = vfio_mdev_open_device, + .close_device = vfio_mdev_close_device, .open = vfio_mdev_open, .release = vfio_mdev_release, .ioctl = vfio_mdev_unlocked_ioctl, diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index cc375df0fd5d..9cc17768c425 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -96,6 +96,79 @@ module_param_named(enable_unsafe_noiommu_mode, MODULE_PARM_DESC(enable_unsafe_noiommu_mode, "Enable UNSAFE, no-IOMMU mode. This mode provides no device isolation, no DMA translation, no host kernel protection, cannot be used for device assignment to virtual machines, requires RAWIO permissions, and will taint the kernel. If you do not know what this is for, step away. (default: false)"); #endif +static DEFINE_XARRAY(vfio_device_set_xa); + +int vfio_assign_device_set(struct vfio_device *device, void *set_id) +{ + unsigned long idx = (unsigned long)set_id; + struct vfio_device_set *new_dev_set; + struct vfio_device_set *dev_set; + + if (WARN_ON(!set_id)) + return -EINVAL; + + /* + * Atomically acquire a singleton object in the xarray for this set_id + */ + xa_lock(&vfio_device_set_xa); + dev_set = xa_load(&vfio_device_set_xa, idx); + if (dev_set) + goto found_get_ref; + xa_unlock(&vfio_device_set_xa); + + new_dev_set = kzalloc(sizeof(*new_dev_set), GFP_KERNEL); + if (!new_dev_set) + return -ENOMEM; + mutex_init(&new_dev_set->lock); + INIT_LIST_HEAD(&new_dev_set->device_list); + new_dev_set->set_id = set_id; + + xa_lock(&vfio_device_set_xa); + dev_set = __xa_cmpxchg(&vfio_device_set_xa, idx, NULL, new_dev_set, + GFP_KERNEL); + if (!dev_set) { + dev_set = new_dev_set; + goto found_get_ref; + } + + kfree(new_dev_set); + if (xa_is_err(dev_set)) { + xa_unlock(&vfio_device_set_xa); + return xa_err(dev_set); + } + +found_get_ref: + dev_set->device_count++; + xa_unlock(&vfio_device_set_xa); + mutex_lock(&dev_set->lock); + device->dev_set = dev_set; + list_add_tail(&device->dev_set_list, &dev_set->device_list); + mutex_unlock(&dev_set->lock); + return 0; +} +EXPORT_SYMBOL_GPL(vfio_assign_device_set); + +static void vfio_release_device_set(struct vfio_device *device) +{ + struct vfio_device_set *dev_set = device->dev_set; + + if (!dev_set) + return; + + mutex_lock(&dev_set->lock); + list_del(&device->dev_set_list); + mutex_unlock(&dev_set->lock); + + xa_lock(&vfio_device_set_xa); + if (!--dev_set->device_count) { + __xa_erase(&vfio_device_set_xa, + (unsigned long)dev_set->set_id); + mutex_destroy(&dev_set->lock); + kfree(dev_set); + } + xa_unlock(&vfio_device_set_xa); +} + /* * vfio_iommu_group_{get,put} are only intended for VFIO bus driver probe * and remove functions, any use cases other than acquiring the first @@ -751,6 +824,7 @@ EXPORT_SYMBOL_GPL(vfio_init_group_dev); void vfio_uninit_group_dev(struct vfio_device *device) { + vfio_release_device_set(device); } EXPORT_SYMBOL_GPL(vfio_uninit_group_dev); @@ -760,6 +834,13 @@ int vfio_register_group_dev(struct vfio_device *device) struct iommu_group *iommu_group; struct vfio_group *group; + /* + * If the driver doesn't specify a set then the device is added to a + * singleton set just for itself. + */ + if (!device->dev_set) + vfio_assign_device_set(device, device); + iommu_group = iommu_group_get(device->dev); if (!iommu_group) return -EINVAL; @@ -1361,7 +1442,8 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) { struct vfio_device *device; struct file *filep; - int ret; + int fdno; + int ret = 0; if (0 == atomic_read(&group->container_users) || !group->container->iommu_driver || !vfio_group_viable(group)) @@ -1375,38 +1457,38 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) return PTR_ERR(device); if (!try_module_get(device->dev->driver->owner)) { - vfio_device_put(device); - return -ENODEV; + ret = -ENODEV; + goto err_device_put; } - ret = device->ops->open(device); - if (ret) { - module_put(device->dev->driver->owner); - vfio_device_put(device); - return ret; + mutex_lock(&device->dev_set->lock); + device->open_count++; + if (device->open_count == 1 && device->ops->open_device) { + ret = device->ops->open_device(device); + if (ret) + goto err_undo_count; + } + mutex_unlock(&device->dev_set->lock); + + if (device->ops->open) { + ret = device->ops->open(device); + if (ret) + goto err_close_device; } /* * We can't use anon_inode_getfd() because we need to modify * the f_mode flags directly to allow more than just ioctls */ - ret = get_unused_fd_flags(O_CLOEXEC); - if (ret < 0) { - device->ops->release(device); - module_put(device->dev->driver->owner); - vfio_device_put(device); - return ret; - } + fdno = ret = get_unused_fd_flags(O_CLOEXEC); + if (ret < 0) + goto err_release; filep = anon_inode_getfile("[vfio-device]", &vfio_device_fops, device, O_RDWR); if (IS_ERR(filep)) { - put_unused_fd(ret); ret = PTR_ERR(filep); - device->ops->release(device); - module_put(device->dev->driver->owner); - vfio_device_put(device); - return ret; + goto err_fd; } /* @@ -1418,12 +1500,28 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) atomic_inc(&group->container_users); - fd_install(ret, filep); + fd_install(fdno, filep); if (group->noiommu) dev_warn(device->dev, "vfio-noiommu device opened by user " "(%s:%d)\n", current->comm, task_pid_nr(current)); + return fdno; +err_fd: + put_unused_fd(fdno); +err_release: + if (device->ops->release) + device->ops->release(device); +err_close_device: + mutex_lock(&device->dev_set->lock); + if (device->open_count == 1 && device->ops->close_device) + device->ops->close_device(device); +err_undo_count: + device->open_count--; + mutex_unlock(&device->dev_set->lock); + module_put(device->dev->driver->owner); +err_device_put: + vfio_device_put(device); return ret; } @@ -1561,7 +1659,13 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) { struct vfio_device *device = filep->private_data; - device->ops->release(device); + if (device->ops->release) + device->ops->release(device); + + mutex_lock(&device->dev_set->lock); + if (!--device->open_count && device->ops->close_device) + device->ops->close_device(device); + mutex_unlock(&device->dev_set->lock); module_put(device->dev->driver->owner); @@ -2364,6 +2468,7 @@ static void __exit vfio_cleanup(void) class_destroy(vfio.class); vfio.class = NULL; misc_deregister(&vfio_dev); + xa_destroy(&vfio_device_set_xa); } module_init(vfio_init); diff --git a/include/linux/mdev.h b/include/linux/mdev.h index 3a38598c2605..cb5b7ed1d7c3 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -111,6 +111,8 @@ struct mdev_parent_ops { int (*create)(struct mdev_device *mdev); int (*remove)(struct mdev_device *mdev); + int (*open_device)(struct mdev_device *mdev); + void (*close_device)(struct mdev_device *mdev); int (*open)(struct mdev_device *mdev); void (*release)(struct mdev_device *mdev); ssize_t (*read)(struct mdev_device *mdev, char __user *buf, diff --git a/include/linux/vfio.h b/include/linux/vfio.h index b0875cf8e496..f0e6a72875e4 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -15,13 +15,28 @@ #include #include +/* + * VFIO devices can be placed in a set, this allows all devices to share this + * structure and the VFIO core will provide a lock that is held around + * open_device()/close_device() for all devices in the set. + */ +struct vfio_device_set { + void *set_id; + struct mutex lock; + struct list_head device_list; + unsigned int device_count; +}; + struct vfio_device { struct device *dev; const struct vfio_device_ops *ops; struct vfio_group *group; + struct vfio_device_set *dev_set; + struct list_head dev_set_list; /* Members below here are private, not for driver use */ refcount_t refcount; + unsigned int open_count; struct completion comp; struct list_head group_next; }; @@ -29,6 +44,8 @@ struct vfio_device { /** * struct vfio_device_ops - VFIO bus driver device callbacks * + * @open_device: Called when the first file descriptor is opened for this device + * @close_device: Opposite of open_device * @open: Called when userspace creates new file descriptor for device * @release: Called when userspace releases file descriptor for device * @read: Perform read(2) on device file descriptor @@ -43,6 +60,8 @@ struct vfio_device { */ struct vfio_device_ops { char *name; + int (*open_device)(struct vfio_device *vdev); + void (*close_device)(struct vfio_device *vdev); int (*open)(struct vfio_device *vdev); void (*release)(struct vfio_device *vdev); ssize_t (*read)(struct vfio_device *vdev, char __user *buf, @@ -67,6 +86,8 @@ void vfio_unregister_group_dev(struct vfio_device *device); extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); extern void vfio_device_put(struct vfio_device *device); +int vfio_assign_device_set(struct vfio_device *device, void *set_id); + /* events for the backend driver notify callback */ enum vfio_iommu_notify_type { VFIO_IOMMU_CONTAINER_CLOSE = 0, -- cgit v1.2.3-70-g09d2 From 17a1e4fa3f7f07f541c751745b5aa6f2fcab9a48 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:01 -0300 Subject: vfio/samples: Delete useless open/close The core code no longer requires these ops to be defined, so delete these empty functions and leave the op as NULL. mtty's functions only log a pointless message, delete that entirely. Signed-off-by: Yishai Hadas Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/5-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- samples/vfio-mdev/mbochs.c | 6 ------ samples/vfio-mdev/mdpy.c | 11 ----------- samples/vfio-mdev/mtty.c | 13 ------------- 3 files changed, 30 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 0f1511849b7c..7b2e12fe7082 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1278,11 +1278,6 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mbochs_open(struct vfio_device *vdev) -{ - return 0; -} - static void mbochs_close(struct vfio_device *vdev) { struct mdev_state *mdev_state = @@ -1401,7 +1396,6 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mbochs_dev_ops = { - .open = mbochs_open, .release = mbochs_close, .read = mbochs_read, .write = mbochs_write, diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c index 57334034cde6..8d1a80a0722a 100644 --- a/samples/vfio-mdev/mdpy.c +++ b/samples/vfio-mdev/mdpy.c @@ -614,15 +614,6 @@ static long mdpy_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mdpy_open(struct vfio_device *vdev) -{ - return 0; -} - -static void mdpy_close(struct vfio_device *vdev) -{ -} - static ssize_t resolution_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -717,8 +708,6 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mdpy_dev_ops = { - .open = mdpy_open, - .release = mdpy_close, .read = mdpy_read, .write = mdpy_write, .ioctl = mdpy_ioctl, diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c index 37cc9067e160..5983cdb16e3d 100644 --- a/samples/vfio-mdev/mtty.c +++ b/samples/vfio-mdev/mtty.c @@ -1207,17 +1207,6 @@ static long mtty_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static int mtty_open(struct vfio_device *vdev) -{ - pr_info("%s\n", __func__); - return 0; -} - -static void mtty_close(struct vfio_device *mdev) -{ - pr_info("%s\n", __func__); -} - static ssize_t sample_mtty_dev_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1325,8 +1314,6 @@ static struct attribute_group *mdev_type_groups[] = { static const struct vfio_device_ops mtty_dev_ops = { .name = "vfio-mtty", - .open = mtty_open, - .release = mtty_close, .read = mtty_read, .write = mtty_write, .ioctl = mtty_ioctl, -- cgit v1.2.3-70-g09d2 From da119f387e94642da959a22ae9c22e09abe34926 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:02 -0300 Subject: vfio/fsl: Move to the device set infrastructure FSL uses the internal reflck to implement the open_device() functionality, conversion to the core code is straightforward. The decision on which set to be part of is trivially based on the is_fsl_mc_bus_dprc() and we use a 'struct device *' pointer as the set_id. The dev_set lock is protecting the interrupts setup. The FSL MC devices are using MSIs and only the DPRC device is allocating the MSIs from the MSI domain. The other devices just take interrupts from a pool. The lock is protecting the access to this pool. Signed-off-by: Yishai Hadas Tested-by: Diana Craciun OSS Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/6-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/fsl-mc/vfio_fsl_mc.c | 154 +++++------------------------- drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c | 6 +- drivers/vfio/fsl-mc/vfio_fsl_mc_private.h | 7 -- 3 files changed, 28 insertions(+), 139 deletions(-) diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 122997c61ba4..0ead91bfa838 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -19,81 +19,10 @@ static struct fsl_mc_driver vfio_fsl_mc_driver; -static DEFINE_MUTEX(reflck_lock); - -static void vfio_fsl_mc_reflck_get(struct vfio_fsl_mc_reflck *reflck) -{ - kref_get(&reflck->kref); -} - -static void vfio_fsl_mc_reflck_release(struct kref *kref) -{ - struct vfio_fsl_mc_reflck *reflck = container_of(kref, - struct vfio_fsl_mc_reflck, - kref); - - mutex_destroy(&reflck->lock); - kfree(reflck); - mutex_unlock(&reflck_lock); -} - -static void vfio_fsl_mc_reflck_put(struct vfio_fsl_mc_reflck *reflck) -{ - kref_put_mutex(&reflck->kref, vfio_fsl_mc_reflck_release, &reflck_lock); -} - -static struct vfio_fsl_mc_reflck *vfio_fsl_mc_reflck_alloc(void) -{ - struct vfio_fsl_mc_reflck *reflck; - - reflck = kzalloc(sizeof(*reflck), GFP_KERNEL); - if (!reflck) - return ERR_PTR(-ENOMEM); - - kref_init(&reflck->kref); - mutex_init(&reflck->lock); - - return reflck; -} - -static int vfio_fsl_mc_reflck_attach(struct vfio_fsl_mc_device *vdev) -{ - int ret = 0; - - mutex_lock(&reflck_lock); - if (is_fsl_mc_bus_dprc(vdev->mc_dev)) { - vdev->reflck = vfio_fsl_mc_reflck_alloc(); - ret = PTR_ERR_OR_ZERO(vdev->reflck); - } else { - struct device *mc_cont_dev = vdev->mc_dev->dev.parent; - struct vfio_device *device; - struct vfio_fsl_mc_device *cont_vdev; - - device = vfio_device_get_from_dev(mc_cont_dev); - if (!device) { - ret = -ENODEV; - goto unlock; - } - - cont_vdev = - container_of(device, struct vfio_fsl_mc_device, vdev); - if (!cont_vdev || !cont_vdev->reflck) { - vfio_device_put(device); - ret = -ENODEV; - goto unlock; - } - vfio_fsl_mc_reflck_get(cont_vdev->reflck); - vdev->reflck = cont_vdev->reflck; - vfio_device_put(device); - } - -unlock: - mutex_unlock(&reflck_lock); - return ret; -} - -static int vfio_fsl_mc_regions_init(struct vfio_fsl_mc_device *vdev) +static int vfio_fsl_mc_open_device(struct vfio_device *core_vdev) { + struct vfio_fsl_mc_device *vdev = + container_of(core_vdev, struct vfio_fsl_mc_device, vdev); struct fsl_mc_device *mc_dev = vdev->mc_dev; int count = mc_dev->obj_desc.region_count; int i; @@ -136,58 +65,30 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev) kfree(vdev->regions); } -static int vfio_fsl_mc_open(struct vfio_device *core_vdev) -{ - struct vfio_fsl_mc_device *vdev = - container_of(core_vdev, struct vfio_fsl_mc_device, vdev); - int ret = 0; - - mutex_lock(&vdev->reflck->lock); - if (!vdev->refcnt) { - ret = vfio_fsl_mc_regions_init(vdev); - if (ret) - goto out; - } - vdev->refcnt++; -out: - mutex_unlock(&vdev->reflck->lock); - return ret; -} - -static void vfio_fsl_mc_release(struct vfio_device *core_vdev) +static void vfio_fsl_mc_close_device(struct vfio_device *core_vdev) { struct vfio_fsl_mc_device *vdev = container_of(core_vdev, struct vfio_fsl_mc_device, vdev); + struct fsl_mc_device *mc_dev = vdev->mc_dev; + struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev); + struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev); int ret; - mutex_lock(&vdev->reflck->lock); - - if (!(--vdev->refcnt)) { - struct fsl_mc_device *mc_dev = vdev->mc_dev; - struct device *cont_dev = fsl_mc_cont_dev(&mc_dev->dev); - struct fsl_mc_device *mc_cont = to_fsl_mc_device(cont_dev); - - vfio_fsl_mc_regions_cleanup(vdev); + vfio_fsl_mc_regions_cleanup(vdev); - /* reset the device before cleaning up the interrupts */ - ret = dprc_reset_container(mc_cont->mc_io, 0, - mc_cont->mc_handle, - mc_cont->obj_desc.id, - DPRC_RESET_OPTION_NON_RECURSIVE); + /* reset the device before cleaning up the interrupts */ + ret = dprc_reset_container(mc_cont->mc_io, 0, mc_cont->mc_handle, + mc_cont->obj_desc.id, + DPRC_RESET_OPTION_NON_RECURSIVE); - if (ret) { - dev_warn(&mc_cont->dev, "VFIO_FLS_MC: reset device has failed (%d)\n", - ret); - WARN_ON(1); - } + if (WARN_ON(ret)) + dev_warn(&mc_cont->dev, + "VFIO_FLS_MC: reset device has failed (%d)\n", ret); - vfio_fsl_mc_irqs_cleanup(vdev); + vfio_fsl_mc_irqs_cleanup(vdev); - fsl_mc_cleanup_irq_pool(mc_cont); - } - - mutex_unlock(&vdev->reflck->lock); + fsl_mc_cleanup_irq_pool(mc_cont); } static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev, @@ -504,8 +405,8 @@ static int vfio_fsl_mc_mmap(struct vfio_device *core_vdev, static const struct vfio_device_ops vfio_fsl_mc_ops = { .name = "vfio-fsl-mc", - .open = vfio_fsl_mc_open, - .release = vfio_fsl_mc_release, + .open_device = vfio_fsl_mc_open_device, + .close_device = vfio_fsl_mc_close_device, .ioctl = vfio_fsl_mc_ioctl, .read = vfio_fsl_mc_read, .write = vfio_fsl_mc_write, @@ -625,13 +526,16 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) vdev->mc_dev = mc_dev; mutex_init(&vdev->igate); - ret = vfio_fsl_mc_reflck_attach(vdev); + if (is_fsl_mc_bus_dprc(mc_dev)) + ret = vfio_assign_device_set(&vdev->vdev, &mc_dev->dev); + else + ret = vfio_assign_device_set(&vdev->vdev, mc_dev->dev.parent); if (ret) goto out_uninit; ret = vfio_fsl_mc_init_device(vdev); if (ret) - goto out_reflck; + goto out_uninit; ret = vfio_register_group_dev(&vdev->vdev); if (ret) { @@ -639,12 +543,6 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev) goto out_device; } - /* - * This triggers recursion into vfio_fsl_mc_probe() on another device - * and the vfio_fsl_mc_reflck_attach() must succeed, which relies on the - * vfio_add_group_dev() above. It has no impact on this vdev, so it is - * safe to be after the vfio device is made live. - */ ret = vfio_fsl_mc_scan_container(mc_dev); if (ret) goto out_group_dev; @@ -655,8 +553,6 @@ out_group_dev: vfio_unregister_group_dev(&vdev->vdev); out_device: vfio_fsl_uninit_device(vdev); -out_reflck: - vfio_fsl_mc_reflck_put(vdev->reflck); out_uninit: vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); @@ -675,7 +571,7 @@ static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev) dprc_remove_devices(mc_dev, NULL, 0); vfio_fsl_uninit_device(vdev); - vfio_fsl_mc_reflck_put(vdev->reflck); + vfio_uninit_group_dev(&vdev->vdev); kfree(vdev); vfio_iommu_group_put(mc_dev->dev.iommu_group, dev); diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c index 0d9f3002df7f..77e584093a23 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c @@ -120,7 +120,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev, if (start != 0 || count != 1) return -EINVAL; - mutex_lock(&vdev->reflck->lock); + mutex_lock(&vdev->vdev.dev_set->lock); ret = fsl_mc_populate_irq_pool(mc_cont, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); if (ret) @@ -129,7 +129,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev, ret = vfio_fsl_mc_irqs_allocate(vdev); if (ret) goto unlock; - mutex_unlock(&vdev->reflck->lock); + mutex_unlock(&vdev->vdev.dev_set->lock); if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { s32 fd = *(s32 *)data; @@ -154,7 +154,7 @@ static int vfio_fsl_mc_set_irq_trigger(struct vfio_fsl_mc_device *vdev, return 0; unlock: - mutex_unlock(&vdev->reflck->lock); + mutex_unlock(&vdev->vdev.dev_set->lock); return ret; } diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h index 89700e00e77d..4ad63ececb91 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_private.h @@ -22,11 +22,6 @@ struct vfio_fsl_mc_irq { char *name; }; -struct vfio_fsl_mc_reflck { - struct kref kref; - struct mutex lock; -}; - struct vfio_fsl_mc_region { u32 flags; u32 type; @@ -39,9 +34,7 @@ struct vfio_fsl_mc_device { struct vfio_device vdev; struct fsl_mc_device *mc_dev; struct notifier_block nb; - int refcnt; struct vfio_fsl_mc_region *regions; - struct vfio_fsl_mc_reflck *reflck; struct mutex igate; struct vfio_fsl_mc_irq *mc_irqs; }; -- cgit v1.2.3-70-g09d2 From ab7e5e34a9f661f5649f48d4531c4a75713ff7cf Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:03 -0300 Subject: vfio/platform: Use open_device() instead of open coding a refcnt scheme Platform simply wants to run some code when the device is first opened/last closed. Use the core framework and locking for this. Aside from removing a bit of code this narrows the locking scope from a global lock. Reviewed-by: Cornelia Huck Reviewed-by: Eric Auger Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Link: https://lore.kernel.org/r/7-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/platform/vfio_platform_common.c | 79 +++++++++++---------------- drivers/vfio/platform/vfio_platform_private.h | 1 - 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index bdde8605178c..6af7ce7d619c 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -218,65 +218,52 @@ static int vfio_platform_call_reset(struct vfio_platform_device *vdev, return -EINVAL; } -static void vfio_platform_release(struct vfio_device *core_vdev) +static void vfio_platform_close_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev = container_of(core_vdev, struct vfio_platform_device, vdev); + const char *extra_dbg = NULL; + int ret; - mutex_lock(&driver_lock); - - if (!(--vdev->refcnt)) { - const char *extra_dbg = NULL; - int ret; - - ret = vfio_platform_call_reset(vdev, &extra_dbg); - if (ret && vdev->reset_required) { - dev_warn(vdev->device, "reset driver is required and reset call failed in release (%d) %s\n", - ret, extra_dbg ? extra_dbg : ""); - WARN_ON(1); - } - pm_runtime_put(vdev->device); - vfio_platform_regions_cleanup(vdev); - vfio_platform_irq_cleanup(vdev); + ret = vfio_platform_call_reset(vdev, &extra_dbg); + if (WARN_ON(ret && vdev->reset_required)) { + dev_warn( + vdev->device, + "reset driver is required and reset call failed in release (%d) %s\n", + ret, extra_dbg ? extra_dbg : ""); } - - mutex_unlock(&driver_lock); + pm_runtime_put(vdev->device); + vfio_platform_regions_cleanup(vdev); + vfio_platform_irq_cleanup(vdev); } -static int vfio_platform_open(struct vfio_device *core_vdev) +static int vfio_platform_open_device(struct vfio_device *core_vdev) { struct vfio_platform_device *vdev = container_of(core_vdev, struct vfio_platform_device, vdev); + const char *extra_dbg = NULL; int ret; - mutex_lock(&driver_lock); - - if (!vdev->refcnt) { - const char *extra_dbg = NULL; - - ret = vfio_platform_regions_init(vdev); - if (ret) - goto err_reg; + ret = vfio_platform_regions_init(vdev); + if (ret) + return ret; - ret = vfio_platform_irq_init(vdev); - if (ret) - goto err_irq; + ret = vfio_platform_irq_init(vdev); + if (ret) + goto err_irq; - ret = pm_runtime_get_sync(vdev->device); - if (ret < 0) - goto err_rst; + ret = pm_runtime_get_sync(vdev->device); + if (ret < 0) + goto err_rst; - ret = vfio_platform_call_reset(vdev, &extra_dbg); - if (ret && vdev->reset_required) { - dev_warn(vdev->device, "reset driver is required and reset call failed in open (%d) %s\n", - ret, extra_dbg ? extra_dbg : ""); - goto err_rst; - } + ret = vfio_platform_call_reset(vdev, &extra_dbg); + if (ret && vdev->reset_required) { + dev_warn( + vdev->device, + "reset driver is required and reset call failed in open (%d) %s\n", + ret, extra_dbg ? extra_dbg : ""); + goto err_rst; } - - vdev->refcnt++; - - mutex_unlock(&driver_lock); return 0; err_rst: @@ -284,8 +271,6 @@ err_rst: vfio_platform_irq_cleanup(vdev); err_irq: vfio_platform_regions_cleanup(vdev); -err_reg: - mutex_unlock(&driver_lock); return ret; } @@ -616,8 +601,8 @@ static int vfio_platform_mmap(struct vfio_device *core_vdev, struct vm_area_stru static const struct vfio_device_ops vfio_platform_ops = { .name = "vfio-platform", - .open = vfio_platform_open, - .release = vfio_platform_release, + .open_device = vfio_platform_open_device, + .close_device = vfio_platform_close_device, .ioctl = vfio_platform_ioctl, .read = vfio_platform_read, .write = vfio_platform_write, diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h index dfb834c13659..520d2a8e8375 100644 --- a/drivers/vfio/platform/vfio_platform_private.h +++ b/drivers/vfio/platform/vfio_platform_private.h @@ -48,7 +48,6 @@ struct vfio_platform_device { u32 num_regions; struct vfio_platform_irq *irqs; u32 num_irqs; - int refcnt; struct mutex igate; const char *compat; const char *acpihid; -- cgit v1.2.3-70-g09d2 From 2cd8b14aaa667f5c6b7918e8d769872fa9acb0ac Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Thu, 5 Aug 2021 22:19:04 -0300 Subject: vfio/pci: Move to the device set infrastructure PCI wants to have the usual open/close_device() logic with the slight twist that the open/close_device() must be done under a singelton lock shared by all of the vfio_devices that are in the PCI "reset group". The reset group, and thus the device set, is determined by what devices pci_reset_bus() touches, which is either the entire bus or only the slot. Rely on the core code to do everything reflck was doing and delete reflck entirely. Signed-off-by: Yishai Hadas Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/8-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 162 ++++++++---------------------------- drivers/vfio/pci/vfio_pci_private.h | 7 -- 2 files changed, 37 insertions(+), 132 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index fab3715d60d4..5d6db93d6c68 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -530,53 +530,40 @@ static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val) vfio_device_put(&pf_vdev->vdev); } -static void vfio_pci_release(struct vfio_device *core_vdev) +static void vfio_pci_close_device(struct vfio_device *core_vdev) { struct vfio_pci_device *vdev = container_of(core_vdev, struct vfio_pci_device, vdev); - mutex_lock(&vdev->reflck->lock); - - if (!(--vdev->refcnt)) { - vfio_pci_vf_token_user_add(vdev, -1); - vfio_spapr_pci_eeh_release(vdev->pdev); - vfio_pci_disable(vdev); + vfio_pci_vf_token_user_add(vdev, -1); + vfio_spapr_pci_eeh_release(vdev->pdev); + vfio_pci_disable(vdev); - mutex_lock(&vdev->igate); - if (vdev->err_trigger) { - eventfd_ctx_put(vdev->err_trigger); - vdev->err_trigger = NULL; - } - if (vdev->req_trigger) { - eventfd_ctx_put(vdev->req_trigger); - vdev->req_trigger = NULL; - } - mutex_unlock(&vdev->igate); + mutex_lock(&vdev->igate); + if (vdev->err_trigger) { + eventfd_ctx_put(vdev->err_trigger); + vdev->err_trigger = NULL; } - - mutex_unlock(&vdev->reflck->lock); + if (vdev->req_trigger) { + eventfd_ctx_put(vdev->req_trigger); + vdev->req_trigger = NULL; + } + mutex_unlock(&vdev->igate); } -static int vfio_pci_open(struct vfio_device *core_vdev) +static int vfio_pci_open_device(struct vfio_device *core_vdev) { struct vfio_pci_device *vdev = container_of(core_vdev, struct vfio_pci_device, vdev); int ret = 0; - mutex_lock(&vdev->reflck->lock); - - if (!vdev->refcnt) { - ret = vfio_pci_enable(vdev); - if (ret) - goto error; + ret = vfio_pci_enable(vdev); + if (ret) + return ret; - vfio_spapr_pci_eeh_open(vdev->pdev); - vfio_pci_vf_token_user_add(vdev, 1); - } - vdev->refcnt++; -error: - mutex_unlock(&vdev->reflck->lock); - return ret; + vfio_spapr_pci_eeh_open(vdev->pdev); + vfio_pci_vf_token_user_add(vdev, 1); + return 0; } static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) @@ -1870,8 +1857,8 @@ static int vfio_pci_match(struct vfio_device *core_vdev, char *buf) static const struct vfio_device_ops vfio_pci_ops = { .name = "vfio-pci", - .open = vfio_pci_open, - .release = vfio_pci_release, + .open_device = vfio_pci_open_device, + .close_device = vfio_pci_close_device, .ioctl = vfio_pci_ioctl, .read = vfio_pci_read, .write = vfio_pci_write, @@ -1880,9 +1867,6 @@ static const struct vfio_device_ops vfio_pci_ops = { .match = vfio_pci_match, }; -static int vfio_pci_reflck_attach(struct vfio_pci_device *vdev); -static void vfio_pci_reflck_put(struct vfio_pci_reflck *reflck); - static int vfio_pci_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) { @@ -2020,12 +2004,23 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) INIT_LIST_HEAD(&vdev->vma_list); init_rwsem(&vdev->memory_lock); - ret = vfio_pci_reflck_attach(vdev); + if (pci_is_root_bus(pdev->bus)) { + ret = vfio_assign_device_set(&vdev->vdev, vdev); + } else if (!pci_probe_reset_slot(pdev->slot)) { + ret = vfio_assign_device_set(&vdev->vdev, pdev->slot); + } else { + /* + * If there is no slot reset support for this device, the whole + * bus needs to be grouped together to support bus-wide resets. + */ + ret = vfio_assign_device_set(&vdev->vdev, pdev->bus); + } + if (ret) goto out_uninit; ret = vfio_pci_vf_init(vdev); if (ret) - goto out_reflck; + goto out_uninit; ret = vfio_pci_vga_init(vdev); if (ret) goto out_vf; @@ -2057,8 +2052,6 @@ out_power: vfio_pci_set_power_state(vdev, PCI_D0); out_vf: vfio_pci_vf_uninit(vdev); -out_reflck: - vfio_pci_reflck_put(vdev->reflck); out_uninit: vfio_uninit_group_dev(&vdev->vdev); kfree(vdev->pm_save); @@ -2077,7 +2070,6 @@ static void vfio_pci_remove(struct pci_dev *pdev) vfio_unregister_group_dev(&vdev->vdev); vfio_pci_vf_uninit(vdev); - vfio_pci_reflck_put(vdev->reflck); vfio_uninit_group_dev(&vdev->vdev); vfio_pci_vga_uninit(vdev); @@ -2153,86 +2145,6 @@ static struct pci_driver vfio_pci_driver = { .err_handler = &vfio_err_handlers, }; -static DEFINE_MUTEX(reflck_lock); - -static struct vfio_pci_reflck *vfio_pci_reflck_alloc(void) -{ - struct vfio_pci_reflck *reflck; - - reflck = kzalloc(sizeof(*reflck), GFP_KERNEL); - if (!reflck) - return ERR_PTR(-ENOMEM); - - kref_init(&reflck->kref); - mutex_init(&reflck->lock); - - return reflck; -} - -static void vfio_pci_reflck_get(struct vfio_pci_reflck *reflck) -{ - kref_get(&reflck->kref); -} - -static int vfio_pci_reflck_find(struct pci_dev *pdev, void *data) -{ - struct vfio_pci_reflck **preflck = data; - struct vfio_device *device; - struct vfio_pci_device *vdev; - - device = vfio_device_get_from_dev(&pdev->dev); - if (!device) - return 0; - - if (pci_dev_driver(pdev) != &vfio_pci_driver) { - vfio_device_put(device); - return 0; - } - - vdev = container_of(device, struct vfio_pci_device, vdev); - - if (vdev->reflck) { - vfio_pci_reflck_get(vdev->reflck); - *preflck = vdev->reflck; - vfio_device_put(device); - return 1; - } - - vfio_device_put(device); - return 0; -} - -static int vfio_pci_reflck_attach(struct vfio_pci_device *vdev) -{ - bool slot = !pci_probe_reset_slot(vdev->pdev->slot); - - mutex_lock(&reflck_lock); - - if (pci_is_root_bus(vdev->pdev->bus) || - vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_reflck_find, - &vdev->reflck, slot) <= 0) - vdev->reflck = vfio_pci_reflck_alloc(); - - mutex_unlock(&reflck_lock); - - return PTR_ERR_OR_ZERO(vdev->reflck); -} - -static void vfio_pci_reflck_release(struct kref *kref) -{ - struct vfio_pci_reflck *reflck = container_of(kref, - struct vfio_pci_reflck, - kref); - - kfree(reflck); - mutex_unlock(&reflck_lock); -} - -static void vfio_pci_reflck_put(struct vfio_pci_reflck *reflck) -{ - kref_put_mutex(&reflck->kref, vfio_pci_reflck_release, &reflck_lock); -} - static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) { struct vfio_devices *devs = data; @@ -2254,7 +2166,7 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) vdev = container_of(device, struct vfio_pci_device, vdev); /* Fault if the device is not unused */ - if (vdev->refcnt) { + if (device->open_count) { vfio_device_put(device); return -EBUSY; } @@ -2303,7 +2215,7 @@ static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) * - At least one of the affected devices is marked dirty via * needs_reset (such as by lack of FLR support) * Then attempt to perform that bus or slot reset. Callers are required - * to hold vdev->reflck->lock, protecting the bus/slot reset group from + * to hold vdev->dev_set->lock, protecting the bus/slot reset group from * concurrent opens. A vfio_device reference is acquired for each device * to prevent unbinds during the reset operation. * diff --git a/drivers/vfio/pci/vfio_pci_private.h b/drivers/vfio/pci/vfio_pci_private.h index bbc56c857ef0..70414b6c904d 100644 --- a/drivers/vfio/pci/vfio_pci_private.h +++ b/drivers/vfio/pci/vfio_pci_private.h @@ -83,11 +83,6 @@ struct vfio_pci_dummy_resource { struct list_head res_next; }; -struct vfio_pci_reflck { - struct kref kref; - struct mutex lock; -}; - struct vfio_pci_vf_token { struct mutex lock; uuid_t uuid; @@ -130,8 +125,6 @@ struct vfio_pci_device { bool needs_pm_restore; struct pci_saved_state *pci_saved_state; struct pci_saved_state *pm_save; - struct vfio_pci_reflck *reflck; - int refcnt; int ioeventfds_nr; struct eventfd_ctx *err_trigger; struct eventfd_ctx *req_trigger; -- cgit v1.2.3-70-g09d2 From a882c16a2b7ef6e0ab3f0d1e41345b667893cbfd Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:05 -0300 Subject: vfio/pci: Change vfio_pci_try_bus_reset() to use the dev_set vfio_pci_try_bus_reset() is triggering a reset of the entire_dev set if any device within it has accumulated a needs_reset. This reset can only be done once all of the drivers operating the PCI devices to be reset are in a known safe state. Make this clearer by directly operating on the dev_set instead of the vfio_pci_device. Rename the function to vfio_pci_dev_set_try_reset(). Use the device list inside the dev_set to check that all drivers are in a safe state instead of working backwards from the pci_device. The dev_set->lock directly prevents devices from joining/leaving the set, or changing their state, which further implies the pci_device cannot change drivers or that the vfio_device be freed, eliminating the need for get/put's. If a pci_device to be reset is not in the dev_set then the reset cannot be used as we can't know what the state of that driver is. Directly measure this by checking that every pci_device is in the dev_set - which effectively proves that VFIO drivers are attached to everything. Remove the odd interaction around vfio_pci_set_power_state() - have the only caller avoid its redundant vfio_pci_set_power_state() instead of avoiding it inside vfio_pci_dev_set_try_reset(). This restructuring corrects a call to pci_dev_driver() without holding the device_lock() and removes a hard wiring to &vfio_pci_driver. Signed-off-by: Jason Gunthorpe Reviewed-by: Christoph Hellwig Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/9-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 174 +++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 92 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 5d6db93d6c68..0147f04c91b2 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -223,7 +223,7 @@ no_mmap: } } -static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev); +static bool vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set); static void vfio_pci_disable(struct vfio_pci_device *vdev); static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data); @@ -404,6 +404,9 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) struct vfio_pci_ioeventfd *ioeventfd, *ioeventfd_tmp; int i, bar; + /* For needs_reset */ + lockdep_assert_held(&vdev->vdev.dev_set->lock); + /* Stop the device from further DMA */ pci_clear_master(pdev); @@ -487,9 +490,7 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) out: pci_disable_device(pdev); - vfio_pci_try_bus_reset(vdev); - - if (!disable_idle_d3) + if (!vfio_pci_dev_set_try_reset(vdev->vdev.dev_set) && !disable_idle_d3) vfio_pci_set_power_state(vdev, PCI_D3hot); } @@ -2145,7 +2146,7 @@ static struct pci_driver vfio_pci_driver = { .err_handler = &vfio_err_handlers, }; -static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) +static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) { struct vfio_devices *devs = data; struct vfio_device *device; @@ -2165,8 +2166,11 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) vdev = container_of(device, struct vfio_pci_device, vdev); - /* Fault if the device is not unused */ - if (device->open_count) { + /* + * Locking multiple devices is prone to deadlock, runaway and + * unwind if we hit contention. + */ + if (!vfio_pci_zap_and_vma_lock(vdev, true)) { vfio_device_put(device); return -EBUSY; } @@ -2175,112 +2179,98 @@ static int vfio_pci_get_unused_devs(struct pci_dev *pdev, void *data) return 0; } -static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) +static int vfio_pci_is_device_in_set(struct pci_dev *pdev, void *data) { - struct vfio_devices *devs = data; - struct vfio_device *device; - struct vfio_pci_device *vdev; + struct vfio_device_set *dev_set = data; + struct vfio_device *cur; - if (devs->cur_index == devs->max_index) - return -ENOSPC; - - device = vfio_device_get_from_dev(&pdev->dev); - if (!device) - return -EINVAL; + list_for_each_entry(cur, &dev_set->device_list, dev_set_list) + if (cur->dev == &pdev->dev) + return 0; + return -EBUSY; +} - if (pci_dev_driver(pdev) != &vfio_pci_driver) { - vfio_device_put(device); - return -EBUSY; - } +/* + * vfio-core considers a group to be viable and will create a vfio_device even + * if some devices are bound to drivers like pci-stub or pcieport. Here we + * require all PCI devices to be inside our dev_set since that ensures they stay + * put and that every driver controlling the device can co-ordinate with the + * device reset. + * + * Returns the pci_dev to pass to pci_reset_bus() if every PCI device to be + * reset is inside the dev_set, and pci_reset_bus() can succeed. NULL otherwise. + */ +static struct pci_dev * +vfio_pci_dev_set_resettable(struct vfio_device_set *dev_set) +{ + struct pci_dev *pdev; - vdev = container_of(device, struct vfio_pci_device, vdev); + lockdep_assert_held(&dev_set->lock); /* - * Locking multiple devices is prone to deadlock, runaway and - * unwind if we hit contention. + * By definition all PCI devices in the dev_set share the same PCI + * reset, so any pci_dev will have the same outcomes for + * pci_probe_reset_*() and pci_reset_bus(). */ - if (!vfio_pci_zap_and_vma_lock(vdev, true)) { - vfio_device_put(device); - return -EBUSY; - } + pdev = list_first_entry(&dev_set->device_list, struct vfio_pci_device, + vdev.dev_set_list)->pdev; - devs->devices[devs->cur_index++] = vdev; - return 0; + /* pci_reset_bus() is supported */ + if (pci_probe_reset_slot(pdev->slot) && pci_probe_reset_bus(pdev->bus)) + return NULL; + + if (vfio_pci_for_each_slot_or_bus(pdev, vfio_pci_is_device_in_set, + dev_set, + !pci_probe_reset_slot(pdev->slot))) + return NULL; + return pdev; +} + +static bool vfio_pci_dev_set_needs_reset(struct vfio_device_set *dev_set) +{ + struct vfio_pci_device *cur; + bool needs_reset = false; + + list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) { + /* No VFIO device in the set can have an open device FD */ + if (cur->vdev.open_count) + return false; + needs_reset |= cur->needs_reset; + } + return needs_reset; } /* - * If a bus or slot reset is available for the provided device and: + * If a bus or slot reset is available for the provided dev_set and: * - All of the devices affected by that bus or slot reset are unused - * (!refcnt) * - At least one of the affected devices is marked dirty via * needs_reset (such as by lack of FLR support) - * Then attempt to perform that bus or slot reset. Callers are required - * to hold vdev->dev_set->lock, protecting the bus/slot reset group from - * concurrent opens. A vfio_device reference is acquired for each device - * to prevent unbinds during the reset operation. - * - * NB: vfio-core considers a group to be viable even if some devices are - * bound to drivers like pci-stub or pcieport. Here we require all devices - * to be bound to vfio_pci since that's the only way we can be sure they - * stay put. + * Then attempt to perform that bus or slot reset. + * Returns true if the dev_set was reset. */ -static void vfio_pci_try_bus_reset(struct vfio_pci_device *vdev) +static bool vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set) { - struct vfio_devices devs = { .cur_index = 0 }; - int i = 0, ret = -EINVAL; - bool slot = false; - struct vfio_pci_device *tmp; - - if (!pci_probe_reset_slot(vdev->pdev->slot)) - slot = true; - else if (pci_probe_reset_bus(vdev->pdev->bus)) - return; - - if (vfio_pci_for_each_slot_or_bus(vdev->pdev, vfio_pci_count_devs, - &i, slot) || !i) - return; - - devs.max_index = i; - devs.devices = kcalloc(i, sizeof(struct vfio_device *), GFP_KERNEL); - if (!devs.devices) - return; - - if (vfio_pci_for_each_slot_or_bus(vdev->pdev, - vfio_pci_get_unused_devs, - &devs, slot)) - goto put_devs; - - /* Does at least one need a reset? */ - for (i = 0; i < devs.cur_index; i++) { - tmp = devs.devices[i]; - if (tmp->needs_reset) { - ret = pci_reset_bus(vdev->pdev); - break; - } - } + struct vfio_pci_device *cur; + struct pci_dev *pdev; + int ret; -put_devs: - for (i = 0; i < devs.cur_index; i++) { - tmp = devs.devices[i]; + if (!vfio_pci_dev_set_needs_reset(dev_set)) + return false; - /* - * If reset was successful, affected devices no longer need - * a reset and we should return all the collateral devices - * to low power. If not successful, we either didn't reset - * the bus or timed out waiting for it, so let's not touch - * the power state. - */ - if (!ret) { - tmp->needs_reset = false; + pdev = vfio_pci_dev_set_resettable(dev_set); + if (!pdev) + return false; - if (tmp != vdev && !disable_idle_d3) - vfio_pci_set_power_state(tmp, PCI_D3hot); - } + ret = pci_reset_bus(pdev); + if (ret) + return false; - vfio_device_put(&tmp->vdev); + list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) { + cur->needs_reset = false; + if (!disable_idle_d3) + vfio_pci_set_power_state(cur, PCI_D3hot); } - - kfree(devs.devices); + return true; } static void __exit vfio_pci_cleanup(void) -- cgit v1.2.3-70-g09d2 From db44c17458fb54880b9a65479e464b64c365a87d Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:06 -0300 Subject: vfio/pci: Reorganize VFIO_DEVICE_PCI_HOT_RESET to use the device set Like vfio_pci_dev_set_try_reset() this code wants to reset all of the devices in the "reset group" which is the same membership as the device set. Instead of trying to reconstruct the device set from the PCI list go directly from the device set's device list to execute the reset. The same basic structure as vfio_pci_dev_set_try_reset() is used. The 'vfio_devices' struct is replaced with the device set linked list and we simply sweep it multiple times under the lock. This eliminates a memory allocation and get/put traffic and another improperly locked test of pci_dev_driver(). Reviewed-off-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/10-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 213 ++++++++++++++++++-------------------------- 1 file changed, 89 insertions(+), 124 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 0147f04c91b2..a4f44ea52fa3 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -223,9 +223,11 @@ no_mmap: } } +struct vfio_pci_group_info; static bool vfio_pci_dev_set_try_reset(struct vfio_device_set *dev_set); static void vfio_pci_disable(struct vfio_pci_device *vdev); -static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data); +static int vfio_pci_dev_set_hot_reset(struct vfio_device_set *dev_set, + struct vfio_pci_group_info *groups); /* * INTx masking requires the ability to disable INTx signaling via PCI_COMMAND @@ -643,37 +645,11 @@ static int vfio_pci_fill_devs(struct pci_dev *pdev, void *data) return 0; } -struct vfio_pci_group_entry { - struct vfio_group *group; - int id; -}; - struct vfio_pci_group_info { int count; - struct vfio_pci_group_entry *groups; + struct vfio_group **groups; }; -static int vfio_pci_validate_devs(struct pci_dev *pdev, void *data) -{ - struct vfio_pci_group_info *info = data; - struct iommu_group *group; - int id, i; - - group = iommu_group_get(&pdev->dev); - if (!group) - return -EPERM; - - id = iommu_group_id(group); - - for (i = 0; i < info->count; i++) - if (info->groups[i].id == id) - break; - - iommu_group_put(group); - - return (i == info->count) ? -EINVAL : 0; -} - static bool vfio_pci_dev_below_slot(struct pci_dev *pdev, struct pci_slot *slot) { for (; pdev; pdev = pdev->bus->self) @@ -751,12 +727,6 @@ int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, return 0; } -struct vfio_devices { - struct vfio_pci_device **devices; - int cur_index; - int max_index; -}; - static long vfio_pci_ioctl(struct vfio_device *core_vdev, unsigned int cmd, unsigned long arg) { @@ -1125,11 +1095,10 @@ reset_info_exit: } else if (cmd == VFIO_DEVICE_PCI_HOT_RESET) { struct vfio_pci_hot_reset hdr; int32_t *group_fds; - struct vfio_pci_group_entry *groups; + struct vfio_group **groups; struct vfio_pci_group_info info; - struct vfio_devices devs = { .cur_index = 0 }; bool slot = false; - int i, group_idx, mem_idx = 0, count = 0, ret = 0; + int group_idx, count = 0, ret = 0; minsz = offsetofend(struct vfio_pci_hot_reset, count); @@ -1196,9 +1165,7 @@ reset_info_exit: break; } - groups[group_idx].group = group; - groups[group_idx].id = - vfio_external_user_iommu_id(group); + groups[group_idx] = group; } kfree(group_fds); @@ -1210,64 +1177,11 @@ reset_info_exit: info.count = hdr.count; info.groups = groups; - /* - * Test whether all the affected devices are contained - * by the set of groups provided by the user. - */ - ret = vfio_pci_for_each_slot_or_bus(vdev->pdev, - vfio_pci_validate_devs, - &info, slot); - if (ret) - goto hot_reset_release; - - devs.max_index = count; - devs.devices = kcalloc(count, sizeof(struct vfio_device *), - GFP_KERNEL); - if (!devs.devices) { - ret = -ENOMEM; - goto hot_reset_release; - } - - /* - * We need to get memory_lock for each device, but devices - * can share mmap_lock, therefore we need to zap and hold - * the vma_lock for each device, and only then get each - * memory_lock. - */ - ret = vfio_pci_for_each_slot_or_bus(vdev->pdev, - vfio_pci_try_zap_and_vma_lock_cb, - &devs, slot); - if (ret) - goto hot_reset_release; - - for (; mem_idx < devs.cur_index; mem_idx++) { - struct vfio_pci_device *tmp = devs.devices[mem_idx]; - - ret = down_write_trylock(&tmp->memory_lock); - if (!ret) { - ret = -EBUSY; - goto hot_reset_release; - } - mutex_unlock(&tmp->vma_lock); - } - - /* User has access, do the reset */ - ret = pci_reset_bus(vdev->pdev); + ret = vfio_pci_dev_set_hot_reset(vdev->vdev.dev_set, &info); hot_reset_release: - for (i = 0; i < devs.cur_index; i++) { - struct vfio_pci_device *tmp = devs.devices[i]; - - if (i < mem_idx) - up_write(&tmp->memory_lock); - else - mutex_unlock(&tmp->vma_lock); - vfio_device_put(&tmp->vdev); - } - kfree(devs.devices); - for (group_idx--; group_idx >= 0; group_idx--) - vfio_group_put_external_user(groups[group_idx].group); + vfio_group_put_external_user(groups[group_idx]); kfree(groups); return ret; @@ -2146,37 +2060,15 @@ static struct pci_driver vfio_pci_driver = { .err_handler = &vfio_err_handlers, }; -static int vfio_pci_try_zap_and_vma_lock_cb(struct pci_dev *pdev, void *data) +static bool vfio_dev_in_groups(struct vfio_pci_device *vdev, + struct vfio_pci_group_info *groups) { - struct vfio_devices *devs = data; - struct vfio_device *device; - struct vfio_pci_device *vdev; - - if (devs->cur_index == devs->max_index) - return -ENOSPC; - - device = vfio_device_get_from_dev(&pdev->dev); - if (!device) - return -EINVAL; - - if (pci_dev_driver(pdev) != &vfio_pci_driver) { - vfio_device_put(device); - return -EBUSY; - } - - vdev = container_of(device, struct vfio_pci_device, vdev); + unsigned int i; - /* - * Locking multiple devices is prone to deadlock, runaway and - * unwind if we hit contention. - */ - if (!vfio_pci_zap_and_vma_lock(vdev, true)) { - vfio_device_put(device); - return -EBUSY; - } - - devs->devices[devs->cur_index++] = vdev; - return 0; + for (i = 0; i < groups->count; i++) + if (groups->groups[i] == vdev->vdev.group) + return true; + return false; } static int vfio_pci_is_device_in_set(struct pci_dev *pdev, void *data) @@ -2226,6 +2118,79 @@ vfio_pci_dev_set_resettable(struct vfio_device_set *dev_set) return pdev; } +/* + * We need to get memory_lock for each device, but devices can share mmap_lock, + * therefore we need to zap and hold the vma_lock for each device, and only then + * get each memory_lock. + */ +static int vfio_pci_dev_set_hot_reset(struct vfio_device_set *dev_set, + struct vfio_pci_group_info *groups) +{ + struct vfio_pci_device *cur_mem; + struct vfio_pci_device *cur_vma; + struct vfio_pci_device *cur; + struct pci_dev *pdev; + bool is_mem = true; + int ret; + + mutex_lock(&dev_set->lock); + cur_mem = list_first_entry(&dev_set->device_list, + struct vfio_pci_device, vdev.dev_set_list); + + pdev = vfio_pci_dev_set_resettable(dev_set); + if (!pdev) { + ret = -EINVAL; + goto err_unlock; + } + + list_for_each_entry(cur_vma, &dev_set->device_list, vdev.dev_set_list) { + /* + * Test whether all the affected devices are contained by the + * set of groups provided by the user. + */ + if (!vfio_dev_in_groups(cur_vma, groups)) { + ret = -EINVAL; + goto err_undo; + } + + /* + * Locking multiple devices is prone to deadlock, runaway and + * unwind if we hit contention. + */ + if (!vfio_pci_zap_and_vma_lock(cur_vma, true)) { + ret = -EBUSY; + goto err_undo; + } + } + cur_vma = NULL; + + list_for_each_entry(cur_mem, &dev_set->device_list, vdev.dev_set_list) { + if (!down_write_trylock(&cur_mem->memory_lock)) { + ret = -EBUSY; + goto err_undo; + } + mutex_unlock(&cur_mem->vma_lock); + } + cur_mem = NULL; + + ret = pci_reset_bus(pdev); + +err_undo: + list_for_each_entry(cur, &dev_set->device_list, vdev.dev_set_list) { + if (cur == cur_mem) + is_mem = false; + if (cur == cur_vma) + break; + if (is_mem) + up_write(&cur->memory_lock); + else + mutex_unlock(&cur->vma_lock); + } +err_unlock: + mutex_unlock(&dev_set->lock); + return ret; +} + static bool vfio_pci_dev_set_needs_reset(struct vfio_device_set *dev_set) { struct vfio_pci_device *cur; -- cgit v1.2.3-70-g09d2 From 3cb24827147b75557bddc5b39d63897786935b14 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:07 -0300 Subject: vfio/mbochs: Fix close when multiple device FDs are open mbochs_close() iterates over global device state and frees it. Currently this is done every time a device FD is closed, but if multiple device FDs are open this could corrupt other still active FDs. Change this to use close_device() so it only runs on the last close. Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/11-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- samples/vfio-mdev/mbochs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c index 7b2e12fe7082..c313ab4d1f4e 100644 --- a/samples/vfio-mdev/mbochs.c +++ b/samples/vfio-mdev/mbochs.c @@ -1278,7 +1278,7 @@ static long mbochs_ioctl(struct vfio_device *vdev, unsigned int cmd, return -ENOTTY; } -static void mbochs_close(struct vfio_device *vdev) +static void mbochs_close_device(struct vfio_device *vdev) { struct mdev_state *mdev_state = container_of(vdev, struct mdev_state, vdev); @@ -1396,7 +1396,7 @@ static struct attribute_group *mdev_type_groups[] = { }; static const struct vfio_device_ops mbochs_dev_ops = { - .release = mbochs_close, + .close_device = mbochs_close_device, .read = mbochs_read, .write = mbochs_write, .ioctl = mbochs_ioctl, -- cgit v1.2.3-70-g09d2 From 9b0d6b7e28a9bbbf4cee0727a299c2107047b1a5 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:08 -0300 Subject: vfio/ap,ccw: Fix open/close when multiple device FDs are open The user can open multiple device FDs if it likes, however these open() functions call vfio_register_notifier() on some device global state. Calling vfio_register_notifier() twice in will trigger a WARN_ON from notifier_chain_register() and the first close will wrongly delete the notifier and more. Since these really want the new open/close_device() semantics just change the functions over. Reviewed-by: Cornelia Huck Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/12-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/s390/cio/vfio_ccw_ops.c | 8 ++++---- drivers/s390/crypto/vfio_ap_ops.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index c57d2a7f0919..7f540ad0b568 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -159,7 +159,7 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev) return 0; } -static int vfio_ccw_mdev_open(struct mdev_device *mdev) +static int vfio_ccw_mdev_open_device(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev)); @@ -194,7 +194,7 @@ out_unregister: return ret; } -static void vfio_ccw_mdev_release(struct mdev_device *mdev) +static void vfio_ccw_mdev_close_device(struct mdev_device *mdev) { struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev)); @@ -638,8 +638,8 @@ static const struct mdev_parent_ops vfio_ccw_mdev_ops = { .supported_type_groups = mdev_type_groups, .create = vfio_ccw_mdev_create, .remove = vfio_ccw_mdev_remove, - .open = vfio_ccw_mdev_open, - .release = vfio_ccw_mdev_release, + .open_device = vfio_ccw_mdev_open_device, + .close_device = vfio_ccw_mdev_close_device, .read = vfio_ccw_mdev_read, .write = vfio_ccw_mdev_write, .ioctl = vfio_ccw_mdev_ioctl, diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 122c85c22469..cee5626fe0a4 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -1315,7 +1315,7 @@ static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) return rc; } -static int vfio_ap_mdev_open(struct mdev_device *mdev) +static int vfio_ap_mdev_open_device(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); unsigned long events; @@ -1348,7 +1348,7 @@ static int vfio_ap_mdev_open(struct mdev_device *mdev) return ret; } -static void vfio_ap_mdev_release(struct mdev_device *mdev) +static void vfio_ap_mdev_close_device(struct mdev_device *mdev) { struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); @@ -1427,8 +1427,8 @@ static const struct mdev_parent_ops vfio_ap_matrix_ops = { .mdev_attr_groups = vfio_ap_mdev_attr_groups, .create = vfio_ap_mdev_create, .remove = vfio_ap_mdev_remove, - .open = vfio_ap_mdev_open, - .release = vfio_ap_mdev_release, + .open_device = vfio_ap_mdev_open_device, + .close_device = vfio_ap_mdev_close_device, .ioctl = vfio_ap_mdev_ioctl, }; -- cgit v1.2.3-70-g09d2 From dd574d9b728d583e30289244be139f82d0de3fb3 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:09 -0300 Subject: vfio/gvt: Fix open/close when multiple device FDs are open The user can open multiple device FDs if it likes, however the open function calls vfio_register_notifier() on device global state. Calling vfio_register_notifier() twice will trigger a WARN_ON from notifier_chain_register() and the first close will wrongly delete the notifier and more. Since these really want the new open/close_device() semantics just change the function over. Reviewed-by: Zhenyu Wang Reviewed-by: Cornelia Huck Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Link: https://lore.kernel.org/r/13-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/gpu/drm/i915/gvt/kvmgt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 1ac98f8aba31..7efa386449d1 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -885,7 +885,7 @@ static int intel_vgpu_group_notifier(struct notifier_block *nb, return NOTIFY_OK; } -static int intel_vgpu_open(struct mdev_device *mdev) +static int intel_vgpu_open_device(struct mdev_device *mdev) { struct intel_vgpu *vgpu = mdev_get_drvdata(mdev); struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu); @@ -1004,7 +1004,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) vgpu->handle = 0; } -static void intel_vgpu_release(struct mdev_device *mdev) +static void intel_vgpu_close_device(struct mdev_device *mdev) { struct intel_vgpu *vgpu = mdev_get_drvdata(mdev); @@ -1753,8 +1753,8 @@ static struct mdev_parent_ops intel_vgpu_ops = { .create = intel_vgpu_create, .remove = intel_vgpu_remove, - .open = intel_vgpu_open, - .release = intel_vgpu_release, + .open_device = intel_vgpu_open_device, + .close_device = intel_vgpu_close_device, .read = intel_vgpu_read, .write = intel_vgpu_write, -- cgit v1.2.3-70-g09d2 From eb24c1007e6852e024dc33b0dd9617b8500a1291 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 5 Aug 2021 22:19:10 -0300 Subject: vfio: Remove struct vfio_device_ops open/release Nothing uses this anymore, delete it. Signed-off-by: Yishai Hadas Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe Reviewed-by: Cornelia Huck Link: https://lore.kernel.org/r/14-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson --- drivers/vfio/mdev/vfio_mdev.c | 22 ---------------------- drivers/vfio/vfio.c | 14 +------------- include/linux/mdev.h | 7 ------- include/linux/vfio.h | 4 ---- 4 files changed, 1 insertion(+), 46 deletions(-) diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c index e12196ffd487..7a9883048216 100644 --- a/drivers/vfio/mdev/vfio_mdev.c +++ b/drivers/vfio/mdev/vfio_mdev.c @@ -37,26 +37,6 @@ static void vfio_mdev_close_device(struct vfio_device *core_vdev) parent->ops->close_device(mdev); } -static int vfio_mdev_open(struct vfio_device *core_vdev) -{ - struct mdev_device *mdev = to_mdev_device(core_vdev->dev); - struct mdev_parent *parent = mdev->type->parent; - - if (unlikely(!parent->ops->open)) - return 0; - - return parent->ops->open(mdev); -} - -static void vfio_mdev_release(struct vfio_device *core_vdev) -{ - struct mdev_device *mdev = to_mdev_device(core_vdev->dev); - struct mdev_parent *parent = mdev->type->parent; - - if (likely(parent->ops->release)) - parent->ops->release(mdev); -} - static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev, unsigned int cmd, unsigned long arg) { @@ -122,8 +102,6 @@ static const struct vfio_device_ops vfio_mdev_dev_ops = { .name = "vfio-mdev", .open_device = vfio_mdev_open_device, .close_device = vfio_mdev_close_device, - .open = vfio_mdev_open, - .release = vfio_mdev_release, .ioctl = vfio_mdev_unlocked_ioctl, .read = vfio_mdev_read, .write = vfio_mdev_write, diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 9cc17768c425..3c034fe14ccb 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -1470,19 +1470,13 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) } mutex_unlock(&device->dev_set->lock); - if (device->ops->open) { - ret = device->ops->open(device); - if (ret) - goto err_close_device; - } - /* * We can't use anon_inode_getfd() because we need to modify * the f_mode flags directly to allow more than just ioctls */ fdno = ret = get_unused_fd_flags(O_CLOEXEC); if (ret < 0) - goto err_release; + goto err_close_device; filep = anon_inode_getfile("[vfio-device]", &vfio_device_fops, device, O_RDWR); @@ -1509,9 +1503,6 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) err_fd: put_unused_fd(fdno); -err_release: - if (device->ops->release) - device->ops->release(device); err_close_device: mutex_lock(&device->dev_set->lock); if (device->open_count == 1 && device->ops->close_device) @@ -1659,9 +1650,6 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) { struct vfio_device *device = filep->private_data; - if (device->ops->release) - device->ops->release(device); - mutex_lock(&device->dev_set->lock); if (!--device->open_count && device->ops->close_device) device->ops->close_device(device); diff --git a/include/linux/mdev.h b/include/linux/mdev.h index cb5b7ed1d7c3..68427e8fadeb 100644 --- a/include/linux/mdev.h +++ b/include/linux/mdev.h @@ -72,11 +72,6 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype); * @mdev: mdev_device device structure which is being * destroyed * Returns integer: success (0) or error (< 0) - * @open: Open mediated device. - * @mdev: mediated device. - * Returns integer: success (0) or error (< 0) - * @release: release mediated device - * @mdev: mediated device. * @read: Read emulation callback * @mdev: mediated device structure * @buf: read buffer @@ -113,8 +108,6 @@ struct mdev_parent_ops { int (*remove)(struct mdev_device *mdev); int (*open_device)(struct mdev_device *mdev); void (*close_device)(struct mdev_device *mdev); - int (*open)(struct mdev_device *mdev); - void (*release)(struct mdev_device *mdev); ssize_t (*read)(struct mdev_device *mdev, char __user *buf, size_t count, loff_t *ppos); ssize_t (*write)(struct mdev_device *mdev, const char __user *buf, diff --git a/include/linux/vfio.h b/include/linux/vfio.h index f0e6a72875e4..b53a9557884a 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -46,8 +46,6 @@ struct vfio_device { * * @open_device: Called when the first file descriptor is opened for this device * @close_device: Opposite of open_device - * @open: Called when userspace creates new file descriptor for device - * @release: Called when userspace releases file descriptor for device * @read: Perform read(2) on device file descriptor * @write: Perform write(2) on device file descriptor * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_* @@ -62,8 +60,6 @@ struct vfio_device_ops { char *name; int (*open_device)(struct vfio_device *vdev); void (*close_device)(struct vfio_device *vdev); - int (*open)(struct vfio_device *vdev); - void (*release)(struct vfio_device *vdev); ssize_t (*read)(struct vfio_device *vdev, char __user *buf, size_t count, loff_t *ppos); ssize_t (*write)(struct vfio_device *vdev, const char __user *buf, -- cgit v1.2.3-70-g09d2 From 5e68b4c7fb6414c4a48b6d2988312e3b1f31978e Mon Sep 17 00:00:00 2001 From: Allison Henderson Date: Sun, 8 Aug 2021 08:27:14 -0700 Subject: xfs: Rename __xfs_attr_rmtval_remove Now that xfs_attr_rmtval_remove is gone, rename __xfs_attr_rmtval_remove to xfs_attr_rmtval_remove Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Reviewed-by: Chandan Babu R Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 6 +++--- fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_attr_remote.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index dec538d336d7..010d499b237c 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -495,7 +495,7 @@ xfs_attr_set_iter( /* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */ dac->dela_state = XFS_DAS_RM_LBLK; if (args->rmtblkno) { - error = __xfs_attr_rmtval_remove(dac); + error = xfs_attr_rmtval_remove(dac); if (error == -EAGAIN) trace_xfs_attr_set_iter_return( dac->dela_state, args->dp); @@ -609,7 +609,7 @@ xfs_attr_set_iter( /* Set state in case xfs_attr_rmtval_remove returns -EAGAIN */ dac->dela_state = XFS_DAS_RM_NBLK; if (args->rmtblkno) { - error = __xfs_attr_rmtval_remove(dac); + error = xfs_attr_rmtval_remove(dac); if (error == -EAGAIN) trace_xfs_attr_set_iter_return( dac->dela_state, args->dp); @@ -1442,7 +1442,7 @@ xfs_attr_remove_iter( * May return -EAGAIN. Roll and repeat until all remote * blocks are removed. */ - error = __xfs_attr_rmtval_remove(dac); + error = xfs_attr_rmtval_remove(dac); if (error == -EAGAIN) { trace_xfs_attr_remove_iter_return( dac->dela_state, args->dp); diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 70f880da563b..16690439121e 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -672,7 +672,7 @@ xfs_attr_rmtval_invalidate( * routine until it returns something other than -EAGAIN. */ int -__xfs_attr_rmtval_remove( +xfs_attr_rmtval_remove( struct xfs_delattr_context *dac) { struct xfs_da_args *args = dac->da_args; diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h index 61b85b918db8..d72eff30ca18 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.h +++ b/fs/xfs/libxfs/xfs_attr_remote.h @@ -12,7 +12,7 @@ int xfs_attr_rmtval_get(struct xfs_da_args *args); int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map, xfs_buf_flags_t incore_flags); int xfs_attr_rmtval_invalidate(struct xfs_da_args *args); -int __xfs_attr_rmtval_remove(struct xfs_delattr_context *dac); +int xfs_attr_rmtval_remove(struct xfs_delattr_context *dac); int xfs_attr_rmt_find_hole(struct xfs_da_args *args); int xfs_attr_rmtval_set_value(struct xfs_da_args *args); int xfs_attr_rmtval_set_blk(struct xfs_delattr_context *dac); -- cgit v1.2.3-70-g09d2 From edf27485eb566abae809517520a9adbc242b8b39 Mon Sep 17 00:00:00 2001 From: Dwaipayan Ray Date: Mon, 9 Aug 2021 10:14:45 -0700 Subject: xfs: cleanup __FUNCTION__ usage __FUNCTION__ exists only for backwards compatibility reasons with old gcc versions. Replace it with __func__. Signed-off-by: Dwaipayan Ray Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icreate_item.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c index 9b3994b9c716..017904a34c02 100644 --- a/fs/xfs/xfs_icreate_item.c +++ b/fs/xfs/xfs_icreate_item.c @@ -201,7 +201,7 @@ xlog_recover_icreate_commit_pass2( if (length != igeo->ialloc_blks && length != igeo->ialloc_min_blks) { xfs_warn(log->l_mp, - "%s: unsupported chunk length", __FUNCTION__); + "%s: unsupported chunk length", __func__); return -EINVAL; } @@ -209,7 +209,7 @@ xlog_recover_icreate_commit_pass2( if ((count >> mp->m_sb.sb_inopblog) != length) { xfs_warn(log->l_mp, "%s: inconsistent inode count and chunk length", - __FUNCTION__); + __func__); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From ed5aacc81cd41efc4d561e14af408d1003f7b855 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 26 May 2021 00:03:37 -0700 Subject: xtensa: fix kconfig unmet dependency warning for HAVE_FUTEX_CMPXCHG XTENSA should only select HAVE_FUTEX_CMPXCHG when FUTEX is set/enabled. This prevents a kconfig warning. WARNING: unmet direct dependencies detected for HAVE_FUTEX_CMPXCHG Depends on [n]: FUTEX [=n] Selected by [y]: - XTENSA [=y] && !MMU [=n] Fixes: d951ba21b959 ("xtensa: nommu: select HAVE_FUTEX_CMPXCHG") Signed-off-by: Randy Dunlap Cc: Max Filippov Cc: Chris Zankel Cc: linux-xtensa@linux-xtensa.org Message-Id: <20210526070337.28130-1-rdunlap@infradead.org> Signed-off-by: Max Filippov --- arch/xtensa/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3878880469d1..b843902ad9fd 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -30,7 +30,7 @@ config XTENSA select HAVE_DMA_CONTIGUOUS select HAVE_EXIT_THREAD select HAVE_FUNCTION_TRACER - select HAVE_FUTEX_CMPXCHG if !MMU + select HAVE_FUTEX_CMPXCHG if !MMU && FUTEX select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING select HAVE_PCI -- cgit v1.2.3-70-g09d2 From 43ba2237281a59b40ea2393da9e89ea3a68de2a5 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 9 Jul 2021 04:13:23 -0700 Subject: xtensa: add fairness to IRQ handling Track which IRQs have been served at each level to make sure that no IRQ is served more than once while other IRQs at the same level are pending. Signed-off-by: Max Filippov --- arch/xtensa/kernel/traps.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index efc3a29cde80..874b6efc6fb3 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -268,6 +268,7 @@ void do_interrupt(struct pt_regs *regs) XCHAL_INTLEVEL7_MASK, }; struct pt_regs *old_regs; + unsigned unhandled = ~0u; trace_hardirqs_off(); @@ -283,6 +284,10 @@ void do_interrupt(struct pt_regs *regs) for (level = LOCKLEVEL; level > 0; --level) { if (int_at_level & int_level_mask[level]) { int_at_level &= int_level_mask[level]; + if (int_at_level & unhandled) + int_at_level &= unhandled; + else + unhandled |= int_level_mask[level]; break; } } @@ -290,6 +295,8 @@ void do_interrupt(struct pt_regs *regs) if (level == 0) break; + /* clear lowest pending irq in the unhandled mask */ + unhandled ^= (int_at_level & -int_at_level); do_IRQ(__ffs(int_at_level), regs); } -- cgit v1.2.3-70-g09d2 From 13066c303769b5c6bc67c0b990a4eb80058fb1b4 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 10 Aug 2021 16:08:06 -0700 Subject: xtensa: ISS: don't use string pointer before NULL check Move strlen call inside the if block that checks string pointer for NULL. While at it also fix the following coccicheck warning: ./arch/xtensa/platforms/iss/console.c:204:10-11: WARNING comparing pointer to 0. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Max Filippov --- arch/xtensa/platforms/iss/console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 21184488c277..f6e5fc5579be 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -186,10 +186,10 @@ late_initcall(rs_init); static void iss_console_write(struct console *co, const char *s, unsigned count) { - int len = strlen(s); - - if (s != 0 && *s != 0) + if (s && *s != 0) { + int len = strlen(s); simc_write(1, s, count < len ? count : len); + } } static struct tty_driver* iss_console_device(struct console *c, int *index) -- cgit v1.2.3-70-g09d2 From ef71db4845c02fe9f898e09046857ab1a9ff4be8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Aug 2021 01:37:28 +0900 Subject: xtensa: remove unneeded exports These are not used in any of subdirectories. Signed-off-by: Masahiro Yamada Message-Id: <20210811163731.186125-1-masahiroy@kernel.org> Signed-off-by: Max Filippov --- arch/xtensa/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index e9c8f064c44d..6fab7fc87579 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -17,7 +17,6 @@ variant-y := $(patsubst "%",%,$(CONFIG_XTENSA_VARIANT_NAME)) VARIANT = $(variant-y) -export VARIANT ifneq ($(VARIANT),) ifdef cross_compiling @@ -34,7 +33,6 @@ platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga PLATFORM = $(platform-y) -export PLATFORM # temporarily until string.h is fixed KBUILD_CFLAGS += -ffreestanding -D__linux__ -- cgit v1.2.3-70-g09d2 From c548584438d1a447900797a40571d95fb36a605f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Aug 2021 01:37:29 +0900 Subject: xtensa: do not build variants directory None of arch/xtensa/variants/*/ has Makefile, so 'buildvar' is always empty. Perhaps, downstream variant code might be dropped in, but given the fact that none of upstream variants builds anything in their variant directory, I doubt this is needed. Signed-off-by: Masahiro Yamada Message-Id: <20210811163731.186125-2-masahiroy@kernel.org> Signed-off-by: Max Filippov --- arch/xtensa/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 6fab7fc87579..3c0573fe6761 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -55,9 +55,7 @@ KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(vardirs) $(plfdirs)) KBUILD_DEFCONFIG := iss_defconfig -# Only build variant and/or platform if it includes a Makefile - -buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/) +# Only build platform if it includes a Makefile buildplf := $(shell test -e $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) # Find libgcc.a @@ -66,7 +64,7 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o core-y += arch/xtensa/kernel/ arch/xtensa/mm/ -core-y += $(buildvar) $(buildplf) +core-y += $(buildplf) core-y += arch/xtensa/boot/dts/ libs-y += arch/xtensa/lib/ $(LIBGCC) -- cgit v1.2.3-70-g09d2 From 59210499a02a58e5b2c6da763d08adecb760d74b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Aug 2021 01:37:30 +0900 Subject: xtensa: build platform directories unconditionally All of arch/xtensa/platforms/*/ have Makefile. You do not need to check the presence of Makefile. Signed-off-by: Masahiro Yamada Message-Id: <20210811163731.186125-3-masahiroy@kernel.org> Signed-off-by: Max Filippov --- arch/xtensa/Makefile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 3c0573fe6761..093e87b889be 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -32,8 +32,6 @@ platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga -PLATFORM = $(platform-y) - # temporarily until string.h is fixed KBUILD_CFLAGS += -ffreestanding -D__linux__ KBUILD_CFLAGS += -pipe -mlongcalls -mtext-section-literals @@ -55,16 +53,13 @@ KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(vardirs) $(plfdirs)) KBUILD_DEFCONFIG := iss_defconfig -# Only build platform if it includes a Makefile -buildplf := $(shell test -e $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/) - # Find libgcc.a LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o core-y += arch/xtensa/kernel/ arch/xtensa/mm/ -core-y += $(buildplf) +core-y += arch/xtensa/platforms/$(platform-y)/ core-y += arch/xtensa/boot/dts/ libs-y += arch/xtensa/lib/ $(LIBGCC) -- cgit v1.2.3-70-g09d2 From 7b7cec477fc3cd42ce565dfc3e53f144504fc95c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 12 Aug 2021 01:37:31 +0900 Subject: xtensa: move core-y in arch/xtensa/Makefile to arch/xtensa/Kbuild Use obj-y to clean up Makefile. Signed-off-by: Masahiro Yamada Message-Id: <20210811163731.186125-4-masahiroy@kernel.org> Signed-off-by: Max Filippov --- arch/xtensa/Kbuild | 1 + arch/xtensa/Makefile | 3 --- arch/xtensa/platforms/Makefile | 4 ++++ 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 arch/xtensa/platforms/Makefile diff --git a/arch/xtensa/Kbuild b/arch/xtensa/Kbuild index a4e40e534e6a..fd12f61745ba 100644 --- a/arch/xtensa/Kbuild +++ b/arch/xtensa/Kbuild @@ -1 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-y += kernel/ mm/ platforms/ boot/dts/ diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 093e87b889be..96714ef7c89e 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -58,9 +58,6 @@ KBUILD_DEFCONFIG := iss_defconfig LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o -core-y += arch/xtensa/kernel/ arch/xtensa/mm/ -core-y += arch/xtensa/platforms/$(platform-y)/ -core-y += arch/xtensa/boot/dts/ libs-y += arch/xtensa/lib/ $(LIBGCC) diff --git a/arch/xtensa/platforms/Makefile b/arch/xtensa/platforms/Makefile new file mode 100644 index 000000000000..e2e7e0726979 --- /dev/null +++ b/arch/xtensa/platforms/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_XTENSA_PLATFORM_XT2000) += xt2000/ +obj-$(CONFIG_XTENSA_PLATFORM_ISS) += iss/ +obj-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += xtfpga/ -- cgit v1.2.3-70-g09d2 From 12593568d7319c34c72038ea799ab1bd0f0eb01c Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Wed, 11 Aug 2021 18:36:25 +0100 Subject: KVM: arm64: Return -EPERM from __pkvm_host_share_hyp() Fix the error code returned by __pkvm_host_share_hyp() when the host attempts to share with EL2 a page that has already been shared with another entity. Reported-by: Will Deacon Signed-off-by: Quentin Perret Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20210811173630.2536721-1-qperret@google.com --- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 8165390d3ec9..6ec695311498 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -404,7 +404,7 @@ int __pkvm_host_share_hyp(u64 pfn) cur = kvm_pgtable_hyp_pte_prot(pte); prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_SHARED_BORROWED); if (!check_prot(cur, prot, ~prot)) - ret = EPERM; + ret = -EPERM; goto unlock; map_shared: -- cgit v1.2.3-70-g09d2 From ebdf90a4a1c6d7f4a8a820d1f41bc7fcad95b823 Mon Sep 17 00:00:00 2001 From: Riccardo Mancini Date: Wed, 11 Aug 2021 20:06:26 +0200 Subject: perf test: Make --skip work on shell tests perf-test has the option --skip to provide a list of tests to skip. However, this option does not work with shell scripts. This patch passes the skiplist to run_shell_tests, so that also shell scripts could be skipped using --skip. Committer tests: Tests 79 onwards are shell tests: Before: # perf test --skip 1,2,81,82,84,88,90 1: vmlinux symtab matches kallsyms : Skip (user override) 2: Detect openat syscall event : Skip (user override) 3: Detect openat syscall event on all cpus : Ok 4: Read samples using the mmap interface : Ok 5: Test data source output : Ok 78: x86 Sample parsing : Ok 79: build id cache operations : Ok 80: daemon operations : Ok 81: perf pipe recording and injection test : Ok 82: Add vfs_getname probe to get syscall args filenames : FAILED! 83: probe libc's inet_pton & backtrace it with ping : Ok 84: Use vfs_getname probe to get syscall args filenames : FAILED! 85: Zstd perf.data compression/decompression : Ok 86: perf stat csv summary test : Ok 87: perf stat metrics (shadow stat) test : Ok 88: perf stat --bpf-counters test : Ok 89: Check Arm CoreSight trace data recording and synthesized samples: Skip 90: Check open filename arg using perf trace + vfs_getname : FAILED! # After: # perf test --skip 1,2,81,82,84,88,90 1: vmlinux symtab matches kallsyms : Skip (user override) 2: Detect openat syscall event : Skip (user override) 3: Detect openat syscall event on all cpus : Ok 4: Read samples using the mmap interface : Ok 5: Test data source output : Ok 78: x86 Sample parsing : Ok 79: build id cache operations : Ok 80: daemon operations : Ok 81: perf pipe recording and injection test : Skip (user override) 82: Add vfs_getname probe to get syscall args filenames : Skip (user override) 83: probe libc's inet_pton & backtrace it with ping : Ok 84: Use vfs_getname probe to get syscall args filenames : Skip (user override) 85: Zstd perf.data compression/decompression : Ok 86: perf stat csv summary test : Ok 87: perf stat metrics (shadow stat) test : Ok 88: perf stat --bpf-counters test : Skip (user override) 89: Check Arm CoreSight trace data recording and synthesized samples: Skip 90: Check open filename arg using perf trace + vfs_getname : Skip (user override) # Signed-off-by: Riccardo Mancini Tested-by: Arnaldo Carvalho de Melo Cc: Ian Rogers Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20210811180625.160944-1-rickyman7@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index fb5846db02e1..da7dc5e45d0c 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -598,7 +598,8 @@ static int shell_test__run(struct test *test, int subdir __maybe_unused) return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL; } -static int run_shell_tests(int argc, const char *argv[], int i, int width) +static int run_shell_tests(int argc, const char *argv[], int i, int width, + struct intlist *skiplist) { struct dirent **entlist; struct dirent *ent; @@ -632,6 +633,12 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width) st.file = ent->d_name; pr_info("%2d: %-*s:", i, width, test.desc); + + if (intlist__find(skiplist, i)) { + color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); + continue; + } + test_and_print(&test, false, -1); } @@ -731,7 +738,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } } - return run_shell_tests(argc, argv, i, width); + return run_shell_tests(argc, argv, i, width, skiplist); } static int perf_test__list_shell(int argc, const char **argv, int i) -- cgit v1.2.3-70-g09d2 From 2696d6e59c00b13a0b27cfc39a509577f937b44e Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 23 Jul 2021 14:34:31 +0800 Subject: libperf: Add perf_cpu_map__default_new() libperf already has a static function called 'cpu_map__default_new()'. Add a new API perf_cpu_map__default_new() to export the function. Signed-off-by: Jin Yao Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jin Yao Cc: Kan Liang Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210723063433.7318-2-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/perf/cpumap.c | 5 +++++ tools/lib/perf/include/perf/cpumap.h | 1 + 2 files changed, 6 insertions(+) diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c index ca0215047c32..51b6553912e0 100644 --- a/tools/lib/perf/cpumap.c +++ b/tools/lib/perf/cpumap.c @@ -68,6 +68,11 @@ static struct perf_cpu_map *cpu_map__default_new(void) return cpus; } +struct perf_cpu_map *perf_cpu_map__default_new(void) +{ + return cpu_map__default_new(); +} + static int cmp_int(const void *a, const void *b) { return *(const int *)a - *(const int*)b; diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h index 6a17ad730cbc..7c27766ea0bf 100644 --- a/tools/lib/perf/include/perf/cpumap.h +++ b/tools/lib/perf/include/perf/cpumap.h @@ -9,6 +9,7 @@ struct perf_cpu_map; LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void); +LIBPERF_API struct perf_cpu_map *perf_cpu_map__default_new(void); LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list); LIBPERF_API struct perf_cpu_map *perf_cpu_map__read(FILE *file); LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map); -- cgit v1.2.3-70-g09d2 From b726e3634eb3605bd61d3a7a69dad6455b947256 Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 23 Jul 2021 14:34:32 +0800 Subject: perf tools: Create hybrid flag in target The user may count or collect only on a cpu list via '-C/--cpus' option. Previously cpus for an evsel were retrieved from PMU's sysfs. But if the target cpu list is defined, the retrieved cpus are not kept and the target cpu list is used instead. But for hybrid system, we can't directly use target cpu list. The cpu list may not be available on hybrid pmu (e.g. cpu_core or cpu_atom). So we should not set the 'has_user_cpus' flag for hybrid system. The difficulity is that we can't call perf_pmu__has_hybrid() in evlist.c to check hybrid system otherwise 'perf test python' would be failed (undefined symbol for perf_pmu__has_hybrid). If we add pmu.c to python-ext-sources, too many symbol dependencies are hard to resolve. We use an alternative method by using a new 'hybrid' flag in target for hybrid system checking. Signed-off-by: Jin Yao Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jin Yao Cc: Kan Liang Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210723063433.7318-3-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- tools/perf/util/target.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 47581a237c7a..06f8890816c3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1002,7 +1002,7 @@ int evlist__create_maps(struct evlist *evlist, struct target *target) if (!cpus) goto out_delete_threads; - evlist->core.has_user_cpus = !!target->cpu_list; + evlist->core.has_user_cpus = !!target->cpu_list && !target->hybrid; perf_evlist__set_maps(&evlist->core, cpus, threads); diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h index 4ff56217f2a6..daec6cba500d 100644 --- a/tools/perf/util/target.h +++ b/tools/perf/util/target.h @@ -17,6 +17,7 @@ struct target { bool default_per_cpu; bool per_thread; bool use_bpf; + bool hybrid; const char *attr_map; }; -- cgit v1.2.3-70-g09d2 From 1d3351e631fc34d73b530a67263188062fe598ba Mon Sep 17 00:00:00 2001 From: Jin Yao Date: Fri, 23 Jul 2021 14:34:33 +0800 Subject: perf tools: Enable on a list of CPUs for hybrid The 'perf record' and 'perf stat' commands have supported the option '-C/--cpus' to count or collect only on the list of CPUs provided. This option needs to be supported for hybrid as well. For hybrid support, it needs to check that the cpu list are available on hybrid PMU. One example for AlderLake, cpu0-7 is 'cpu_core', cpu8-11 is 'cpu_atom'. Before: # perf stat -e cpu_core/cycles/ -C11 -- sleep 1 Performance counter stats for 'CPU(s) 11': cpu_core/cycles/ 1.006179431 seconds time elapsed The 'perf stat' command silently returned "" without any helpful information. It should error out pointing out that that cpu11 was not 'cpu_core'. After: # perf stat -e cpu_core/cycles/ -C11 -- sleep 1 WARNING: 11 isn't a 'cpu_core', please use a CPU list in the 'cpu_core' range (0-7) failed to use cpu list 11 We also need to support the events without pmu prefix specified. # perf stat -e cycles -C11 -- sleep 1 WARNING: 11 isn't a 'cpu_core', please use a CPU list in the 'cpu_core' range (0-7) Performance counter stats for 'CPU(s) 11': 1,067,373 cpu_atom/cycles/ 1.005544738 seconds time elapsed The perf tool creates two cycles events automatically, cpu_core/cycles/ and cpu_atom/cycles/. It checks that cpu11 is not 'cpu_core', then shows a warning for cpu_core/cycles/ and only count the cpu_atom/cycles/. If part of cpus are 'cpu_core' and part of cpus are 'cpu_atom', for example, # perf stat -e cycles -C0,11 -- sleep 1 WARNING: use 0 in 'cpu_core' for 'cycles', skip other cpus in list. WARNING: use 11 in 'cpu_atom' for 'cycles', skip other cpus in list. Performance counter stats for 'CPU(s) 0,11': 1,914,704 cpu_core/cycles/ 2,036,983 cpu_atom/cycles/ 1.005815641 seconds time elapsed It now automatically selects cpu0 for cpu_core/cycles/, selects cpu11 for cpu_atom/cycles/, and output with some warnings. Some more complex examples, # perf stat -e cycles,instructions -C0,11 -- sleep 1 WARNING: use 0 in 'cpu_core' for 'cycles', skip other cpus in list. WARNING: use 11 in 'cpu_atom' for 'cycles', skip other cpus in list. WARNING: use 0 in 'cpu_core' for 'instructions', skip other cpus in list. WARNING: use 11 in 'cpu_atom' for 'instructions', skip other cpus in list. Performance counter stats for 'CPU(s) 0,11': 2,780,387 cpu_core/cycles/ 1,583,432 cpu_atom/cycles/ 3,957,277 cpu_core/instructions/ 1,167,089 cpu_atom/instructions/ 1.006005124 seconds time elapsed # perf stat -e cycles,cpu_atom/instructions/ -C0,11 -- sleep 1 WARNING: use 0 in 'cpu_core' for 'cycles', skip other cpus in list. WARNING: use 11 in 'cpu_atom' for 'cycles', skip other cpus in list. WARNING: use 11 in 'cpu_atom' for 'cpu_atom/instructions/', skip other cpus in list. Performance counter stats for 'CPU(s) 0,11': 3,290,301 cpu_core/cycles/ 1,953,073 cpu_atom/cycles/ 1,407,869 cpu_atom/instructions/ 1.006260912 seconds time elapsed Signed-off-by: Jin Yao Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Andi Kleen Cc: Ingo Molnar Cc: Jin Yao Cc: Kan Liang Cc: Peter Zijlstra Link: https //lore.kernel.org/r/20210723063433.7318-4-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 7 ++++ tools/perf/builtin-stat.c | 6 ++++ tools/perf/util/evlist-hybrid.c | 73 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/evlist-hybrid.h | 1 + tools/perf/util/evlist.c | 1 + tools/perf/util/pmu.c | 35 ++++++++++++++++++++ tools/perf/util/pmu.h | 4 +++ 7 files changed, 127 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 548c1dbde6c5..cc801fecf079 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2854,6 +2854,13 @@ int cmd_record(int argc, const char **argv) /* Enable ignoring missing threads when -u/-p option is defined. */ rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid; + if (evlist__fix_hybrid_cpus(rec->evlist, rec->opts.target.cpu_list)) { + pr_err("failed to use cpu list %s\n", + rec->opts.target.cpu_list); + goto out; + } + + rec->opts.target.hybrid = perf_pmu__has_hybrid(); err = -ENOMEM; if (evlist__create_maps(rec->evlist, &rec->opts.target) < 0) usage_with_options(record_usage, record_options); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 84de61795e67..f4253ba26c3f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2430,6 +2430,12 @@ int cmd_stat(int argc, const char **argv) if ((stat_config.aggr_mode == AGGR_THREAD) && (target.system_wide)) target.per_thread = true; + if (evlist__fix_hybrid_cpus(evsel_list, target.cpu_list)) { + pr_err("failed to use cpu list %s\n", target.cpu_list); + goto out; + } + + target.hybrid = perf_pmu__has_hybrid(); if (evlist__create_maps(evsel_list, &target) < 0) { if (target__has_task(&target)) { pr_err("Problems finding threads of monitor\n"); diff --git a/tools/perf/util/evlist-hybrid.c b/tools/perf/util/evlist-hybrid.c index db3f5fbdebe1..7c554234b43d 100644 --- a/tools/perf/util/evlist-hybrid.c +++ b/tools/perf/util/evlist-hybrid.c @@ -86,3 +86,76 @@ bool evlist__has_hybrid(struct evlist *evlist) return false; } + +int evlist__fix_hybrid_cpus(struct evlist *evlist, const char *cpu_list) +{ + struct perf_cpu_map *cpus; + struct evsel *evsel, *tmp; + struct perf_pmu *pmu; + int ret, unmatched_count = 0, events_nr = 0; + + if (!perf_pmu__has_hybrid() || !cpu_list) + return 0; + + cpus = perf_cpu_map__new(cpu_list); + if (!cpus) + return -1; + + /* + * The evsels are created with hybrid pmu's cpus. But now we + * need to check and adjust the cpus of evsel by cpu_list because + * cpu_list may cause conflicts with cpus of evsel. For example, + * cpus of evsel is cpu0-7, but the cpu_list is cpu6-8, we need + * to adjust the cpus of evsel to cpu6-7. And then propatate maps + * in evlist__create_maps(). + */ + evlist__for_each_entry_safe(evlist, tmp, evsel) { + struct perf_cpu_map *matched_cpus, *unmatched_cpus; + char buf1[128], buf2[128]; + + pmu = perf_pmu__find_hybrid_pmu(evsel->pmu_name); + if (!pmu) + continue; + + ret = perf_pmu__cpus_match(pmu, cpus, &matched_cpus, + &unmatched_cpus); + if (ret) + goto out; + + events_nr++; + + if (matched_cpus->nr > 0 && (unmatched_cpus->nr > 0 || + matched_cpus->nr < cpus->nr || + matched_cpus->nr < pmu->cpus->nr)) { + perf_cpu_map__put(evsel->core.cpus); + perf_cpu_map__put(evsel->core.own_cpus); + evsel->core.cpus = perf_cpu_map__get(matched_cpus); + evsel->core.own_cpus = perf_cpu_map__get(matched_cpus); + + if (unmatched_cpus->nr > 0) { + cpu_map__snprint(matched_cpus, buf1, sizeof(buf1)); + pr_warning("WARNING: use %s in '%s' for '%s', skip other cpus in list.\n", + buf1, pmu->name, evsel->name); + } + } + + if (matched_cpus->nr == 0) { + evlist__remove(evlist, evsel); + evsel__delete(evsel); + + cpu_map__snprint(cpus, buf1, sizeof(buf1)); + cpu_map__snprint(pmu->cpus, buf2, sizeof(buf2)); + pr_warning("WARNING: %s isn't a '%s', please use a CPU list in the '%s' range (%s)\n", + buf1, pmu->name, pmu->name, buf2); + unmatched_count++; + } + + perf_cpu_map__put(matched_cpus); + perf_cpu_map__put(unmatched_cpus); + } + + ret = (unmatched_count == events_nr) ? -1 : 0; +out: + perf_cpu_map__put(cpus); + return ret; +} diff --git a/tools/perf/util/evlist-hybrid.h b/tools/perf/util/evlist-hybrid.h index 19f74b4c340a..aacdb1b0f948 100644 --- a/tools/perf/util/evlist-hybrid.h +++ b/tools/perf/util/evlist-hybrid.h @@ -10,5 +10,6 @@ int evlist__add_default_hybrid(struct evlist *evlist, bool precise); void evlist__warn_hybrid_group(struct evlist *evlist); bool evlist__has_hybrid(struct evlist *evlist); +int evlist__fix_hybrid_cpus(struct evlist *evlist, const char *cpu_list); #endif /* __PERF_EVLIST_HYBRID_H */ diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 06f8890816c3..5f92319ce258 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -27,6 +27,7 @@ #include "util/perf_api_probe.h" #include "util/evsel_fprintf.h" #include "util/evlist-hybrid.h" +#include "util/pmu.h" #include #include #include diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 6cdbee8a12e7..5f486ccb6fe6 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1927,3 +1927,38 @@ int perf_pmu__match(char *pattern, char *name, char *tok) return 0; } + +int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus, + struct perf_cpu_map **mcpus_ptr, + struct perf_cpu_map **ucpus_ptr) +{ + struct perf_cpu_map *pmu_cpus = pmu->cpus; + struct perf_cpu_map *matched_cpus, *unmatched_cpus; + int matched_nr = 0, unmatched_nr = 0; + + matched_cpus = perf_cpu_map__default_new(); + if (!matched_cpus) + return -1; + + unmatched_cpus = perf_cpu_map__default_new(); + if (!unmatched_cpus) { + perf_cpu_map__put(matched_cpus); + return -1; + } + + for (int i = 0; i < cpus->nr; i++) { + int cpu; + + cpu = perf_cpu_map__idx(pmu_cpus, cpus->map[i]); + if (cpu == -1) + unmatched_cpus->map[unmatched_nr++] = cpus->map[i]; + else + matched_cpus->map[matched_nr++] = cpus->map[i]; + } + + unmatched_cpus->nr = unmatched_nr; + matched_cpus->nr = matched_nr; + *mcpus_ptr = matched_cpus; + *ucpus_ptr = unmatched_cpus; + return 0; +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 033e8211c025..5133bc456034 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -11,6 +11,7 @@ #include "pmu-events/pmu-events.h" struct evsel_config_term; +struct perf_cpu_map; enum { PERF_PMU_FORMAT_VALUE_CONFIG, @@ -136,4 +137,7 @@ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config, bool perf_pmu__has_hybrid(void); int perf_pmu__match(char *pattern, char *name, char *tok); +int perf_pmu__cpus_match(struct perf_pmu *pmu, struct perf_cpu_map *cpus, + struct perf_cpu_map **mcpus_ptr, + struct perf_cpu_map **ucpus_ptr); #endif /* __PMU_H */ -- cgit v1.2.3-70-g09d2 From 59a27e1122133831111f9e2e40fec2307d742487 Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Wed, 21 Jul 2021 09:59:37 +0200 Subject: riscv: Optimize kernel virtual address conversion macro The current test in kernel_mapping_va_to_pa only applies when CONFIG_XIP_KERNEL is set, so use IS_ENABLED to optimize this macro at compile-time in standard kernels that do not require this test. Signed-off-by: Alexandre Ghiti Tested-by: Emil Renner Berthing Reviewed-by: Jisheng Zhang Reviewed-By: Vitaly Wool Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index cca8764aed83..d40d77d76d82 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -122,7 +122,7 @@ extern struct kernel_mapping kernel_map; #define linear_mapping_va_to_pa(x) ((unsigned long)(x) - kernel_map.va_pa_offset) #define kernel_mapping_va_to_pa(y) ({ \ unsigned long _y = y; \ - (_y < kernel_map.virt_addr + XIP_OFFSET) ? \ + (IS_ENABLED(CONFIG_XIP_KERNEL) && _y < kernel_map.virt_addr + XIP_OFFSET) ? \ ((unsigned long)(_y) - kernel_map.va_kernel_xip_pa_offset) : \ ((unsigned long)(_y) - kernel_map.va_kernel_pa_offset - XIP_OFFSET); \ }) -- cgit v1.2.3-70-g09d2 From 283e61c5a9bed2c2acde3f50a3f76f09816c0aab Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Sun, 8 Aug 2021 12:00:21 +0300 Subject: scsi: ufs: ufshpb: Rewind the read timeout on every read The purpose of the "cold"-timer is not to hang-on to active regions with no reads. Therefore the read timeout should be rewound on every read, and not just when the region is activated. Link: https://lore.kernel.org/r/20210808090024.21721-2-avri.altman@wdc.com Fixes: 13c044e91678 (scsi: ufs: ufshpb: Add "cold" regions timer) Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index d0eb14be47a3..8e92c61ed9d4 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -178,9 +178,19 @@ next_srgn: set_bit_len = cnt; spin_lock_irqsave(&hpb->rgn_state_lock, flags); - if (set_dirty && rgn->rgn_state != HPB_RGN_INACTIVE && - srgn->srgn_state == HPB_SRGN_VALID) - bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); + if (rgn->rgn_state != HPB_RGN_INACTIVE) { + if (set_dirty) { + if (srgn->srgn_state == HPB_SRGN_VALID) + bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, + set_bit_len); + } else if (hpb->is_hcm) { + /* rewind the read timer for lru regions */ + rgn->read_timeout = ktime_add_ms(ktime_get(), + rgn->hpb->params.read_timeout_ms); + rgn->read_timeout_expiries = + rgn->hpb->params.read_timeout_expiries; + } + } spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); if (hpb->is_hcm && prev_srgn != srgn) { -- cgit v1.2.3-70-g09d2 From 07106f86ae13d9197bfd38c2d47743304b14099e Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Sun, 8 Aug 2021 12:00:22 +0300 Subject: scsi: ufs: ufshpb: Use a correct max multi chunk In HPB2.0, if pre_req_min_tr_len < transfer_len < pre_req_max_tr_len, the driver is expected to send a HPB-WRITE-BUFFER companion to HPB-READ. The upper bound should fit into a single byte, regardless of bMAX_ DATA_SIZE_FOR_HPB_SINGLE_CMD which being an attribute (u32) can be significantly larger. To further illustrate the issue, consider the following scenario: - SCSI_DEFAULT_MAX_SECTORS is 1024 limiting the I/O chunks to 512KB - The OEM changes scsi_host_template .max_sectors to be 2048 which allows for 1MB requests: transfer_len = 256 - pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH = 256 - ufshpb_is_supported_chunk() returns true (256 <= 256) - WARN_ON_ONCE(256 > 256) doesn't warn - ufshpb_set_hpb_read_to_upiu() casts transfer_len to u8: transfer_len = 0 - The command is failing with ILLEGAL REQUEST Link: https://lore.kernel.org/r/20210808090024.21721-3-avri.altman@wdc.com Fixes: 41d8a9333cc9 (scsi: ufs: ufshpb: Add HPB 2.0 support) Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index c74a6c35a446..6df317dfe034 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -32,7 +32,7 @@ /* hpb support chunk size */ #define HPB_LEGACY_CHUNK_HIGH 1 #define HPB_MULTI_CHUNK_LOW 7 -#define HPB_MULTI_CHUNK_HIGH 256 +#define HPB_MULTI_CHUNK_HIGH 255 /* hpb vender defined opcode */ #define UFSHPB_READ 0xF8 -- cgit v1.2.3-70-g09d2 From 22aede9f48b6766fb67441610120db9b04adf109 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Sun, 8 Aug 2021 12:00:23 +0300 Subject: scsi: ufs: ufshpb: Verify that 'num_inflight_map_req' is non-negative 'num_inflight_map_req' should not be negative. It is incremented and decremented without any protection, allowing it theoretically to be negative, should some weird unbalanced count occur. Verify that the those calls are properly serialized. Link: https://lore.kernel.org/r/20210808090024.21721-4-avri.altman@wdc.com Fixes: 33845a2d844b (scsi: ufs: ufshpb: Limit the number of in-flight map requests) Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 10 ++++++++++ drivers/scsi/ufs/ufshpb.h | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 8e92c61ed9d4..cd48367f94cc 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -756,6 +756,7 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, { struct ufshpb_req *map_req; struct bio *bio; + unsigned long flags; if (hpb->is_hcm && hpb->num_inflight_map_req >= hpb->params.inflight_map_req) { @@ -780,7 +781,10 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, map_req->rb.srgn_idx = srgn->srgn_idx; map_req->rb.mctx = srgn->mctx; + + spin_lock_irqsave(&hpb->param_lock, flags); hpb->num_inflight_map_req++; + spin_unlock_irqrestore(&hpb->param_lock, flags); return map_req; } @@ -788,9 +792,14 @@ static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, static void ufshpb_put_map_req(struct ufshpb_lu *hpb, struct ufshpb_req *map_req) { + unsigned long flags; + bio_put(map_req->bio); ufshpb_put_req(hpb, map_req); + + spin_lock_irqsave(&hpb->param_lock, flags); hpb->num_inflight_map_req--; + spin_unlock_irqrestore(&hpb->param_lock, flags); } static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, @@ -2387,6 +2396,7 @@ static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) spin_lock_init(&hpb->rgn_state_lock); spin_lock_init(&hpb->rsp_list_lock); + spin_lock_init(&hpb->param_lock); INIT_LIST_HEAD(&hpb->lru_info.lh_lru_rgn); INIT_LIST_HEAD(&hpb->lh_act_srgn); diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index 6df317dfe034..a79e07398970 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -237,7 +237,9 @@ struct ufshpb_lu { struct ufshpb_req *pre_req; int num_inflight_pre_req; int throttle_pre_req; - int num_inflight_map_req; + int num_inflight_map_req; /* hold param_lock */ + spinlock_t param_lock; + struct list_head lh_pre_req_free; int cur_read_id; int pre_req_min_tr_len; -- cgit v1.2.3-70-g09d2 From 10163cee1f06fc2e17bcf7bbc2982337202d1d5c Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Sun, 8 Aug 2021 12:00:24 +0300 Subject: scsi: ufs: ufshpb: Do not report victim error in HCM In host control mode, eviction is perceived as an extreme measure. There are several conditions that both the entering and exiting regions should meet, so that eviction will take place. The common case however, is that those conditions are rarely met, so it is normal that the act of eviction fails. Therefore, do not report an error in host control mode if eviction fails. Link: https://lore.kernel.org/r/20210808090024.21721-5-avri.altman@wdc.com Fixes: 6c59cb501b86 (scsi: ufs: ufshpb: Make eviction depend on region's reads) Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index cd48367f94cc..aafb55136c7e 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -1385,7 +1385,8 @@ static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) victim_rgn = ufshpb_victim_lru_info(hpb); if (!victim_rgn) { dev_warn(&hpb->sdev_ufs_lu->sdev_dev, - "cannot get victim region error\n"); + "cannot get victim region %s\n", + hpb->is_hcm ? "" : "error"); ret = -ENOMEM; goto out; } -- cgit v1.2.3-70-g09d2 From 51f3a478892873337c54068d1185bcd797000a52 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:04 -0700 Subject: scsi: core: Introduce the scsi_cmd_to_rq() function The 'request' member of struct scsi_cmnd is superfluous. The struct request and struct scsi_cmnd data structures are adjacent and hence the request pointer can be derived easily from a scsi_cmnd pointer. Introduce a helper function that performs that conversion in a type-safe way. This patch is the first step towards removing the request member from struct scsi_cmnd. Making that change has the following advantages: - This is a performance optimization since adding an offset to a pointer takes less time than dereferencing a pointer. - struct scsi_cmnd becomes smaller. Link: https://lore.kernel.org/r/20210809230355.8186-2-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- include/scsi/scsi_cmnd.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 90da9617d28a..e76278ea1fee 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -146,6 +146,12 @@ struct scsi_cmnd { unsigned int extra_len; /* length of alignment and padding */ }; +/* Variant of blk_mq_rq_from_pdu() that verifies the type of its argument. */ +static inline struct request *scsi_cmd_to_rq(struct scsi_cmnd *scmd) +{ + return blk_mq_rq_from_pdu(scmd); +} + /* * Return the driver private allocation behind the command. * Only works if cmd_size is set in the host template. -- cgit v1.2.3-70-g09d2 From aa8e25e5006aac52c943c84e9056ab488630ee19 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:05 -0700 Subject: scsi: core: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. Cast away constness where necessary when passing a SCSI command pointer to scsi_cmd_to_rq(). This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-3-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi.c | 2 +- drivers/scsi/scsi_error.c | 15 ++++++++------- drivers/scsi/scsi_lib.c | 28 +++++++++++++++------------- drivers/scsi/scsi_logging.c | 18 ++++++++++-------- include/scsi/scsi_cmnd.h | 8 +++++--- include/scsi/scsi_device.h | 16 +++++++++------- 6 files changed, 48 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index d26025cf5de3..b241f9e3885c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -190,7 +190,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "(result %x)\n", cmd->result)); good_bytes = scsi_bufflen(cmd); - if (!blk_rq_is_passthrough(cmd->request)) { + if (!blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) { int old_good_bytes = good_bytes; drv = scsi_cmd_to_driver(cmd); if (drv->done) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 58a252c38992..d85d308a0683 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -242,7 +242,7 @@ scsi_abort_command(struct scsi_cmnd *scmd) */ static void scsi_eh_reset(struct scsi_cmnd *scmd) { - if (!blk_rq_is_passthrough(scmd->request)) { + if (!blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) { struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); if (sdrv->eh_reset) sdrv->eh_reset(scmd); @@ -1182,7 +1182,7 @@ static enum scsi_disposition scsi_request_sense(struct scsi_cmnd *scmd) static enum scsi_disposition scsi_eh_action(struct scsi_cmnd *scmd, enum scsi_disposition rtn) { - if (!blk_rq_is_passthrough(scmd->request)) { + if (!blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) { struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); if (sdrv->eh_action) rtn = sdrv->eh_action(scmd, rtn); @@ -1750,21 +1750,23 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, */ int scsi_noretry_cmd(struct scsi_cmnd *scmd) { + struct request *req = scsi_cmd_to_rq(scmd); + switch (host_byte(scmd->result)) { case DID_OK: break; case DID_TIME_OUT: goto check_type; case DID_BUS_BUSY: - return (scmd->request->cmd_flags & REQ_FAILFAST_TRANSPORT); + return req->cmd_flags & REQ_FAILFAST_TRANSPORT; case DID_PARITY: - return (scmd->request->cmd_flags & REQ_FAILFAST_DEV); + return req->cmd_flags & REQ_FAILFAST_DEV; case DID_ERROR: if (get_status_byte(scmd) == SAM_STAT_RESERVATION_CONFLICT) return 0; fallthrough; case DID_SOFT_ERROR: - return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER); + return req->cmd_flags & REQ_FAILFAST_DRIVER; } if (!scsi_status_is_check_condition(scmd->result)) @@ -1775,8 +1777,7 @@ check_type: * assume caller has checked sense and determined * the check condition was retryable. */ - if (scmd->request->cmd_flags & REQ_FAILFAST_DEV || - blk_rq_is_passthrough(scmd->request)) + if (req->cmd_flags & REQ_FAILFAST_DEV || blk_rq_is_passthrough(req)) return 1; return 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 77578b221a71..909a422ec8f4 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -119,13 +119,15 @@ scsi_set_blocked(struct scsi_cmnd *cmd, int reason) static void scsi_mq_requeue_cmd(struct scsi_cmnd *cmd) { - if (cmd->request->rq_flags & RQF_DONTPREP) { - cmd->request->rq_flags &= ~RQF_DONTPREP; + struct request *rq = scsi_cmd_to_rq(cmd); + + if (rq->rq_flags & RQF_DONTPREP) { + rq->rq_flags &= ~RQF_DONTPREP; scsi_mq_uninit_cmd(cmd); } else { WARN_ON_ONCE(true); } - blk_mq_requeue_request(cmd->request, true); + blk_mq_requeue_request(rq, true); } /** @@ -164,7 +166,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; - blk_mq_requeue_request(cmd->request, true); + blk_mq_requeue_request(scsi_cmd_to_rq(cmd), true); } /** @@ -478,7 +480,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) static void scsi_uninit_cmd(struct scsi_cmnd *cmd) { - if (!blk_rq_is_passthrough(cmd->request)) { + if (!blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) { struct scsi_driver *drv = scsi_cmd_to_driver(cmd); if (drv->uninit_command) @@ -624,7 +626,7 @@ static void scsi_io_completion_reprep(struct scsi_cmnd *cmd, static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) { - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); unsigned long wait_for; if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) @@ -643,7 +645,7 @@ static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) { struct request_queue *q = cmd->device->request_queue; - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); int level = 0; enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY, ACTION_DELAYED_RETRY} action; @@ -818,7 +820,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, { bool sense_valid; bool sense_current = true; /* false implies "deferred sense" */ - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); struct scsi_sense_hdr sshdr; sense_valid = scsi_command_normalize_sense(cmd, &sshdr); @@ -907,7 +909,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; struct request_queue *q = cmd->device->request_queue; - struct request *req = cmd->request; + struct request *req = scsi_cmd_to_rq(cmd); blk_status_t blk_stat = BLK_STS_OK; if (unlikely(result)) /* a nz result may or may not be an error */ @@ -978,7 +980,7 @@ static inline bool scsi_cmd_needs_dma_drain(struct scsi_device *sdev, blk_status_t scsi_alloc_sgtables(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); unsigned short nr_segs = blk_rq_nr_phys_segments(rq); struct scatterlist *last_sg = NULL; blk_status_t ret; @@ -1112,7 +1114,7 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) { void *buf = cmd->sense_buffer; void *prot = cmd->prot_sdb; - struct request *rq = blk_mq_rq_from_pdu(cmd); + struct request *rq = scsi_cmd_to_rq(cmd); unsigned int flags = cmd->flags & SCMD_PRESERVED_FLAGS; unsigned long jiffies_at_alloc; int retries, to_clear; @@ -1577,12 +1579,12 @@ static blk_status_t scsi_prepare_cmd(struct request *req) static void scsi_mq_done(struct scsi_cmnd *cmd) { - if (unlikely(blk_should_fake_timeout(cmd->request->q))) + if (unlikely(blk_should_fake_timeout(scsi_cmd_to_rq(cmd)->q))) return; if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) return; trace_scsi_dispatch_cmd_done(cmd); - blk_mq_complete_request(cmd->request); + blk_mq_complete_request(scsi_cmd_to_rq(cmd)); } static void scsi_mq_put_budget(struct request_queue *q, int budget_token) diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c index 2317717935e9..ed9572252a42 100644 --- a/drivers/scsi/scsi_logging.c +++ b/drivers/scsi/scsi_logging.c @@ -28,8 +28,9 @@ static void scsi_log_release_buffer(char *bufptr) static inline const char *scmd_name(const struct scsi_cmnd *scmd) { - return scmd->request->rq_disk ? - scmd->request->rq_disk->disk_name : NULL; + struct request *rq = scsi_cmd_to_rq((struct scsi_cmnd *)scmd); + + return rq->rq_disk ? rq->rq_disk->disk_name : NULL; } static size_t sdev_format_header(char *logbuf, size_t logbuf_len, @@ -91,7 +92,7 @@ void scmd_printk(const char *level, const struct scsi_cmnd *scmd, if (!logbuf) return; off = sdev_format_header(logbuf, logbuf_len, scmd_name(scmd), - scmd->request->tag); + scsi_cmd_to_rq((struct scsi_cmnd *)scmd)->tag); if (off < logbuf_len) { va_start(args, fmt); off += vscnprintf(logbuf + off, logbuf_len - off, fmt, args); @@ -188,7 +189,7 @@ void scsi_print_command(struct scsi_cmnd *cmd) return; off = sdev_format_header(logbuf, logbuf_len, - scmd_name(cmd), cmd->request->tag); + scmd_name(cmd), scsi_cmd_to_rq(cmd)->tag); if (off >= logbuf_len) goto out_printk; off += scnprintf(logbuf + off, logbuf_len - off, "CDB: "); @@ -210,7 +211,7 @@ void scsi_print_command(struct scsi_cmnd *cmd) off = sdev_format_header(logbuf, logbuf_len, scmd_name(cmd), - cmd->request->tag); + scsi_cmd_to_rq(cmd)->tag); if (!WARN_ON(off > logbuf_len - 58)) { off += scnprintf(logbuf + off, logbuf_len - off, "CDB[%02x]: ", k); @@ -373,7 +374,8 @@ EXPORT_SYMBOL(__scsi_print_sense); /* Normalize and print sense buffer in SCSI command */ void scsi_print_sense(const struct scsi_cmnd *cmd) { - scsi_log_print_sense(cmd->device, scmd_name(cmd), cmd->request->tag, + scsi_log_print_sense(cmd->device, scmd_name(cmd), + scsi_cmd_to_rq((struct scsi_cmnd *)cmd)->tag, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); } EXPORT_SYMBOL(scsi_print_sense); @@ -391,8 +393,8 @@ void scsi_print_result(const struct scsi_cmnd *cmd, const char *msg, if (!logbuf) return; - off = sdev_format_header(logbuf, logbuf_len, - scmd_name(cmd), cmd->request->tag); + off = sdev_format_header(logbuf, logbuf_len, scmd_name(cmd), + scsi_cmd_to_rq((struct scsi_cmnd *)cmd)->tag); if (off >= logbuf_len) goto out_printk; diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index e76278ea1fee..b9265b15d37a 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -164,7 +164,9 @@ static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd) /* make sure not to use it with passthrough commands */ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) { - return *(struct scsi_driver **)cmd->request->rq_disk->private_data; + struct request *rq = scsi_cmd_to_rq(cmd); + + return *(struct scsi_driver **)rq->rq_disk->private_data; } extern void scsi_finish_command(struct scsi_cmnd *cmd); @@ -228,14 +230,14 @@ static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, static inline sector_t scsi_get_sector(struct scsi_cmnd *scmd) { - return blk_rq_pos(scmd->request); + return blk_rq_pos(scsi_cmd_to_rq(scmd)); } static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) { unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; - return blk_rq_pos(scmd->request) >> shift; + return blk_rq_pos(scsi_cmd_to_rq(scmd)) >> shift; } /* diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 7137e7924913..09a17f6e93a7 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -271,13 +271,15 @@ sdev_prefix_printk(const char *, const struct scsi_device *, const char *, __printf(3, 4) void scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...); -#define scmd_dbg(scmd, fmt, a...) \ - do { \ - if ((scmd)->request->rq_disk) \ - sdev_dbg((scmd)->device, "[%s] " fmt, \ - (scmd)->request->rq_disk->disk_name, ##a);\ - else \ - sdev_dbg((scmd)->device, fmt, ##a); \ +#define scmd_dbg(scmd, fmt, a...) \ + do { \ + struct request *__rq = scsi_cmd_to_rq((scmd)); \ + \ + if (__rq->rq_disk) \ + sdev_dbg((scmd)->device, "[%s] " fmt, \ + __rq->rq_disk->disk_name, ##a); \ + else \ + sdev_dbg((scmd)->device, fmt, ##a); \ } while (0) enum scsi_target_state { -- cgit v1.2.3-70-g09d2 From 5999ccff0fd664e0dac0fe0093b9a5962161d636 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:06 -0700 Subject: scsi: sd: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-4-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 33 +++++++++++++++++---------------- drivers/scsi/sd_zbc.c | 10 +++++----- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c1b75f159e0c..ac431b0477da 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -776,8 +776,9 @@ static unsigned int sd_prot_flag_mask(unsigned int prot_op) static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd, unsigned int dix, unsigned int dif) { - struct bio *bio = scmd->request->bio; - unsigned int prot_op = sd_prot_op(rq_data_dir(scmd->request), dix, dif); + struct request *rq = scsi_cmd_to_rq(scmd); + struct bio *bio = rq->bio; + unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif); unsigned int protect = 0; if (dix) { /* DIX Type 0, 1, 2, 3 */ @@ -868,7 +869,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd) { struct scsi_device *sdp = cmd->device; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); @@ -904,7 +905,7 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd, bool unmap) { struct scsi_device *sdp = cmd->device; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); @@ -936,7 +937,7 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, bool unmap) { struct scsi_device *sdp = cmd->device; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); @@ -966,7 +967,7 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd, static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_device *sdp = cmd->device; struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); @@ -1063,7 +1064,7 @@ out: **/ static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_device *sdp = cmd->device; struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); struct bio *bio = rq->bio; @@ -1112,7 +1113,7 @@ static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd) static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); /* flush requests don't perform I/O, zero the S/G table */ @@ -1210,7 +1211,7 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write, static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_device *sdp = cmd->device; struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq)); @@ -1324,7 +1325,7 @@ fail: static blk_status_t sd_init_command(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); switch (req_op(rq)) { case REQ_OP_DISCARD: @@ -1370,7 +1371,7 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd) static void sd_uninit_command(struct scsi_cmnd *SCpnt) { - struct request *rq = SCpnt->request; + struct request *rq = scsi_cmd_to_rq(SCpnt); u8 *cmnd; if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) @@ -1875,7 +1876,7 @@ static const struct block_device_operations sd_fops = { **/ static void sd_eh_reset(struct scsi_cmnd *scmd) { - struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk); + struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk); /* New SCSI EH run, reset gate variable */ sdkp->ignore_medium_access_errors = false; @@ -1895,7 +1896,7 @@ static void sd_eh_reset(struct scsi_cmnd *scmd) **/ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp) { - struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk); + struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk); struct scsi_device *sdev = scmd->device; if (!scsi_device_online(sdev) || @@ -1936,7 +1937,7 @@ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp) static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) { - struct request *req = scmd->request; + struct request *req = scsi_cmd_to_rq(scmd); struct scsi_device *sdev = scmd->device; unsigned int transferred, good_bytes; u64 start_lba, end_lba, bad_lba; @@ -1991,8 +1992,8 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned int sector_size = SCpnt->device->sector_size; unsigned int resid; struct scsi_sense_hdr sshdr; - struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); - struct request *req = SCpnt->request; + struct request *req = scsi_cmd_to_rq(SCpnt); + struct scsi_disk *sdkp = scsi_disk(req->rq_disk); int sense_valid = 0; int sense_deferred = 0; diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 186b5ff52c3a..b9757f24b0d6 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -243,7 +243,7 @@ out: static blk_status_t sd_zbc_cmnd_checks(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t sector = blk_rq_pos(rq); @@ -321,7 +321,7 @@ static void sd_zbc_update_wp_offset_workfn(struct work_struct *work) blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, unsigned int nr_blocks) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); unsigned int wp_offset, zno = blk_rq_zone_no(rq); unsigned long flags; @@ -386,7 +386,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, unsigned char op, bool all) { - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); sector_t sector = blk_rq_pos(rq); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t block = sectors_to_logical(sdkp->device, sector); @@ -442,7 +442,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); unsigned int zno = blk_rq_zone_no(rq); enum req_opf op = req_op(rq); @@ -516,7 +516,7 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, struct scsi_sense_hdr *sshdr) { int result = cmd->result; - struct request *rq = cmd->request; + struct request *rq = scsi_cmd_to_rq(cmd); if (op_is_zone_mgmt(req_op(rq)) && result && -- cgit v1.2.3-70-g09d2 From c4deb5b5ddd4d924d5067988290bde43ec2b519d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:07 -0700 Subject: scsi: sr: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-5-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sr.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 6203a8b58d40..6a96151d3630 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -331,7 +331,8 @@ static int sr_done(struct scsi_cmnd *SCpnt) int good_bytes = (result == 0 ? this_count : 0); int block_sectors = 0; long error_sector; - struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); + struct request *rq = scsi_cmd_to_rq(SCpnt); + struct scsi_cd *cd = scsi_cd(rq->rq_disk); #ifdef DEBUG scmd_printk(KERN_INFO, SCpnt, "done: %x\n", result); @@ -353,16 +354,14 @@ static int sr_done(struct scsi_cmnd *SCpnt) break; error_sector = get_unaligned_be32(&SCpnt->sense_buffer[3]); - if (SCpnt->request->bio != NULL) - block_sectors = - bio_sectors(SCpnt->request->bio); + if (rq->bio != NULL) + block_sectors = bio_sectors(rq->bio); if (block_sectors < 4) block_sectors = 4; if (cd->device->sector_size == 2048) error_sector <<= 2; error_sector &= ~(block_sectors - 1); - good_bytes = (error_sector - - blk_rq_pos(SCpnt->request)) << 9; + good_bytes = (error_sector - blk_rq_pos(rq)) << 9; if (good_bytes < 0 || good_bytes >= this_count) good_bytes = 0; /* @@ -394,7 +393,7 @@ static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt) { int block = 0, this_count, s_size; struct scsi_cd *cd; - struct request *rq = SCpnt->request; + struct request *rq = scsi_cmd_to_rq(SCpnt); blk_status_t ret; ret = scsi_alloc_sgtables(SCpnt); -- cgit v1.2.3-70-g09d2 From 3b4720fc8d1c94cabf1a5cfe29f62d49c33aaea3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:08 -0700 Subject: scsi: scsi_transport_fc: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-6-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 49748cd817a5..60e406bcf42a 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3804,7 +3804,7 @@ bool fc_eh_should_retry_cmd(struct scsi_cmnd *scmd) struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device)); if ((rport->port_state != FC_PORTSTATE_ONLINE) && - (scmd->request->cmd_flags & REQ_FAILFAST_TRANSPORT)) { + (scsi_cmd_to_rq(scmd)->cmd_flags & REQ_FAILFAST_TRANSPORT)) { set_host_byte(scmd, DID_TRANSPORT_MARGINAL); return false; } -- cgit v1.2.3-70-g09d2 From eb43d41de2917a5b290fd1f3e48af85f81495edf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:09 -0700 Subject: scsi: scsi_transport_spi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-7-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_transport_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 5af7a10e9514..bd72c38d7bfc 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -1230,7 +1230,7 @@ int spi_populate_tag_msg(unsigned char *msg, struct scsi_cmnd *cmd) { if (cmd->flags & SCMD_TAGGED) { *msg++ = SIMPLE_QUEUE_TAG; - *msg++ = cmd->request->tag; + *msg++ = scsi_cmd_to_rq(cmd)->tag; return 2; } -- cgit v1.2.3-70-g09d2 From c8329cd55bf4f2ae294121b3db1e44d7612b30fc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:10 -0700 Subject: scsi: ata: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-8-bvanassche@acm.org Cc: Jens Axboe Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/ata/libata-eh.c | 5 ++--- drivers/ata/libata-scsi.c | 10 +++++----- drivers/ata/pata_falcon.c | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index bb3637762985..bf9c4b6c5c3d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -912,7 +912,7 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) * Note that ATA_QCFLAG_FAILED is unconditionally set after * this function completes. */ - blk_abort_request(qc->scsicmd->request); + blk_abort_request(scsi_cmd_to_rq(qc->scsicmd)); } /** @@ -1893,8 +1893,7 @@ static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) */ static inline bool ata_eh_quiet(struct ata_queued_cmd *qc) { - if (qc->scsicmd && - qc->scsicmd->request->rq_flags & RQF_QUIET) + if (qc->scsicmd && scsi_cmd_to_rq(qc->scsicmd)->rq_flags & RQF_QUIET) qc->flags |= ATA_QCFLAG_QUIET; return qc->flags & ATA_QCFLAG_QUIET; } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b9588c52815d..f7f630485465 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -631,7 +631,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, { struct ata_queued_cmd *qc; - qc = ata_qc_new_init(dev, cmd->request->tag); + qc = ata_qc_new_init(dev, scsi_cmd_to_rq(cmd)->tag); if (qc) { qc->scsicmd = cmd; qc->scsidone = cmd->scsi_done; @@ -639,7 +639,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, qc->sg = scsi_sglist(cmd); qc->n_elem = scsi_sg_count(cmd); - if (cmd->request->rq_flags & RQF_QUIET) + if (scsi_cmd_to_rq(cmd)->rq_flags & RQF_QUIET) qc->flags |= ATA_QCFLAG_QUIET; } else { cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL; @@ -1496,7 +1496,7 @@ nothing_to_do: static bool ata_check_nblocks(struct scsi_cmnd *scmd, u32 n_blocks) { - struct request *rq = scmd->request; + struct request *rq = scsi_cmd_to_rq(scmd); u32 req_blocks; if (!blk_rq_is_passthrough(rq)) @@ -1531,7 +1531,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) { struct scsi_cmnd *scmd = qc->scsicmd; const u8 *cdb = scmd->cmnd; - struct request *rq = scmd->request; + struct request *rq = scsi_cmd_to_rq(scmd); int class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); unsigned int tf_flags = 0; u64 block; @@ -3181,7 +3181,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) * as it modifies the DATA OUT buffer, which would corrupt user * memory for SG_IO commands. */ - if (unlikely(blk_rq_is_passthrough(scmd->request))) + if (unlikely(blk_rq_is_passthrough(scsi_cmd_to_rq(scmd)))) goto invalid_opcode; if (unlikely(scmd->cmd_len < 16)) { diff --git a/drivers/ata/pata_falcon.c b/drivers/ata/pata_falcon.c index 9d0dd8f4c21c..121635aa8c00 100644 --- a/drivers/ata/pata_falcon.c +++ b/drivers/ata/pata_falcon.c @@ -48,8 +48,8 @@ static unsigned int pata_falcon_data_xfer(struct ata_queued_cmd *qc, struct scsi_cmnd *cmd = qc->scsicmd; bool swap = 1; - if (dev->class == ATA_DEV_ATA && cmd && cmd->request && - !blk_rq_is_passthrough(cmd->request)) + if (dev->class == ATA_DEV_ATA && cmd && + !blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) swap = 0; /* Transfer multiple of 2 bytes */ -- cgit v1.2.3-70-g09d2 From 99247108c0f2aac3a153fd255f12e17db40432a2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:11 -0700 Subject: scsi: RDMA/iser: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-9-bvanassche@acm.org Reviewed-by: Max Gurtovoy Reviewed-by: Sagi Grimberg Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/iser/iser_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index afec40da9b58..9776b755d848 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c @@ -159,7 +159,7 @@ iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_domain *domain) { domain->sig_type = IB_SIG_TYPE_T10_DIF; domain->sig.dif.pi_interval = scsi_prot_interval(sc); - domain->sig.dif.ref_tag = t10_pi_ref_tag(sc->request); + domain->sig.dif.ref_tag = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); /* * At the moment we hard code those, but in the future * we will take them from sc. -- cgit v1.2.3-70-g09d2 From 9c5274eec75b13e8d26fe562c5276b0b91a254a9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:12 -0700 Subject: scsi: RDMA/srp: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-10-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srp/ib_srp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 8d5cf5eb5778..71eda91e810c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -1280,7 +1280,7 @@ static bool srp_terminate_cmd(struct scsi_cmnd *scmnd, void *context_ptr, { struct srp_terminate_context *context = context_ptr; struct srp_target_port *target = context->srp_target; - u32 tag = blk_mq_unique_tag(scmnd->request); + u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmnd)); struct srp_rdma_ch *ch = &target->ch[blk_mq_unique_tag_to_hwq(tag)]; struct srp_request *req = scsi_cmd_priv(scmnd); @@ -2152,6 +2152,7 @@ static void srp_handle_qp_err(struct ib_cq *cq, struct ib_wc *wc, static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) { + struct request *rq = scsi_cmd_to_rq(scmnd); struct srp_target_port *target = host_to_target(shost); struct srp_rdma_ch *ch; struct srp_request *req = scsi_cmd_priv(scmnd); @@ -2166,8 +2167,8 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) if (unlikely(scmnd->result)) goto err; - WARN_ON_ONCE(scmnd->request->tag < 0); - tag = blk_mq_unique_tag(scmnd->request); + WARN_ON_ONCE(rq->tag < 0); + tag = blk_mq_unique_tag(rq); ch = &target->ch[blk_mq_unique_tag_to_hwq(tag)]; spin_lock_irqsave(&ch->lock, flags); @@ -2791,7 +2792,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) if (!req) return SUCCESS; - tag = blk_mq_unique_tag(scmnd->request); + tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmnd)); ch_idx = blk_mq_unique_tag_to_hwq(tag); if (WARN_ON_ONCE(ch_idx >= target->ch_count)) return SUCCESS; -- cgit v1.2.3-70-g09d2 From d78f31ce7ef9a3bccb63ecb668d124166e591dfc Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:13 -0700 Subject: scsi: zfcp: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-11-bvanassche@acm.org Acked-by: Benjamin Block Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_fsf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 1990216cf289..6da8f6d05d39 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2377,7 +2377,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) } } - blk_add_driver_data(scsi->request, &blktrc, sizeof(blktrc)); + blk_add_driver_data(scsi_cmd_to_rq(scsi), &blktrc, sizeof(blktrc)); } /** -- cgit v1.2.3-70-g09d2 From cd4b46cdb4917a3186bbf6c068aa30cd8d64b6a4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:14 -0700 Subject: scsi: 53c700: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-12-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/53c700.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 1c6b4e672687..a12e3525977d 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1823,7 +1823,7 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *) if ((hostdata->tag_negotiated & (1<device->simple_tags) { - slot->tag = SCp->request->tag; + slot->tag = scsi_cmd_to_rq(SCp)->tag; CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n", slot->tag, slot); } else { -- cgit v1.2.3-70-g09d2 From 2e4b231ac1252cff05cb9c1a737cf4850ecbcd17 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:15 -0700 Subject: scsi: NCR5380: Use sc_data_direction instead of rq_data_dir() This patch prepares for the removal of the request pointer from struct scsi_cmnd and does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-13-bvanassche@acm.org Cc: Michael Schmitz Suggested-by: Finn Thain Acked-by: Finn Thain Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 6 +++--- drivers/scsi/sun3_scsi.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 3baadd068768..a85589a2a8af 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -778,7 +778,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) } #ifdef CONFIG_SUN3 - if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) { + if (sun3scsi_dma_finish(hostdata->connected->sc_data_direction)) { pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", instance->host_no); BUG(); @@ -1710,7 +1710,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) count = sun3scsi_dma_xfer_len(hostdata, cmd); if (count > 0) { - if (rq_data_dir(cmd->request)) + if (cmd->sc_data_direction == DMA_TO_DEVICE) sun3scsi_dma_send_setup(hostdata, cmd->SCp.ptr, count); else @@ -2158,7 +2158,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) count = sun3scsi_dma_xfer_len(hostdata, tmp); if (count > 0) { - if (rq_data_dir(tmp->request)) + if (tmp->sc_data_direction == DMA_TO_DEVICE) sun3scsi_dma_send_setup(hostdata, tmp->SCp.ptr, count); else diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 2e3fbc2fae97..9ed0bb7ecece 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -366,8 +366,9 @@ static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) } /* clean up after our dma is done */ -static int sun3scsi_dma_finish(int write_flag) +static int sun3scsi_dma_finish(enum dma_data_direction data_dir) { + const bool write_flag = data_dir == DMA_TO_DEVICE; unsigned short __maybe_unused count; unsigned short fifo; int ret = 0; -- cgit v1.2.3-70-g09d2 From 8779b4bdbc12c3fd3a6567a8ec2a8d375b874ad2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:16 -0700 Subject: scsi: aacraid: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-14-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 267934d2f14b..c2d6f0a9e0b1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1504,7 +1504,7 @@ static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd srbcmd->id = cpu_to_le32(scmd_id(cmd)); srbcmd->lun = cpu_to_le32(cmd->device->lun); srbcmd->flags = cpu_to_le32(flag); - timeout = cmd->request->timeout/HZ; + timeout = scsi_cmd_to_rq(cmd)->timeout / HZ; if (timeout == 0) timeout = (dev->sa_firmware ? AAC_SA_TIMEOUT : AAC_ARC_TIMEOUT); srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 54eb4d41bc2c..deb32c9f4b3e 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -224,7 +224,7 @@ struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd) { struct fib *fibptr; - fibptr = &dev->fibs[scmd->request->tag]; + fibptr = &dev->fibs[scsi_cmd_to_rq(scmd)->tag]; /* * Null out fields that depend on being zero at the start of * each I/O -- cgit v1.2.3-70-g09d2 From 40e16ce7b6fa6c75b000bcd984d5094a667b7529 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:17 -0700 Subject: scsi: advansys: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-15-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/advansys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index f3377e2ef5fb..ffb391967573 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7423,7 +7423,7 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, * Set the srb_tag to the command tag + 1, as * srb_tag '0' is used internally by the chip. */ - srb_tag = scp->request->tag + 1; + srb_tag = scsi_cmd_to_rq(scp)->tag + 1; asc_scsi_q->q2.srb_tag = srb_tag; /* @@ -7637,7 +7637,7 @@ static int adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, adv_req_t **adv_reqpp) { - u32 srb_tag = scp->request->tag; + u32 srb_tag = scsi_cmd_to_rq(scp)->tag; adv_req_t *reqp; ADV_SCSI_REQ_Q *scsiqp; int ret; -- cgit v1.2.3-70-g09d2 From 11bf4ec580737c77755c1c4ab698d12988dd93e6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:18 -0700 Subject: scsi: aha1542: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-16-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aha1542.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 1210e61afb18..584a59522038 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -262,11 +262,12 @@ static void aha1542_free_cmd(struct scsi_cmnd *cmd) struct aha1542_cmd *acmd = scsi_cmd_priv(cmd); if (cmd->sc_data_direction == DMA_FROM_DEVICE) { + struct request *rq = scsi_cmd_to_rq(cmd); void *buf = acmd->data_buffer; struct req_iterator iter; struct bio_vec bv; - rq_for_each_segment(bv, cmd->request, iter) { + rq_for_each_segment(bv, rq, iter) { memcpy_to_page(bv.bv_page, bv.bv_offset, buf, bv.bv_len); buf += bv.bv_len; @@ -447,11 +448,12 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) #endif if (cmd->sc_data_direction == DMA_TO_DEVICE) { + struct request *rq = scsi_cmd_to_rq(cmd); void *buf = acmd->data_buffer; struct req_iterator iter; struct bio_vec bv; - rq_for_each_segment(bv, cmd->request, iter) { + rq_for_each_segment(bv, rq, iter) { memcpy_from_page(buf, bv.bv_page, bv.bv_offset, bv.bv_len); buf += bv.bv_len; -- cgit v1.2.3-70-g09d2 From 4bfb9809b877ee9ee8bfdeec7104f0ec80c94ada Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:19 -0700 Subject: scsi: bnx2i: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-17-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 43e8a1dafec0..5521469ce678 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1918,7 +1918,7 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session, spin_unlock(&session->back_lock); - p = &per_cpu(bnx2i_percpu, blk_mq_rq_cpu(sc->request)); + p = &per_cpu(bnx2i_percpu, blk_mq_rq_cpu(scsi_cmd_to_rq(sc))); spin_lock(&p->p_work_lock); if (unlikely(!p->iothread)) { rc = -EINVAL; -- cgit v1.2.3-70-g09d2 From c14f1fee18f07bd9073defd101ac4ffb4178efb9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:20 -0700 Subject: scsi: csiostor: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-18-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 56b9ad0a1ca0..3b2eb6ce1fcf 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1786,7 +1786,7 @@ csio_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmnd) struct csio_scsi_qset *sqset; struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); - sqset = &hw->sqset[ln->portid][blk_mq_rq_cpu(cmnd->request)]; + sqset = &hw->sqset[ln->portid][blk_mq_rq_cpu(scsi_cmd_to_rq(cmnd))]; nr = fc_remote_port_chkready(rport); if (nr) { @@ -1989,13 +1989,13 @@ inval_scmnd: csio_info(hw, "Aborted SCSI command to (%d:%llu) tag %u\n", cmnd->device->id, cmnd->device->lun, - cmnd->request->tag); + scsi_cmd_to_rq(cmnd)->tag); return SUCCESS; } else { csio_info(hw, "Failed to abort SCSI command, (%d:%llu) tag %u\n", cmnd->device->id, cmnd->device->lun, - cmnd->request->tag); + scsi_cmd_to_rq(cmnd)->tag); return FAILED; } } -- cgit v1.2.3-70-g09d2 From d3e16aecea2bee65ef80c4da797029156c014bc6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:21 -0700 Subject: scsi: cxlflash: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-19-bvanassche@acm.org Reviewed-by: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 222593bc2afe..2f1894588e0b 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -433,7 +433,7 @@ static u32 cmd_to_target_hwq(struct Scsi_Host *host, struct scsi_cmnd *scp, hwq = afu->hwq_rr_count++ % afu->num_hwqs; break; case HWQ_MODE_TAG: - tag = blk_mq_unique_tag(scp->request); + tag = blk_mq_unique_tag(scsi_cmd_to_rq(scp)); hwq = blk_mq_unique_tag_to_hwq(tag); break; case HWQ_MODE_CPU: -- cgit v1.2.3-70-g09d2 From 3ada9c791b1df0aa1d101d97e6ab46c4bbeb8374 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:22 -0700 Subject: scsi: dpt_i2o: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-20-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/dpt_i2o.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index a18a4a08f049..7af96d14c9bc 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -652,7 +652,7 @@ static int adpt_abort(struct scsi_cmnd * cmd) msg[2] = 0; msg[3]= 0; /* Add 1 to avoid firmware treating it as invalid command */ - msg[4] = cmd->request->tag + 1; + msg[4] = scsi_cmd_to_rq(cmd)->tag + 1; if (pHba->host) spin_lock_irq(pHba->host->host_lock); rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); @@ -2236,7 +2236,7 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid); msg[2] = 0; /* Add 1 to avoid firmware treating it as invalid command */ - msg[3] = cmd->request->tag + 1; + msg[3] = scsi_cmd_to_rq(cmd)->tag + 1; // Our cards use the transaction context as the tag for queueing // Adaptec/DPT Private stuff msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16); -- cgit v1.2.3-70-g09d2 From e1c9f0cfac4f2ed2bc6e89f2f4061dcf1538d4cd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:23 -0700 Subject: scsi: fnic: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-21-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_scsi.c | 51 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 762cc8bd2653..0f9cedf78872 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -107,7 +107,7 @@ static void fnic_cleanup_io(struct fnic *fnic); static inline spinlock_t *fnic_io_lock_hash(struct fnic *fnic, struct scsi_cmnd *sc) { - u32 hash = sc->request->tag & (FNIC_IO_LOCKS - 1); + u32 hash = scsi_cmd_to_rq(sc)->tag & (FNIC_IO_LOCKS - 1); return &fnic->io_req_lock[hash]; } @@ -390,7 +390,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, (rp->flags & FC_RP_FLAGS_RETRY)) exch_flags |= FCPIO_ICMND_SRFLAG_RETRY; - fnic_queue_wq_copy_desc_icmnd_16(wq, sc->request->tag, + fnic_queue_wq_copy_desc_icmnd_16(wq, scsi_cmd_to_rq(sc)->tag, 0, exch_flags, io_req->sgl_cnt, SCSI_SENSE_BUFFERSIZE, io_req->sgl_list_pa, @@ -422,6 +422,7 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, */ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { + const int tag = scsi_cmd_to_rq(sc)->tag; struct fc_lport *lp = shost_priv(sc->device->host); struct fc_rport *rport; struct fnic_io_req *io_req = NULL; @@ -511,8 +512,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ sg_count = scsi_dma_map(sc); if (sg_count < 0) { FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, - sc->request->tag, sc, 0, sc->cmnd[0], - sg_count, CMD_STATE(sc)); + tag, sc, 0, sc->cmnd[0], sg_count, CMD_STATE(sc)); mempool_free(io_req, fnic->io_req_pool); goto out; } @@ -571,7 +571,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ * refetch the pointer under the lock. */ FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, - sc->request->tag, sc, 0, 0, 0, + tag, sc, 0, 0, 0, (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); io_req = (struct fnic_io_req *)CMD_SP(sc); CMD_SP(sc) = NULL; @@ -603,8 +603,7 @@ out: sc->cmnd[5]); FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, - sc->request->tag, sc, io_req, - sg_count, cmd_trace, + tag, sc, io_req, sg_count, cmd_trace, (((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc))); /* if only we issued IO, will we have the io lock */ @@ -1364,6 +1363,7 @@ int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do) static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data, bool reserved) { + const int tag = scsi_cmd_to_rq(sc)->tag; struct fnic *fnic = data; struct fnic_io_req *io_req; unsigned long flags = 0; @@ -1371,7 +1371,7 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data, unsigned long start_time = 0; struct fnic_stats *fnic_stats = &fnic->fnic_stats; - io_lock = fnic_io_lock_tag(fnic, sc->request->tag); + io_lock = fnic_io_lock_tag(fnic, tag); spin_lock_irqsave(io_lock, flags); io_req = (struct fnic_io_req *)CMD_SP(sc); @@ -1413,7 +1413,7 @@ cleanup_scsi_cmd: sc->result = DID_TRANSPORT_DISRUPTED << 16; FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "fnic_cleanup_io: tag:0x%x : sc:0x%p duration = %lu DID_TRANSPORT_DISRUPTED\n", - sc->request->tag, sc, (jiffies - start_time)); + tag, sc, jiffies - start_time); if (atomic64_read(&fnic->io_cmpl_skip)) atomic64_dec(&fnic->io_cmpl_skip); @@ -1425,10 +1425,10 @@ cleanup_scsi_cmd: if (!(CMD_FLAGS(sc) & FNIC_IO_ISSUED)) shost_printk(KERN_ERR, fnic->lport->host, "Calling done for IO not issued to fw: tag:0x%x sc:0x%p\n", - sc->request->tag, sc); + tag, sc); FNIC_TRACE(fnic_cleanup_io, - sc->device->host->host_no, sc->request->tag, sc, + sc->device->host->host_no, tag, sc, jiffies_to_msecs(jiffies - start_time), 0, ((u64)sc->cmnd[0] << 32 | (u64)sc->cmnd[2] << 24 | @@ -1566,7 +1566,7 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data, { struct fnic_rport_abort_io_iter_data *iter_data = data; struct fnic *fnic = iter_data->fnic; - int abt_tag = sc->request->tag; + int abt_tag = scsi_cmd_to_rq(sc)->tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -1727,6 +1727,7 @@ void fnic_terminate_rport_io(struct fc_rport *rport) */ int fnic_abort_cmd(struct scsi_cmnd *sc) { + struct request *const rq = scsi_cmd_to_rq(sc); struct fc_lport *lp; struct fnic *fnic; struct fnic_io_req *io_req = NULL; @@ -1741,7 +1742,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) struct abort_stats *abts_stats; struct terminate_stats *term_stats; enum fnic_ioreq_state old_ioreq_state; - int tag; + const int tag = rq->tag; unsigned long abt_issued_time; DECLARE_COMPLETION_ONSTACK(tm_done); @@ -1757,7 +1758,6 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) term_stats = &fnic->fnic_stats.term_stats; rport = starget_to_rport(scsi_target(sc->device)); - tag = sc->request->tag; FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "Abort Cmd called FCID 0x%x, LUN 0x%llx TAG %x flags %x\n", @@ -1842,8 +1842,8 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) /* Now queue the abort command to firmware */ int_to_scsilun(sc->device->lun, &fc_lun); - if (fnic_queue_abort_io_req(fnic, sc->request->tag, task_req, - fc_lun.scsi_lun, io_req)) { + if (fnic_queue_abort_io_req(fnic, tag, task_req, fc_lun.scsi_lun, + io_req)) { spin_lock_irqsave(io_lock, flags); if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) CMD_STATE(sc) = old_ioreq_state; @@ -1943,8 +1943,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) } fnic_abort_cmd_end: - FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no, - sc->request->tag, sc, + FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no, tag, sc, jiffies_to_msecs(jiffies - start_time), 0, ((u64)sc->cmnd[0] << 32 | (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | @@ -1994,7 +1993,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic, /* fill in the lun info */ int_to_scsilun(sc->device->lun, &fc_lun); - fnic_queue_wq_copy_desc_itmf(wq, sc->request->tag | FNIC_TAG_DEV_RST, + fnic_queue_wq_copy_desc_itmf(wq, scsi_cmd_to_rq(sc)->tag | FNIC_TAG_DEV_RST, 0, FCPIO_ITMF_LUN_RESET, SCSI_NO_TAG, fc_lun.scsi_lun, io_req->port_id, fnic->config.ra_tov, fnic->config.ed_tov); @@ -2025,7 +2024,7 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc, struct fnic_pending_aborts_iter_data *iter_data = data; struct fnic *fnic = iter_data->fnic; struct scsi_device *lun_dev = iter_data->lun_dev; - int abt_tag = sc->request->tag; + int abt_tag = scsi_cmd_to_rq(sc)->tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -2206,14 +2205,15 @@ clean_pending_aborts_end: static inline int fnic_scsi_host_start_tag(struct fnic *fnic, struct scsi_cmnd *sc) { - struct request_queue *q = sc->request->q; + struct request *rq = scsi_cmd_to_rq(sc); + struct request_queue *q = rq->q; struct request *dummy; dummy = blk_mq_alloc_request(q, REQ_OP_WRITE, BLK_MQ_REQ_NOWAIT); if (IS_ERR(dummy)) return SCSI_NO_TAG; - sc->tag = sc->request->tag = dummy->tag; + sc->tag = rq->tag = dummy->tag; sc->host_scribble = (unsigned char *)dummy; return dummy->tag; @@ -2238,6 +2238,7 @@ fnic_scsi_host_end_tag(struct fnic *fnic, struct scsi_cmnd *sc) */ int fnic_device_reset(struct scsi_cmnd *sc) { + struct request *rq = scsi_cmd_to_rq(sc); struct fc_lport *lp; struct fnic *fnic; struct fnic_io_req *io_req = NULL; @@ -2250,7 +2251,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) struct scsi_lun fc_lun; struct fnic_stats *fnic_stats; struct reset_stats *reset_stats; - int tag = 0; + int tag = rq->tag; DECLARE_COMPLETION_ONSTACK(tm_done); int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/ bool new_sc = 0; @@ -2284,7 +2285,6 @@ int fnic_device_reset(struct scsi_cmnd *sc) CMD_FLAGS(sc) = FNIC_DEVICE_RESET; /* Allocate tag if not present */ - tag = sc->request->tag; if (unlikely(tag < 0)) { /* * Really should fix the midlayer to pass in a proper @@ -2458,8 +2458,7 @@ fnic_device_reset_clean: } fnic_device_reset_end: - FNIC_TRACE(fnic_device_reset, sc->device->host->host_no, - sc->request->tag, sc, + FNIC_TRACE(fnic_device_reset, sc->device->host->host_no, rq->tag, sc, jiffies_to_msecs(jiffies - start_time), 0, ((u64)sc->cmnd[0] << 32 | (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | -- cgit v1.2.3-70-g09d2 From 1effbface9671659f187547bf60caae043724ba3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:24 -0700 Subject: scsi: hisi_sas: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-22-bvanassche@acm.org Acked-by: John Garry Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 4 ++-- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 3a903e8e0384..9515c45affa5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -185,7 +185,7 @@ static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, void *bitmap = hisi_hba->slot_index_tags; if (scsi_cmnd) - return scsi_cmnd->request->tag; + return scsi_cmd_to_rq(scsi_cmnd)->tag; spin_lock(&hisi_hba->lock); index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, @@ -449,7 +449,7 @@ static int hisi_sas_task_prep(struct sas_task *task, unsigned int dq_index; u32 blk_tag; - blk_tag = blk_mq_unique_tag(scmd->request); + blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); dq_index = blk_mq_unique_tag_to_hwq(blk_tag); *dq_pointer = dq = &hisi_hba->dq[dq_index]; } else { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index a4885d03afe2..3ab669dc806f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1153,7 +1153,7 @@ static void fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd, { unsigned char prot_op = scsi_get_prot_op(scsi_cmnd); unsigned int interval = scsi_prot_interval(scsi_cmnd); - u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmnd->request); + u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmd_to_rq(scsi_cmnd)); switch (prot_op) { case SCSI_PROT_READ_INSERT: -- cgit v1.2.3-70-g09d2 From 84090d42c437a510598da3710eb5db705cfbe133 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:25 -0700 Subject: scsi: hpsa: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-23-bvanassche@acm.org Acked-by: Don Brace Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index f135a10f582b..3faa87fa296a 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5686,7 +5686,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) /* Get the ptr to our adapter structure out of cmd->host. */ h = sdev_to_hba(cmd->device); - BUG_ON(cmd->request->tag < 0); + BUG_ON(scsi_cmd_to_rq(cmd)->tag < 0); dev = cmd->device->hostdata; if (!dev) { @@ -5729,7 +5729,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd) * and is therefore a brand-new command. */ if (likely(cmd->retries == 0 && - !blk_rq_is_passthrough(cmd->request) && + !blk_rq_is_passthrough(scsi_cmd_to_rq(cmd)) && h->acciopath_status)) { /* Submit with the retry_pending flag unset. */ rc = hpsa_ioaccel_submit(h, c, cmd, false); @@ -5894,7 +5894,7 @@ static int hpsa_scsi_add_host(struct ctlr_info *h) */ static int hpsa_get_cmd_index(struct scsi_cmnd *scmd) { - int idx = scmd->request->tag; + int idx = scsi_cmd_to_rq(scmd)->tag; if (idx < 0) return idx; -- cgit v1.2.3-70-g09d2 From e9ddad785ec2da58ba1d48a280cea868d2009785 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:26 -0700 Subject: scsi: ibmvfc: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-24-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index bee1bec49c09..c372bbc5e218 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -1911,7 +1911,7 @@ static int ibmvfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) struct ibmvfc_cmd *vfc_cmd; struct ibmvfc_fcp_cmd_iu *iu; struct ibmvfc_event *evt; - u32 tag_and_hwq = blk_mq_unique_tag(cmnd->request); + u32 tag_and_hwq = blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); u16 hwq = blk_mq_unique_tag_to_hwq(tag_and_hwq); u16 scsi_channel; int rc; -- cgit v1.2.3-70-g09d2 From 0cd75102014b8a72192f3ca72c68a423bede0bc7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:27 -0700 Subject: scsi: ibmvscsi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-25-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index e6a3eaaa57d9..50df7dd9cb91 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1072,7 +1072,7 @@ static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd, init_event_struct(evt_struct, handle_cmd_rsp, VIOSRP_SRP_FORMAT, - cmnd->request->timeout/HZ); + scsi_cmd_to_rq(cmnd)->timeout / HZ); evt_struct->cmnd = cmnd; evt_struct->cmnd_done = done; -- cgit v1.2.3-70-g09d2 From 240ec1197786f5c81e957f256f9eebc46d5a07a4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:28 -0700 Subject: scsi: ips: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-26-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ips.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 8b33c9871484..cdd94fb2aab7 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -3735,7 +3735,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) scb->cmd.dcdb.segment_4G = 0; scb->cmd.dcdb.enhanced_sg = 0; - TimeOut = scb->scsi_cmd->request->timeout; + TimeOut = scsi_cmd_to_rq(scb->scsi_cmd)->timeout; if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ if (!scb->sg_len) { -- cgit v1.2.3-70-g09d2 From cad1a780e065b7789df7f947dfa635e6481a8379 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:29 -0700 Subject: scsi: libsas: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-27-bvanassche@acm.org Reviewed-by: John Garry Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_ata.c | 2 +- drivers/scsi/libsas/sas_scsi_host.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 1e0df6b17227..a315715b3622 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -596,7 +596,7 @@ void sas_ata_task_abort(struct sas_task *task) /* Bounce SCSI-initiated commands to the SCSI EH */ if (qc->scsicmd) { - blk_abort_request(qc->scsicmd->request); + blk_abort_request(scsi_cmd_to_rq(qc->scsicmd)); return; } diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 5db10248f187..08ffb8788290 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -908,7 +908,7 @@ void sas_task_abort(struct sas_task *task) if (dev_is_sata(task->dev)) sas_ata_task_abort(task); else - blk_abort_request(sc->request); + blk_abort_request(scsi_cmd_to_rq(sc)); } int sas_slave_alloc(struct scsi_device *sdev) -- cgit v1.2.3-70-g09d2 From 4221c8a4bdd347b561ad865f890ffebd8e018ccd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:30 -0700 Subject: scsi: lpfc: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-28-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 71 ++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index ee4ff4855866..f905a53d050f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -683,7 +683,7 @@ lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, cpu = raw_smp_processor_id(); if (cmnd && phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) { - tag = blk_mq_unique_tag(cmnd->request); + tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); idx = blk_mq_unique_tag_to_hwq(tag); } else { idx = phba->sli4_hba.cpu_map[cpu].hdwq; @@ -1046,7 +1046,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, return 0; sgpe = scsi_prot_sglist(sc); - lba = t10_pi_ref_tag(sc->request); + lba = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); if (lba == LPFC_INVALID_REFTAG) return 0; @@ -1629,7 +1629,7 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, goto out; /* extract some info from the scsi command for pde*/ - reftag = t10_pi_ref_tag(sc->request); + reftag = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); if (reftag == LPFC_INVALID_REFTAG) goto out; @@ -1792,7 +1792,7 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = lpfc_cmd_blksize(sc); - reftag = t10_pi_ref_tag(sc->request); + reftag = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); if (reftag == LPFC_INVALID_REFTAG) goto out; @@ -2023,7 +2023,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, goto out; /* extract some info from the scsi command for pde*/ - reftag = t10_pi_ref_tag(sc->request); + reftag = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); if (reftag == LPFC_INVALID_REFTAG) goto out; @@ -2224,7 +2224,7 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = lpfc_cmd_blksize(sc); - reftag = t10_pi_ref_tag(sc->request); + reftag = t10_pi_ref_tag(scsi_cmd_to_rq(sc)); if (reftag == LPFC_INVALID_REFTAG) goto out; @@ -2818,7 +2818,7 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) chk_guard = 1; src = (struct scsi_dif_tuple *)sg_virt(sgpe); - start_ref_tag = t10_pi_ref_tag(cmd->request); + start_ref_tag = t10_pi_ref_tag(scsi_cmd_to_rq(cmd)); if (start_ref_tag == LPFC_INVALID_REFTAG) goto out; start_app_tag = src->app_tag; @@ -2910,7 +2910,7 @@ out: phba->bg_guard_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, "9069 BLKGRD: reftag %x grd_tag err %x != %x\n", - t10_pi_ref_tag(cmd->request), + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), sum, guard_tag); } else if (err_type == BGS_REFTAG_ERR_MASK) { @@ -2920,7 +2920,7 @@ out: phba->bg_reftag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, "9066 BLKGRD: reftag %x ref_tag err %x != %x\n", - t10_pi_ref_tag(cmd->request), + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), ref_tag, start_ref_tag); } else if (err_type == BGS_APPTAG_ERR_MASK) { @@ -2930,7 +2930,7 @@ out: phba->bg_apptag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, "9041 BLKGRD: reftag %x app_tag err %x != %x\n", - t10_pi_ref_tag(cmd->request), + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), app_tag, start_app_tag); } } @@ -2992,7 +2992,7 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, " 0x%x lba 0x%llx blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_reftag_err(bgstat)) { @@ -3007,7 +3007,7 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, " 0x%x lba 0x%llx blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_apptag_err(bgstat)) { @@ -3022,7 +3022,7 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, " 0x%x lba 0x%llx blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { @@ -3066,7 +3066,7 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, " 0x%x lba 0x%llx blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); /* Calcuate what type of error it was */ lpfc_calc_bg_err(phba, lpfc_cmd); @@ -3103,8 +3103,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9072 BLKGRD: Invalid BG Profile in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); ret = (-1); goto out; } @@ -3115,8 +3115,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9073 BLKGRD: Invalid BG PDIF Block in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); ret = (-1); goto out; } @@ -3131,8 +3131,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9055 BLKGRD: Guard Tag error in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_reftag_err(bgstat)) { @@ -3146,8 +3146,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9056 BLKGRD: Ref Tag error in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_apptag_err(bgstat)) { @@ -3161,8 +3161,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9061 BLKGRD: App Tag error in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); } if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { @@ -3205,8 +3205,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, "9057 BLKGRD: Unknown error in cmd " "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - t10_pi_ref_tag(cmd->request), - blk_rq_sectors(cmd->request), bgstat, bghm); + t10_pi_ref_tag(scsi_cmd_to_rq(cmd)), + blk_rq_sectors(scsi_cmd_to_rq(cmd)), bgstat, bghm); /* Calcuate what type of error it was */ lpfc_calc_bg_err(phba, lpfc_cmd); @@ -5419,13 +5419,9 @@ static int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid, struct */ static char *lpfc_is_command_vm_io(struct scsi_cmnd *cmd) { - char *uuid = NULL; + struct bio *bio = scsi_cmd_to_rq(cmd)->bio; - if (cmd->request) { - if (cmd->request->bio) - uuid = blkcg_get_fc_appid(cmd->request->bio); - } - return uuid; + return bio ? blkcg_get_fc_appid(bio) : NULL; } /** @@ -5553,8 +5549,8 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) "reftag x%x cnt %u pt %x\n", dif_op_str[scsi_get_prot_op(cmnd)], cmnd->cmnd[0], - t10_pi_ref_tag(cmnd->request), - blk_rq_sectors(cmnd->request), + t10_pi_ref_tag(scsi_cmd_to_rq(cmnd)), + blk_rq_sectors(scsi_cmd_to_rq(cmnd)), (cmnd->cmnd[1]>>5)); } err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd); @@ -5565,8 +5561,8 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) "9038 BLKGRD: rcvd PROT_NORMAL cmd: " "x%x reftag x%x cnt %u pt %x\n", cmnd->cmnd[0], - t10_pi_ref_tag(cmnd->request), - blk_rq_sectors(cmnd->request), + t10_pi_ref_tag(scsi_cmd_to_rq(cmnd)), + blk_rq_sectors(scsi_cmd_to_rq(cmnd)), (cmnd->cmnd[1]>>5)); } err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd); @@ -5637,8 +5633,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) bf_get(wqe_tmo, &lpfc_cmd->cur_iocbq.wqe.generic.wqe_com) : lpfc_cmd->cur_iocbq.iocb.ulpTimeout, - (uint32_t) - (cmnd->request->timeout / 1000)); + (uint32_t)(scsi_cmd_to_rq(cmnd)->timeout / 1000)); goto out_host_busy_free_buf; } -- cgit v1.2.3-70-g09d2 From 4bccecf1c9a95b7094ba75319955e29a3c76e959 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:31 -0700 Subject: scsi: megaraid: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-29-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 4 ++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index ec10b2497310..e4298bf4a482 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1451,10 +1451,10 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, * pthru timeout to the os layer timeout value. */ if (scp->device->type == TYPE_TAPE) { - if ((scp->request->timeout / HZ) > 0xFFFF) + if (scsi_cmd_to_rq(scp)->timeout / HZ > 0xFFFF) pthru->timeout = cpu_to_le16(0xFFFF); else - pthru->timeout = cpu_to_le16(scp->request->timeout / HZ); + pthru->timeout = cpu_to_le16(scsi_cmd_to_rq(scp)->timeout / HZ); } /* diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 06399c026a8d..26d0cf9353dd 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -402,7 +402,7 @@ megasas_get_msix_index(struct megasas_instance *instance, (mega_mod64(atomic64_add_return(1, &instance->total_io_count), instance->msix_vectors)); } else if (instance->host->nr_hw_queues > 1) { - u32 tag = blk_mq_unique_tag(scmd->request); + u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); cmd->request_desc->SCSIIO.MSIxIndex = blk_mq_unique_tag_to_hwq(tag) + instance->low_latency_index_start; @@ -3023,7 +3023,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, io_request->DevHandle = cpu_to_le16(device_id); io_request->LUN[1] = scmd->device->lun; pRAID_Context->timeout_value = - cpu_to_le16 (scmd->request->timeout / HZ); + cpu_to_le16(scsi_cmd_to_rq(scmd)->timeout / HZ); cmd->request_desc->SCSIIO.RequestFlags = (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); @@ -3086,7 +3086,7 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, device_id = MEGASAS_DEV_INDEX(scmd); pd_index = MEGASAS_PD_INDEX(scmd); - os_timeout_value = scmd->request->timeout / HZ; + os_timeout_value = scsi_cmd_to_rq(scmd)->timeout / HZ; mr_device_priv_data = scmd->device->hostdata; cmd->pd_interface = mr_device_priv_data->interface_type; @@ -3381,7 +3381,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, return SCSI_MLQUEUE_HOST_BUSY; } - cmd = megasas_get_cmd_fusion(instance, scmd->request->tag); + cmd = megasas_get_cmd_fusion(instance, scsi_cmd_to_rq(scmd)->tag); if (!cmd) { atomic_dec(&instance->fw_outstanding); @@ -3422,7 +3422,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, */ if (cmd->r1_alt_dev_handle != MR_DEVHANDLE_INVALID) { r1_cmd = megasas_get_cmd_fusion(instance, - (scmd->request->tag + instance->max_fw_cmds)); + scsi_cmd_to_rq(scmd)->tag + instance->max_fw_cmds); megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd); } -- cgit v1.2.3-70-g09d2 From 69868c3b69391ac52922c9d907a36f41b8bccb7e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:32 -0700 Subject: scsi: mpi3mr: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-30-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpi3mr/mpi3mr_os.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 24ac7ddec749..bc1c32f599de 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -50,7 +50,7 @@ static u16 mpi3mr_host_tag_for_scmd(struct mpi3mr_ioc *mrioc, u32 unique_tag; u16 host_tag, hw_queue; - unique_tag = blk_mq_unique_tag(scmd->request); + unique_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); hw_queue = blk_mq_unique_tag_to_hwq(unique_tag); if (hw_queue >= mrioc->num_op_reply_q) @@ -2016,7 +2016,7 @@ static void mpi3mr_setup_eedp(struct mpi3mr_ioc *mrioc, case SCSI_PROT_DIF_TYPE0: eedp_flags |= MPI3_EEDPFLAGS_INCR_PRI_REF_TAG; scsiio_req->cdb.eedp32.primary_reference_tag = - cpu_to_be32(t10_pi_ref_tag(scmd->request)); + cpu_to_be32(t10_pi_ref_tag(scsi_cmd_to_rq(scmd))); break; case SCSI_PROT_DIF_TYPE1: case SCSI_PROT_DIF_TYPE2: @@ -2024,7 +2024,7 @@ static void mpi3mr_setup_eedp(struct mpi3mr_ioc *mrioc, MPI3_EEDPFLAGS_ESC_MODE_APPTAG_DISABLE | MPI3_EEDPFLAGS_CHK_GUARD; scsiio_req->cdb.eedp32.primary_reference_tag = - cpu_to_be32(t10_pi_ref_tag(scmd->request)); + cpu_to_be32(t10_pi_ref_tag(scsi_cmd_to_rq(scmd))); break; case SCSI_PROT_DIF_TYPE3: eedp_flags |= MPI3_EEDPFLAGS_CHK_GUARD | @@ -3451,7 +3451,7 @@ static int mpi3mr_qcmd(struct Scsi_Host *shost, u16 dev_handle; u16 host_tag; u32 scsiio_flags = 0; - struct request *rq = scmd->request; + struct request *rq = scsi_cmd_to_rq(scmd); int iprio_class; sdev_priv_data = scmd->device->hostdata; -- cgit v1.2.3-70-g09d2 From 24b3c922bc8318dda1047d79489d77596f39eee7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:33 -0700 Subject: scsi: mpt3sas: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-31-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 ++-- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 54fd9aef21ac..e7f6fbb282bd 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3848,7 +3848,7 @@ _base_get_msix_index(struct MPT3SAS_ADAPTER *ioc, &ioc->total_io_cnt), ioc->reply_queue_count) : 0; if (scmd && ioc->shost->nr_hw_queues > 1) { - u32 tag = blk_mq_unique_tag(scmd->request); + u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); return blk_mq_unique_tag_to_hwq(tag) + ioc->high_iops_queues; @@ -3932,7 +3932,7 @@ mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, u16 smid; u32 tag, unique_tag; - unique_tag = blk_mq_unique_tag(scmd->request); + unique_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); tag = blk_mq_unique_tag_to_tag(unique_tag); /* diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index b30f271888f7..f7a5ec0add5a 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -3305,7 +3305,7 @@ scsih_abort(struct scsi_cmnd *scmd) sdev_printk(KERN_INFO, scmd->device, "attempting task abort!" "scmd(0x%p), outstanding for %u ms & timeout %u ms\n", scmd, jiffies_to_msecs(jiffies - scmd->jiffies_at_alloc), - (scmd->request->timeout / HZ) * 1000); + (scsi_cmd_to_rq(scmd)->timeout / HZ) * 1000); _scsih_tm_display_info(ioc, scmd); sas_device_priv_data = scmd->device->hostdata; @@ -5075,7 +5075,7 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; mpi_request->CDB.EEDP32.PrimaryReferenceTag = - cpu_to_be32(t10_pi_ref_tag(scmd->request)); + cpu_to_be32(t10_pi_ref_tag(scsi_cmd_to_rq(scmd))); break; case SCSI_PROT_DIF_TYPE3: @@ -5142,7 +5142,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) struct MPT3SAS_DEVICE *sas_device_priv_data; struct MPT3SAS_TARGET *sas_target_priv_data; struct _raid_device *raid_device; - struct request *rq = scmd->request; + struct request *rq = scsi_cmd_to_rq(scmd); int class; Mpi25SCSIIORequest_t *mpi_request; struct _pcie_device *pcie_device = NULL; -- cgit v1.2.3-70-g09d2 From ce425dd7dbc9a35ebd6016ca03beb5736cf96fa2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:34 -0700 Subject: scsi: mvumi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-32-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mvumi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 6bb03d7a254d..4d251bf630a3 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -702,7 +702,7 @@ static int mvumi_host_reset(struct scsi_cmnd *scmd) mhba = (struct mvumi_hba *) scmd->device->host->hostdata; scmd_printk(KERN_NOTICE, scmd, "RESET -%u cmd=%x retries=%x\n", - scmd->request->tag, scmd->cmnd[0], scmd->retries); + scsi_cmd_to_rq(scmd)->tag, scmd->cmnd[0], scmd->retries); return mhba->instancet->reset_host(mhba); } -- cgit v1.2.3-70-g09d2 From 2fd8f23aae36113d35827d38aba8ac391b7dcace Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:35 -0700 Subject: scsi: myrb: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-33-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index 542ed88ef90d..a4a88323e020 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -1263,6 +1263,7 @@ static int myrb_host_reset(struct scsi_cmnd *scmd) static int myrb_pthru_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { + struct request *rq = scsi_cmd_to_rq(scmd); struct myrb_hba *cb = shost_priv(shost); struct myrb_cmdblk *cmd_blk = scsi_cmd_priv(scmd); union myrb_cmd_mbox *mbox = &cmd_blk->mbox; @@ -1286,7 +1287,7 @@ static int myrb_pthru_queuecommand(struct Scsi_Host *shost, } mbox->type3.opcode = MYRB_CMD_DCDB; - mbox->type3.id = scmd->request->tag + 3; + mbox->type3.id = rq->tag + 3; mbox->type3.addr = dcdb_addr; dcdb->channel = sdev->channel; dcdb->target = sdev->id; @@ -1305,11 +1306,11 @@ static int myrb_pthru_queuecommand(struct Scsi_Host *shost, break; } dcdb->early_status = false; - if (scmd->request->timeout <= 10) + if (rq->timeout <= 10) dcdb->timeout = MYRB_DCDB_TMO_10_SECS; - else if (scmd->request->timeout <= 60) + else if (rq->timeout <= 60) dcdb->timeout = MYRB_DCDB_TMO_60_SECS; - else if (scmd->request->timeout <= 600) + else if (rq->timeout <= 600) dcdb->timeout = MYRB_DCDB_TMO_10_MINS; else dcdb->timeout = MYRB_DCDB_TMO_24_HRS; @@ -1550,7 +1551,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost, } myrb_reset_cmd(cmd_blk); - mbox->type5.id = scmd->request->tag + 3; + mbox->type5.id = scsi_cmd_to_rq(scmd)->tag + 3; if (scmd->sc_data_direction == DMA_NONE) goto submit; nsge = scsi_dma_map(scmd); -- cgit v1.2.3-70-g09d2 From 43b2d1b14ed01442f5b9850d8964365e3df4f7e9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:36 -0700 Subject: scsi: myrs: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-34-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 26326af23dbc..07f274afd7e5 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1582,6 +1582,7 @@ static void myrs_mode_sense(struct myrs_hba *cs, struct scsi_cmnd *scmd, static int myrs_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { + struct request *rq = scsi_cmd_to_rq(scmd); struct myrs_hba *cs = shost_priv(shost); struct myrs_cmdblk *cmd_blk = scsi_cmd_priv(scmd); union myrs_cmd_mbox *mbox = &cmd_blk->mbox; @@ -1628,7 +1629,7 @@ static int myrs_queuecommand(struct Scsi_Host *shost, return SCSI_MLQUEUE_HOST_BUSY; cmd_blk->sense_addr = sense_addr; - timeout = scmd->request->timeout; + timeout = rq->timeout; if (scmd->cmd_len <= 10) { if (scmd->device->channel >= cs->ctlr_info->physchan_present) { struct myrs_ldev_info *ldev_info = sdev->hostdata; @@ -1644,10 +1645,10 @@ static int myrs_queuecommand(struct Scsi_Host *shost, mbox->SCSI_10.pdev.target = sdev->id; mbox->SCSI_10.pdev.channel = sdev->channel; } - mbox->SCSI_10.id = scmd->request->tag + 3; + mbox->SCSI_10.id = rq->tag + 3; mbox->SCSI_10.control.dma_ctrl_to_host = (scmd->sc_data_direction == DMA_FROM_DEVICE); - if (scmd->request->cmd_flags & REQ_FUA) + if (rq->cmd_flags & REQ_FUA) mbox->SCSI_10.control.fua = true; mbox->SCSI_10.dma_size = scsi_bufflen(scmd); mbox->SCSI_10.sense_addr = cmd_blk->sense_addr; @@ -1690,10 +1691,10 @@ static int myrs_queuecommand(struct Scsi_Host *shost, mbox->SCSI_255.pdev.target = sdev->id; mbox->SCSI_255.pdev.channel = sdev->channel; } - mbox->SCSI_255.id = scmd->request->tag + 3; + mbox->SCSI_255.id = rq->tag + 3; mbox->SCSI_255.control.dma_ctrl_to_host = (scmd->sc_data_direction == DMA_FROM_DEVICE); - if (scmd->request->cmd_flags & REQ_FUA) + if (rq->cmd_flags & REQ_FUA) mbox->SCSI_255.control.fua = true; mbox->SCSI_255.dma_size = scsi_bufflen(scmd); mbox->SCSI_255.sense_addr = cmd_blk->sense_addr; -- cgit v1.2.3-70-g09d2 From 0f8f3ea84a894b637b6353191b56ced57f0e69a8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:37 -0700 Subject: scsi: ncr53c8xx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-35-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ncr53c8xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index c76e9f05d042..09958f78b70f 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -4164,8 +4164,8 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd) ** **---------------------------------------------------- */ - if (np->settle_time && cmd->request->timeout >= HZ) { - u_long tlimit = jiffies + cmd->request->timeout - HZ; + if (np->settle_time && scsi_cmd_to_rq(cmd)->timeout >= HZ) { + u_long tlimit = jiffies + scsi_cmd_to_rq(cmd)->timeout - HZ; if (time_after(np->settle_time, tlimit)) np->settle_time = tlimit; } -- cgit v1.2.3-70-g09d2 From d995da61228608bbd4cc986874359e8ad634b13b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:38 -0700 Subject: scsi: qedf: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-36-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf_io.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 6b5b6a75ac88..3404782988d5 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -1162,13 +1162,7 @@ void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, return; } - if (!sc_cmd->request) { - QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd->request is NULL, " - "sc_cmd=%p.\n", sc_cmd); - return; - } - - if (!sc_cmd->request->q) { + if (!scsi_cmd_to_rq(sc_cmd)->q) { QEDF_WARN(&(qedf->dbg_ctx), "request->q is NULL so request " "is not valid, sc_cmd=%p.\n", sc_cmd); return; -- cgit v1.2.3-70-g09d2 From 44656cfb01028d742410e9c1159f33ceee5e8615 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:39 -0700 Subject: scsi: qedi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-37-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qedi/qedi_fw.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 71333d3c5c86..ac99e980bb31 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -609,14 +609,7 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, goto error; } - if (!sc_cmd->request) { - QEDI_WARN(&qedi->dbg_ctx, - "sc_cmd->request is NULL, sc_cmd=%p.\n", - sc_cmd); - goto error; - } - - if (!sc_cmd->request->q) { + if (!scsi_cmd_to_rq(sc_cmd)->q) { QEDI_WARN(&qedi->dbg_ctx, "request->q is NULL so request is not valid, sc_cmd=%p.\n", sc_cmd); -- cgit v1.2.3-70-g09d2 From 3f5e62c5e074242449567ed8843ea99952e13ae8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:40 -0700 Subject: scsi: qla1280: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. Remove the unused CMD_REQUEST() macro. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-38-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla1280.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 928da90b79be..9f9b4900c3ab 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -490,7 +490,6 @@ __setup("qla1280=", qla1280_setup); #define CMD_SNSLEN(Cmnd) SCSI_SENSE_BUFFERSIZE #define CMD_RESULT(Cmnd) Cmnd->result #define CMD_HANDLE(Cmnd) Cmnd->host_scribble -#define CMD_REQUEST(Cmnd) Cmnd->request->cmd #define CMD_HOST(Cmnd) Cmnd->device->host #define SCSI_BUS_32(Cmnd) Cmnd->device->channel @@ -2827,7 +2826,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(cmd->request->timeout/HZ); + pkt->timeout = cpu_to_le16(scsi_cmd_to_rq(cmd)->timeout / HZ); /* Set device target ID and LUN */ pkt->lun = SCSI_LUN_32(cmd); @@ -3082,7 +3081,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8)); /* Set ISP command timeout. */ - pkt->timeout = cpu_to_le16(cmd->request->timeout/HZ); + pkt->timeout = cpu_to_le16(scsi_cmd_to_rq(cmd)->timeout / HZ); /* Set device target ID and LUN */ pkt->lun = SCSI_LUN_32(cmd); -- cgit v1.2.3-70-g09d2 From c7d6b2c2cd5656b05849afb0de3f422da1742d0f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:41 -0700 Subject: scsi: qla2xxx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-39-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 868037c7d608..126ac7e24ea9 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -854,7 +854,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) uint16_t hwq; struct qla_qpair *qpair = NULL; - tag = blk_mq_unique_tag(cmd->request); + tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmd)); hwq = blk_mq_unique_tag_to_hwq(tag); qpair = ha->queue_pair_map[hwq]; @@ -1763,7 +1763,7 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, } spin_lock_irqsave(qp->qp_lock_ptr, *flags); - if (ret_cmd && blk_mq_request_started(cmd->request)) + if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd))) sp->done(sp, res); } else { sp->done(sp, res); -- cgit v1.2.3-70-g09d2 From 924b3d7a3a74f4b719369b9d25f76f01a6babc06 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:42 -0700 Subject: scsi: qla4xxx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-40-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_iocb.c | 2 +- drivers/scsi/qla4xxx/ql4_os.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index c57cec6fff6d..28eab07935ba 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c @@ -288,7 +288,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) /* Acquire hardware specific lock */ spin_lock_irqsave(&ha->hardware_lock, flags); - index = (uint32_t)cmd->request->tag; + index = scsi_cmd_to_rq(cmd)->tag; /* * Check to see if adapter is online before placing request on diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 3f7737386193..f1ea65c6e5f5 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -9282,7 +9282,7 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) DEBUG2(printk(KERN_INFO "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x," "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no, - cmd, jiffies, cmd->request->timeout / HZ, + cmd, jiffies, scsi_cmd_to_rq(cmd)->timeout / HZ, ha->dpc_flags, cmd->result, cmd->allowed)); rval = qla4xxx_isp_check_reg(ha); @@ -9349,7 +9349,7 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) DEBUG2(printk(KERN_INFO "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", - ha->host_no, cmd, jiffies, cmd->request->timeout / HZ, + ha->host_no, cmd, jiffies, scsi_cmd_to_rq(cmd)->timeout / HZ, ha->dpc_flags, cmd->result, cmd->allowed)); rval = qla4xxx_isp_check_reg(ha); -- cgit v1.2.3-70-g09d2 From ba4baf0951bba4bf51eb3ab088063c92c35950d1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:43 -0700 Subject: scsi: qlogicpti: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-41-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qlogicpti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index d84e218d32cb..8e7e833a36cc 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -890,7 +890,7 @@ static inline void cmd_frob(struct Command_Entry *cmd, struct scsi_cmnd *Cmnd, cmd->control_flags |= CFLAG_WRITE; else cmd->control_flags |= CFLAG_READ; - cmd->time_out = Cmnd->request->timeout/HZ; + cmd->time_out = scsi_cmd_to_rq(Cmnd)->timeout / HZ; memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len); } -- cgit v1.2.3-70-g09d2 From a6e76e6f2c0efd9e2cf8cf93f532c4d46070e5c5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:44 -0700 Subject: scsi: scsi_debug: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-42-bvanassche@acm.org Acked-by: Douglas Gilbert Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 25112b15ab14..31529d8add0d 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -4722,7 +4722,7 @@ fini: static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd) { u16 hwq; - u32 tag = blk_mq_unique_tag(cmnd->request); + u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); hwq = blk_mq_unique_tag_to_hwq(tag); @@ -4735,7 +4735,7 @@ static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd) static u32 get_tag(struct scsi_cmnd *cmnd) { - return blk_mq_unique_tag(cmnd->request); + return blk_mq_unique_tag(scsi_cmd_to_rq(cmnd)); } /* Queued (deferred) command completions converge here. */ @@ -5384,7 +5384,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, { bool new_sd_dp; bool inject = false; - bool hipri = (cmnd->request->cmd_flags & REQ_HIPRI); + bool hipri = scsi_cmd_to_rq(cmnd)->cmd_flags & REQ_HIPRI; int k, num_in_q, qdepth; unsigned long iflags; u64 ns_from_boot = 0; @@ -5587,8 +5587,9 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, if (sdebug_statistics) sd_dp->issuing_cpu = raw_smp_processor_id(); if (unlikely(sd_dp->aborted)) { - sdev_printk(KERN_INFO, sdp, "abort request tag %d\n", cmnd->request->tag); - blk_abort_request(cmnd->request); + sdev_printk(KERN_INFO, sdp, "abort request tag %d\n", + scsi_cmd_to_rq(cmnd)->tag); + blk_abort_request(scsi_cmd_to_rq(cmnd)); atomic_set(&sdeb_inject_pending, 0); sd_dp->aborted = false; } @@ -7414,7 +7415,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, (u32)cmd[k]); } sdev_printk(KERN_INFO, sdp, "%s: tag=%#x, cmd %s\n", my_name, - blk_mq_unique_tag(scp->request), b); + blk_mq_unique_tag(scsi_cmd_to_rq(scp)), b); } if (unlikely(inject_now && (sdebug_opts & SDEBUG_OPT_HOST_BUSY))) return SCSI_MLQUEUE_HOST_BUSY; -- cgit v1.2.3-70-g09d2 From 12db0f9347ad1ff82c8b686959a9d73bb046ec9a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:45 -0700 Subject: scsi: smartpqi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-43-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c1f0f8da9fe2..d95498ff136a 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5568,7 +5568,7 @@ static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, { u16 hw_queue; - hw_queue = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scmd->request)); + hw_queue = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scsi_cmd_to_rq(scmd))); if (hw_queue > ctrl_info->max_hw_queue_index) hw_queue = 0; @@ -5577,7 +5577,7 @@ static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) { - if (blk_rq_is_passthrough(scmd->request)) + if (blk_rq_is_passthrough(scsi_cmd_to_rq(scmd))) return false; return scmd->SCp.this_residual == 0; -- cgit v1.2.3-70-g09d2 From ec808ef9b83874ffdfef76b0bab4b49e8e1e3e09 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:46 -0700 Subject: scsi: snic: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-44-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/snic/snic_scsi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c index 92f5b65c2a27..95740caa1eb0 100644 --- a/drivers/scsi/snic/snic_scsi.c +++ b/drivers/scsi/snic/snic_scsi.c @@ -33,7 +33,7 @@ #include "snic_io.h" #include "snic.h" -#define snic_cmd_tag(sc) (((struct scsi_cmnd *) sc)->request->tag) +#define snic_cmd_tag(sc) (scsi_cmd_to_rq(sc)->tag) const char *snic_state_str[] = { [SNIC_INIT] = "SNIC_INIT", @@ -1636,7 +1636,7 @@ snic_abort_cmd(struct scsi_cmnd *sc) u32 start_time = jiffies; SNIC_SCSI_DBG(snic->shost, "abt_cmd:sc %p :0x%x :req = %p :tag = %d\n", - sc, sc->cmnd[0], sc->request, tag); + sc, sc->cmnd[0], scsi_cmd_to_rq(sc), tag); if (unlikely(snic_get_state(snic) != SNIC_ONLINE)) { SNIC_HOST_ERR(snic->shost, @@ -2152,7 +2152,7 @@ snic_device_reset(struct scsi_cmnd *sc) int dr_supp = 0; SNIC_SCSI_DBG(shost, "dev_reset:sc %p :0x%x :req = %p :tag = %d\n", - sc, sc->cmnd[0], sc->request, + sc, sc->cmnd[0], scsi_cmd_to_rq(sc), snic_cmd_tag(sc)); dr_supp = snic_dev_reset_supported(sc->device); if (!dr_supp) { @@ -2387,7 +2387,7 @@ snic_host_reset(struct scsi_cmnd *sc) SNIC_SCSI_DBG(shost, "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n", - sc, sc->cmnd[0], sc->request, + sc, sc->cmnd[0], scsi_cmd_to_rq(sc), snic_cmd_tag(sc), CMD_FLAGS(sc)); ret = snic_reset(shost, sc); @@ -2494,7 +2494,7 @@ cleanup: sc->result = DID_TRANSPORT_DISRUPTED << 16; SNIC_HOST_INFO(snic->shost, "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p, Tag %d flags 0x%llx rqi %p duration %u msecs\n", - sc, sc->request->tag, CMD_FLAGS(sc), rqi, + sc, scsi_cmd_to_rq(sc)->tag, CMD_FLAGS(sc), rqi, jiffies_to_msecs(jiffies - st_time)); /* Update IO stats */ -- cgit v1.2.3-70-g09d2 From bbfa8d7d128397bcfaaf5c0b08f4772047efe086 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:47 -0700 Subject: scsi: stex: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-45-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/stex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 491b435273a6..f1ba7f5b52a8 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -540,7 +540,7 @@ stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag) msg_h = (struct st_msg_header *)req - 1; if (likely(cmd)) { msg_h->channel = (u8)cmd->device->channel; - msg_h->timeout = cpu_to_le16(cmd->request->timeout/HZ); + msg_h->timeout = cpu_to_le16(scsi_cmd_to_rq(cmd)->timeout / HZ); } addr = hba->dma_handle + hba->req_head * hba->rq_size; addr += (hba->ccb[tag].sg_count+4)/11; @@ -690,7 +690,7 @@ stex_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) cmd->scsi_done = done; - tag = cmd->request->tag; + tag = scsi_cmd_to_rq(cmd)->tag; if (unlikely(tag >= host->can_queue)) return SCSI_MLQUEUE_HOST_BUSY; @@ -1246,7 +1246,7 @@ static int stex_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct st_hba *hba = (struct st_hba *)host->hostdata; - u16 tag = cmd->request->tag; + u16 tag = scsi_cmd_to_rq(cmd)->tag; void __iomem *base; u32 data; int result = SUCCESS; -- cgit v1.2.3-70-g09d2 From 6c5d5422c5337ec496991defe2b6bea2b422289a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:48 -0700 Subject: scsi: sun3_scsi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-46-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sun3_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 9ed0bb7ecece..f7f724a3ff1d 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -336,7 +336,7 @@ static int sun3scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata, { int wanted_len = cmd->SCp.this_residual; - if (wanted_len < DMA_MIN_SIZE || blk_rq_is_passthrough(cmd->request)) + if (wanted_len < DMA_MIN_SIZE || blk_rq_is_passthrough(scsi_cmd_to_rq(cmd))) return 0; return wanted_len; -- cgit v1.2.3-70-g09d2 From 77ff7756c73ebebd2dac936e965b01e645feb53d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:49 -0700 Subject: scsi: sym53c8xx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-47-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sym53c8xx_2/sym_glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 16b65fc4405c..6d0b07b9cb31 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -500,8 +500,8 @@ static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd, * Shorten our settle_time if needed for * this command not to time out. */ - if (np->s.settle_time_valid && cmd->request->timeout) { - unsigned long tlimit = jiffies + cmd->request->timeout; + if (np->s.settle_time_valid && scsi_cmd_to_rq(cmd)->timeout) { + unsigned long tlimit = jiffies + scsi_cmd_to_rq(cmd)->timeout; tlimit -= SYM_CONF_TIMER_INTERVAL*2; if (time_after(np->s.settle_time, tlimit)) { np->s.settle_time = tlimit; -- cgit v1.2.3-70-g09d2 From 3f2c1002e0fcb61f0b0776cb24c7dd8f06a152b9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:50 -0700 Subject: scsi: ufs: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-48-bvanassche@acm.org Reviewed-by: Daejun Park Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 6736fb42e2a4..a3b419848f0a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -365,6 +365,7 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, u32 intr, doorbell; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; struct scsi_cmnd *cmd = lrbp->cmd; + struct request *rq = scsi_cmd_to_rq(cmd); int transfer_len = -1; if (!cmd) @@ -390,7 +391,7 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag, /* * The number of Bytes to be unmapped beginning with the lba. */ - transfer_len = blk_rq_bytes(cmd->request); + transfer_len = blk_rq_bytes(rq); } intr = ufshcd_readl(hba, REG_INTERRUPT_STATUS); @@ -2054,7 +2055,7 @@ static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) spin_lock_irqsave(hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) { - struct request *req = lrbp->cmd->request; + struct request *req = scsi_cmd_to_rq(lrbp->cmd); struct ufs_hba_monitor *m = &hba->monitor; ktime_t now, inc, lat; @@ -2675,7 +2676,7 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i) static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { struct ufs_hba *hba = shost_priv(host); - int tag = cmd->request->tag; + int tag = scsi_cmd_to_rq(cmd)->tag; struct ufshcd_lrb *lrbp; int err = 0; @@ -2734,7 +2735,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; - ufshcd_prepare_lrbp_crypto(cmd->request, lrbp); + ufshcd_prepare_lrbp_crypto(scsi_cmd_to_rq(cmd), lrbp); lrbp->req_abort_skip = false; @@ -6993,7 +6994,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *host = cmd->device->host; struct ufs_hba *hba = shost_priv(host); - int tag = cmd->request->tag; + int tag = scsi_cmd_to_rq(cmd)->tag; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; unsigned long flags; int err = FAILED; -- cgit v1.2.3-70-g09d2 From 7cc4554ef2c2eef56aaf96610c3bda37a93fd701 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:51 -0700 Subject: scsi: virtio_scsi: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-49-bvanassche@acm.org Acked-by: Michael S. Tsirkin Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/virtio_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index b0deaf4af5a3..c25ce8f0e0af 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -519,7 +519,7 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev, struct virtio_scsi_cmd_req_pi *cmd_pi, struct scsi_cmnd *sc) { - struct request *rq = sc->request; + struct request *rq = scsi_cmd_to_rq(sc); struct blk_integrity *bi; virtio_scsi_init_hdr(vdev, (struct virtio_scsi_cmd_req *)cmd_pi, sc); @@ -543,7 +543,7 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev, static struct virtio_scsi_vq *virtscsi_pick_vq_mq(struct virtio_scsi *vscsi, struct scsi_cmnd *sc) { - u32 tag = blk_mq_unique_tag(sc->request); + u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(sc)); u16 hwq = blk_mq_unique_tag_to_hwq(tag); return &vscsi->req_vqs[hwq]; -- cgit v1.2.3-70-g09d2 From 80ca10b6052dd0148095a6a9825ed1b817a538c7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:52 -0700 Subject: scsi: xen-scsifront: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-50-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/xen-scsifront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index ec9d399fbbd8..0204e314b482 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -212,7 +212,7 @@ static int scsifront_do_request(struct vscsifrnt_info *info, memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len); ring_req->sc_data_direction = (uint8_t)sc->sc_data_direction; - ring_req->timeout_per_command = sc->request->timeout / HZ; + ring_req->timeout_per_command = scsi_cmd_to_rq(sc)->timeout / HZ; for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++) ring_req->seg[i] = shadow->seg[i]; -- cgit v1.2.3-70-g09d2 From cb22f89e7a12a4a9b3a203b78b3c9a275693d47f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:53 -0700 Subject: scsi: tcm_loop: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-51-bvanassche@acm.org Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/loopback/tcm_loop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index fdc36274cb39..3dfc7ed79ba4 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -183,7 +183,7 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) memset(tl_cmd, 0, sizeof(*tl_cmd)); tl_cmd->sc = sc; - tl_cmd->sc_cmd_tag = sc->request->tag; + tl_cmd->sc_cmd_tag = scsi_cmd_to_rq(sc)->tag; tcm_loop_target_queue_cmd(tl_cmd); return 0; @@ -249,7 +249,7 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc) tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, - sc->request->tag, TMR_ABORT_TASK); + scsi_cmd_to_rq(sc)->tag, TMR_ABORT_TASK); return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; } -- cgit v1.2.3-70-g09d2 From 9c4a6d5281854e1491acd51c7e3794c5d00574ce Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:54 -0700 Subject: scsi: usb-storage: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-52-bvanassche@acm.org Acked-by: Alan Stern Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/usb/storage/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index f4304ce69350..4c5a0a49035f 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -551,7 +551,7 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) /* Did this command access the last sector? */ sector = (srb->cmnd[2] << 24) | (srb->cmnd[3] << 16) | (srb->cmnd[4] << 8) | (srb->cmnd[5]); - disk = srb->request->rq_disk; + disk = scsi_cmd_to_rq(srb)->rq_disk; if (!disk) goto done; sdkp = scsi_disk(disk); -- cgit v1.2.3-70-g09d2 From c5bf198c5edcf279313948029527a755732cd753 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 10 Aug 2021 00:52:41 -0400 Subject: scsi: storvsc: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-1-bvanassche@acm.org Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 328bb961c281..e2278b0125e7 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -710,7 +710,7 @@ static u64 storvsc_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) * Cannot return an ID of 0, which is reserved for an unsolicited * message from Hyper-V. */ - return (u64)blk_mq_unique_tag(request->cmd->request) + 1; + return (u64)blk_mq_unique_tag(scsi_cmd_to_rq(request->cmd)) + 1; } static void handle_sc_creation(struct vmbus_channel *new_sc) @@ -1202,7 +1202,7 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS) storvsc_log(device, STORVSC_LOGGING_ERROR, "tag#%d cmd 0x%x status: scsi 0x%x srb 0x%x hv 0x%x\n", - request->cmd->request->tag, + scsi_cmd_to_rq(request->cmd)->tag, stor_pkt->vm_srb.cdb[0], vstor_packet->vm_srb.scsi_status, vstor_packet->vm_srb.srb_status, -- cgit v1.2.3-70-g09d2 From 12bc2f13f3813e95d7b13239291f9eb36dae83cb Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 10 Aug 2021 00:55:09 -0400 Subject: scsi: ufs: ufshpb: Use scsi_cmd_to_rq() instead of scsi_cmnd.request Prepare for removal of the request pointer by using scsi_cmd_to_rq() instead. This patch does not change any functionality. Link: https://lore.kernel.org/r/20210809230355.8186-1-bvanassche@acm.org Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshpb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index aafb55136c7e..9acce92a356b 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -70,13 +70,13 @@ static int ufshpb_is_valid_srgn(struct ufshpb_region *rgn, static bool ufshpb_is_read_cmd(struct scsi_cmnd *cmd) { - return req_op(cmd->request) == REQ_OP_READ; + return req_op(scsi_cmd_to_rq(cmd)) == REQ_OP_READ; } static bool ufshpb_is_write_or_discard(struct scsi_cmnd *cmd) { - return op_is_write(req_op(cmd->request)) || - op_is_discard(req_op(cmd->request)); + return op_is_write(req_op(scsi_cmd_to_rq(cmd))) || + op_is_discard(req_op(scsi_cmd_to_rq(cmd))); } static bool ufshpb_is_supported_chunk(struct ufshpb_lu *hpb, int transfer_len) @@ -526,9 +526,9 @@ static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd, pre_req->hpb = hpb; pre_req->wb.lpn = sectors_to_logical(cmd->device, - blk_rq_pos(cmd->request)); + blk_rq_pos(scsi_cmd_to_rq(cmd))); pre_req->wb.len = sectors_to_logical(cmd->device, - blk_rq_sectors(cmd->request)); + blk_rq_sectors(scsi_cmd_to_rq(cmd))); if (ufshpb_pre_req_add_bio_page(hpb, q, pre_req)) return -ENOMEM; @@ -626,17 +626,17 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) return -ENODEV; } - if (blk_rq_is_passthrough(cmd->request) || + if (blk_rq_is_passthrough(scsi_cmd_to_rq(cmd)) || (!ufshpb_is_write_or_discard(cmd) && !ufshpb_is_read_cmd(cmd))) return 0; transfer_len = sectors_to_logical(cmd->device, - blk_rq_sectors(cmd->request)); + blk_rq_sectors(scsi_cmd_to_rq(cmd))); if (unlikely(!transfer_len)) return 0; - lpn = sectors_to_logical(cmd->device, blk_rq_pos(cmd->request)); + lpn = sectors_to_logical(cmd->device, blk_rq_pos(scsi_cmd_to_rq(cmd))); ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); rgn = hpb->rgn_tbl + rgn_idx; srgn = rgn->srgn_tbl + srgn_idx; -- cgit v1.2.3-70-g09d2 From 2266a2def97ce11ec979b6c58a1b637a16eca7dd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 9 Aug 2021 16:03:55 -0700 Subject: scsi: core: Remove the request member from struct scsi_cmnd Since all scsi_cmnd.request users are gone, remove the request pointer from struct scsi_cmnd. Link: https://lore.kernel.org/r/20210809230355.8186-53-bvanassche@acm.org Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Ming Lei Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_error.c | 1 - drivers/scsi/scsi_lib.c | 1 - include/scsi/scsi_cmnd.h | 3 --- 3 files changed, 5 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index d85d308a0683..b6c86cce57bf 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -2377,7 +2377,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) scmd = (struct scsi_cmnd *)(rq + 1); scsi_init_command(dev, scmd); - scmd->request = rq; scmd->cmnd = scsi_req(rq)->cmd; scmd->scsi_done = scsi_reset_provider_done_command; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 909a422ec8f4..9ba1aa7530a9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1540,7 +1540,6 @@ static blk_status_t scsi_prepare_cmd(struct request *req) scsi_init_command(sdev, cmd); - cmd->request = req; cmd->tag = req->tag; cmd->prot_op = SCSI_PROT_NORMAL; if (blk_rq_bytes(req)) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index b9265b15d37a..ddc9671b325b 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -111,9 +111,6 @@ struct scsi_cmnd { reconnects. Probably == sector size */ - struct request *request; /* The command we are - working on */ - unsigned char *sense_buffer; /* obtained by REQUEST SENSE when * CHECK CONDITION is received on original -- cgit v1.2.3-70-g09d2 From 6a20e21ae1e25f73385cc248f53440e78dd3cb94 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 6 Aug 2021 00:00:19 -0400 Subject: scsi: core: Add helper to return number of logical blocks in a request Link: https://lore.kernel.org/r/20210806040023.5355-2-martin.petersen@oracle.com Cc: Bart Van Assche Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- include/scsi/scsi_cmnd.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index ddc9671b325b..6c5a1c1c6b1e 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -237,6 +237,13 @@ static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd) return blk_rq_pos(scsi_cmd_to_rq(scmd)) >> shift; } +static inline unsigned int scsi_logical_block_count(struct scsi_cmnd *scmd) +{ + unsigned int shift = ilog2(scmd->device->sector_size) - SECTOR_SHIFT; + + return blk_rq_bytes(scsi_cmd_to_rq(scmd)) >> shift; +} + /* * The operations below are hints that tell the controller driver how * to handle I/Os with DIF or similar types of protection information. -- cgit v1.2.3-70-g09d2 From 4cc0096e2d54bc31ead127be59e3a2d02a187ac9 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Fri, 6 Aug 2021 00:00:20 -0400 Subject: scsi: isci: Use the proper SCSI midlayer interfaces for PI Use scsi_prot_ref_tag() instead of scsi_get_lba() to get the reference tag for a given I/O. Link: https://lore.kernel.org/r/20210806040023.5355-3-martin.petersen@oracle.com Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/request.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index e1ff79464131..fcaa84a3c210 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -341,7 +341,7 @@ static void scu_ssp_ireq_dif_insert(struct isci_request *ireq, u8 type, u8 op) tc->reserved_E8_0 = 0; if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) - tc->ref_tag_seed_gen = scsi_get_lba(scmd) & 0xffffffff; + tc->ref_tag_seed_gen = scsi_prot_ref_tag(scmd); else if (type & SCSI_PROT_DIF_TYPE3) tc->ref_tag_seed_gen = 0; } @@ -369,7 +369,7 @@ static void scu_ssp_ireq_dif_strip(struct isci_request *ireq, u8 type, u8 op) tc->app_tag_gen = 0; if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) - tc->ref_tag_seed_verify = scsi_get_lba(scmd) & 0xffffffff; + tc->ref_tag_seed_verify = scsi_prot_ref_tag(scmd); else if (type & SCSI_PROT_DIF_TYPE3) tc->ref_tag_seed_verify = 0; -- cgit v1.2.3-70-g09d2 From 9757f8af04423f60b6ecbd6802ff4e3f618fbb44 Mon Sep 17 00:00:00 2001 From: Shai Malin Date: Thu, 5 Aug 2021 01:14:12 +0300 Subject: scsi: qedi: Add support for fastpath doorbell recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver fastpath employs doorbells to indicate to the device that work is available. Each doorbell translates to a message sent to the device over PCI. These messages are queued by the doorbell queue HW block, and handled by the HW. If a sufficient amount of CPU cores are sending messages at a sufficient rate, the queue can overflow, and messages can be dropped. There are many entities in the driver which can send doorbell messages. When overflow happens, a fatal HW attention is indicated, and the Doorbell HW block stops accepting new doorbell messages until recovery procedure is done. When overflow occurs, all doorbells are dropped. Since doorbells are aggregatives, if more doorbells are sent nothing has to be done. But if the "last" doorbell is dropped, the doorbelling entity doesn’t know this happened, and may wait forever for the device to perform the action. The doorbell recovery mechanism addresses just that - it sends the last doorbell of every entity. [mkp: fix missing brackets reported by Guenter Roeck] Link: https://lore.kernel.org/r/20210804221412.5048-1-smalin@marvell.com Co-developed-by: Manish Rangankar Signed-off-by: Manish Rangankar Signed-off-by: Shai Malin Signed-off-by: Martin K. Petersen --- drivers/scsi/qedi/qedi_fw.c | 14 ++++---------- drivers/scsi/qedi/qedi_iscsi.c | 36 ++++++++++++++++++++++++++++++++++-- drivers/scsi/qedi/qedi_iscsi.h | 1 + 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index ac99e980bb31..d01cd829ef97 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -929,17 +929,11 @@ exit_fp_process: static void qedi_ring_doorbell(struct qedi_conn *qedi_conn) { - struct iscsi_db_data dbell = { 0 }; + qedi_conn->ep->db_data.sq_prod = qedi_conn->ep->fw_sq_prod_idx; - dbell.agg_flags = 0; - - dbell.params |= DB_DEST_XCM << ISCSI_DB_DATA_DEST_SHIFT; - dbell.params |= DB_AGG_CMD_SET << ISCSI_DB_DATA_AGG_CMD_SHIFT; - dbell.params |= - DQ_XCM_ISCSI_SQ_PROD_CMD << ISCSI_DB_DATA_AGG_VAL_SEL_SHIFT; - - dbell.sq_prod = qedi_conn->ep->fw_sq_prod_idx; - writel(*(u32 *)&dbell, qedi_conn->ep->p_doorbell); + /* wmb - Make sure fw idx is coherent */ + wmb(); + writel(*(u32 *)&qedi_conn->ep->db_data, qedi_conn->ep->p_doorbell); /* Make sure fw write idx is coherent, and include both memory barriers * as a failsafe as for some architectures the call is the same but on diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 97f83760da88..c5260429c637 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -499,8 +499,8 @@ static u16 qedi_calc_mss(u16 pmtu, u8 is_ipv6, u8 tcp_ts_en, u8 vlan_en) static int qedi_iscsi_offload_conn(struct qedi_endpoint *qedi_ep) { - struct qedi_ctx *qedi = qedi_ep->qedi; struct qed_iscsi_params_offload *conn_info; + struct qedi_ctx *qedi = qedi_ep->qedi; int rval; int i; @@ -577,10 +577,37 @@ static int qedi_iscsi_offload_conn(struct qedi_endpoint *qedi_ep) "Default cq index [%d], mss [%d]\n", conn_info->default_cq, conn_info->mss); + /* Prepare the doorbell parameters */ + qedi_ep->db_data.agg_flags = 0; + qedi_ep->db_data.params = 0; + SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_DEST, DB_DEST_XCM); + SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_AGG_CMD, + DB_AGG_CMD_MAX); + SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_AGG_VAL_SEL, + DQ_XCM_ISCSI_SQ_PROD_CMD); + SET_FIELD(qedi_ep->db_data.params, ISCSI_DB_DATA_BYPASS_EN, 1); + + /* Register doorbell with doorbell recovery mechanism */ + rval = qedi_ops->common->db_recovery_add(qedi->cdev, + qedi_ep->p_doorbell, + &qedi_ep->db_data, + DB_REC_WIDTH_32B, + DB_REC_KERNEL); + if (rval) { + kfree(conn_info); + return rval; + } + rval = qedi_ops->offload_conn(qedi->cdev, qedi_ep->handle, conn_info); - if (rval) + if (rval) { + /* delete doorbell from doorbell recovery mechanism */ + rval = qedi_ops->common->db_recovery_del(qedi->cdev, + qedi_ep->p_doorbell, + &qedi_ep->db_data); + QEDI_ERR(&qedi->dbg_ctx, "offload_conn returned %d, ep=%p\n", rval, qedi_ep); + } kfree(conn_info); return rval; @@ -1109,6 +1136,11 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep) test_bit(QEDI_IN_RECOVERY, &qedi->flags)) goto ep_release_conn; + /* Delete doorbell from doorbell recovery mechanism */ + ret = qedi_ops->common->db_recovery_del(qedi->cdev, + qedi_ep->p_doorbell, + &qedi_ep->db_data); + ret = qedi_ops->destroy_conn(qedi->cdev, qedi_ep->handle, abrt_conn); if (ret) { QEDI_WARN(&qedi->dbg_ctx, diff --git a/drivers/scsi/qedi/qedi_iscsi.h b/drivers/scsi/qedi/qedi_iscsi.h index 758735209e15..a31c5de74754 100644 --- a/drivers/scsi/qedi/qedi_iscsi.h +++ b/drivers/scsi/qedi/qedi_iscsi.h @@ -80,6 +80,7 @@ struct qedi_endpoint { u32 handle; u32 fw_cid; void __iomem *p_doorbell; + struct iscsi_db_data db_data; /* Send queue management */ struct iscsi_wqe *sq; -- cgit v1.2.3-70-g09d2 From 4c15442d9c06ae6ce0a03fd69c4869f343d67473 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 9 Aug 2021 21:37:07 -0700 Subject: scsi: qla2xxx: Add host attribute to trigger MPI hang Add a mechanism to trigger MPI pause for debugging purposes. Link: https://lore.kernel.org/r/20210810043720.1137-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 22191e9a04a0..4a0a5b4e688d 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1887,6 +1887,30 @@ qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); } +static ssize_t +qla2x00_mpi_pause_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + int rval = 0; + + if (sscanf(buf, "%d", &rval) != 1) + return -EINVAL; + + ql_log(ql_log_warn, vha, 0x7089, "Pausing MPI...\n"); + + rval = qla83xx_wr_reg(vha, 0x002012d4, 0x30000001); + + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0x708a, "Unable to pause MPI.\n"); + count = 0; + } + + return count; +} + +static DEVICE_ATTR(mpi_pause, S_IWUSR, NULL, qla2x00_mpi_pause_store); + /* ----- */ static ssize_t @@ -2482,6 +2506,7 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_fw_attr, &dev_attr_dport_diagnostics, &dev_attr_edif_doorbell, + &dev_attr_mpi_pause, NULL, /* reserve for qlini_mode */ NULL, /* reserve for ql2xiniexchg */ NULL, /* reserve for ql2xexchoffld */ -- cgit v1.2.3-70-g09d2 From ade660d4d50645521b6ce16703ccbbf21f1367a1 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 9 Aug 2021 21:37:09 -0700 Subject: scsi: qla2xxx: Adjust request/response queue size for 28xx Adjust request/respond queue size for 28xx to match 27xx adapter. Link: https://lore.kernel.org/r/20210810043720.1137-4-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 126ac7e24ea9..68da8c6b0cb8 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3065,8 +3065,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->portnum = PCI_FUNC(ha->pdev->devfn); ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; ha->mbx_count = MAILBOX_REGISTER_COUNT; - req_length = REQUEST_ENTRY_CNT_24XX; - rsp_length = RESPONSE_ENTRY_CNT_2300; + req_length = REQUEST_ENTRY_CNT_83XX; + rsp_length = RESPONSE_ENTRY_CNT_83XX; ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; ha->max_loop_id = SNS_LAST_LOOP_ID_2300; ha->init_cb_size = sizeof(struct mid_init_cb_81xx); -- cgit v1.2.3-70-g09d2 From 44c57f205876518b14ab2b4b5d88a181f41260bb Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Mon, 9 Aug 2021 21:37:10 -0700 Subject: scsi: qla2xxx: Changes to support FCP2 Target Add changes to support FCP2 Target. Link: https://lore.kernel.org/r/20210810043720.1137-5-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_dbg.c | 3 +-- drivers/scsi/qla2xxx/qla_init.c | 6 ++++++ drivers/scsi/qla2xxx/qla_os.c | 10 ++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index f2d05592c1e2..25549a8a2d72 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -12,8 +12,7 @@ * ---------------------------------------------------------------------- * | Module Init and Probe | 0x0199 | | * | Mailbox commands | 0x1206 | 0x11a5-0x11ff | - * | Device Discovery | 0x2134 | 0x210e-0x2116 | - * | | | 0x211a | + * | Device Discovery | 0x2134 | 0x210e-0x2115 | * | | | 0x211c-0x2128 | * | | | 0x212c-0x2134 | * | Queue Command and IO tracing | 0x3074 | 0x300b | diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index ad0d3f536a31..89b3bc900b22 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1787,6 +1787,12 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); if (fcport) { + if (fcport->flags & FCF_FCP2_DEVICE) { + ql_dbg(ql_dbg_disc, vha, 0x2115, + "Delaying session delete for FCP2 portid=%06x %8phC ", + fcport->d_id.b24, fcport->port_name); + return; + } fcport->scan_needed = 1; fcport->rscn_gen++; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 68da8c6b0cb8..4db7e433bb38 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3981,6 +3981,16 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha) "Mark all dev lost\n"); list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->loop_id != FC_NO_LOOP_ID && + (fcport->flags & FCF_FCP2_DEVICE) && + fcport->port_type == FCT_TARGET && + !qla2x00_reset_active(vha)) { + ql_dbg(ql_dbg_disc, vha, 0x211a, + "Delaying session delete for FCP2 flags 0x%x port_type = 0x%x port_id=%06x %phC", + fcport->flags, fcport->port_type, + fcport->d_id.b24, fcport->port_name); + continue; + } fcport->scan_state = 0; qlt_schedule_sess_for_deletion(fcport); } -- cgit v1.2.3-70-g09d2 From 137316ba79a686d7193ea6c8e5eb284fa24e4f9f Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 9 Aug 2021 21:37:11 -0700 Subject: scsi: qla2xxx: Show OS name and version in FDMI-1 To be consistent with other OS drivers, register OS name and version in FDMI-1 fabric registration. Link: https://lore.kernel.org/r/20210810043720.1137-6-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_gs.c | 4 ++-- drivers/scsi/qla2xxx/qla_os.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index af0e8be0eb9b..c081bf1c7578 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2790,7 +2790,7 @@ static const char * const port_dstate_str[] = { /* * FDMI HBA attribute types. */ -#define FDMI1_HBA_ATTR_COUNT 9 +#define FDMI1_HBA_ATTR_COUNT 10 #define FDMI2_HBA_ATTR_COUNT 17 #define FDMI_HBA_NODE_NAME 0x1 diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index b16b7d16be12..11401cfc35a1 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1730,8 +1730,6 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries, size += alen; ql_dbg(ql_dbg_disc, vha, 0x20a8, "FIRMWARE VERSION = %s.\n", eiter->a.fw_version); - if (callopt == CALLOPT_FDMI1) - goto done; /* OS Name and Version */ eiter = entries + size; eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION); @@ -1754,6 +1752,8 @@ qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries, size += alen; ql_dbg(ql_dbg_disc, vha, 0x20a9, "OS VERSION = %s.\n", eiter->a.os_version); + if (callopt == CALLOPT_FDMI1) + goto done; /* MAX CT Payload Length */ eiter = entries + size; eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 4db7e433bb38..222bcd80c255 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7990,7 +7990,7 @@ qla2x00_module_init(void) BUILD_BUG_ON(sizeof(struct cmd_type_7_fx00) != 64); BUILD_BUG_ON(sizeof(struct cmd_type_crc_2) != 64); BUILD_BUG_ON(sizeof(struct ct_entry_24xx) != 64); - BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2344); + BUILD_BUG_ON(sizeof(struct ct_fdmi1_hba_attributes) != 2604); BUILD_BUG_ON(sizeof(struct ct_fdmi2_hba_attributes) != 4424); BUILD_BUG_ON(sizeof(struct ct_fdmi2_port_attributes) != 4164); BUILD_BUG_ON(sizeof(struct ct_fdmi_hba_attr) != 260); -- cgit v1.2.3-70-g09d2 From 85818882c3d91485a153e7df3a8fdd8a0c4ff763 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 9 Aug 2021 21:37:12 -0700 Subject: scsi: qla2xxx: Add debug print of 64G link speed Add debug print of 64G link speed. Link: https://lore.kernel.org/r/20210810043720.1137-7-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_isr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index e8928fd83049..2e2597383053 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -648,7 +648,7 @@ const char * qla2x00_get_link_speed_str(struct qla_hw_data *ha, uint16_t speed) { static const char *const link_speeds[] = { - "1", "2", "?", "4", "8", "16", "32", "10" + "1", "2", "?", "4", "8", "16", "32", "64", "10" }; #define QLA_LAST_SPEED (ARRAY_SIZE(link_speeds) - 1) -- cgit v1.2.3-70-g09d2 From 01c97f2dd8fb4d2188c779a975031c0fe1ec061d Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 9 Aug 2021 21:37:13 -0700 Subject: scsi: qla2xxx: Fix port type info Over time, fcport->port_type became a flag field. The flags within this field were not defined properly. This caused external tools to read wrong info. Link: https://lore.kernel.org/r/20210810043720.1137-8-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c081bf1c7578..60702d066ed9 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2428,11 +2428,9 @@ struct mbx_24xx_entry { */ typedef enum { FCT_UNKNOWN, - FCT_RSCN, - FCT_SWITCH, - FCT_BROADCAST, - FCT_INITIATOR, - FCT_TARGET, + FCT_BROADCAST = 0x01, + FCT_INITIATOR = 0x02, + FCT_TARGET = 0x04, FCT_NVME_INITIATOR = 0x10, FCT_NVME_TARGET = 0x20, FCT_NVME_DISCOVERY = 0x40, -- cgit v1.2.3-70-g09d2 From 0c9a5f3e42f75dbad5966aa59db935b694ab00d1 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 9 Aug 2021 21:37:14 -0700 Subject: scsi: qla2xxx: Fix unsafe removal from linked list On NPIV delete, the VPort is taken off a linked list in an unsafe manner. The check for VPort refcount should be done behind lock before taking off the element. [ 2733.016907] general protection fault: 0000 [#1] SMP NOPTI [ 2733.016908] qla2xxx [0000:22:00.1]-7088:27: VP[4] deleted. [ 2733.016912] CPU: 22 PID: 23481 Comm: qla2xxx_15_dpc Kdump: loaded Tainted: G OE KX 5.3.18-47-default #1 SLE15-SP3 [ 2733.016914] Hardware name: Dell Inc. PowerEdge R7525/0PYVT1, BIOS 2.1.4 02/17/2021 [ 2733.016929] RIP: 0010:qla2x00_abort_isp+0x90/0x850 [qla2xxx] [ 2733.016933] RSP: 0018:ffffb9cfc91efe98 EFLAGS: 00010087 [ 2733.016935] RAX: 0000000000000292 RBX: dead000000000100 RCX: 0000000000000000 [ 2733.016936] RDX: 0000000000000001 RSI: ffff944bfeb99558 RDI: ffff944bfc4b4488 [ 2733.016937] RBP: ffff944bfc4b2868 R08: 00000000000187a2 R09: 0000000000000001 [ 2733.016937] R10: ffffb9cfc91efcc8 R11: 0000000000000001 R12: ffff944bfc4b4000 [ 2733.016938] R13: ffff944bfc4b4870 R14: ffff944bfc4b4488 R15: ffff944bda895c80 [ 2733.016939] FS: 0000000000000000(0000) GS:ffff944bfeb80000(0000) knlGS:0000000000000000 [ 2733.016940] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2733.016940] CR2: 00007fc173e74458 CR3: 0000001ff57de000 CR4: 0000000000350ee0 [ 2733.016941] Call Trace: [ 2733.016951] qla2xxx_pci_error_detected+0x190/0x190 [qla2xxx] [ 2733.016957] qla2x00_do_dpc+0x560/0xa10 [qla2xxx] [ 2733.016962] kthread+0x10d/0x130 [ 2733.016963] kthread_park+0xa0/0xa0 [ 2733.016966] ret_from_fork+0x22/0x40 Link: https://lore.kernel.org/r/20210810043720.1137-9-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 33 +++++++++++++++++++++----------- drivers/scsi/qla2xxx/qla_mid.c | 42 ++++++++++++++++++++++++----------------- drivers/scsi/qla2xxx/qla_os.c | 6 +++--- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 89b3bc900b22..e9a399697188 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -6573,13 +6573,13 @@ void qla2x00_update_fcports(scsi_qla_host_t *base_vha) { fc_port_t *fcport; - struct scsi_qla_host *vha; + struct scsi_qla_host *vha, *tvp; struct qla_hw_data *ha = base_vha->hw; unsigned long flags; spin_lock_irqsave(&ha->vport_slock, flags); /* Go with deferred removal of rport references. */ - list_for_each_entry(vha, &base_vha->hw->vp_list, list) { + list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list) { atomic_inc(&vha->vref_count); list_for_each_entry(fcport, &vha->vp_fcports, list) { if (fcport->drport && @@ -6924,7 +6924,8 @@ void qla2x00_quiesce_io(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp; + struct scsi_qla_host *vp, *tvp; + unsigned long flags; ql_dbg(ql_dbg_dpc, vha, 0x401d, "Quiescing I/O - ha=%p.\n", ha); @@ -6933,8 +6934,18 @@ qla2x00_quiesce_io(scsi_qla_host_t *vha) if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); qla2x00_mark_all_devices_lost(vha); - list_for_each_entry(vp, &ha->vp_list, list) + + spin_lock_irqsave(&ha->vport_slock, flags); + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { + atomic_inc(&vp->vref_count); + spin_unlock_irqrestore(&ha->vport_slock, flags); + qla2x00_mark_all_devices_lost(vp); + + spin_lock_irqsave(&ha->vport_slock, flags); + atomic_dec(&vp->vref_count); + } + spin_unlock_irqrestore(&ha->vport_slock, flags); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, @@ -6949,7 +6960,7 @@ void qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp; + struct scsi_qla_host *vp, *tvp; unsigned long flags; fc_port_t *fcport; u16 i; @@ -7017,7 +7028,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); @@ -7039,7 +7050,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) fcport->scan_state = 0; } spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); @@ -7083,7 +7094,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) int rval; uint8_t status = 0; struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp; + struct scsi_qla_host *vp, *tvp; struct req_que *req = ha->req_q_map[0]; unsigned long flags; @@ -7239,7 +7250,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) ql_dbg(ql_dbg_taskm, vha, 0x8022, "%s succeeded.\n", __func__); qla2x00_configure_hba(vha); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { if (vp->vp_idx) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); @@ -8924,7 +8935,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) { int status, rval; struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp; + struct scsi_qla_host *vp, *tvp; unsigned long flags; status = qla2x00_init_rings(vha); @@ -8996,7 +9007,7 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) "qla82xx_restart_isp succeeded.\n"); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { if (vp->vp_idx) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 078d596dbd49..1c024055f8c5 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -65,7 +65,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) uint16_t vp_id; struct qla_hw_data *ha = vha->hw; unsigned long flags = 0; - u8 i; + u32 i, bailout; mutex_lock(&ha->vport_lock); /* @@ -75,21 +75,29 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) * ensures no active vp_list traversal while the vport is removed * from the queue) */ - for (i = 0; i < 10; i++) { - if (wait_event_timeout(vha->vref_waitq, - !atomic_read(&vha->vref_count), HZ) > 0) + bailout = 0; + for (i = 0; i < 500; i++) { + spin_lock_irqsave(&ha->vport_slock, flags); + if (atomic_read(&vha->vref_count) == 0) { + list_del(&vha->list); + qlt_update_vp_map(vha, RESET_VP_IDX); + bailout = 1; + } + spin_unlock_irqrestore(&ha->vport_slock, flags); + + if (bailout) break; + else + msleep(20); } - - spin_lock_irqsave(&ha->vport_slock, flags); - if (atomic_read(&vha->vref_count)) { - ql_dbg(ql_dbg_vport, vha, 0xfffa, - "vha->vref_count=%u timeout\n", vha->vref_count.counter); - vha->vref_count = (atomic_t)ATOMIC_INIT(0); + if (!bailout) { + ql_log(ql_log_info, vha, 0xfffa, + "vha->vref_count=%u timeout\n", vha->vref_count.counter); + spin_lock_irqsave(&ha->vport_slock, flags); + list_del(&vha->list); + qlt_update_vp_map(vha, RESET_VP_IDX); + spin_unlock_irqrestore(&ha->vport_slock, flags); } - list_del(&vha->list); - qlt_update_vp_map(vha, RESET_VP_IDX); - spin_unlock_irqrestore(&ha->vport_slock, flags); vp_id = vha->vp_idx; ha->num_vhosts--; @@ -262,13 +270,13 @@ qla24xx_configure_vp(scsi_qla_host_t *vha) void qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb) { - scsi_qla_host_t *vha; + scsi_qla_host_t *vha, *tvp; struct qla_hw_data *ha = rsp->hw; int i = 0; unsigned long flags; spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vha, &ha->vp_list, list) { + list_for_each_entry_safe(vha, tvp, &ha->vp_list, list) { if (vha->vp_idx) { if (test_bit(VPORT_DELETE, &vha->dpc_flags)) continue; @@ -421,7 +429,7 @@ void qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - scsi_qla_host_t *vp; + scsi_qla_host_t *vp, *tvp; unsigned long flags = 0; if (vha->vp_idx) @@ -435,7 +443,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha) return; spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { if (vp->vp_idx) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 222bcd80c255..de4791e1a2a6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7533,7 +7533,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) struct qla_hw_data *ha = vha->hw; scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); struct qla_qpair *qpair = NULL; - struct scsi_qla_host *vp; + struct scsi_qla_host *vp, *tvp; fc_port_t *fcport; int i; unsigned long flags; @@ -7564,7 +7564,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); qla2x00_mark_all_devices_lost(vp); @@ -7578,7 +7578,7 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &ha->vp_list, list) { + list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); list_for_each_entry(fcport, &vp->vp_fcports, list) -- cgit v1.2.3-70-g09d2 From a57214443f0f85639a0d9bbb8bd658d82dbf0927 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 9 Aug 2021 21:37:15 -0700 Subject: scsi: qla2xxx: Fix NPIV create erroneous error When user creates multiple NPIVs, the switch capabilities field is checked before a vport is allowed to be created. This field is being toggled if a switch scan is in progress. This creates erroneous reject of vport create. Link: https://lore.kernel.org/r/20210810043720.1137-10-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index e9a399697188..9e891d25728f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4623,11 +4623,11 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) /* initialize */ ha->min_external_loopid = SNS_FIRST_LOOP_ID; ha->operating_mode = LOOP; - ha->switch_cap = 0; switch (topo) { case 0: ql_dbg(ql_dbg_disc, vha, 0x200b, "HBA in NL topology.\n"); + ha->switch_cap = 0; ha->current_topology = ISP_CFG_NL; strcpy(connect_type, "(Loop)"); break; @@ -4641,6 +4641,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) case 2: ql_dbg(ql_dbg_disc, vha, 0x200d, "HBA in N P2P topology.\n"); + ha->switch_cap = 0; ha->operating_mode = P2P; ha->current_topology = ISP_CFG_N; strcpy(connect_type, "(N_Port-to-N_Port)"); @@ -4657,6 +4658,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) default: ql_dbg(ql_dbg_disc, vha, 0x200f, "HBA in unknown topology %x, using NL.\n", topo); + ha->switch_cap = 0; ha->current_topology = ISP_CFG_NL; strcpy(connect_type, "(Loop)"); break; -- cgit v1.2.3-70-g09d2 From a5741427322b6158fbe9f1a4c118e95a05cecd53 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 9 Aug 2021 21:37:16 -0700 Subject: scsi: qla2xxx: Suppress unnecessary log messages during login Suppress logging of retryable errors. These can still be seen if extended logging is enabled. Link: https://lore.kernel.org/r/20210810043720.1137-11-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 23 +++++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 9e891d25728f..4b9350f79eb8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -360,7 +360,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; - ql_log(ql_log_warn, vha, 0x2072, + ql_dbg(ql_dbg_disc, vha, 0x2072, "Async-login - %8phC hdl=%x, loopid=%x portid=%06x retries=%d.\n", fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24, fcport->login_retry); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2e2597383053..32fe9682dd9f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2326,6 +2326,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, struct srb_iocb *lio; uint16_t *data; uint32_t iop[2]; + int logit = 1; sp = qla2x00_get_sp_from_handle(vha, func, req, logio); if (!sp) @@ -2403,9 +2404,11 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, case LSC_SCODE_PORTID_USED: data[0] = MBS_PORT_ID_USED; data[1] = LSW(iop[1]); + logit = 0; break; case LSC_SCODE_NPORT_USED: data[0] = MBS_LOOP_ID_USED; + logit = 0; break; case LSC_SCODE_CMD_FAILED: if (iop[1] == 0x0606) { @@ -2438,12 +2441,20 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, break; } - ql_log(ql_log_warn, sp->vha, 0x5037, - "Async-%s failed: handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n", - type, sp->handle, fcport->d_id.b24, fcport->port_name, - le16_to_cpu(logio->comp_status), - le32_to_cpu(logio->io_parameter[0]), - le32_to_cpu(logio->io_parameter[1])); + if (logit) + ql_log(ql_log_warn, sp->vha, 0x5037, "Async-%s failed: " + "handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n", + type, sp->handle, fcport->d_id.b24, fcport->port_name, + le16_to_cpu(logio->comp_status), + le32_to_cpu(logio->io_parameter[0]), + le32_to_cpu(logio->io_parameter[1])); + else + ql_dbg(ql_dbg_disc, sp->vha, 0x5037, "Async-%s failed: " + "handle=%x pid=%06x wwpn=%8phC comp_status=%x iop0=%x iop1=%x\n", + type, sp->handle, fcport->d_id.b24, fcport->port_name, + le16_to_cpu(logio->comp_status), + le32_to_cpu(logio->io_parameter[0]), + le32_to_cpu(logio->io_parameter[1])); logio_done: sp->done(sp, 0); -- cgit v1.2.3-70-g09d2 From 62e0dec59c1e139dab55aff5aa442adc97804271 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Mon, 9 Aug 2021 21:37:17 -0700 Subject: scsi: qla2xxx: Changes to support kdump kernel Avoid allocating firmware dump and only allocate a single queue for a kexec kernel. Link: https://lore.kernel.org/r/20210810043720.1137-12-njavali@marvell.com Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index de4791e1a2a6..5c01b1eaf84e 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -2839,6 +2840,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } + if (is_kdump_kernel()) { + ql2xmqsupport = 0; + ql2xallocfwdump = 0; + } + /* This may fail but that's ok */ pci_enable_pcie_error_reporting(pdev); -- cgit v1.2.3-70-g09d2 From 4a0a542fe5e4273baf9228459ef3f75c29490cba Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Mon, 9 Aug 2021 21:37:18 -0700 Subject: scsi: qla2xxx: Changes to support kdump kernel for NVMe BFS The MSI-X and MSI calls fails in kdump kernel. Because of this qla2xxx_create_qpair() fails leading to .create_queue callback failure. The fix is to return existing qpair instead of allocating new one and allocate a single hw queue. [ 19.975838] qla2xxx [0000:d8:00.1]-00c7:11: MSI-X: Failed to enable support, giving up -- 16/-28. [ 19.984885] qla2xxx [0000:d8:00.1]-0037:11: Falling back-to MSI mode -- ret=-28. [ 19.992278] qla2xxx [0000:d8:00.1]-0039:11: Falling back-to INTa mode -- ret=-28. .. .. .. [ 21.141518] qla2xxx [0000:d8:00.0]-2104:2: qla_nvme_alloc_queue: handle 00000000e7ee499d, idx =1, qsize 32 [ 21.151166] qla2xxx [0000:d8:00.0]-0181:2: FW/Driver is not multi-queue capable. [ 21.158558] qla2xxx [0000:d8:00.0]-2122:2: Failed to allocate qpair [ 21.164824] nvme nvme0: NVME-FC{0}: reset: Reconnect attempt failed (-22) [ 21.171612] nvme nvme0: NVME-FC{0}: Reconnect attempt in 2 seconds Link: https://lore.kernel.org/r/20210810043720.1137-13-njavali@marvell.com Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_isr.c | 2 ++ drivers/scsi/qla2xxx/qla_nvme.c | 40 ++++++++++++++++++---------------------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 60702d066ed9..55175e8a0749 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4022,7 +4022,6 @@ struct qla_hw_data { /* Enabled in Driver */ uint32_t scm_enabled:1; uint32_t edif_enabled:1; - uint32_t max_req_queue_warned:1; uint32_t plogi_template_valid:1; uint32_t port_isolated:1; } flags; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 32fe9682dd9f..cb02dade85f8 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -4508,6 +4508,8 @@ skip_msi: ql_dbg(ql_dbg_init, vha, 0x0125, "INTa mode: Enabled.\n"); ha->flags.mr_intr_valid = 1; + /* Set max_qpair to 0, as MSI-X and MSI in not enabled */ + ha->max_qpairs = 0; } clear_risc_ints: diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index fdac3f7fa080..b12e01dab88d 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -108,19 +108,24 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, return -EINVAL; } - if (ha->queue_pair_map[qidx]) { - *handle = ha->queue_pair_map[qidx]; - ql_log(ql_log_info, vha, 0x2121, - "Returning existing qpair of %p for idx=%x\n", - *handle, qidx); - return 0; - } + /* Use base qpair if max_qpairs is 0 */ + if (!ha->max_qpairs) { + qpair = ha->base_qpair; + } else { + if (ha->queue_pair_map[qidx]) { + *handle = ha->queue_pair_map[qidx]; + ql_log(ql_log_info, vha, 0x2121, + "Returning existing qpair of %p for idx=%x\n", + *handle, qidx); + return 0; + } - qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true); - if (qpair == NULL) { - ql_log(ql_log_warn, vha, 0x2122, - "Failed to allocate qpair\n"); - return -EINVAL; + qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true); + if (!qpair) { + ql_log(ql_log_warn, vha, 0x2122, + "Failed to allocate qpair\n"); + return -EINVAL; + } } *handle = qpair; @@ -731,18 +736,9 @@ int qla_nvme_register_hba(struct scsi_qla_host *vha) WARN_ON(vha->nvme_local_port); - if (ha->max_req_queues < 3) { - if (!ha->flags.max_req_queue_warned) - ql_log(ql_log_info, vha, 0x2120, - "%s: Disabling FC-NVME due to lack of free queue pairs (%d).\n", - __func__, ha->max_req_queues); - ha->flags.max_req_queue_warned = 1; - return ret; - } - qla_nvme_fc_transport.max_hw_queues = min((uint8_t)(qla_nvme_fc_transport.max_hw_queues), - (uint8_t)(ha->max_req_queues - 2)); + (uint8_t)(ha->max_qpairs ? ha->max_qpairs : 1)); pinfo.node_name = wwn_to_u64(vha->node_name); pinfo.port_name = wwn_to_u64(vha->port_name); -- cgit v1.2.3-70-g09d2 From c8fadf019964d0eb1da410ba8b629494d3339db9 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Mon, 9 Aug 2021 21:37:19 -0700 Subject: scsi: qla2xxx: Sync queue idx with queue_pair_map idx The first invocation of function find_first_zero_bit will return 0 and queue_id gets set to 0. An index of queue_pair_map also gets set to 0. qpair_id = find_first_zero_bit(ha->qpair_qid_map, ha->max_qpairs); set_bit(qpair_id, ha->qpair_qid_map); ha->queue_pair_map[qpair_id] = qpair; In the alloc_queue callback driver checks the map, if queue is already allocated: ha->queue_pair_map[qidx] This works fine as long as max_qpairs is greater than nvme_max_hw_queues(8) since the size of the queue_pair_map is equal to max_qpair. In case nr_cpus is less than 8, max_qpairs is less than 8. This creates wrong value returned as qpair. [ 1572.353669] qla2xxx [0000:24:00.3]-2121:6: Returning existing qpair of 4e00000000000000 for idx=2 [ 1572.354458] general protection fault: 0000 [#1] SMP PTI [ 1572.354461] CPU: 1 PID: 44 Comm: kworker/1:1H Kdump: loaded Tainted: G IOE --------- - - 4.18.0-304.el8.x86_64 #1 [ 1572.354462] Hardware name: HP ProLiant DL380p Gen8, BIOS P70 03/01/2013 [ 1572.354467] Workqueue: kblockd blk_mq_run_work_fn [ 1572.354485] RIP: 0010:qla_nvme_post_cmd+0x92/0x760 [qla2xxx] [ 1572.354486] Code: 84 24 5c 01 00 00 00 00 b8 0a 74 1e 66 83 79 48 00 0f 85 a8 03 00 00 48 8b 44 24 08 48 89 ee 4c 89 e7 8b 50 24 e8 5e 8e 00 00 41 ff 47 04 0f ae f0 41 f6 47 24 04 74 19 f0 41 ff 4f 04 b8 f0 [ 1572.354487] RSP: 0018:ffff9c81c645fc90 EFLAGS: 00010246 [ 1572.354489] RAX: 0000000000000001 RBX: ffff8ea3e5070138 RCX: 0000000000000001 [ 1572.354490] RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff8ea4c866b800 [ 1572.354491] RBP: ffff8ea4c866b800 R08: 0000000000005010 R09: ffff8ea4c866b800 [ 1572.354492] R10: 0000000000000001 R11: 000000069d1ca3ff R12: ffff8ea4bc460000 [ 1572.354493] R13: ffff8ea3e50702b0 R14: ffff8ea4c4c16a58 R15: 4e00000000000000 [ 1572.354494] FS: 0000000000000000(0000) GS:ffff8ea4dfd00000(0000) knlGS:0000000000000000 [ 1572.354495] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1572.354496] CR2: 000055884504fa58 CR3: 00000005a1410001 CR4: 00000000000606e0 [ 1572.354497] Call Trace: [ 1572.354503] ? check_preempt_curr+0x62/0x90 [ 1572.354506] ? dma_direct_map_sg+0x72/0x1f0 [ 1572.354509] ? nvme_fc_start_fcp_op.part.32+0x175/0x460 [nvme_fc] [ 1572.354511] ? blk_mq_dispatch_rq_list+0x11c/0x730 [ 1572.354515] ? __switch_to_asm+0x35/0x70 [ 1572.354516] ? __switch_to_asm+0x41/0x70 [ 1572.354518] ? __switch_to_asm+0x35/0x70 [ 1572.354519] ? __switch_to_asm+0x41/0x70 [ 1572.354521] ? __switch_to_asm+0x35/0x70 [ 1572.354522] ? __switch_to_asm+0x41/0x70 [ 1572.354523] ? __switch_to_asm+0x35/0x70 [ 1572.354525] ? entry_SYSCALL_64_after_hwframe+0xb9/0xca [ 1572.354527] ? __switch_to_asm+0x41/0x70 [ 1572.354529] ? __blk_mq_sched_dispatch_requests+0xc6/0x170 [ 1572.354531] ? blk_mq_sched_dispatch_requests+0x30/0x60 [ 1572.354532] ? __blk_mq_run_hw_queue+0x51/0xd0 [ 1572.354535] ? process_one_work+0x1a7/0x360 [ 1572.354537] ? create_worker+0x1a0/0x1a0 [ 1572.354538] ? worker_thread+0x30/0x390 [ 1572.354540] ? create_worker+0x1a0/0x1a0 [ 1572.354541] ? kthread+0x116/0x130 [ 1572.354543] ? kthread_flush_work_fn+0x10/0x10 [ 1572.354545] ? ret_from_fork+0x35/0x40 Fix is to use index 0 for admin and first IO queue. Link: https://lore.kernel.org/r/20210810043720.1137-14-njavali@marvell.com Fixes: e84067d74301 ("scsi: qla2xxx: Add FC-NVMe F/W initialization and transport registration") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nvme.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index b12e01dab88d..05cad06ff165 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -91,8 +91,9 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, struct qla_hw_data *ha; struct qla_qpair *qpair; - if (!qidx) - qidx++; + /* Map admin queue and 1st IO queue to index 0 */ + if (qidx) + qidx--; vha = (struct scsi_qla_host *)lport->private; ha = vha->hw; -- cgit v1.2.3-70-g09d2 From bd19573e05f6e643f003672c799b3b2301f2f493 Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Mon, 9 Aug 2021 21:37:20 -0700 Subject: scsi: qla2xxx: Update version to 10.02.06.100-k Link: https://lore.kernel.org/r/20210810043720.1137-15-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 2e05dd74b5cb..8b0ace50b52f 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.00.107-k" +#define QLA2XXX_VERSION "10.02.06.100-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 -#define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 107 +#define QLA_DRIVER_PATCH_VER 6 +#define QLA_DRIVER_BETA_VER 100 -- cgit v1.2.3-70-g09d2 From bb8c26d9387fe428068dcab35b1873ea3b881de1 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 11 Aug 2021 10:22:55 +0530 Subject: cpufreq: vexpress: Set CPUFREQ_IS_COOLING_DEV flag Reuse the cpufreq core's registration of cooling device by setting the CPUFREQ_IS_COOLING_DEV flag. Set this only if bL switcher isn't enabled. Signed-off-by: Viresh Kumar --- drivers/cpufreq/vexpress-spc-cpufreq.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c index 51dfa9ae6cf5..ab56813b7256 100644 --- a/drivers/cpufreq/vexpress-spc-cpufreq.c +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +46,6 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq >> 1 : freq) -static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; static atomic_t cluster_usage[MAX_CLUSTERS + 1]; @@ -457,11 +455,6 @@ static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy) struct device *cpu_dev; int cur_cluster = cpu_to_cluster(policy->cpu); - if (cur_cluster < MAX_CLUSTERS) { - cpufreq_cooling_unregister(cdev[cur_cluster]); - cdev[cur_cluster] = NULL; - } - cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { pr_err("%s: failed to get cpu%d device\n", __func__, @@ -473,17 +466,6 @@ static int ve_spc_cpufreq_exit(struct cpufreq_policy *policy) return 0; } -static void ve_spc_cpufreq_ready(struct cpufreq_policy *policy) -{ - int cur_cluster = cpu_to_cluster(policy->cpu); - - /* Do not register a cpu_cooling device if we are in IKS mode */ - if (cur_cluster >= MAX_CLUSTERS) - return; - - cdev[cur_cluster] = of_cpufreq_cooling_register(policy); -} - static struct cpufreq_driver ve_spc_cpufreq_driver = { .name = "vexpress-spc", .flags = CPUFREQ_HAVE_GOVERNOR_PER_POLICY | @@ -493,7 +475,6 @@ static struct cpufreq_driver ve_spc_cpufreq_driver = { .get = ve_spc_cpufreq_get_rate, .init = ve_spc_cpufreq_init, .exit = ve_spc_cpufreq_exit, - .ready = ve_spc_cpufreq_ready, .attr = cpufreq_generic_attr, }; @@ -553,6 +534,9 @@ static int ve_spc_cpufreq_probe(struct platform_device *pdev) for (i = 0; i < MAX_CLUSTERS; i++) mutex_init(&cluster_lock[i]); + if (!is_bL_switching_enabled()) + ve_spc_cpufreq_driver.flags |= CPUFREQ_IS_COOLING_DEV; + ret = cpufreq_register_driver(&ve_spc_cpufreq_driver); if (ret) { pr_info("%s: Failed registering platform driver: %s, err: %d\n", -- cgit v1.2.3-70-g09d2 From c17495b01b72b53bd290f442d39b060e015c7aea Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:04:33 +0530 Subject: cpufreq: Add callback to register with energy model Many cpufreq drivers register with the energy model for each policy and do exactly the same thing. Follow the footsteps of thermal-cooling, to get it done from the cpufreq core itself. Provide a new callback, which will be called, if present, by the cpufreq core at the right moment (more on that in the code's comment). Also provide a generic implementation that uses dev_pm_opp_of_register_em(). This also allows us to register with the EM at a later point of time, compared to ->init(), from where the EM core can access cpufreq policy directly using cpufreq_cpu_get() type of helpers and perform other work, like marking few frequencies inefficient, this will be done separately. Reviewed-by: Quentin Perret Reviewed-by: Lukasz Luba Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 13 +++++++++++++ include/linux/cpufreq.h | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 45f3416988f1..d301f39248a0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1491,6 +1491,19 @@ static int cpufreq_online(unsigned int cpu) write_lock_irqsave(&cpufreq_driver_lock, flags); list_add(&policy->policy_list, &cpufreq_policy_list); write_unlock_irqrestore(&cpufreq_driver_lock, flags); + + /* + * Register with the energy model before + * sched_cpufreq_governor_change() is called, which will result + * in rebuilding of the sched domains, which should only be done + * once the energy model is properly initialized for the policy + * first. + * + * Also, this should be called before the policy is registered + * with cooling framework. + */ + if (cpufreq_driver->register_em) + cpufreq_driver->register_em(policy); } ret = cpufreq_init_policy(policy); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 9fd719475fcd..c65a1d7385f8 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -9,10 +9,12 @@ #define _LINUX_CPUFREQ_H #include +#include #include #include #include #include +#include #include #include #include @@ -373,6 +375,12 @@ struct cpufreq_driver { /* platform specific boost support code */ bool boost_enabled; int (*set_boost)(struct cpufreq_policy *policy, int state); + + /* + * Set by drivers that want to register with the energy model after the + * policy is properly initialized, but before the governor is started. + */ + void (*register_em)(struct cpufreq_policy *policy); }; /* flags */ @@ -1046,4 +1054,10 @@ unsigned int cpufreq_generic_get(unsigned int cpu); void cpufreq_generic_init(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, unsigned int transition_latency); + +static inline void cpufreq_register_em_with_opp(struct cpufreq_policy *policy) +{ + dev_pm_opp_of_register_em(get_cpu_device(policy->cpu), + policy->related_cpus); +} #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3-70-g09d2 From 94ab4c3c259c7d00746e5cafb55b5f5125f34b71 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:24:36 +0530 Subject: cpufreq: dt: Use .register_em() to register with energy model Set the newly added .register_em() callback with cpufreq_register_em_with_opp() to register with the EM core. Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq-dt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index ece52863ba62..8fcaba541539 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -143,8 +143,6 @@ static int cpufreq_init(struct cpufreq_policy *policy) cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs; } - dev_pm_opp_of_register_em(cpu_dev, policy->cpus); - return 0; out_clk_put: @@ -184,6 +182,7 @@ static struct cpufreq_driver dt_cpufreq_driver = { .exit = cpufreq_exit, .online = cpufreq_online, .offline = cpufreq_offline, + .register_em = cpufreq_register_em_with_opp, .name = "cpufreq-dt", .attr = cpufreq_dt_attr, .suspend = cpufreq_generic_suspend, -- cgit v1.2.3-70-g09d2 From fcd300c685d5152e76a811c492b0e6eccde29717 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:24:36 +0530 Subject: cpufreq: imx6q: Use .register_em() to register with energy model Set the newly added .register_em() callback with cpufreq_register_em_with_opp() to register with the EM core. Signed-off-by: Viresh Kumar --- drivers/cpufreq/imx6q-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 5bf5fc759881..90beb26ed34e 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -192,7 +192,6 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy) policy->clk = clks[ARM].clk; cpufreq_generic_init(policy, freq_table, transition_latency); policy->suspend_freq = max_freq; - dev_pm_opp_of_register_em(cpu_dev, policy->cpus); return 0; } @@ -204,6 +203,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { .target_index = imx6q_set_target, .get = cpufreq_generic_get, .init = imx6q_cpufreq_init, + .register_em = cpufreq_register_em_with_opp, .name = "imx6q-cpufreq", .attr = cpufreq_generic_attr, .suspend = cpufreq_generic_suspend, -- cgit v1.2.3-70-g09d2 From 3701fd64a3fb947fc805ca0d108ab87562a9659b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:24:36 +0530 Subject: cpufreq: mediatek: Use .register_em() to register with energy model Set the newly added .register_em() callback with cpufreq_register_em_with_opp() to register with the EM core. Signed-off-by: Viresh Kumar --- drivers/cpufreq/mediatek-cpufreq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 87019d5a9547..866163883b48 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -448,8 +448,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) policy->driver_data = info; policy->clk = info->cpu_clk; - dev_pm_opp_of_register_em(info->cpu_dev, policy->cpus); - return 0; } @@ -471,6 +469,7 @@ static struct cpufreq_driver mtk_cpufreq_driver = { .get = cpufreq_generic_get, .init = mtk_cpufreq_init, .exit = mtk_cpufreq_exit, + .register_em = cpufreq_register_em_with_opp, .name = "mtk-cpufreq", .attr = cpufreq_generic_attr, }; -- cgit v1.2.3-70-g09d2 From 361a172d230964807c0b479738749c50d95d7b50 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:24:36 +0530 Subject: cpufreq: omap: Use .register_em() to register with energy model Set the newly added .register_em() callback with cpufreq_register_em_with_opp() to register with the EM core. Signed-off-by: Viresh Kumar --- drivers/cpufreq/omap-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index e035ee216b0f..1b50df06c6bc 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -131,7 +131,6 @@ static int omap_cpu_init(struct cpufreq_policy *policy) /* FIXME: what's the actual transition time? */ cpufreq_generic_init(policy, freq_table, 300 * 1000); - dev_pm_opp_of_register_em(mpu_dev, policy->cpus); return 0; } @@ -150,6 +149,7 @@ static struct cpufreq_driver omap_driver = { .get = cpufreq_generic_get, .init = omap_cpu_init, .exit = omap_cpu_exit, + .register_em = cpufreq_register_em_with_opp, .name = "omap", .attr = cpufreq_generic_attr, }; -- cgit v1.2.3-70-g09d2 From e96c2153d0fc0a1c218bf5ba149ccdf75d19a275 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 10 Aug 2021 12:24:36 +0530 Subject: cpufreq: qcom-cpufreq-hw: Use .register_em() to register with energy model Set the newly added .register_em() callback with cpufreq_register_em_with_opp() to register with the EM core. Signed-off-by: Viresh Kumar --- drivers/cpufreq/qcom-cpufreq-hw.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index f86859bf76f1..c2e71c430fbf 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -362,8 +362,6 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) goto error; } - dev_pm_opp_of_register_em(cpu_dev, policy->cpus); - if (policy_has_boost_freq(policy)) { ret = cpufreq_enable_boost_support(); if (ret) @@ -412,6 +410,7 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = { .get = qcom_cpufreq_hw_get, .init = qcom_cpufreq_hw_cpu_init, .exit = qcom_cpufreq_hw_cpu_exit, + .register_em = cpufreq_register_em_with_opp, .fast_switch = qcom_cpufreq_hw_fast_switch, .name = "qcom-cpufreq-hw", .attr = qcom_cpufreq_hw_attr, -- cgit v1.2.3-70-g09d2 From 0aba691a7443a7541c1dc56423e0c92cc6ea7164 Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 23 Jul 2021 15:01:24 +0200 Subject: riscv: Introduce va_kernel_pa_offset for 32-bit kernel va_kernel_pa_offset was only used for 64-bit as the kernel mapping lies in the linear mapping for 32-bit kernel and then only the offset between the PAGE_OFFSET and the kernel load address is needed. But this distinction complexifies the code with #ifdefs and especially with a separate definition of the address conversions macros. Simplify the code by defining this variable for both 32-bit and 64-bit. Signed-off-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/page.h | 15 ++------------- arch/riscv/mm/init.c | 3 --- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index d40d77d76d82..4da92cf28a19 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -91,10 +91,8 @@ struct kernel_mapping { uintptr_t size; /* Offset between linear mapping virtual address and kernel load address */ unsigned long va_pa_offset; -#ifdef CONFIG_64BIT /* Offset between kernel mapping virtual address and kernel load address */ unsigned long va_kernel_pa_offset; -#endif unsigned long va_kernel_xip_pa_offset; #ifdef CONFIG_XIP_KERNEL uintptr_t xiprom; @@ -104,11 +102,11 @@ struct kernel_mapping { extern struct kernel_mapping kernel_map; -#ifdef CONFIG_64BIT #define is_kernel_mapping(x) \ ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size)) + #define is_linear_mapping(x) \ - ((x) >= PAGE_OFFSET && (x) < kernel_map.virt_addr) + ((x) >= PAGE_OFFSET && (!IS_ENABLED(CONFIG_64BIT) || (x) < kernel_map.virt_addr)) #define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + kernel_map.va_pa_offset)) #define kernel_mapping_pa_to_va(y) ({ \ @@ -132,15 +130,6 @@ extern struct kernel_mapping kernel_map; is_linear_mapping(_x) ? \ linear_mapping_va_to_pa(_x) : kernel_mapping_va_to_pa(_x); \ }) -#else -#define is_kernel_mapping(x) \ - ((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size)) -#define is_linear_mapping(x) \ - ((x) >= PAGE_OFFSET) - -#define __pa_to_va_nodebug(x) ((void *)((unsigned long) (x) + kernel_map.va_pa_offset)) -#define __va_to_pa_nodebug(x) ((unsigned long)(x) - kernel_map.va_pa_offset) -#endif /* CONFIG_64BIT */ #ifdef CONFIG_DEBUG_VIRTUAL extern phys_addr_t __virt_to_phys(unsigned long x); diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 269fc648ef3d..263ae055e81a 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -552,11 +552,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) kernel_map.phys_addr = (uintptr_t)(&_start); kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr; #endif - kernel_map.va_pa_offset = PAGE_OFFSET - kernel_map.phys_addr; -#ifdef CONFIG_64BIT kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr; -#endif pfn_base = PFN_DOWN(kernel_map.phys_addr); -- cgit v1.2.3-70-g09d2 From 526f83df1d83b9c95e571ea5d4dff12be1b215ec Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 23 Jul 2021 15:01:25 +0200 Subject: riscv: Get rid of map_size parameter to create_kernel_page_table The kernel must always be mapped using PMD_SIZE, and this is already the case, this just simplifies create_kernel_page_table. Signed-off-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 263ae055e81a..83d0ed915914 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -495,36 +495,35 @@ static __init pgprot_t pgprot_from_va(uintptr_t va) #endif #ifdef CONFIG_XIP_KERNEL -static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size, +static void __init create_kernel_page_table(pgd_t *pgdir, __always_unused bool early) { uintptr_t va, end_va; /* Map the flash resident part */ end_va = kernel_map.virt_addr + kernel_map.xiprom_sz; - for (va = kernel_map.virt_addr; va < end_va; va += map_size) + for (va = kernel_map.virt_addr; va < end_va; va += PMD_SIZE) create_pgd_mapping(pgdir, va, kernel_map.xiprom + (va - kernel_map.virt_addr), - map_size, PAGE_KERNEL_EXEC); + PMD_SIZE, PAGE_KERNEL_EXEC); /* Map the data in RAM */ end_va = kernel_map.virt_addr + XIP_OFFSET + kernel_map.size; - for (va = kernel_map.virt_addr + XIP_OFFSET; va < end_va; va += map_size) + for (va = kernel_map.virt_addr + XIP_OFFSET; va < end_va; va += PMD_SIZE) create_pgd_mapping(pgdir, va, kernel_map.phys_addr + (va - (kernel_map.virt_addr + XIP_OFFSET)), - map_size, PAGE_KERNEL); + PMD_SIZE, PAGE_KERNEL); } #else -static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size, - bool early) +static void __init create_kernel_page_table(pgd_t *pgdir, bool early) { uintptr_t va, end_va; end_va = kernel_map.virt_addr + kernel_map.size; - for (va = kernel_map.virt_addr; va < end_va; va += map_size) + for (va = kernel_map.virt_addr; va < end_va; va += PMD_SIZE) create_pgd_mapping(pgdir, va, kernel_map.phys_addr + (va - kernel_map.virt_addr), - map_size, + PMD_SIZE, early ? PAGE_KERNEL_EXEC : pgprot_from_va(va)); } @@ -533,7 +532,6 @@ static void __init create_kernel_page_table(pgd_t *pgdir, uintptr_t map_size, asmlinkage void __init setup_vm(uintptr_t dtb_pa) { uintptr_t __maybe_unused pa; - uintptr_t map_size; #ifndef __PAGETABLE_PMD_FOLDED pmd_t fix_bmap_spmd, fix_bmap_epmd; #endif @@ -557,15 +555,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) pfn_base = PFN_DOWN(kernel_map.phys_addr); - /* - * Enforce boot alignment requirements of RV32 and - * RV64 by only allowing PMD or PGD mappings. - */ - map_size = PMD_SIZE; - /* Sanity check alignment and size */ BUG_ON((PAGE_OFFSET % PGDIR_SIZE) != 0); - BUG_ON((kernel_map.phys_addr % map_size) != 0); + BUG_ON((kernel_map.phys_addr % PMD_SIZE) != 0); pt_ops.alloc_pte = alloc_pte_early; pt_ops.get_pte_virt = get_pte_virt_early; @@ -602,7 +594,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) * us to reach paging_init(). We map all memory banks later * in setup_vm_final() below. */ - create_kernel_page_table(early_pg_dir, map_size, true); + create_kernel_page_table(early_pg_dir, true); #ifndef __PAGETABLE_PMD_FOLDED /* Setup early PMD for DTB */ @@ -718,7 +710,7 @@ static void __init setup_vm_final(void) #ifdef CONFIG_64BIT /* Map the kernel */ - create_kernel_page_table(swapper_pg_dir, PMD_SIZE, false); + create_kernel_page_table(swapper_pg_dir, false); #endif /* Clear fixmap PTE and PMD mappings */ -- cgit v1.2.3-70-g09d2 From 6f3e5fd241c33d2407f7aaa930b141af6ad7c35b Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 23 Jul 2021 15:01:26 +0200 Subject: riscv: Use __maybe_unused instead of #ifdefs around variable declarations This allows to simplify the code and make it more readable. Signed-off-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 83d0ed915914..a456b5a68d99 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -532,9 +532,7 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early) asmlinkage void __init setup_vm(uintptr_t dtb_pa) { uintptr_t __maybe_unused pa; -#ifndef __PAGETABLE_PMD_FOLDED - pmd_t fix_bmap_spmd, fix_bmap_epmd; -#endif + pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd; kernel_map.virt_addr = KERNEL_LINK_ADDR; -- cgit v1.2.3-70-g09d2 From 977765ce319b98939205cf07aa1d76150713c69b Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 23 Jul 2021 15:01:27 +0200 Subject: riscv: Simplify BUILTIN_DTB device tree mapping handling __PAGETABLE_PMD_FOLDED defines a 2-level page table that is only used in 32-bit kernel, so there is no need to check for CONFIG_64BIT in #ifndef __PAGETABLE_PMD_FOLDED and vice-versa. Signed-off-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index a456b5a68d99..a93822df9d81 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -607,18 +607,14 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); #else /* CONFIG_BUILTIN_DTB */ -#ifdef CONFIG_64BIT /* * __va can't be used since it would return a linear mapping address * whereas dtb_early_va will be used before setup_vm_final installs * the linear mapping. */ dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); -#else - dtb_early_va = __va(dtb_pa); -#endif /* CONFIG_64BIT */ #endif /* CONFIG_BUILTIN_DTB */ -#else +#else /* __PAGETABLE_PMD_FOLDED */ #ifndef CONFIG_BUILTIN_DTB /* Create two consecutive PGD mappings for FDT early scan */ pa = dtb_pa & ~(PGDIR_SIZE - 1); @@ -628,13 +624,9 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); #else /* CONFIG_BUILTIN_DTB */ -#ifdef CONFIG_64BIT - dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); -#else dtb_early_va = __va(dtb_pa); -#endif /* CONFIG_64BIT */ #endif /* CONFIG_BUILTIN_DTB */ -#endif +#endif /* __PAGETABLE_PMD_FOLDED */ dtb_early_pa = dtb_pa; /* -- cgit v1.2.3-70-g09d2 From fe45ffa4c505783637233609b677446020738b87 Mon Sep 17 00:00:00 2001 From: Alexandre Ghiti Date: Fri, 23 Jul 2021 15:01:28 +0200 Subject: riscv: Move early fdt mapping creation in its own function The code that handles the early fdt mapping is hard to read and does not create the same mapping size depending on the kernel: - for 64-bit, 2 PMD entries are used which amounts to a 4MB mapping - for 32-bit, 2 PGDIR entries are used which amounts to a 8MB mapping So keep using 2 PMD entries for 64-bit and use only one PGD entry for 32-bit needed to cover 4MB. Move that into a new function called create_fdt_early_page_table which, using the same naming as create_kernel_page_table. Signed-off-by: Alexandre Ghiti Signed-off-by: Palmer Dabbelt --- arch/riscv/mm/init.c | 76 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index a93822df9d81..fdf093d01c6f 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -222,6 +222,7 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); +static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); #ifdef CONFIG_XIP_KERNEL #define trampoline_pg_dir ((pgd_t *)XIP_FIXUP(trampoline_pg_dir)) @@ -302,7 +303,6 @@ static void __init create_pte_mapping(pte_t *ptep, static pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss; static pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss; static pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); -static pmd_t early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE); #ifdef CONFIG_XIP_KERNEL #define trampoline_pmd ((pmd_t *)XIP_FIXUP(trampoline_pmd)) @@ -388,6 +388,7 @@ static void __init create_pmd_mapping(pmd_t *pmdp, #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ create_pte_mapping(__nextp, __va, __pa, __sz, __prot) #define fixmap_pgd_next fixmap_pte +#define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) #endif void __init create_pgd_mapping(pgd_t *pgdp, @@ -529,9 +530,44 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early) } #endif +/* + * Setup a 4MB mapping that encompasses the device tree: for 64-bit kernel, + * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR + * entry. + */ +static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa) +{ +#ifndef CONFIG_BUILTIN_DTB + uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1); + + create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, + IS_ENABLED(CONFIG_64BIT) ? (uintptr_t)early_dtb_pmd : pa, + PGDIR_SIZE, + IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL); + + if (IS_ENABLED(CONFIG_64BIT)) { + create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA, + pa, PMD_SIZE, PAGE_KERNEL); + create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE, + pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); + } + + dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); +#else + /* + * For 64-bit kernel, __va can't be used since it would return a linear + * mapping address whereas dtb_early_va will be used before + * setup_vm_final installs the linear mapping. For 32-bit kernel, as the + * kernel is mapped in the linear mapping, that makes no difference. + */ + dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); +#endif + + dtb_early_pa = dtb_pa; +} + asmlinkage void __init setup_vm(uintptr_t dtb_pa) { - uintptr_t __maybe_unused pa; pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd; kernel_map.virt_addr = KERNEL_LINK_ADDR; @@ -594,40 +630,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) */ create_kernel_page_table(early_pg_dir, true); -#ifndef __PAGETABLE_PMD_FOLDED - /* Setup early PMD for DTB */ - create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, - (uintptr_t)early_dtb_pmd, PGDIR_SIZE, PAGE_TABLE); -#ifndef CONFIG_BUILTIN_DTB - /* Create two consecutive PMD mappings for FDT early scan */ - pa = dtb_pa & ~(PMD_SIZE - 1); - create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA, - pa, PMD_SIZE, PAGE_KERNEL); - create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE, - pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); - dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); -#else /* CONFIG_BUILTIN_DTB */ - /* - * __va can't be used since it would return a linear mapping address - * whereas dtb_early_va will be used before setup_vm_final installs - * the linear mapping. - */ - dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); -#endif /* CONFIG_BUILTIN_DTB */ -#else /* __PAGETABLE_PMD_FOLDED */ -#ifndef CONFIG_BUILTIN_DTB - /* Create two consecutive PGD mappings for FDT early scan */ - pa = dtb_pa & ~(PGDIR_SIZE - 1); - create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, - pa, PGDIR_SIZE, PAGE_KERNEL); - create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA + PGDIR_SIZE, - pa + PGDIR_SIZE, PGDIR_SIZE, PAGE_KERNEL); - dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PGDIR_SIZE - 1)); -#else /* CONFIG_BUILTIN_DTB */ - dtb_early_va = __va(dtb_pa); -#endif /* CONFIG_BUILTIN_DTB */ -#endif /* __PAGETABLE_PMD_FOLDED */ - dtb_early_pa = dtb_pa; + /* Setup early mapping for FDT early scan */ + create_fdt_early_page_table(early_pg_dir, dtb_pa); /* * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap -- cgit v1.2.3-70-g09d2 From d36d4a1d75d2a8bd14ec00d5cb0ce166f6886146 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 27 Jul 2021 09:50:52 -0700 Subject: platform/x86: ISST: Fix optimization with use of numa When numa is used to map CPU to PCI device, the optimized path to read from cached data is not working and still calls _isst_if_get_pci_dev(). The reason is that when caching the mapping, numa information is not available as it is read later. So move the assignment of isst_cpu_info[cpu].numa_node before calling _isst_if_get_pci_dev(). Fixes: aa2ddd242572 ("platform/x86: ISST: Use numa node id for cpu pci dev mapping") Signed-off-by: Srinivas Pandruvada Link: https://lore.kernel.org/r/20210727165052.427238-1-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel_speed_select_if/isst_if_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c index 6f0cc679c8e5..8a4d52a9028d 100644 --- a/drivers/platform/x86/intel_speed_select_if/isst_if_common.c +++ b/drivers/platform/x86/intel_speed_select_if/isst_if_common.c @@ -379,6 +379,8 @@ static int isst_if_cpu_online(unsigned int cpu) u64 data; int ret; + isst_cpu_info[cpu].numa_node = cpu_to_node(cpu); + ret = rdmsrl_safe(MSR_CPU_BUS_NUMBER, &data); if (ret) { /* This is not a fatal error on MSR mailbox only I/F */ @@ -397,7 +399,6 @@ static int isst_if_cpu_online(unsigned int cpu) return ret; } isst_cpu_info[cpu].punit_cpu_id = data; - isst_cpu_info[cpu].numa_node = cpu_to_node(cpu); isst_restore_msr_local(cpu); -- cgit v1.2.3-70-g09d2 From 1d18ed5eab2a22d9af8c1cd7d23ea7c8dbb9088a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 2 Aug 2021 14:07:34 +0200 Subject: platform/x86: dell-smbios: Remove unused dmi_system_id table dell-smbios is depended on by dell-laptop and that has this same table + some extra entries for chassis-type 30, 31 and 32. Since dell-laptop will already auto-load based on the DMI table in there (which also is more complete) and since dell-laptop will then bring in the dell-smbios module, the only scenario I can think of where this DMI table inside dell-smbios-smm.c is useful is if users have the dell-laptop module disabled and they want to use the sysfs interface offered by dell-smbios-smm.c. But that is such a corner case, even requiring a custom kernel build, that it does not weigh up against having this duplicate table, which as the current state already shows can only grow stale. Users who do hit this corner-case can always explicitly modprobe / insmod the module. Cc: Mario Limonciello Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210802120734.36732-1-hdegoede@redhat.com --- drivers/platform/x86/dell/dell-smbios-smm.c | 31 ----------------------------- 1 file changed, 31 deletions(-) diff --git a/drivers/platform/x86/dell/dell-smbios-smm.c b/drivers/platform/x86/dell/dell-smbios-smm.c index 97c52a839a3e..320c032418ac 100644 --- a/drivers/platform/x86/dell/dell-smbios-smm.c +++ b/drivers/platform/x86/dell/dell-smbios-smm.c @@ -24,37 +24,6 @@ static struct calling_interface_buffer *buffer; static struct platform_device *platform_device; static DEFINE_MUTEX(smm_mutex); -static const struct dmi_system_id dell_device_table[] __initconst = { - { - .ident = "Dell laptop", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_CHASSIS_TYPE, "8"), - }, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /*Laptop*/ - }, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /*Notebook*/ - }, - }, - { - .ident = "Dell Computer Corporation", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_CHASSIS_TYPE, "8"), - }, - }, - { } -}; -MODULE_DEVICE_TABLE(dmi, dell_device_table); - static void parse_da_table(const struct dmi_header *dm) { struct calling_interface_structure *table = -- cgit v1.2.3-70-g09d2 From 560c71d4250f5f32b7952c290ddaf3cd4548a3ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 3 Aug 2021 16:16:00 +0200 Subject: platform/x86: Replace deprecated CPU-hotplug functions. The functions get_online_cpus() and put_online_cpus() have been deprecated during the CPU hotplug rework. They map directly to cpus_read_lock() and cpus_read_unlock(). Replace deprecated CPU-hotplug functions with the official version. The behavior remains unchanged. Cc: Stuart Hayes Cc: Hans de Goede Cc: Mark Gross Cc: platform-driver-x86@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior Link: https://lore.kernel.org/r/20210803141621.780504-18-bigeasy@linutronix.de Signed-off-by: Hans de Goede --- drivers/platform/x86/dell/dcdbas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/dell/dcdbas.c b/drivers/platform/x86/dell/dcdbas.c index 28447c180be8..5e63d6225048 100644 --- a/drivers/platform/x86/dell/dcdbas.c +++ b/drivers/platform/x86/dell/dcdbas.c @@ -278,9 +278,9 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd) } /* SMI requires CPU 0 */ - get_online_cpus(); + cpus_read_lock(); ret = smp_call_on_cpu(0, raise_smi, smi_cmd, true); - put_online_cpus(); + cpus_read_unlock(); return ret; } -- cgit v1.2.3-70-g09d2 From eddebe6dbe2c961ee7f6dc4a1fafc81212b44177 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Aug 2021 19:32:52 +0300 Subject: platform/surface: surface3_power: Use i2c_acpi_get_i2c_resource() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ACPI provides a generic helper to get I²C Serial Bus resources. Use it instead of open coded variant. Signed-off-by: Andy Shevchenko Reviewed-by: Maximilian Luz Link: https://lore.kernel.org/r/20210803163252.60141-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/surface/surface3_power.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/platform/surface/surface3_power.c b/drivers/platform/surface/surface3_power.c index dea82aa1abd4..90c1568ea4e0 100644 --- a/drivers/platform/surface/surface3_power.c +++ b/drivers/platform/surface/surface3_power.c @@ -384,13 +384,7 @@ mshw0011_space_handler(u32 function, acpi_physical_address command, if (ACPI_FAILURE(ret)) return ret; - if (!value64 || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) { - ret = AE_BAD_PARAMETER; - goto err; - } - - sb = &ares->data.i2c_serial_bus; - if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) { + if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) { ret = AE_BAD_PARAMETER; goto err; } -- cgit v1.2.3-70-g09d2 From b325d78e78a232fb2019023354dd6b7493bc8760 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Aug 2021 22:25:24 +0300 Subject: platform/surface: aggregator: Use y instead of objs in Makefile The 'objs' is for user space tools, for the kernel modules we should use 'y'. Signed-off-by: Andy Shevchenko Reviewed-by: Maximilian Luz Link: https://lore.kernel.org/r/20210803192524.67031-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/surface/aggregator/Makefile | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/platform/surface/aggregator/Makefile b/drivers/platform/surface/aggregator/Makefile index c8498c41e758..c0d550eda5cd 100644 --- a/drivers/platform/surface/aggregator/Makefile +++ b/drivers/platform/surface/aggregator/Makefile @@ -6,12 +6,9 @@ CFLAGS_core.o = -I$(src) obj-$(CONFIG_SURFACE_AGGREGATOR) += surface_aggregator.o -surface_aggregator-objs := core.o -surface_aggregator-objs += ssh_parser.o -surface_aggregator-objs += ssh_packet_layer.o -surface_aggregator-objs += ssh_request_layer.o -surface_aggregator-objs += controller.o - -ifeq ($(CONFIG_SURFACE_AGGREGATOR_BUS),y) -surface_aggregator-objs += bus.o -endif +surface_aggregator-y := core.o +surface_aggregator-y += ssh_parser.o +surface_aggregator-y += ssh_packet_layer.o +surface_aggregator-y += ssh_request_layer.o +surface_aggregator-$(CONFIG_SURFACE_AGGREGATOR_BUS) += bus.o +surface_aggregator-y += controller.o -- cgit v1.2.3-70-g09d2 From bc6b8d7eec4fecb11634bc4256b4b79d0fe617e9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Aug 2021 22:40:39 +0300 Subject: platform/x86: dell-smo8800: Convert to be a platform driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ACPI core in conjunction with platform driver core provides an infrastructure to enumerate ACPI devices. Use it in order to remove a lot of boilerplate code. Signed-off-by: Andy Shevchenko Reviewed-by: Pali Rohár Tested-by: Pali Rohár Link: https://lore.kernel.org/r/20210803194039.35083-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/dell/Kconfig | 2 +- drivers/platform/x86/dell/dell-smo8800.c | 74 ++++++++------------------------ 2 files changed, 20 insertions(+), 56 deletions(-) diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig index 9e7314d90bea..821aba31821c 100644 --- a/drivers/platform/x86/dell/Kconfig +++ b/drivers/platform/x86/dell/Kconfig @@ -140,7 +140,7 @@ config DELL_SMBIOS_SMM config DELL_SMO8800 tristate "Dell Latitude freefall driver (ACPI SMO88XX)" default m - depends on ACPI + depends on ACPI || COMPILE_TEST help Say Y here if you want to support SMO88XX freefall devices on Dell Latitude laptops. diff --git a/drivers/platform/x86/dell/dell-smo8800.c b/drivers/platform/x86/dell/dell-smo8800.c index 5d9304a7de1b..3385e852104c 100644 --- a/drivers/platform/x86/dell/dell-smo8800.c +++ b/drivers/platform/x86/dell/dell-smo8800.c @@ -10,13 +10,14 @@ #define DRIVER_NAME "smo8800" -#include -#include -#include +#include #include +#include #include +#include +#include +#include #include -#include struct smo8800_device { u32 irq; /* acpi device irq */ @@ -44,37 +45,6 @@ static irqreturn_t smo8800_interrupt_thread(int irq, void *data) return IRQ_HANDLED; } -static acpi_status smo8800_get_resource(struct acpi_resource *resource, - void *context) -{ - struct acpi_resource_extended_irq *irq; - - if (resource->type != ACPI_RESOURCE_TYPE_EXTENDED_IRQ) - return AE_OK; - - irq = &resource->data.extended_irq; - if (!irq || !irq->interrupt_count) - return AE_OK; - - *((u32 *)context) = irq->interrupts[0]; - return AE_CTRL_TERMINATE; -} - -static u32 smo8800_get_irq(struct acpi_device *device) -{ - u32 irq = 0; - acpi_status status; - - status = acpi_walk_resources(device->handle, METHOD_NAME__CRS, - smo8800_get_resource, &irq); - if (ACPI_FAILURE(status)) { - dev_err(&device->dev, "acpi_walk_resources failed\n"); - return 0; - } - - return irq; -} - static ssize_t smo8800_misc_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { @@ -136,7 +106,7 @@ static const struct file_operations smo8800_misc_fops = { .release = smo8800_misc_release, }; -static int smo8800_add(struct acpi_device *device) +static int smo8800_probe(struct platform_device *device) { int err; struct smo8800_device *smo8800; @@ -160,14 +130,12 @@ static int smo8800_add(struct acpi_device *device) return err; } - device->driver_data = smo8800; + platform_set_drvdata(device, smo8800); - smo8800->irq = smo8800_get_irq(device); - if (!smo8800->irq) { - dev_err(&device->dev, "failed to obtain IRQ\n"); - err = -EINVAL; + err = platform_get_irq(device, 0); + if (err < 0) goto error; - } + smo8800->irq = err; err = request_threaded_irq(smo8800->irq, smo8800_interrupt_quick, smo8800_interrupt_thread, @@ -189,9 +157,9 @@ error: return err; } -static int smo8800_remove(struct acpi_device *device) +static int smo8800_remove(struct platform_device *device) { - struct smo8800_device *smo8800 = device->driver_data; + struct smo8800_device *smo8800 = platform_get_drvdata(device); free_irq(smo8800->irq, smo8800); misc_deregister(&smo8800->miscdev); @@ -211,21 +179,17 @@ static const struct acpi_device_id smo8800_ids[] = { { "SMO8831", 0 }, { "", 0 }, }; - MODULE_DEVICE_TABLE(acpi, smo8800_ids); -static struct acpi_driver smo8800_driver = { - .name = DRIVER_NAME, - .class = "Latitude", - .ids = smo8800_ids, - .ops = { - .add = smo8800_add, - .remove = smo8800_remove, +static struct platform_driver smo8800_driver = { + .probe = smo8800_probe, + .remove = smo8800_remove, + .driver = { + .name = DRIVER_NAME, + .acpi_match_table = smo8800_ids, }, - .owner = THIS_MODULE, }; - -module_acpi_driver(smo8800_driver); +module_platform_driver(smo8800_driver); MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO88XX)"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From bde53eafb9257a5c9d2327a1cb887c7bcbf6c38f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Aug 2021 18:49:41 +0300 Subject: platform/x86/intel: int33fe: Use y instead of objs in Makefile The 'objs' is for user space tools, for the kernel modules we should use 'y'. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210806154941.4491-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/int33fe/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/int33fe/Makefile b/drivers/platform/x86/intel/int33fe/Makefile index cc11183ce179..9456e3b37f6f 100644 --- a/drivers/platform/x86/intel/int33fe/Makefile +++ b/drivers/platform/x86/intel/int33fe/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o -intel_cht_int33fe-objs := intel_cht_int33fe_common.o \ +intel_cht_int33fe-y := intel_cht_int33fe_common.o \ intel_cht_int33fe_typec.o \ intel_cht_int33fe_microb.o -- cgit v1.2.3-70-g09d2 From cb84acd1165cf3b0f79d2ad09388bb263835974a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Aug 2021 18:50:17 +0300 Subject: platform/x86/intel: pmt: Use y instead of objs in Makefile The 'objs' is for user space tools, for the kernel modules we should use 'y'. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210806155017.4633-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/pmt/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel/pmt/Makefile b/drivers/platform/x86/intel/pmt/Makefile index 019103ee6522..279e158c7c23 100644 --- a/drivers/platform/x86/intel/pmt/Makefile +++ b/drivers/platform/x86/intel/pmt/Makefile @@ -4,9 +4,9 @@ # Intel Platform Monitoring Technology Drivers # -pmt_class-objs += class.o obj-$(CONFIG_INTEL_PMT_CLASS) += pmt_class.o -pmt_telemetry-objs += telemetry.o +pmt_class-y := class.o obj-$(CONFIG_INTEL_PMT_TELEMETRY) += pmt_telemetry.o -pmt_crashlog-objs += crashlog.o +pmt_telemetry-y := telemetry.o obj-$(CONFIG_INTEL_PMT_CRASHLOG) += pmt_crashlog.o +pmt_crashlog-y := crashlog.o -- cgit v1.2.3-70-g09d2 From f6413ba357b7d78a0e2828b51412037447df5d75 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 6 Aug 2021 18:49:51 +0300 Subject: platform/x86/intel: int3472: Use y instead of objs in Makefile The 'objs' is for user space tools, for the kernel modules we should use 'y'. Signed-off-by: Andy Shevchenko Reviewed-by: Daniel Scally Link: https://lore.kernel.org/r/20210806154951.4564-1-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/int3472/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel/int3472/Makefile b/drivers/platform/x86/intel/int3472/Makefile index 48bd97f0a04e..2362e04db18d 100644 --- a/drivers/platform/x86/intel/int3472/Makefile +++ b/drivers/platform/x86/intel/int3472/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o -intel_skl_int3472-objs := intel_skl_int3472_common.o \ +intel_skl_int3472-y := intel_skl_int3472_common.o \ intel_skl_int3472_discrete.o \ intel_skl_int3472_tps68470.o \ intel_skl_int3472_clk_and_regulator.o -- cgit v1.2.3-70-g09d2 From 636a1e697555e73c28cdd6952a409edbfdd16475 Mon Sep 17 00:00:00 2001 From: Chris Blake Date: Mon, 9 Aug 2021 19:40:21 -0500 Subject: platform/x86: add meraki-mx100 platform driver This adds platform support for the Cisco Meraki MX100 (Tinkerbell) network appliance. This sets up the network LEDs and Reset button. Depends-on: ef0eea5b151ae ("mfd: lpc_ich: Enable GPIO driver for DH89xxCC") Co-developed-by: Christian Lamparter Signed-off-by: Christian Lamparter Signed-off-by: Chris Blake Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210810004021.2538308-1-chrisrblake93@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/Kconfig | 13 ++ drivers/platform/x86/Makefile | 3 + drivers/platform/x86/meraki-mx100.c | 230 ++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 drivers/platform/x86/meraki-mx100.c diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 6ad35158ae4e..432d72170b00 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -302,6 +302,19 @@ config ASUS_NB_WMI If you have an ACPI-WMI compatible Asus Notebook, say Y or M here. +config MERAKI_MX100 + tristate "Cisco Meraki MX100 Platform Driver" + depends on GPIOLIB + depends on GPIO_ICH + depends on LEDS_CLASS + select LEDS_GPIO + help + This driver provides support for the front button and LEDs on + the Cisco Meraki MX100 (Tinkerbell) 1U appliance. + + To compile this driver as a module, choose M here: the module + will be called meraki-mx100. + config EEEPC_LAPTOP tristate "Eee PC Hotkey Driver" depends on ACPI diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 5edfdc2ea7f2..9bb3c3f77386 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -39,6 +39,9 @@ obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o +# Cisco/Meraki +obj-$(CONFIG_MERAKI_MX100) += meraki-mx100.o + # Dell obj-$(CONFIG_X86_PLATFORM_DRIVERS_DELL) += dell/ diff --git a/drivers/platform/x86/meraki-mx100.c b/drivers/platform/x86/meraki-mx100.c new file mode 100644 index 000000000000..3751ed36a980 --- /dev/null +++ b/drivers/platform/x86/meraki-mx100.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Cisco Meraki MX100 (Tinkerbell) board platform driver + * + * Based off of arch/x86/platform/meraki/tink.c from the + * Meraki GPL release meraki-firmware-sources-r23-20150601 + * + * Format inspired by platform/x86/pcengines-apuv2.c + * + * Copyright (C) 2021 Chris Blake + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TINK_GPIO_DRIVER_NAME "gpio_ich" + +/* LEDs */ +static const struct gpio_led tink_leds[] = { + { + .name = "mx100:green:internet", + .default_trigger = "default-on", + }, + { + .name = "mx100:green:lan2", + }, + { + .name = "mx100:green:lan3", + }, + { + .name = "mx100:green:lan4", + }, + { + .name = "mx100:green:lan5", + }, + { + .name = "mx100:green:lan6", + }, + { + .name = "mx100:green:lan7", + }, + { + .name = "mx100:green:lan8", + }, + { + .name = "mx100:green:lan9", + }, + { + .name = "mx100:green:lan10", + }, + { + .name = "mx100:green:lan11", + }, + { + .name = "mx100:green:ha", + }, + { + .name = "mx100:orange:ha", + }, + { + .name = "mx100:green:usb", + }, + { + .name = "mx100:orange:usb", + }, +}; + +static const struct gpio_led_platform_data tink_leds_pdata = { + .num_leds = ARRAY_SIZE(tink_leds), + .leds = tink_leds, +}; + +static struct gpiod_lookup_table tink_leds_table = { + .dev_id = "leds-gpio", + .table = { + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 11, + NULL, 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 18, + NULL, 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 20, + NULL, 2, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 22, + NULL, 3, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 23, + NULL, 4, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 32, + NULL, 5, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 34, + NULL, 6, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 35, + NULL, 7, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 36, + NULL, 8, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 37, + NULL, 9, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 48, + NULL, 10, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 16, + NULL, 11, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 7, + NULL, 12, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 21, + NULL, 13, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 19, + NULL, 14, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ + } +}; + +/* Reset Button */ +static struct gpio_keys_button tink_buttons[] = { + { + .desc = "Reset", + .type = EV_KEY, + .code = KEY_RESTART, + .active_low = 1, + .debounce_interval = 100, + }, +}; + +static const struct gpio_keys_platform_data tink_buttons_pdata = { + .buttons = tink_buttons, + .nbuttons = ARRAY_SIZE(tink_buttons), + .poll_interval = 20, + .rep = 0, + .name = "mx100-keys", +}; + +static struct gpiod_lookup_table tink_keys_table = { + .dev_id = "gpio-keys-polled", + .table = { + GPIO_LOOKUP_IDX(TINK_GPIO_DRIVER_NAME, 60, + NULL, 0, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ + } +}; + +/* Board setup */ +static const struct dmi_system_id tink_systems[] __initconst = { + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Cisco"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MX100-HW"), + }, + }, + {} /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(dmi, tink_systems); + +static struct platform_device *tink_leds_pdev; +static struct platform_device *tink_keys_pdev; + +static struct platform_device * __init tink_create_dev( + const char *name, const void *pdata, size_t sz) +{ + struct platform_device *pdev; + + pdev = platform_device_register_data(NULL, + name, PLATFORM_DEVID_NONE, pdata, sz); + if (IS_ERR(pdev)) + pr_err("failed registering %s: %ld\n", name, PTR_ERR(pdev)); + + return pdev; +} + +static int __init tink_board_init(void) +{ + int ret; + + if (!dmi_first_match(tink_systems)) + return -ENODEV; + + /* + * We need to make sure that GPIO60 isn't set to native mode as is default since it's our + * Reset Button. To do this, write to GPIO_USE_SEL2 to have GPIO60 set to GPIO mode. + * This is documented on page 1609 of the PCH datasheet, order number 327879-005US + */ + outl(inl(0x530) | BIT(28), 0x530); + + gpiod_add_lookup_table(&tink_leds_table); + gpiod_add_lookup_table(&tink_keys_table); + + tink_leds_pdev = tink_create_dev("leds-gpio", + &tink_leds_pdata, sizeof(tink_leds_pdata)); + if (IS_ERR(tink_leds_pdev)) { + ret = PTR_ERR(tink_leds_pdev); + goto err; + } + + tink_keys_pdev = tink_create_dev("gpio-keys-polled", + &tink_buttons_pdata, sizeof(tink_buttons_pdata)); + if (IS_ERR(tink_keys_pdev)) { + ret = PTR_ERR(tink_keys_pdev); + platform_device_unregister(tink_leds_pdev); + goto err; + } + + return 0; + +err: + gpiod_remove_lookup_table(&tink_keys_table); + gpiod_remove_lookup_table(&tink_leds_table); + return ret; +} +module_init(tink_board_init); + +static void __exit tink_board_exit(void) +{ + platform_device_unregister(tink_keys_pdev); + platform_device_unregister(tink_leds_pdev); + gpiod_remove_lookup_table(&tink_keys_table); + gpiod_remove_lookup_table(&tink_leds_table); +} +module_exit(tink_board_exit); + +MODULE_AUTHOR("Chris Blake "); +MODULE_DESCRIPTION("Cisco Meraki MX100 Platform Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:meraki-mx100"); -- cgit v1.2.3-70-g09d2 From 892384cd998a17960dff6ebefc27375f63364111 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Tue, 3 Aug 2021 14:16:49 +0200 Subject: iommu/io-pgtable: Add DART pagetable format Apple's DART iommu uses a pagetable format that shares some similarities with the ones already implemented by io-pgtable.c. Add a new format variant to support the required differences so that we don't have to duplicate the pagetable handling code. Reviewed-by: Alexander Graf Reviewed-by: Alyssa Rosenzweig Reviewed-by: Robin Murphy Signed-off-by: Sven Peter Link: https://lore.kernel.org/r/20210803121651.61594-2-sven@svenpeter.dev Signed-off-by: Joerg Roedel --- drivers/iommu/io-pgtable-arm.c | 63 ++++++++++++++++++++++++++++++++++++++++++ drivers/iommu/io-pgtable.c | 1 + include/linux/io-pgtable.h | 7 +++++ 3 files changed, 71 insertions(+) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 053df4048a29..0779eb96bd29 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -130,6 +130,9 @@ #define ARM_MALI_LPAE_MEMATTR_IMP_DEF 0x88ULL #define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL +#define APPLE_DART_PTE_PROT_NO_WRITE (1<<7) +#define APPLE_DART_PTE_PROT_NO_READ (1<<8) + /* IOPTE accessors */ #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d)) @@ -402,6 +405,15 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, { arm_lpae_iopte pte; + if (data->iop.fmt == APPLE_DART) { + pte = 0; + if (!(prot & IOMMU_WRITE)) + pte |= APPLE_DART_PTE_PROT_NO_WRITE; + if (!(prot & IOMMU_READ)) + pte |= APPLE_DART_PTE_PROT_NO_READ; + return pte; + } + if (data->iop.fmt == ARM_64_LPAE_S1 || data->iop.fmt == ARM_32_LPAE_S1) { pte = ARM_LPAE_PTE_nG; @@ -1102,6 +1114,52 @@ out_free_data: return NULL; } +static struct io_pgtable * +apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) +{ + struct arm_lpae_io_pgtable *data; + int i; + + if (cfg->oas > 36) + return NULL; + + data = arm_lpae_alloc_pgtable(cfg); + if (!data) + return NULL; + + /* + * The table format itself always uses two levels, but the total VA + * space is mapped by four separate tables, making the MMIO registers + * an effective "level 1". For simplicity, though, we treat this + * equivalently to LPAE stage 2 concatenation at level 2, with the + * additional TTBRs each just pointing at consecutive pages. + */ + if (data->start_level < 1) + goto out_free_data; + if (data->start_level == 1 && data->pgd_bits > 2) + goto out_free_data; + if (data->start_level > 1) + data->pgd_bits = 0; + data->start_level = 2; + cfg->apple_dart_cfg.n_ttbrs = 1 << data->pgd_bits; + data->pgd_bits += data->bits_per_level; + + data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data), GFP_KERNEL, + cfg); + if (!data->pgd) + goto out_free_data; + + for (i = 0; i < cfg->apple_dart_cfg.n_ttbrs; ++i) + cfg->apple_dart_cfg.ttbr[i] = + virt_to_phys(data->pgd + i * ARM_LPAE_GRANULE(data)); + + return &data->iop; + +out_free_data: + kfree(data); + return NULL; +} + struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = { .alloc = arm_64_lpae_alloc_pgtable_s1, .free = arm_lpae_free_pgtable, @@ -1127,6 +1185,11 @@ struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns = { .free = arm_lpae_free_pgtable, }; +struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns = { + .alloc = apple_dart_alloc_pgtable, + .free = arm_lpae_free_pgtable, +}; + #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST static struct io_pgtable_cfg *cfg_cookie __initdata; diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c index 6e9917ce980f..f4bfcef98297 100644 --- a/drivers/iommu/io-pgtable.c +++ b/drivers/iommu/io-pgtable.c @@ -20,6 +20,7 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = { [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns, [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns, [ARM_MALI_LPAE] = &io_pgtable_arm_mali_lpae_init_fns, + [APPLE_DART] = &io_pgtable_apple_dart_init_fns, #endif #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S [ARM_V7S] = &io_pgtable_arm_v7s_init_fns, diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index c43f3b899d2a..a738483fb4da 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -16,6 +16,7 @@ enum io_pgtable_fmt { ARM_V7S, ARM_MALI_LPAE, AMD_IOMMU_V1, + APPLE_DART, IO_PGTABLE_NUM_FMTS, }; @@ -136,6 +137,11 @@ struct io_pgtable_cfg { u64 transtab; u64 memattr; } arm_mali_lpae_cfg; + + struct { + u64 ttbr[4]; + u32 n_ttbrs; + } apple_dart_cfg; }; }; @@ -254,5 +260,6 @@ extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns; extern struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns; extern struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns; extern struct io_pgtable_init_fns io_pgtable_amd_iommu_v1_init_fns; +extern struct io_pgtable_init_fns io_pgtable_apple_dart_init_fns; #endif /* __IO_PGTABLE_H */ -- cgit v1.2.3-70-g09d2 From 9d9cafb45c71c9fe302234807fae8f743056f88a Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Tue, 3 Aug 2021 14:16:50 +0200 Subject: dt-bindings: iommu: add DART iommu bindings DART (Device Address Resolution Table) is the iommu found on Apple ARM SoCs such as the M1. Reviewed-by: Rob Herring Reviewed-by: Alyssa Rosenzweig Signed-off-by: Sven Peter Link: https://lore.kernel.org/r/20210803121651.61594-3-sven@svenpeter.dev Signed-off-by: Joerg Roedel --- .../devicetree/bindings/iommu/apple,dart.yaml | 81 ++++++++++++++++++++++ MAINTAINERS | 6 ++ 2 files changed, 87 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/apple,dart.yaml diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Documentation/devicetree/bindings/iommu/apple,dart.yaml new file mode 100644 index 000000000000..94aa9e9afa59 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iommu/apple,dart.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple DART IOMMU + +maintainers: + - Sven Peter + +description: |+ + Apple SoCs may contain an implementation of their Device Address + Resolution Table which provides a mandatory layer of address + translations for various masters. + + Each DART instance is capable of handling up to 16 different streams + with individual pagetables and page-level read/write protection flags. + + This DART IOMMU also raises interrupts in response to various + fault conditions. + +properties: + compatible: + const: apple,t8103-dart + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + description: + Reference to the gate clock phandle if required for this IOMMU. + Optional since not all IOMMUs are attached to a clock gate. + + '#iommu-cells': + const: 1 + description: + Has to be one. The single cell describes the stream id emitted by + a master to the IOMMU. + +required: + - compatible + - reg + - '#iommu-cells' + - interrupts + +additionalProperties: false + +examples: + - |+ + dart1: iommu@82f80000 { + compatible = "apple,t8103-dart"; + reg = <0x82f80000 0x4000>; + interrupts = <1 781 4>; + #iommu-cells = <1>; + }; + + master1 { + iommus = <&dart1 0>; + }; + + - |+ + dart2a: iommu@82f00000 { + compatible = "apple,t8103-dart"; + reg = <0x82f00000 0x4000>; + interrupts = <1 781 4>; + #iommu-cells = <1>; + }; + dart2b: iommu@82f80000 { + compatible = "apple,t8103-dart"; + reg = <0x82f80000 0x4000>; + interrupts = <1 781 4>; + #iommu-cells = <1>; + }; + + master2 { + iommus = <&dart2a 0>, <&dart2b 1>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 19135a9d778e..d5a8f7087a74 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1262,6 +1262,12 @@ L: linux-input@vger.kernel.org S: Odd fixes F: drivers/input/mouse/bcm5974.c +APPLE DART IOMMU DRIVER +M: Sven Peter +L: iommu@lists.linux-foundation.org +S: Maintained +F: Documentation/devicetree/bindings/iommu/apple,dart.yaml + APPLE SMC DRIVER M: Henrik Rydberg L: linux-hwmon@vger.kernel.org -- cgit v1.2.3-70-g09d2 From 46d1fb072e76b161b0fb1ada9e37bf7e4d1f123f Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Tue, 3 Aug 2021 14:16:51 +0200 Subject: iommu/dart: Add DART iommu driver Apple's new SoCs use iommus for almost all peripherals. These Device Address Resolution Tables must be setup before these peripherals can act as DMA masters. Tested-by: Alyssa Rosenzweig Signed-off-by: Sven Peter Link: https://lore.kernel.org/r/20210803121651.61594-4-sven@svenpeter.dev Signed-off-by: Joerg Roedel --- MAINTAINERS | 1 + drivers/iommu/Kconfig | 14 + drivers/iommu/Makefile | 1 + drivers/iommu/apple-dart.c | 923 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 939 insertions(+) create mode 100644 drivers/iommu/apple-dart.c diff --git a/MAINTAINERS b/MAINTAINERS index d5a8f7087a74..5e03acfb00f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1267,6 +1267,7 @@ M: Sven Peter L: iommu@lists.linux-foundation.org S: Maintained F: Documentation/devicetree/bindings/iommu/apple,dart.yaml +F: drivers/iommu/apple-dart.c APPLE SMC DRIVER M: Henrik Rydberg diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index c84da8205be7..dfe81da483e9 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -290,6 +290,20 @@ config SPAPR_TCE_IOMMU Enables bits of IOMMU API required by VFIO. The iommu_ops is not implemented as it is not necessary for VFIO. +config APPLE_DART + tristate "Apple DART IOMMU Support" + depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64) + select IOMMU_API + select IOMMU_IO_PGTABLE_LPAE + default ARCH_APPLE + help + Support for Apple DART (Device Address Resolution Table) IOMMUs + found in Apple ARM SoCs like the M1. + This IOMMU is required for most peripherals using DMA to access + the main memory. + + Say Y here if you are using an Apple SoC. + # ARM IOMMU support config ARM_SMMU tristate "ARM Ltd. System MMU (SMMU) Support" diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index c0fb0ba88143..bc7f730edbb0 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o +obj-$(CONFIG_APPLE_DART) += apple-dart.o diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c new file mode 100644 index 000000000000..559db9259e65 --- /dev/null +++ b/drivers/iommu/apple-dart.c @@ -0,0 +1,923 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Apple DART (Device Address Resolution Table) IOMMU driver + * + * Copyright (C) 2021 The Asahi Linux Contributors + * + * Based on arm/arm-smmu/arm-ssmu.c and arm/arm-smmu-v3/arm-smmu-v3.c + * Copyright (C) 2013 ARM Limited + * Copyright (C) 2015 ARM Limited + * and on exynos-iommu.c + * Copyright (c) 2011,2016 Samsung Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DART_MAX_STREAMS 16 +#define DART_MAX_TTBR 4 +#define MAX_DARTS_PER_DEVICE 2 + +#define DART_STREAM_ALL 0xffff + +#define DART_PARAMS1 0x00 +#define DART_PARAMS_PAGE_SHIFT GENMASK(27, 24) + +#define DART_PARAMS2 0x04 +#define DART_PARAMS_BYPASS_SUPPORT BIT(0) + +#define DART_STREAM_COMMAND 0x20 +#define DART_STREAM_COMMAND_BUSY BIT(2) +#define DART_STREAM_COMMAND_INVALIDATE BIT(20) + +#define DART_STREAM_SELECT 0x34 + +#define DART_ERROR 0x40 +#define DART_ERROR_STREAM GENMASK(27, 24) +#define DART_ERROR_CODE GENMASK(11, 0) +#define DART_ERROR_FLAG BIT(31) + +#define DART_ERROR_READ_FAULT BIT(4) +#define DART_ERROR_WRITE_FAULT BIT(3) +#define DART_ERROR_NO_PTE BIT(2) +#define DART_ERROR_NO_PMD BIT(1) +#define DART_ERROR_NO_TTBR BIT(0) + +#define DART_CONFIG 0x60 +#define DART_CONFIG_LOCK BIT(15) + +#define DART_STREAM_COMMAND_BUSY_TIMEOUT 100 + +#define DART_ERROR_ADDR_HI 0x54 +#define DART_ERROR_ADDR_LO 0x50 + +#define DART_TCR(sid) (0x100 + 4 * (sid)) +#define DART_TCR_TRANSLATE_ENABLE BIT(7) +#define DART_TCR_BYPASS0_ENABLE BIT(8) +#define DART_TCR_BYPASS1_ENABLE BIT(12) + +#define DART_TTBR(sid, idx) (0x200 + 16 * (sid) + 4 * (idx)) +#define DART_TTBR_VALID BIT(31) +#define DART_TTBR_SHIFT 12 + +/* + * Private structure associated with each DART device. + * + * @dev: device struct + * @regs: mapped MMIO region + * @irq: interrupt number, can be shared with other DARTs + * @clks: clocks associated with this DART + * @num_clks: number of @clks + * @lock: lock for hardware operations involving this dart + * @pgsize: pagesize supported by this DART + * @supports_bypass: indicates if this DART supports bypass mode + * @force_bypass: force bypass mode due to pagesize mismatch? + * @sid2group: maps stream ids to iommu_groups + * @iommu: iommu core device + */ +struct apple_dart { + struct device *dev; + + void __iomem *regs; + + int irq; + struct clk_bulk_data *clks; + int num_clks; + + spinlock_t lock; + + u32 pgsize; + u32 supports_bypass : 1; + u32 force_bypass : 1; + + struct iommu_group *sid2group[DART_MAX_STREAMS]; + struct iommu_device iommu; +}; + +/* + * Convenience struct to identify streams. + * + * The normal variant is used inside apple_dart_master_cfg which isn't written + * to concurrently. + * The atomic variant is used inside apple_dart_domain where we have to guard + * against races from potential parallel calls to attach/detach_device. + * Note that even inside the atomic variant the apple_dart pointer is not + * protected: This pointer is initialized once under the domain init mutex + * and never changed again afterwards. Devices with different dart pointers + * cannot be attached to the same domain. + * + * @dart dart pointer + * @sid stream id bitmap + */ +struct apple_dart_stream_map { + struct apple_dart *dart; + unsigned long sidmap; +}; +struct apple_dart_atomic_stream_map { + struct apple_dart *dart; + atomic64_t sidmap; +}; + +/* + * This structure is attached to each iommu domain handled by a DART. + * + * @pgtbl_ops: pagetable ops allocated by io-pgtable + * @finalized: true if the domain has been completely initialized + * @init_lock: protects domain initialization + * @stream_maps: streams attached to this domain (valid for DMA/UNMANAGED only) + * @domain: core iommu domain pointer + */ +struct apple_dart_domain { + struct io_pgtable_ops *pgtbl_ops; + + bool finalized; + struct mutex init_lock; + struct apple_dart_atomic_stream_map stream_maps[MAX_DARTS_PER_DEVICE]; + + struct iommu_domain domain; +}; + +/* + * This structure is attached to devices with dev_iommu_priv_set() on of_xlate + * and contains a list of streams bound to this device. + * So far the worst case seen is a single device with two streams + * from different darts, such that this simple static array is enough. + * + * @streams: streams for this device + */ +struct apple_dart_master_cfg { + struct apple_dart_stream_map stream_maps[MAX_DARTS_PER_DEVICE]; +}; + +/* + * Helper macro to iterate over apple_dart_master_cfg.stream_maps and + * apple_dart_domain.stream_maps + * + * @i int used as loop variable + * @base pointer to base struct (apple_dart_master_cfg or apple_dart_domain) + * @stream pointer to the apple_dart_streams struct for each loop iteration + */ +#define for_each_stream_map(i, base, stream_map) \ + for (i = 0, stream_map = &(base)->stream_maps[0]; \ + i < MAX_DARTS_PER_DEVICE && stream_map->dart; \ + stream_map = &(base)->stream_maps[++i]) + +static struct platform_driver apple_dart_driver; +static const struct iommu_ops apple_dart_iommu_ops; +static const struct iommu_flush_ops apple_dart_tlb_ops; + +static struct apple_dart_domain *to_dart_domain(struct iommu_domain *dom) +{ + return container_of(dom, struct apple_dart_domain, domain); +} + +static void +apple_dart_hw_enable_translation(struct apple_dart_stream_map *stream_map) +{ + int sid; + + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + writel(DART_TCR_TRANSLATE_ENABLE, + stream_map->dart->regs + DART_TCR(sid)); +} + +static void apple_dart_hw_disable_dma(struct apple_dart_stream_map *stream_map) +{ + int sid; + + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + writel(0, stream_map->dart->regs + DART_TCR(sid)); +} + +static void +apple_dart_hw_enable_bypass(struct apple_dart_stream_map *stream_map) +{ + int sid; + + WARN_ON(!stream_map->dart->supports_bypass); + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + writel(DART_TCR_BYPASS0_ENABLE | DART_TCR_BYPASS1_ENABLE, + stream_map->dart->regs + DART_TCR(sid)); +} + +static void apple_dart_hw_set_ttbr(struct apple_dart_stream_map *stream_map, + u8 idx, phys_addr_t paddr) +{ + int sid; + + WARN_ON(paddr & ((1 << DART_TTBR_SHIFT) - 1)); + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + writel(DART_TTBR_VALID | (paddr >> DART_TTBR_SHIFT), + stream_map->dart->regs + DART_TTBR(sid, idx)); +} + +static void apple_dart_hw_clear_ttbr(struct apple_dart_stream_map *stream_map, + u8 idx) +{ + int sid; + + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + writel(0, stream_map->dart->regs + DART_TTBR(sid, idx)); +} + +static void +apple_dart_hw_clear_all_ttbrs(struct apple_dart_stream_map *stream_map) +{ + int i; + + for (i = 0; i < DART_MAX_TTBR; ++i) + apple_dart_hw_clear_ttbr(stream_map, i); +} + +static int +apple_dart_hw_stream_command(struct apple_dart_stream_map *stream_map, + u32 command) +{ + unsigned long flags; + int ret; + u32 command_reg; + + spin_lock_irqsave(&stream_map->dart->lock, flags); + + writel(stream_map->sidmap, stream_map->dart->regs + DART_STREAM_SELECT); + writel(command, stream_map->dart->regs + DART_STREAM_COMMAND); + + ret = readl_poll_timeout_atomic( + stream_map->dart->regs + DART_STREAM_COMMAND, command_reg, + !(command_reg & DART_STREAM_COMMAND_BUSY), 1, + DART_STREAM_COMMAND_BUSY_TIMEOUT); + + spin_unlock_irqrestore(&stream_map->dart->lock, flags); + + if (ret) { + dev_err(stream_map->dart->dev, + "busy bit did not clear after command %x for streams %lx\n", + command, stream_map->sidmap); + return ret; + } + + return 0; +} + +static int +apple_dart_hw_invalidate_tlb(struct apple_dart_stream_map *stream_map) +{ + return apple_dart_hw_stream_command(stream_map, + DART_STREAM_COMMAND_INVALIDATE); +} + +static int apple_dart_hw_reset(struct apple_dart *dart) +{ + u32 config; + struct apple_dart_stream_map stream_map; + + config = readl(dart->regs + DART_CONFIG); + if (config & DART_CONFIG_LOCK) { + dev_err(dart->dev, "DART is locked down until reboot: %08x\n", + config); + return -EINVAL; + } + + stream_map.dart = dart; + stream_map.sidmap = DART_STREAM_ALL; + apple_dart_hw_disable_dma(&stream_map); + apple_dart_hw_clear_all_ttbrs(&stream_map); + + /* clear any pending errors before the interrupt is unmasked */ + writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR); + + return apple_dart_hw_invalidate_tlb(&stream_map); +} + +static void apple_dart_domain_flush_tlb(struct apple_dart_domain *domain) +{ + int i; + struct apple_dart_atomic_stream_map *domain_stream_map; + struct apple_dart_stream_map stream_map; + + for_each_stream_map(i, domain, domain_stream_map) { + stream_map.dart = domain_stream_map->dart; + stream_map.sidmap = atomic64_read(&domain_stream_map->sidmap); + apple_dart_hw_invalidate_tlb(&stream_map); + } +} + +static void apple_dart_flush_iotlb_all(struct iommu_domain *domain) +{ + apple_dart_domain_flush_tlb(to_dart_domain(domain)); +} + +static void apple_dart_iotlb_sync(struct iommu_domain *domain, + struct iommu_iotlb_gather *gather) +{ + apple_dart_domain_flush_tlb(to_dart_domain(domain)); +} + +static void apple_dart_iotlb_sync_map(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ + apple_dart_domain_flush_tlb(to_dart_domain(domain)); +} + +static void apple_dart_tlb_flush_all(void *cookie) +{ + apple_dart_domain_flush_tlb(cookie); +} + +static void apple_dart_tlb_flush_walk(unsigned long iova, size_t size, + size_t granule, void *cookie) +{ + apple_dart_domain_flush_tlb(cookie); +} + +static const struct iommu_flush_ops apple_dart_tlb_ops = { + .tlb_flush_all = apple_dart_tlb_flush_all, + .tlb_flush_walk = apple_dart_tlb_flush_walk, +}; + +static phys_addr_t apple_dart_iova_to_phys(struct iommu_domain *domain, + dma_addr_t iova) +{ + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + struct io_pgtable_ops *ops = dart_domain->pgtbl_ops; + + if (!ops) + return 0; + + return ops->iova_to_phys(ops, iova); +} + +static int apple_dart_map_pages(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t pgsize, + size_t pgcount, int prot, gfp_t gfp, + size_t *mapped) +{ + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + struct io_pgtable_ops *ops = dart_domain->pgtbl_ops; + + if (!ops) + return -ENODEV; + + return ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot, gfp, + mapped); +} + +static size_t apple_dart_unmap_pages(struct iommu_domain *domain, + unsigned long iova, size_t pgsize, + size_t pgcount, + struct iommu_iotlb_gather *gather) +{ + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + struct io_pgtable_ops *ops = dart_domain->pgtbl_ops; + + return ops->unmap_pages(ops, iova, pgsize, pgcount, gather); +} + +static void +apple_dart_setup_translation(struct apple_dart_domain *domain, + struct apple_dart_stream_map *stream_map) +{ + int i; + struct io_pgtable_cfg *pgtbl_cfg = + &io_pgtable_ops_to_pgtable(domain->pgtbl_ops)->cfg; + + for (i = 0; i < pgtbl_cfg->apple_dart_cfg.n_ttbrs; ++i) + apple_dart_hw_set_ttbr(stream_map, i, + pgtbl_cfg->apple_dart_cfg.ttbr[i]); + for (; i < DART_MAX_TTBR; ++i) + apple_dart_hw_clear_ttbr(stream_map, i); + + apple_dart_hw_enable_translation(stream_map); + apple_dart_hw_invalidate_tlb(stream_map); +} + +static int apple_dart_finalize_domain(struct iommu_domain *domain, + struct apple_dart_master_cfg *cfg) +{ + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + struct apple_dart *dart = cfg->stream_maps[0].dart; + struct io_pgtable_cfg pgtbl_cfg; + int ret = 0; + int i; + + mutex_lock(&dart_domain->init_lock); + + if (dart_domain->finalized) + goto done; + + for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) { + dart_domain->stream_maps[i].dart = cfg->stream_maps[i].dart; + atomic64_set(&dart_domain->stream_maps[i].sidmap, + cfg->stream_maps[i].sidmap); + } + + pgtbl_cfg = (struct io_pgtable_cfg){ + .pgsize_bitmap = dart->pgsize, + .ias = 32, + .oas = 36, + .coherent_walk = 1, + .tlb = &apple_dart_tlb_ops, + .iommu_dev = dart->dev, + }; + + dart_domain->pgtbl_ops = + alloc_io_pgtable_ops(APPLE_DART, &pgtbl_cfg, domain); + if (!dart_domain->pgtbl_ops) { + ret = -ENOMEM; + goto done; + } + + domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap; + domain->geometry.aperture_start = 0; + domain->geometry.aperture_end = DMA_BIT_MASK(32); + domain->geometry.force_aperture = true; + + dart_domain->finalized = true; + +done: + mutex_unlock(&dart_domain->init_lock); + return ret; +} + +static int +apple_dart_mod_streams(struct apple_dart_atomic_stream_map *domain_maps, + struct apple_dart_stream_map *master_maps, + bool add_streams) +{ + int i; + + for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) { + if (domain_maps[i].dart != master_maps[i].dart) + return -EINVAL; + } + + for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) { + if (!domain_maps[i].dart) + break; + if (add_streams) + atomic64_or(master_maps[i].sidmap, + &domain_maps[i].sidmap); + else + atomic64_and(~master_maps[i].sidmap, + &domain_maps[i].sidmap); + } + + return 0; +} + +static int apple_dart_domain_add_streams(struct apple_dart_domain *domain, + struct apple_dart_master_cfg *cfg) +{ + return apple_dart_mod_streams(domain->stream_maps, cfg->stream_maps, + true); +} + +static int apple_dart_domain_remove_streams(struct apple_dart_domain *domain, + struct apple_dart_master_cfg *cfg) +{ + return apple_dart_mod_streams(domain->stream_maps, cfg->stream_maps, + false); +} + +static int apple_dart_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + int ret, i; + struct apple_dart_stream_map *stream_map; + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + + if (cfg->stream_maps[0].dart->force_bypass && + domain->type != IOMMU_DOMAIN_IDENTITY) + return -EINVAL; + if (!cfg->stream_maps[0].dart->supports_bypass && + domain->type == IOMMU_DOMAIN_IDENTITY) + return -EINVAL; + + ret = apple_dart_finalize_domain(domain, cfg); + if (ret) + return ret; + + switch (domain->type) { + case IOMMU_DOMAIN_DMA: + case IOMMU_DOMAIN_UNMANAGED: + ret = apple_dart_domain_add_streams(dart_domain, cfg); + if (ret) + return ret; + + for_each_stream_map(i, cfg, stream_map) + apple_dart_setup_translation(dart_domain, stream_map); + break; + case IOMMU_DOMAIN_BLOCKED: + for_each_stream_map(i, cfg, stream_map) + apple_dart_hw_disable_dma(stream_map); + break; + case IOMMU_DOMAIN_IDENTITY: + for_each_stream_map(i, cfg, stream_map) + apple_dart_hw_enable_bypass(stream_map); + break; + } + + return ret; +} + +static void apple_dart_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + int i; + struct apple_dart_stream_map *stream_map; + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + + for_each_stream_map(i, cfg, stream_map) + apple_dart_hw_disable_dma(stream_map); + + if (domain->type == IOMMU_DOMAIN_DMA || + domain->type == IOMMU_DOMAIN_UNMANAGED) + apple_dart_domain_remove_streams(dart_domain, cfg); +} + +static struct iommu_device *apple_dart_probe_device(struct device *dev) +{ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + struct apple_dart_stream_map *stream_map; + int i; + + if (!cfg) + return ERR_PTR(-ENODEV); + + for_each_stream_map(i, cfg, stream_map) + device_link_add( + dev, stream_map->dart->dev, + DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER); + + return &cfg->stream_maps[0].dart->iommu; +} + +static void apple_dart_release_device(struct device *dev) +{ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + + if (!cfg) + return; + + dev_iommu_priv_set(dev, NULL); + kfree(cfg); +} + +static struct iommu_domain *apple_dart_domain_alloc(unsigned int type) +{ + struct apple_dart_domain *dart_domain; + + if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED && + type != IOMMU_DOMAIN_IDENTITY && type != IOMMU_DOMAIN_BLOCKED) + return NULL; + + dart_domain = kzalloc(sizeof(*dart_domain), GFP_KERNEL); + if (!dart_domain) + return NULL; + + iommu_get_dma_cookie(&dart_domain->domain); + mutex_init(&dart_domain->init_lock); + + /* no need to allocate pgtbl_ops or do any other finalization steps */ + if (type == IOMMU_DOMAIN_IDENTITY || type == IOMMU_DOMAIN_BLOCKED) + dart_domain->finalized = true; + + return &dart_domain->domain; +} + +static void apple_dart_domain_free(struct iommu_domain *domain) +{ + struct apple_dart_domain *dart_domain = to_dart_domain(domain); + + if (dart_domain->pgtbl_ops) + free_io_pgtable_ops(dart_domain->pgtbl_ops); + + kfree(dart_domain); +} + +static int apple_dart_of_xlate(struct device *dev, struct of_phandle_args *args) +{ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + struct platform_device *iommu_pdev = of_find_device_by_node(args->np); + struct apple_dart *dart = platform_get_drvdata(iommu_pdev); + struct apple_dart *cfg_dart; + int i, sid; + + if (args->args_count != 1) + return -EINVAL; + sid = args->args[0]; + + if (!cfg) + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + dev_iommu_priv_set(dev, cfg); + + cfg_dart = cfg->stream_maps[0].dart; + if (cfg_dart) { + if (cfg_dart->supports_bypass != dart->supports_bypass) + return -EINVAL; + if (cfg_dart->force_bypass != dart->force_bypass) + return -EINVAL; + if (cfg_dart->pgsize != dart->pgsize) + return -EINVAL; + } + + for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) { + if (cfg->stream_maps[i].dart == dart) { + cfg->stream_maps[i].sidmap |= 1 << sid; + return 0; + } + } + for (i = 0; i < MAX_DARTS_PER_DEVICE; ++i) { + if (!cfg->stream_maps[i].dart) { + cfg->stream_maps[i].dart = dart; + cfg->stream_maps[i].sidmap = 1 << sid; + return 0; + } + } + + return -EINVAL; +} + +static struct iommu_group *apple_dart_device_group(struct device *dev) +{ + static DEFINE_MUTEX(lock); + int i, sid; + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + struct apple_dart_stream_map *stream_map; + struct iommu_group *group = NULL; + struct iommu_group *res = ERR_PTR(-EINVAL); + + mutex_lock(&lock); + + for_each_stream_map(i, cfg, stream_map) { + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) { + struct iommu_group *stream_group = + stream_map->dart->sid2group[sid]; + + if (group && group != stream_group) { + res = ERR_PTR(-EINVAL); + goto out; + } + + group = stream_group; + } + } + + if (group) { + res = iommu_group_ref_get(group); + goto out; + } + +#ifdef CONFIG_PCI + if (dev_is_pci(dev)) + group = pci_device_group(dev); + else +#endif + group = generic_device_group(dev); + + for_each_stream_map(i, cfg, stream_map) + for_each_set_bit(sid, &stream_map->sidmap, DART_MAX_STREAMS) + stream_map->dart->sid2group[sid] = group; + + res = group; + +out: + mutex_unlock(&lock); + return res; +} + +static int apple_dart_def_domain_type(struct device *dev) +{ + struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev); + + if (cfg->stream_maps[0].dart->force_bypass) + return IOMMU_DOMAIN_IDENTITY; + if (!cfg->stream_maps[0].dart->supports_bypass) + return IOMMU_DOMAIN_DMA; + + return 0; +} + +static const struct iommu_ops apple_dart_iommu_ops = { + .domain_alloc = apple_dart_domain_alloc, + .domain_free = apple_dart_domain_free, + .attach_dev = apple_dart_attach_dev, + .detach_dev = apple_dart_detach_dev, + .map_pages = apple_dart_map_pages, + .unmap_pages = apple_dart_unmap_pages, + .flush_iotlb_all = apple_dart_flush_iotlb_all, + .iotlb_sync = apple_dart_iotlb_sync, + .iotlb_sync_map = apple_dart_iotlb_sync_map, + .iova_to_phys = apple_dart_iova_to_phys, + .probe_device = apple_dart_probe_device, + .release_device = apple_dart_release_device, + .device_group = apple_dart_device_group, + .of_xlate = apple_dart_of_xlate, + .def_domain_type = apple_dart_def_domain_type, + .pgsize_bitmap = -1UL, /* Restricted during dart probe */ +}; + +static irqreturn_t apple_dart_irq(int irq, void *dev) +{ + struct apple_dart *dart = dev; + const char *fault_name = NULL; + u32 error = readl(dart->regs + DART_ERROR); + u32 error_code = FIELD_GET(DART_ERROR_CODE, error); + u32 addr_lo = readl(dart->regs + DART_ERROR_ADDR_LO); + u32 addr_hi = readl(dart->regs + DART_ERROR_ADDR_HI); + u64 addr = addr_lo | (((u64)addr_hi) << 32); + u8 stream_idx = FIELD_GET(DART_ERROR_STREAM, error); + + if (!(error & DART_ERROR_FLAG)) + return IRQ_NONE; + + /* there should only be a single bit set but let's use == to be sure */ + if (error_code == DART_ERROR_READ_FAULT) + fault_name = "READ FAULT"; + else if (error_code == DART_ERROR_WRITE_FAULT) + fault_name = "WRITE FAULT"; + else if (error_code == DART_ERROR_NO_PTE) + fault_name = "NO PTE FOR IOVA"; + else if (error_code == DART_ERROR_NO_PMD) + fault_name = "NO PMD FOR IOVA"; + else if (error_code == DART_ERROR_NO_TTBR) + fault_name = "NO TTBR FOR IOVA"; + else + fault_name = "unknown"; + + dev_err_ratelimited( + dart->dev, + "translation fault: status:0x%x stream:%d code:0x%x (%s) at 0x%llx", + error, stream_idx, error_code, fault_name, addr); + + writel(error, dart->regs + DART_ERROR); + return IRQ_HANDLED; +} + +static int apple_dart_set_bus_ops(const struct iommu_ops *ops) +{ + int ret; + + if (!iommu_present(&platform_bus_type)) { + ret = bus_set_iommu(&platform_bus_type, ops); + if (ret) + return ret; + } +#ifdef CONFIG_PCI + if (!iommu_present(&pci_bus_type)) { + ret = bus_set_iommu(&pci_bus_type, ops); + if (ret) { + bus_set_iommu(&platform_bus_type, NULL); + return ret; + } + } +#endif + return 0; +} + +static int apple_dart_probe(struct platform_device *pdev) +{ + int ret; + u32 dart_params[2]; + struct resource *res; + struct apple_dart *dart; + struct device *dev = &pdev->dev; + + dart = devm_kzalloc(dev, sizeof(*dart), GFP_KERNEL); + if (!dart) + return -ENOMEM; + + dart->dev = dev; + spin_lock_init(&dart->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (resource_size(res) < 0x4000) { + dev_err(dev, "MMIO region too small (%pr)\n", res); + return -EINVAL; + } + + dart->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(dart->regs)) + return PTR_ERR(dart->regs); + + dart->irq = platform_get_irq(pdev, 0); + if (dart->irq < 0) + return -ENODEV; + + ret = devm_clk_bulk_get_all(dev, &dart->clks); + if (ret < 0) + return ret; + dart->num_clks = ret; + + ret = clk_bulk_prepare_enable(dart->num_clks, dart->clks); + if (ret) + return ret; + + ret = apple_dart_hw_reset(dart); + if (ret) + goto err_clk_disable; + + dart_params[0] = readl(dart->regs + DART_PARAMS1); + dart_params[1] = readl(dart->regs + DART_PARAMS2); + dart->pgsize = 1 << FIELD_GET(DART_PARAMS_PAGE_SHIFT, dart_params[0]); + dart->supports_bypass = dart_params[1] & DART_PARAMS_BYPASS_SUPPORT; + dart->force_bypass = dart->pgsize > PAGE_SIZE; + + ret = request_irq(dart->irq, apple_dart_irq, IRQF_SHARED, + "apple-dart fault handler", dart); + if (ret) + goto err_clk_disable; + + platform_set_drvdata(pdev, dart); + + ret = apple_dart_set_bus_ops(&apple_dart_iommu_ops); + if (ret) + goto err_free_irq; + + ret = iommu_device_sysfs_add(&dart->iommu, dev, NULL, "apple-dart.%s", + dev_name(&pdev->dev)); + if (ret) + goto err_remove_bus_ops; + + ret = iommu_device_register(&dart->iommu, &apple_dart_iommu_ops, dev); + if (ret) + goto err_sysfs_remove; + + dev_info( + &pdev->dev, + "DART [pagesize %x, bypass support: %d, bypass forced: %d] initialized\n", + dart->pgsize, dart->supports_bypass, dart->force_bypass); + return 0; + +err_sysfs_remove: + iommu_device_sysfs_remove(&dart->iommu); +err_remove_bus_ops: + apple_dart_set_bus_ops(NULL); +err_free_irq: + free_irq(dart->irq, dart); +err_clk_disable: + clk_bulk_disable_unprepare(dart->num_clks, dart->clks); + + return ret; +} + +static int apple_dart_remove(struct platform_device *pdev) +{ + struct apple_dart *dart = platform_get_drvdata(pdev); + + apple_dart_hw_reset(dart); + free_irq(dart->irq, dart); + apple_dart_set_bus_ops(NULL); + + iommu_device_unregister(&dart->iommu); + iommu_device_sysfs_remove(&dart->iommu); + + clk_bulk_disable_unprepare(dart->num_clks, dart->clks); + + return 0; +} + +static const struct of_device_id apple_dart_of_match[] = { + { .compatible = "apple,t8103-dart", .data = NULL }, + {}, +}; +MODULE_DEVICE_TABLE(of, apple_dart_of_match); + +static struct platform_driver apple_dart_driver = { + .driver = { + .name = "apple-dart", + .of_match_table = apple_dart_of_match, + .suppress_bind_attrs = true, + }, + .probe = apple_dart_probe, + .remove = apple_dart_remove, +}; + +module_platform_driver(apple_dart_driver); + +MODULE_DESCRIPTION("IOMMU API for Apple's DART"); +MODULE_AUTHOR("Sven Peter "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From faf8e7539643ed958174ad3dfeb43c179a9c4397 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 10 Aug 2021 15:47:19 +0200 Subject: iommu/dart: APPLE_DART should depend on ARCH_APPLE The Apple DART (Device Address Resolution Table) IOMMU is only present on Apple ARM SoCs like the M1. Hence add a dependency on ARCH_APPLE, to prevent asking the user about this driver when configuring a kernel without support for the Apple Silicon SoC family. Signed-off-by: Geert Uytterhoeven Acked-by: Sven Peter Link: https://lore.kernel.org/r/44fcf525273b32c9afcd7e99acbd346d47f0e047.1628603162.git.geert+renesas@glider.be Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index dfe81da483e9..e908b8222e4e 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -292,7 +292,7 @@ config SPAPR_TCE_IOMMU config APPLE_DART tristate "Apple DART IOMMU Support" - depends on ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64) + depends on ARCH_APPLE || (COMPILE_TEST && !GENERIC_ATOMIC64) select IOMMU_API select IOMMU_IO_PGTABLE_LPAE default ARCH_APPLE -- cgit v1.2.3-70-g09d2 From a58b06083f789f6672ae44a21054e8f621125704 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Thu, 12 Aug 2021 17:23:22 +0530 Subject: MAINTAINERS: Add maintainers for amd-pinctrl driver Adding Basavaraj and myself to the maintainers list for amd-pinctrl driver. Signed-off-by: Basavaraj Natikar Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20210812115322.765379-1-Shyam-sundar.S-k@amd.com Signed-off-by: Linus Walleij --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0b36fa427d8f..63cb724577b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14617,6 +14617,12 @@ F: Documentation/driver-api/pin-control.rst F: drivers/pinctrl/ F: include/linux/pinctrl/ +PIN CONTROLLER - AMD +M: Basavaraj Natikar +M: Shyam Sundar S K +S: Maintained +F: drivers/pinctrl/pinctrl-amd.c + PIN CONTROLLER - FREESCALE M: Dong Aisheng M: Fabio Estevam -- cgit v1.2.3-70-g09d2 From 666173ee32e2d6f2853bd54b11b8127ac97eb019 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:35 +0800 Subject: MIPS: generic: Allow generating FIT image for Marduk board Marduk is based on IMG pistachio SoC. The platform is using MIPS UHI booting protocol and does have a proper devicetree implement, thus it could be a part of generic kernel. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/boot/dts/Makefile | 1 + arch/mips/boot/dts/img/Makefile | 2 ++ arch/mips/generic/Kconfig | 6 ++++++ arch/mips/generic/Platform | 1 + arch/mips/generic/board-marduk.its.S | 22 ++++++++++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 arch/mips/generic/board-marduk.its.S diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 60bd7d2a9ad8..188301164d9e 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -2,6 +2,7 @@ subdir-$(CONFIG_BMIPS_GENERIC) += brcm subdir-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon subdir-$(CONFIG_MACH_PISTACHIO) += img +subdir-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += img subdir-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += img subdir-$(CONFIG_MACH_INGENIC) += ingenic subdir-$(CONFIG_LANTIQ) += lantiq diff --git a/arch/mips/boot/dts/img/Makefile b/arch/mips/boot/dts/img/Makefile index 441a3c16efb0..24f6bbeadd48 100644 --- a/arch/mips/boot/dts/img/Makefile +++ b/arch/mips/boot/dts/img/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += boston.dtb +dtb-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += pistachio_marduk.dtb + dtb-$(CONFIG_MACH_PISTACHIO) += pistachio_marduk.dtb obj-$(CONFIG_MACH_PISTACHIO) += pistachio_marduk.dtb.o diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 657dd93c5e76..7dc5b3821cc6 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -58,6 +58,12 @@ config FIT_IMAGE_FDT_BOSTON enable this if you wish to boot on a MIPS Boston board, as it is expected by the bootloader. +config FIT_IMAGE_FDT_MARDUK + bool "Include FDT for IMG Pistachio Marduk (CI40) boards" + help + Enable this to include the FDT for the IMG Pistachio Marduk (CI40) + from Imagination Technologies in the FIT kernel image. + config FIT_IMAGE_FDT_NI169445 bool "Include FDT for NI 169445" help diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform index b871af16b5b6..e1abc113b409 100644 --- a/arch/mips/generic/Platform +++ b/arch/mips/generic/Platform @@ -24,3 +24,4 @@ its-$(CONFIG_FIT_IMAGE_FDT_LUTON) += board-luton.its.S its-$(CONFIG_FIT_IMAGE_FDT_JAGUAR2) += board-jaguar2.its.S its-$(CONFIG_FIT_IMAGE_FDT_SERVAL) += board-serval.its.S its-$(CONFIG_FIT_IMAGE_FDT_XILFPGA) += board-xilfpga.its.S +its-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += board-marduk.its.S diff --git a/arch/mips/generic/board-marduk.its.S b/arch/mips/generic/board-marduk.its.S new file mode 100644 index 000000000000..4f633794db90 --- /dev/null +++ b/arch/mips/generic/board-marduk.its.S @@ -0,0 +1,22 @@ +/ { + images { + fdt-marduk { + description = "img,pistachio-marduk Device Tree"; + data = /incbin/("boot/dts/img/pistachio_marduk.dtb"); + type = "flat_dt"; + arch = "mips"; + compression = "none"; + hash { + algo = "sha1"; + }; + }; + }; + + configurations { + conf-marduk { + description = "Marduk Linux kernel"; + kernel = "kernel"; + fdt = "fdt-marduk"; + }; + }; +}; -- cgit v1.2.3-70-g09d2 From d32524a2d05791181756bb4ab4f6e0628471fde2 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:36 +0800 Subject: MIPS: DTS: Pistachio add missing cpc and cdmm CPC and CDMM addresses are adjustable and we should tell kernel how to place them in devicetree. Note that MACH_PISTACHIO code hardcoded CDMM base to 0x1bdd0000, however it will collide with GIC address range. As we don't have any CDMM device on this platform it won't be a problem. I found another spare range, 0x1bdf0000~0x1be00000 to place CDMM instead. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/boot/dts/img/pistachio.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/mips/boot/dts/img/pistachio.dtsi b/arch/mips/boot/dts/img/pistachio.dtsi index dc3b7909de73..b1db8b8f446f 100644 --- a/arch/mips/boot/dts/img/pistachio.dtsi +++ b/arch/mips/boot/dts/img/pistachio.dtsi @@ -900,6 +900,16 @@ }; }; + cpc: cpc@1bde0000 { + compatible = "mti,mips-cpc"; + reg = <0x1bde0000 0x10000>; + }; + + cdmm: cdmm@1bdf0000 { + compatible = "mti,mips-cdmm"; + reg = <0x1bdf0000 0x10000>; + }; + usb_phy: usb-phy { compatible = "img,pistachio-usb-phy"; clocks = <&clk_core CLK_USB_PHY>; -- cgit v1.2.3-70-g09d2 From 90429205c000f4befdc212cfade39e358292584c Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:37 +0800 Subject: clk: pistachio: Make it selectable for generic MIPS kernel We're moving pistachio to generic MIPS kernel. The clk driver should be avilable to the generic MIPS kernel. Signed-off-by: Jiaxun Yang Acked-by: Stephen Boyd Signed-off-by: Thomas Bogendoerfer --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/pistachio/Kconfig | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/pistachio/Kconfig diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e873f9ea2e65..c5b3dc97396a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -403,6 +403,7 @@ source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mstar/Kconfig" source "drivers/clk/mvebu/Kconfig" +source "drivers/clk/pistachio/Kconfig" source "drivers/clk/qcom/Kconfig" source "drivers/clk/ralink/Kconfig" source "drivers/clk/renesas/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 2b91d34c582b..e42312121e51 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -97,7 +97,7 @@ obj-y += mstar/ obj-y += mvebu/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_COMMON_CLK_NXP) += nxp/ -obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ +obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pistachio/ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-y += ralink/ diff --git a/drivers/clk/pistachio/Kconfig b/drivers/clk/pistachio/Kconfig new file mode 100644 index 000000000000..d00f7b4a25fc --- /dev/null +++ b/drivers/clk/pistachio/Kconfig @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + +config COMMON_CLK_PISTACHIO + bool "Support for IMG Pistachio SoC clock controllers" + depends on MIPS || COMPILE_TEST + help + Support for the IMG Pistachio SoC clock controller. + Say Y if you want to include clock support. -- cgit v1.2.3-70-g09d2 From 1e4fd60b54cf9f65d2d5b89a9289cbbc42922adf Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:38 +0800 Subject: clocksource/drivers/pistachio: Make it selectable for MIPS So it will be avilable for generic MIPS kernel. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- drivers/clocksource/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index eb661b539a3e..0f5e3983951a 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -234,8 +234,9 @@ config CLKSRC_LPC32XX Support for the LPC32XX clocksource. config CLKSRC_PISTACHIO - bool "Clocksource for Pistachio SoC" if COMPILE_TEST + bool "Clocksource for Pistachio SoC" depends on HAS_IOMEM + depends on MIPS || COMPILE_TEST select TIMER_OF help Enables the clocksource for the Pistachio SoC. -- cgit v1.2.3-70-g09d2 From e238f10d8606ddb9a1728628a218c3f740b940be Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:39 +0800 Subject: phy: pistachio-usb: Depend on MIPS || COMPILE_TEST So it will be avilable for generic MIPS kernel. Signed-off-by: Jiaxun Yang Acked-By: Vinod Koul Signed-off-by: Thomas Bogendoerfer --- drivers/phy/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7dd35f1b9cc5..82b63e60c5a2 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -37,7 +37,7 @@ config PHY_LPC18XX_USB_OTG config PHY_PISTACHIO_USB tristate "IMG Pistachio USB2.0 PHY driver" - depends on MACH_PISTACHIO + depends on MIPS || COMPILE_TEST select GENERIC_PHY help Enable this to support the USB2.0 PHY on the IMG Pistachio SoC. -- cgit v1.2.3-70-g09d2 From f14973038d814c3ad032209794693dceca5eb7cf Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:40 +0800 Subject: pinctrl: pistachio: Make it as an option So it will be avilable for generic MIPS kernel. -- Signed-off-by: Jiaxun Yang v3: Depend on OF as well Acked-by: Linus Walleij Signed-off-by: Thomas Bogendoerfer --- drivers/pinctrl/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index f38f12801f18..eb981713b40d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -248,12 +248,15 @@ config PINCTRL_SX150X - 16 bits: sx1509q, sx1506q config PINCTRL_PISTACHIO - def_bool y if MACH_PISTACHIO + bool "IMG Pistachio SoC pinctrl driver" + depends on OF && (MIPS || COMPILE_TEST) depends on GPIOLIB select PINMUX select GENERIC_PINCONF select GPIOLIB_IRQCHIP select OF_GPIO + help + This support pinctrl and gpio driver for IMG Pistachio SoC. config PINCTRL_ST bool -- cgit v1.2.3-70-g09d2 From 917b64f1df2b9cec0a0859bd8d96b24679038f78 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:41 +0800 Subject: MIPS: config: generic: Add config for Marduk board The config is minimal config to allow it boot from SD Card. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/configs/generic/board-marduk.config | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 arch/mips/configs/generic/board-marduk.config diff --git a/arch/mips/configs/generic/board-marduk.config b/arch/mips/configs/generic/board-marduk.config new file mode 100644 index 000000000000..05ca34cd5a73 --- /dev/null +++ b/arch/mips/configs/generic/board-marduk.config @@ -0,0 +1,53 @@ +CONFIG_FIT_IMAGE_FDT_MARDUK=y + +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y + +CONFIG_CLKSRC_PISTACHIO=y + +CONFIG_COMMON_CLK_PISTACHIO=y + +CONFIG_DMADEVICES=y +CONFIG_IMG_MDC_DMA=y + +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_PCH=y + +CONFIG_I2C=y +CONFIG_I2C_IMG=y + +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_PLTFM=y + +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y + +CONFIG_PHY_PISTACHIO_USB=y + +CONFIG_PINCTRL=y +CONFIG_PINCTRL_PISTACHIO=y + +CONFIG_RESET_PISTACHIO=y + +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_8250_DW=y + +CONFIG_SPI=y +CONFIG_SRAM=y + +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_DWC2=y + +CONFIG_CRYPTO_DEV_IMGTEC_HASH=y +CONFIG_IMGPDC_WDT=y +CONFIG_IR_IMG=y +CONFIG_CC10001_ADC=y +CONFIG_SND_SOC_IMG=y -- cgit v1.2.3-70-g09d2 From 104f942b2832ab1340dab34ae2dad8b31b772788 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:42 +0800 Subject: MIPS: Retire MACH_PISTACHIO Now it can be replaced by generic kernel. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/Kbuild.platforms | 1 - arch/mips/Kconfig | 30 ---- arch/mips/boot/dts/Makefile | 1 - arch/mips/boot/dts/img/Makefile | 3 - arch/mips/configs/pistachio_defconfig | 316 ---------------------------------- arch/mips/pistachio/Kconfig | 14 -- arch/mips/pistachio/Makefile | 2 - arch/mips/pistachio/Platform | 6 - arch/mips/pistachio/init.c | 125 -------------- arch/mips/pistachio/irq.c | 24 --- arch/mips/pistachio/time.c | 55 ------ 11 files changed, 577 deletions(-) delete mode 100644 arch/mips/configs/pistachio_defconfig delete mode 100644 arch/mips/pistachio/Kconfig delete mode 100644 arch/mips/pistachio/Makefile delete mode 100644 arch/mips/pistachio/Platform delete mode 100644 arch/mips/pistachio/init.c delete mode 100644 arch/mips/pistachio/irq.c delete mode 100644 arch/mips/pistachio/time.c diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index e4f6e49417a9..584081df89c2 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -21,7 +21,6 @@ platform-$(CONFIG_MIPS_MALTA) += mti-malta/ platform-$(CONFIG_MACH_NINTENDO64) += n64/ platform-$(CONFIG_NLM_COMMON) += netlogic/ platform-$(CONFIG_PIC32MZDA) += pic32/ -platform-$(CONFIG_MACH_PISTACHIO) += pistachio/ platform-$(CONFIG_RALINK) += ralink/ platform-$(CONFIG_MIKROTIK_RB532) += rb532/ platform-$(CONFIG_SGI_IP22) += sgi-ip22/ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cee6087cd686..b783264243e4 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -513,35 +513,6 @@ config MACH_LOONGSON64 and Loongson-2F which will be removed), developed by the Institute of Computing Technology (ICT), Chinese Academy of Sciences (CAS). -config MACH_PISTACHIO - bool "IMG Pistachio SoC based boards" - select BOOT_ELF32 - select BOOT_RAW - select CEVT_R4K - select CLKSRC_MIPS_GIC - select COMMON_CLK - select CSRC_R4K - select DMA_NONCOHERENT - select GPIOLIB - select IRQ_MIPS_CPU - select MFD_SYSCON - select MIPS_CPU_SCACHE - select MIPS_GIC - select PINCTRL - select REGULATOR - select SYS_HAS_CPU_MIPS32_R2 - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_MIPS_CPS - select SYS_SUPPORTS_MULTITHREADING - select SYS_SUPPORTS_RELOCATABLE - select SYS_SUPPORTS_ZBOOT - select SYS_HAS_EARLY_PRINTK - select USE_GENERIC_EARLY_PRINTK_8250 - select USE_OF - help - This enables support for the IMG Pistachio SoC platform. - config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC @@ -1088,7 +1059,6 @@ source "arch/mips/ingenic/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lantiq/Kconfig" source "arch/mips/pic32/Kconfig" -source "arch/mips/pistachio/Kconfig" source "arch/mips/ralink/Kconfig" source "arch/mips/sgi-ip27/Kconfig" source "arch/mips/sibyte/Kconfig" diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index 188301164d9e..be96d35eb582 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 subdir-$(CONFIG_BMIPS_GENERIC) += brcm subdir-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon -subdir-$(CONFIG_MACH_PISTACHIO) += img subdir-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += img subdir-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += img subdir-$(CONFIG_MACH_INGENIC) += ingenic diff --git a/arch/mips/boot/dts/img/Makefile b/arch/mips/boot/dts/img/Makefile index 24f6bbeadd48..ebb47490b04b 100644 --- a/arch/mips/boot/dts/img/Makefile +++ b/arch/mips/boot/dts/img/Makefile @@ -2,6 +2,3 @@ dtb-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += boston.dtb dtb-$(CONFIG_FIT_IMAGE_FDT_MARDUK) += pistachio_marduk.dtb - -dtb-$(CONFIG_MACH_PISTACHIO) += pistachio_marduk.dtb -obj-$(CONFIG_MACH_PISTACHIO) += pistachio_marduk.dtb.o diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig deleted file mode 100644 index b9adf15ebbec..000000000000 --- a/arch/mips/configs/pistachio_defconfig +++ /dev/null @@ -1,316 +0,0 @@ -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_DEFAULT_HOSTNAME="localhost" -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_PREEMPT_VOLUNTARY=y -CONFIG_IKCONFIG=m -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=18 -CONFIG_CGROUPS=y -CONFIG_CGROUP_SCHED=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_CGROUP_FREEZER=y -CONFIG_NAMESPACES=y -CONFIG_USER_NS=y -CONFIG_BLK_DEV_INITRD=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_LZO is not set -# CONFIG_RD_LZ4 is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EMBEDDED=y -# CONFIG_COMPAT_BRK is not set -CONFIG_PROFILING=y -CONFIG_MACH_PISTACHIO=y -CONFIG_MIPS_CPS=y -CONFIG_NR_CPUS=4 -CONFIG_PM_DEBUG=y -CONFIG_PM_ADVANCED_DEBUG=y -CONFIG_CPU_IDLE=y -# CONFIG_MIPS_CPS_CPUIDLE is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_PARTITION_ADVANCED=y -# CONFIG_COMPACTION is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 -CONFIG_ZSMALLOC=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_DIAG is not set -CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_HTCP is not set -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_MD5SIG=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_IPV6_SIT=m -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_BRIDGE_NETFILTER is not set -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CT_NETLINK=y -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_DSCP=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -CONFIG_NETFILTER_XT_TARGET_SECMARK=y -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_DSCP=y -CONFIG_NETFILTER_XT_MATCH_POLICY=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NF_NAT_IPV4=m -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_MANGLE=y -CONFIG_NF_NAT_IPV6=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_FQ_CODEL=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_MARK=y -CONFIG_BT=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_HCIBTUSB=m -CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m -CONFIG_CFG80211=m -CONFIG_NL80211_TESTMODE=y -CONFIG_CFG80211_DEBUGFS=y -CONFIG_CFG80211_WEXT=y -CONFIG_MAC80211=m -CONFIG_MAC80211_LEDS=y -CONFIG_MAC80211_DEBUGFS=y -CONFIG_MAC80211_DEBUG_MENU=y -CONFIG_MAC80211_VERBOSE_DEBUG=y -CONFIG_RFKILL=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_DEBUG_DEVRES=y -CONFIG_CONNECTOR=y -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BLOCK=y -CONFIG_ZRAM=m -CONFIG_BLK_DEV_LOOP=y -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=m -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_MD=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_CRYPT=y -CONFIG_DM_VERITY=y -CONFIG_NETDEVICES=y -CONFIG_TUN=m -CONFIG_VETH=m -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SMSC is not set -CONFIG_STMMAC_ETH=y -# CONFIG_NET_VENDOR_VIA is not set -CONFIG_PPP=m -CONFIG_PPP_ASYNC=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_RTL8152=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=m -CONFIG_USB_NET_MCS7830=m -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -CONFIG_LIBERTAS_THINFIRM=m -CONFIG_RT2X00=m -CONFIG_RT2800USB=m -CONFIG_MAC80211_HWSIM=m -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_INPUT_EVDEV=y -# CONFIG_KEYBOARD_ATKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_HW_RANDOM=y -CONFIG_TCG_TPM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_IMG=y -CONFIG_I2C_STUB=m -CONFIG_SPI=y -CONFIG_SPI_BITBANG=m -CONFIG_SPI_IMG_SPFI=y -CONFIG_SPI_SPIDEV=y -CONFIG_DEBUG_GPIO=y -CONFIG_GPIO_SYSFS=y -CONFIG_POWER_SUPPLY=y -CONFIG_THERMAL=y -CONFIG_WATCHDOG=y -CONFIG_IMGPDC_WDT=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_RC_CORE=y -CONFIG_RC_DEVICES=y -CONFIG_IR_IMG=y -CONFIG_IR_IMG_NEC=y -CONFIG_IR_IMG_JVC=y -CONFIG_IR_IMG_SONY=y -CONFIG_IR_IMG_SHARP=y -CONFIG_IR_IMG_SANYO=y -CONFIG_IR_IMG_RC5=y -CONFIG_IR_IMG_RC6=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_FB=y -CONFIG_FB_MODE_HELPERS=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_HRTIMER=m -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m -# CONFIG_SND_SPI is not set -CONFIG_SND_USB_AUDIO=m -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEFAULT_PERSIST is not set -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_ACM=y -CONFIG_USB_STORAGE=y -CONFIG_USB_DWC2=y -CONFIG_USB_SERIAL=y -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_CP210X=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_QUALCOMM=m -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -CONFIG_USB_SERIAL_OPTION=m -CONFIG_MMC=y -CONFIG_MMC_BLOCK_MINORS=16 -CONFIG_MMC_TEST=m -CONFIG_MMC_DW=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_RTC_CLASS=y -CONFIG_DMADEVICES=y -CONFIG_IMG_MDC_DMA=y -CONFIG_STAGING=y -CONFIG_ASHMEM=y -# CONFIG_IOMMU_SUPPORT is not set -CONFIG_MEMORY=y -CONFIG_IIO=y -CONFIG_CC10001_ADC=y -CONFIG_PWM=y -CONFIG_PWM_IMG=y -CONFIG_PHY_PISTACHIO_USB=y -CONFIG_ANDROID=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_DNOTIFY is not set -CONFIG_FUSE_FS=m -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_ECRYPT_FS=y -CONFIG_HFSPLUS_FS=m -CONFIG_UBIFS_FS=y -CONFIG_SQUASHFS=y -CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_LZO=y -CONFIG_PSTORE=y -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_RAM=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_DEFAULT="utf8" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_SECURITY_YAMA=y -CONFIG_CRYPTO_AUTHENC=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_DES=y -CONFIG_CRC_CCITT=y -CONFIG_CRC_T10DIF=m -CONFIG_CRC7=m -# CONFIG_XZ_DEC_X86 is not set -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHEDSTATS=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_CREDENTIALS=y -CONFIG_FUNCTION_TRACER=y -CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_LKDTM=y -CONFIG_TEST_UDELAY=m diff --git a/arch/mips/pistachio/Kconfig b/arch/mips/pistachio/Kconfig deleted file mode 100644 index 9a0e06c95184..000000000000 --- a/arch/mips/pistachio/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config PISTACHIO_GPTIMER_CLKSRC - bool "Enable General Purpose Timer based clocksource" - depends on MACH_PISTACHIO - select CLKSRC_PISTACHIO - select MIPS_EXTERNAL_TIMER - help - This option enables a clocksource driver based on a Pistachio - SoC General Purpose external timer. - - If you want to enable the CPUFreq, you need to enable - this option. - - If you don't want to enable CPUFreq, you can leave this disabled. diff --git a/arch/mips/pistachio/Makefile b/arch/mips/pistachio/Makefile deleted file mode 100644 index 66f4af17fb66..000000000000 --- a/arch/mips/pistachio/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y += init.o irq.o time.o diff --git a/arch/mips/pistachio/Platform b/arch/mips/pistachio/Platform deleted file mode 100644 index c59de86dbddf..000000000000 --- a/arch/mips/pistachio/Platform +++ /dev/null @@ -1,6 +0,0 @@ -# -# IMG Pistachio SoC -# -load-$(CONFIG_MACH_PISTACHIO) += 0xffffffff80400000 -zload-$(CONFIG_MACH_PISTACHIO) += 0xffffffff81000000 -all-$(CONFIG_MACH_PISTACHIO) := uImage.gz diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c deleted file mode 100644 index e0bacfc3c6b4..000000000000 --- a/arch/mips/pistachio/init.c +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Pistachio platform setup - * - * Copyright (C) 2014 Google, Inc. - * Copyright (C) 2016 Imagination Technologies - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * Core revision register decoding - * Bits 23 to 20: Major rev - * Bits 15 to 8: Minor rev - * Bits 7 to 0: Maintenance rev - */ -#define PISTACHIO_CORE_REV_REG 0xB81483D0 -#define PISTACHIO_CORE_REV_A1 0x00100006 -#define PISTACHIO_CORE_REV_B0 0x00100106 - -const char *get_system_type(void) -{ - u32 core_rev; - const char *sys_type; - - core_rev = __raw_readl((const void *)PISTACHIO_CORE_REV_REG); - - switch (core_rev) { - case PISTACHIO_CORE_REV_B0: - sys_type = "IMG Pistachio SoC (B0)"; - break; - - case PISTACHIO_CORE_REV_A1: - sys_type = "IMG Pistachio SoC (A1)"; - break; - - default: - sys_type = "IMG Pistachio SoC"; - break; - } - - return sys_type; -} - -void __init *plat_get_fdt(void) -{ - if (fw_arg0 != -2) - panic("Device-tree not present"); - return (void *)fw_arg1; -} - -void __init plat_mem_setup(void) -{ - __dt_setup_arch(plat_get_fdt()); -} - -#define DEFAULT_CPC_BASE_ADDR 0x1bde0000 -#define DEFAULT_CDMM_BASE_ADDR 0x1bdd0000 - -phys_addr_t mips_cpc_default_phys_base(void) -{ - return DEFAULT_CPC_BASE_ADDR; -} - -phys_addr_t mips_cdmm_phys_base(void) -{ - return DEFAULT_CDMM_BASE_ADDR; -} - -static void __init mips_nmi_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); - memcpy(base, except_vec_nmi, 0x80); - flush_icache_range((unsigned long)base, - (unsigned long)base + 0x80); -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - extern char except_vec_ejtag_debug[]; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); - memcpy(base, except_vec_ejtag_debug, 0x80); - flush_icache_range((unsigned long)base, - (unsigned long)base + 0x80); -} - -void __init prom_init(void) -{ - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - - mips_cm_probe(); - mips_cpc_probe(); - register_cps_smp_ops(); - - pr_info("SoC Type: %s\n", get_system_type()); -} - -void __init device_tree_init(void) -{ - if (!initial_boot_params) - return; - - unflatten_and_copy_device_tree(); -} diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c deleted file mode 100644 index 437c3101ac45..000000000000 --- a/arch/mips/pistachio/irq.c +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Pistachio IRQ setup - * - * Copyright (C) 2014 Google, Inc. - */ - -#include -#include -#include - -#include -#include - -void __init arch_init_irq(void) -{ - pr_info("EIC is %s\n", cpu_has_veic ? "on" : "off"); - pr_info("VINT is %s\n", cpu_has_vint ? "on" : "off"); - - if (!cpu_has_veic) - mips_cpu_irq_init(); - - irqchip_init(); -} diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c deleted file mode 100644 index de64751dec40..000000000000 --- a/arch/mips/pistachio/time.c +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Pistachio clocksource/timer setup - * - * Copyright (C) 2014 Google, Inc. - */ - -#include -#include -#include -#include -#include - -#include -#include - -unsigned int get_c0_compare_int(void) -{ - return gic_get_c0_compare_int(); -} - -int get_c0_perfcount_int(void) -{ - return gic_get_c0_perfcount_int(); -} -EXPORT_SYMBOL_GPL(get_c0_perfcount_int); - -int get_c0_fdc_int(void) -{ - return gic_get_c0_fdc_int(); -} - -void __init plat_time_init(void) -{ - struct device_node *np; - struct clk *clk; - - of_clk_init(NULL); - timer_probe(); - - np = of_get_cpu_node(0, NULL); - if (!np) { - pr_err("Failed to get CPU node\n"); - return; - } - - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) { - pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); - return; - } - - mips_hpt_frequency = clk_get_rate(clk) / 2; - clk_put(clk); -} -- cgit v1.2.3-70-g09d2 From 3f66601ef3f3e336c1f8181f183001b58be62067 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Fri, 23 Jul 2021 10:25:43 +0800 Subject: MIPS: Make a alias for pistachio_defconfig For those who miss the old defconfig, make a alias to generic kernel. Signed-off-by: Jiaxun Yang Signed-off-by: Thomas Bogendoerfer --- arch/mips/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 4e942b7ef022..6eaeee3fb46c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -560,6 +560,9 @@ sead3micro_defconfig-y := micro32r2el_defconfig BOARDS=sead-3 legacy_defconfigs += xilfpga_defconfig xilfpga_defconfig-y := 32r2el_defconfig BOARDS=xilfpga +legacy_defconfigs += pistachio_defconfig +pistachio_defconfig-y := 32r2el_defconfig BOARDS=marduk + .PHONY: $(legacy_defconfigs) $(legacy_defconfigs): $(Q)$(MAKE) -f $(srctree)/Makefile $($@-y) -- cgit v1.2.3-70-g09d2 From 4d2ee1be4c2a5552f083b6d7db4be224f96313b5 Mon Sep 17 00:00:00 2001 From: Huilong Deng Date: Wed, 11 Aug 2021 12:36:15 +0800 Subject: MIPS: generic: Return true/false (not 1/0) from bool functions ./arch/mips/generic/board-ocelot.c:29:9-10: WARNING: return of 0/1 in function 'ocelot_detect' with return type bool Signed-off-by: Huilong Deng Signed-off-by: Thomas Bogendoerfer --- arch/mips/generic/board-ocelot.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/generic/board-ocelot.c b/arch/mips/generic/board-ocelot.c index c238e95190ac..7115410acb4f 100644 --- a/arch/mips/generic/board-ocelot.c +++ b/arch/mips/generic/board-ocelot.c @@ -26,13 +26,13 @@ static __init bool ocelot_detect(void) tlb_probe_hazard(); idx = read_c0_index(); if (idx < 0) - return 0; + return false; /* A TLB entry exists, lets assume its usable and check the CHIP ID */ rev = __raw_readl((void __iomem *)DEVCPU_GCB_CHIP_REGS_CHIP_ID); if ((rev & CHIP_ID_PART_ID) != OCELOT_PART_ID) - return 0; + return false; /* Copy command line from bootloader early for Initrd detection */ if (fw_arg0 < 10 && (fw_arg1 & 0xFFF00000) == 0x80000000) { @@ -44,7 +44,7 @@ static __init bool ocelot_detect(void) strcpy(arcs_cmdline, prom_argv[1]); } - return 1; + return true; } static void __init ocelot_earlyprintk_init(void) -- cgit v1.2.3-70-g09d2 From 8ce1162a396068d8e69a88f35562ef3f29d4ab4e Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:39 +0800 Subject: docs/zh_CN: add virt index translation Add virt to .../zh_CN/index and translate it into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/b28d3a530fe0c3635e7be2462fd14a4ae18f0220.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/index.rst | 2 +- Documentation/translations/zh_CN/virt/index.rst | 37 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/index.rst diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst index e0d51a167032..c311c8741e6f 100644 --- a/Documentation/translations/zh_CN/index.rst +++ b/Documentation/translations/zh_CN/index.rst @@ -102,6 +102,7 @@ TODOList: iio/index sound/index filesystems/index + virt/index TODOList: @@ -127,7 +128,6 @@ TODOList: * spi/index * w1/index * watchdog/index -* virt/index * input/index * hwmon/index * gpu/index diff --git a/Documentation/translations/zh_CN/virt/index.rst b/Documentation/translations/zh_CN/virt/index.rst new file mode 100644 index 000000000000..9e5df5b5de15 --- /dev/null +++ b/Documentation/translations/zh_CN/virt/index.rst @@ -0,0 +1,37 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/virt/index.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_index: + +=============== +Linux虚拟化支持 +=============== + +.. toctree:: + :maxdepth: 2 + +TODOLIST: + + kvm/index + uml/user_mode_linux_howto_v2 + paravirt_ops + guest-halt-polling + ne_overview + acrn/index + +.. only:: html and subproject + + Indices + ======= + + * :ref:`genindex` -- cgit v1.2.3-70-g09d2 From ccb00ddc88cf3953249cd9595df174ff863b18bd Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:40 +0800 Subject: docs/zh_CN: add virt paravirt_ops translation Translate Documentation/virt/paravirt_ops.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/abba361233e2a58999ef5d31c20f24370d7724f2.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/virt/index.rst | 3 +- .../translations/zh_CN/virt/paravirt_ops.rst | 41 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/paravirt_ops.rst diff --git a/Documentation/translations/zh_CN/virt/index.rst b/Documentation/translations/zh_CN/virt/index.rst index 9e5df5b5de15..b9b23bb88ffa 100644 --- a/Documentation/translations/zh_CN/virt/index.rst +++ b/Documentation/translations/zh_CN/virt/index.rst @@ -20,11 +20,12 @@ Linux虚拟化支持 .. toctree:: :maxdepth: 2 + paravirt_ops + TODOLIST: kvm/index uml/user_mode_linux_howto_v2 - paravirt_ops guest-halt-polling ne_overview acrn/index diff --git a/Documentation/translations/zh_CN/virt/paravirt_ops.rst b/Documentation/translations/zh_CN/virt/paravirt_ops.rst new file mode 100644 index 000000000000..06b122bc915d --- /dev/null +++ b/Documentation/translations/zh_CN/virt/paravirt_ops.rst @@ -0,0 +1,41 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/virt/paravirt_ops.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 陈飞杨 Feiyang Chen + 时奎亮 Alex Shi + +.. _cn_virt_paravirt_ops: + +============ +半虚拟化操作 +============ + +Linux提供了对不同管理程序虚拟化技术的支持。历史上,为了支持不同的虚拟机超级管理器 +(hypervisor,下文简称超级管理器),需要不同的二进制内核,这个限制已经被pv_ops移 +除了。Linux pv_ops是一个虚拟化API,它能够支持不同的管理程序。它允许每个管理程序 +优先于关键操作,并允许单一的内核二进制文件在所有支持的执行环境中运行,包括本机——没 +有任何管理程序。 + +pv_ops提供了一组函数指针,代表了与低级关键指令和各领域高级功能相对应的操作。 +pv-ops允许在运行时进行优化,在启动时对低级关键操作进行二进制修补。 + +pv_ops操作被分为三类: + +- 简单的间接调用 + 这些操作对应于高水平的函数,众所周知,间接调用的开销并不十分重要。 + +- 间接调用,允许用二进制补丁进行优化 + 通常情况下,这些操作对应于低级别的关键指令。它们被频繁地调用,并且是对性能关 + 键。开销是非常重要的。 + +- 一套用于手写汇编代码的宏程序 + 手写的汇编代码(.S文件)也需要半虚拟化,因为它们包括敏感指令或其中的一些代 + 码路径对性能非常关键。 -- cgit v1.2.3-70-g09d2 From 9c987b10fefa6472e49be3f0c6f5b9d9309c42bf Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:41 +0800 Subject: docs/zh_CN: add virt guest-halt-polling translation Translate Documentation/virt/guest-halt-polling.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/658e255eff55bfdadc1576107bf367a2e80b881a.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/virt/guest-halt-polling.rst | 87 ++++++++++++++++++++++ Documentation/translations/zh_CN/virt/index.rst | 2 +- 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/guest-halt-polling.rst diff --git a/Documentation/translations/zh_CN/virt/guest-halt-polling.rst b/Documentation/translations/zh_CN/virt/guest-halt-polling.rst new file mode 100644 index 000000000000..b798d1cf0b48 --- /dev/null +++ b/Documentation/translations/zh_CN/virt/guest-halt-polling.rst @@ -0,0 +1,87 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/virt/guest-halt-polling.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_guest-halt-polling: + +======================================== +客户机停机轮询机制(Guest halt polling) +======================================== + +cpuidle_haltpoll驱动,与haltpoll管理器一起,允许客户机vcpus在停机前轮询 +一定的时间。 + +这为物理机侧的轮询提供了以下好处: + + 1) 在执行轮询时,POLL标志被设置,这允许远程vCPU在执行唤醒时避免发送 + IPI(以及处理IPI的相关成本)。 + + 2) 可以避免虚拟机退出的成本。 + +客户机侧轮询的缺点是,即使在物理机中的其他可运行任务中也会进行轮询。 + +其基本逻辑如下。一个全局值,即guest_halt_poll_ns,是由用户配置的,表示允 +许轮询的最大时间量。这个值是固定的。 + +每个vcpu都有一个可调整的guest_halt_poll_ns("per-cpu guest_halt_poll_ns"), +它由算法响应事件进行调整(解释如下)。 + +模块参数 +======== + +haltpoll管理器有5个可调整的模块参数: + +1) guest_halt_poll_ns: + +轮询停机前执行的最大时间,以纳秒为单位。 + +默认值: 200000 + +2) guest_halt_poll_shrink: + +当唤醒事件发生在全局的guest_halt_poll_ns之后,用于缩减每个CPU的guest_halt_poll_ns +的划分系数。 + +默认值: 2 + +3) guest_halt_poll_grow: + +当事件发生在per-cpu guest_halt_poll_ns之后但在global guest_halt_poll_ns之前, +用于增长per-cpu guest_halt_poll_ns的乘法系数。 + +默认值: 2 + +4) guest_halt_poll_grow_start: + +在系统空闲的情况下,每个cpu guest_halt_poll_ns最终达到零。这个值设置了增长时的 +初始每cpu guest_halt_poll_ns。这个值可以从10000开始增加,以避免在最初的增长阶 +段出现失误。: + +10k, 20k, 40k, ... (例如,假设guest_halt_poll_grow=2). + +默认值: 50000 + +5) guest_halt_poll_allow_shrink: + +允许缩减的Bool参数。设置为N以避免它(一旦达到全局的guest_halt_poll_ns值,每CPU的 +guest_halt_poll_ns将保持高位)。 + +默认值: Y + +模块参数可以从Debugfs文件中设置,在:: + + /sys/module/haltpoll/parameters/ + +进一步说明 +========== + +- 在设置guest_halt_poll_ns参数时应该小心,因为一个大的值有可能使几乎是完全空闲机 + 器上的cpu使用率达到100%。 diff --git a/Documentation/translations/zh_CN/virt/index.rst b/Documentation/translations/zh_CN/virt/index.rst index b9b23bb88ffa..b94f6a3c2257 100644 --- a/Documentation/translations/zh_CN/virt/index.rst +++ b/Documentation/translations/zh_CN/virt/index.rst @@ -21,12 +21,12 @@ Linux虚拟化支持 :maxdepth: 2 paravirt_ops + guest-halt-polling TODOLIST: kvm/index uml/user_mode_linux_howto_v2 - guest-halt-polling ne_overview acrn/index -- cgit v1.2.3-70-g09d2 From e636a91584ad198f222f68a4ad61e27633976596 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:42 +0800 Subject: docs/zh_CN: add virt ne_overview translation Translate Documentation/virt/ne_overview.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/a6e1a2275a397d77957be30d1acdfeda9dc836f4.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/virt/index.rst | 2 +- .../translations/zh_CN/virt/ne_overview.rst | 88 ++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/ne_overview.rst diff --git a/Documentation/translations/zh_CN/virt/index.rst b/Documentation/translations/zh_CN/virt/index.rst index b94f6a3c2257..8e7713163962 100644 --- a/Documentation/translations/zh_CN/virt/index.rst +++ b/Documentation/translations/zh_CN/virt/index.rst @@ -22,12 +22,12 @@ Linux虚拟化支持 paravirt_ops guest-halt-polling + ne_overview TODOLIST: kvm/index uml/user_mode_linux_howto_v2 - ne_overview acrn/index .. only:: html and subproject diff --git a/Documentation/translations/zh_CN/virt/ne_overview.rst b/Documentation/translations/zh_CN/virt/ne_overview.rst new file mode 100644 index 000000000000..2455b371abea --- /dev/null +++ b/Documentation/translations/zh_CN/virt/ne_overview.rst @@ -0,0 +1,88 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/virt/ne_overview.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_ne_overview: + +============== +Nitro Enclaves +============== + +概述 +==== + +Nitro Enclaves(NE)是亚马逊弹性计算云(EC2)的一项新功能,允许客户在EC2实 +例中划分出孤立的计算环境[1]。 + +例如,一个处理敏感数据并在虚拟机中运行的应用程序,可以与在同一虚拟机中运行的 +其他应用程序分开。然后,这个应用程序在一个独立于主虚拟机的虚拟机中运行,即 +enclave。 + +一个enclave与催生它的虚拟机一起运行。这种设置符合低延迟应用的需要。为enclave +分配的资源,如内存和CPU,是从主虚拟机中分割出来的。每个enclave都被映射到一 +个运行在主虚拟机中的进程,该进程通过一个ioctl接口与NE驱动进行通信。 + +在这个意义上,有两个组成部分。 + +1. 一个enclave抽象进程——一个运行在主虚拟机客体中的用户空间进程,它使用NE驱动 +提供的ioctl接口来生成一个enclave虚拟机(这就是下面的2)。 + +有一个NE模拟的PCI设备暴露给主虚拟机。这个新的PCI设备的驱动被包含在NE驱动中。 + +ioctl逻辑被映射到PCI设备命令,例如,NE_START_ENCLAVE ioctl映射到一个enclave +启动PCI命令。然后,PCI设备命令被翻译成在管理程序方面采取的行动;也就是在运 +行主虚拟机的主机上运行的Nitro管理程序。Nitro管理程序是基于KVM核心技术的。 + +2. enclave本身——一个运行在与催生它的主虚拟机相同的主机上的虚拟机。内存和CPU +从主虚拟机中分割出来,专门用于enclave虚拟机。enclave没有连接持久性存储。 + +从主虚拟机中分割出来并给enclave的内存区域需要对齐2 MiB/1 GiB物理连续的内存 +区域(或这个大小的倍数,如8 MiB)。该内存可以通过使用hugetlbfs从用户空间分 +配[2][3]。一个enclave的内存大小需要至少64 MiB。enclave内存和CPU需要来自同 +一个NUMA节点。 + +一个enclave在专用的核心上运行。CPU 0及其同级别的CPU需要保持对主虚拟机的可用 +性。CPU池必须由具有管理能力的用户为NE目的进行设置。关于CPU池的格式,请看内核 +文档[4]中的cpu list部分。 + +enclave通过本地通信通道与主虚拟机进行通信,使用virtio-vsock[5]。主虚拟机有 +virtio-pci vsock模拟设备,而飞地虚拟机有virtio-mmio vsock模拟设备。vsock +设备使用eventfd作为信令。enclave虚拟机看到通常的接口——本地APIC和IOAPIC——从 +virtio-vsock设备获得中断。virtio-mmio设备被放置在典型的4 GiB以下的内存中。 + +在enclave中运行的应用程序需要和将在enclave虚拟机中运行的操作系统(如内核、 +ramdisk、init)一起被打包到enclave镜像中。enclave虚拟机有自己的内核并遵循标 +准的Linux启动协议[6]。 + +内核bzImage、内核命令行、ramdisk(s)是enclave镜像格式(EIF)的一部分;另外 +还有一个EIF头,包括元数据,如magic number、eif版本、镜像大小和CRC。 + +哈希值是为整个enclave镜像(EIF)、内核和ramdisk(s)计算的。例如,这被用来检 +查在enclave虚拟机中加载的enclave镜像是否是打算运行的那个。 + +这些加密测量包括在由Nitro超级管理器成的签名证明文件中,并进一步用来证明enclave +的身份;KMS是NE集成的服务的一个例子,它检查证明文件。 + +enclave镜像(EIF)被加载到enclave内存中,偏移量为8 MiB。enclave中的初始进程 +连接到主虚拟机的vsock CID和一个预定义的端口--9000,以发送一个心跳值--0xb7。这 +个机制用于在主虚拟机中检查enclave是否已经启动。主虚拟机的CID是3。 + +如果enclave虚拟机崩溃或优雅地退出,NE驱动会收到一个中断事件。这个事件会通过轮询 +通知机制进一步发送到运行在主虚拟机中的用户空间enclave进程。然后,用户空间enclave +进程就可以退出了。 + +[1] https://aws.amazon.com/ec2/nitro/nitro-enclaves/ +[2] https://www.kernel.org/doc/html/latest/admin-guide/mm/hugetlbpage.html +[3] https://lwn.net/Articles/807108/ +[4] https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html +[5] https://man7.org/linux/man-pages/man7/vsock.7.html +[6] https://www.kernel.org/doc/html/latest/x86/boot.html -- cgit v1.2.3-70-g09d2 From 8dda2eac96844aac6ed25eb490b061b16eaf2e64 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:43 +0800 Subject: docs/zh_CN: add virt acrn index translation Translate Documentation/virt/acrn/index.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/17a0dac5ecc5bdcc98160bdb028c6876ca38a6bc.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/virt/acrn/index.rst | 27 ++++++++++++++++++++++ Documentation/translations/zh_CN/virt/index.rst | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/acrn/index.rst diff --git a/Documentation/translations/zh_CN/virt/acrn/index.rst b/Documentation/translations/zh_CN/virt/acrn/index.rst new file mode 100644 index 000000000000..6061e790ee83 --- /dev/null +++ b/Documentation/translations/zh_CN/virt/acrn/index.rst @@ -0,0 +1,27 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../../disclaimer-zh_CN.rst + +:Original: Documentation/virt/acrn/index.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_acrn_index: + +============== +ACRN超级管理器 +============== + +.. toctree:: + :maxdepth: 1 + +TODOLIST: + + introduction + io-request + cpuid diff --git a/Documentation/translations/zh_CN/virt/index.rst b/Documentation/translations/zh_CN/virt/index.rst index 8e7713163962..f8dd13681341 100644 --- a/Documentation/translations/zh_CN/virt/index.rst +++ b/Documentation/translations/zh_CN/virt/index.rst @@ -23,12 +23,12 @@ Linux虚拟化支持 paravirt_ops guest-halt-polling ne_overview + acrn/index TODOLIST: kvm/index uml/user_mode_linux_howto_v2 - acrn/index .. only:: html and subproject -- cgit v1.2.3-70-g09d2 From ab03e49f13ca8be59c20d8e59c4a4bf1b6410a99 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:44 +0800 Subject: docs/zh_CN: add virt acrn introduction translation Translate Documentation/virt/acrn/introduction.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/667a6eb64820d2234d12a0c5dd5b642af16c0d99.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/virt/acrn/index.rst | 4 +- .../translations/zh_CN/virt/acrn/introduction.rst | 52 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/acrn/introduction.rst diff --git a/Documentation/translations/zh_CN/virt/acrn/index.rst b/Documentation/translations/zh_CN/virt/acrn/index.rst index 6061e790ee83..b8f502033455 100644 --- a/Documentation/translations/zh_CN/virt/acrn/index.rst +++ b/Documentation/translations/zh_CN/virt/acrn/index.rst @@ -20,8 +20,10 @@ ACRN超级管理器 .. toctree:: :maxdepth: 1 + introduction + TODOLIST: - introduction + io-request cpuid diff --git a/Documentation/translations/zh_CN/virt/acrn/introduction.rst b/Documentation/translations/zh_CN/virt/acrn/introduction.rst new file mode 100644 index 000000000000..7182415cb087 --- /dev/null +++ b/Documentation/translations/zh_CN/virt/acrn/introduction.rst @@ -0,0 +1,52 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../../disclaimer-zh_CN.rst + +:Original: Documentation/virt/acrn/introduction.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_acrn_introduction: + +ACRN超级管理器介绍 +================== + +ACRN超级管理器是一个第一类超级管理器,直接在裸机硬件上运行。它有一个特权管理虚拟机,称为服 +务虚拟机,用于管理用户虚拟机和进行I/O仿真。 + +ACRN用户空间是一个运行在服务虚拟机中的应用程序,它根据命令行配置为用户虚拟机仿真设备。 +ACRN管理程序服务模块(HSM)是服务虚拟机中的一个内核模块,为ACRN用户空间提供管理程序服 +务。 + +下图展示了该架构。 + +:: + + 服务端VM 用户端VM + +----------------------------+ | +------------------+ + | +--------------+ | | | | + | |ACRN用户空间 | | | | | + | +--------------+ | | | | + |-----------------ioctl------| | | | ... + |内核空间 +----------+ | | | | + | | HSM | | | | 驱动 | + | +----------+ | | | | + +--------------------|-------+ | +------------------+ + +---------------------hypercall----------------------------------------+ + | ACRN超级管理器 | + +----------------------------------------------------------------------+ + | 硬件 | + +----------------------------------------------------------------------+ + +ACRN用户空间为用户虚拟机分配内存,配置和初始化用户虚拟机使用的设备,加载虚拟引导程序, +初始化虚拟CPU状态,处理来自用户虚拟机的I/O请求访问。它使用ioctls来与HSM通信。HSM通过 +与ACRN超级管理器的hypercalls进行交互来实现管理服务。HSM向用户空间输出一个char设备接口 +(/dev/acrn_hsm)。 + +ACRN超级管理器是开源的,任何人都可以贡献。源码库在 +https://github.com/projectacrn/acrn-hypervisor。 -- cgit v1.2.3-70-g09d2 From f63c6894f6453e6eedb5f04a1f3d222773abd427 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:45 +0800 Subject: docs/zh_CN: add virt acrn io-request translation Translate Documentation/virt/acrn/io-request.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/291079265a8b0555de4d624d7d11fc5ac37a9422.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/virt/acrn/index.rst | 3 +- .../translations/zh_CN/virt/acrn/io-request.rst | 99 ++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/virt/acrn/io-request.rst diff --git a/Documentation/translations/zh_CN/virt/acrn/index.rst b/Documentation/translations/zh_CN/virt/acrn/index.rst index b8f502033455..b53976e20a34 100644 --- a/Documentation/translations/zh_CN/virt/acrn/index.rst +++ b/Documentation/translations/zh_CN/virt/acrn/index.rst @@ -21,9 +21,10 @@ ACRN超级管理器 :maxdepth: 1 introduction + io-request TODOLIST: - io-request + cpuid diff --git a/Documentation/translations/zh_CN/virt/acrn/io-request.rst b/Documentation/translations/zh_CN/virt/acrn/io-request.rst new file mode 100644 index 000000000000..4b4e7186d9a5 --- /dev/null +++ b/Documentation/translations/zh_CN/virt/acrn/io-request.rst @@ -0,0 +1,99 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../../disclaimer-zh_CN.rst + +:Original: Documentation/virt/acrn/io-request.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_acrn_io-request: + +I/O请求处理 +=========== + +客户虚拟机的I/O请求由超级管理器构建,由ACRN超级管理器服务模块分发到与I/O请求的地址范 +围相对应的I/O客户端。I/O请求处理的细节将在以下章节描述。 + +1. I/O请求 +---------- + +对于每个客户虚拟机,有一个共享的4KB字节的内存区域,用于超级管理器和服务虚拟机之间的 +I/O请求通信。一个I/O请求是一个256字节的结构体缓冲区,它是 "acrn_io_request" 结构 +体,当客户虚拟机中发生被困的I/O访问时,由超级管理器的I/O处理器填充。服务虚拟机中的 +ACRN用户空间首先分配一个4KB字节的页面,并将缓冲区的GPA(客户物理地址)传递给管理平 +台。缓冲区被用作16个I/O请求槽的数组,每个I/O请求槽为256字节。这个数组是按vCPU ID +索引的。 + +2. I/O客户端 +------------ + +一个I/O客户端负责处理客户虚拟机的I/O请求,其访问的GPA在一定范围内。每个客户虚拟机 +可以关联多个I/O客户端。每个客户虚拟机都有一个特殊的客户端,称为默认客户端,负责处理 +所有不在其他客户端范围内的I/O请求。ACRN用户空间充当每个客户虚拟机的默认客户端。 + +下面的图示显示了I/O请求共享缓冲区、I/O请求和I/O客户端之间的关系。 + +:: + + +------------------------------------------------------+ + | 服务VM | + |+--------------------------------------------------+ | + || +----------------------------------------+ | | + || | 共享页 ACRN用户空间 | | | + || | +-----------------+ +------------+ | | | + || +----+->| acrn_io_request |<-+ 默认 | | | | + || | | | +-----------------+ | I/O客户端 | | | | + || | | | | ... | +------------+ | | | + || | | | +-----------------+ | | | + || | +-|--------------------------------------+ | | + ||---|----|-----------------------------------------| | + || | | 内核 | | + || | | +----------------------+ | | + || | | | +-------------+ HSM | | | + || | +--------------+ | | | | + || | | | I/O客户端 | | | | + || | | | | | | | + || | | +-------------+ | | | + || | +----------------------+ | | + |+---|----------------------------------------------+ | + +----|-------------------------------------------------+ + | + +----|-------------------------------------------------+ + | +-+-----------+ | + | | I/O处理 | ACRN超级管理器 | + | +-------------+ | + +------------------------------------------------------+ + +3. I/O请求状态转换 +------------------ + +一个ACRN I/O请求的状态转换如下。 + +:: + + FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ... + +- FREE: 这个I/O请求槽是空的 +- PENDING: 在这个槽位上有一个有效的I/O请求正在等待 +- PROCESSING: 正在处理I/O请求 +- COMPLETE: 该I/O请求已被处理 + +处于COMPLETE或FREE状态的I/O请求是由超级管理器拥有的。HSM和ACRN用户空间负责处理其 +他的。 + +4. I/O请求的处理流程 +-------------------- + +a. 当客户虚拟机中发生被陷入的I/O访问时,超级管理器的I/O处理程序将把I/O请求填充为 + PENDING状态。 +b. 超级管理器向服务虚拟机发出一个向上调用,这是一个通知中断。 +c. upcall处理程序会安排一个工作者来调度I/O请求。 +d. 工作者寻找PENDING I/O请求,根据I/O访问的地址将其分配给不同的注册客户,将其 + 状态更新为PROCESSING,并通知相应的客户进行处理。 +e. 被通知的客户端处理指定的I/O请求。 +f. HSM将I/O请求状态更新为COMPLETE,并通过hypercalls通知超级管理器完成。 -- cgit v1.2.3-70-g09d2 From 3bf5548d8e9602ee01b9f39f3127b5933e9e8be0 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 09:26:46 +0800 Subject: docs/zh_CN: add virt acrn cpuid translation Translate Documentation/virt/acrn/cpuid.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/35730828bc65d3912ba27382d5d70ddacee7d8a5.1628212777.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/virt/acrn/cpuid.rst | 56 ++++++++++++++++++++++ .../translations/zh_CN/virt/acrn/index.rst | 5 -- 2 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 Documentation/translations/zh_CN/virt/acrn/cpuid.rst diff --git a/Documentation/translations/zh_CN/virt/acrn/cpuid.rst b/Documentation/translations/zh_CN/virt/acrn/cpuid.rst new file mode 100644 index 000000000000..6f7be545611b --- /dev/null +++ b/Documentation/translations/zh_CN/virt/acrn/cpuid.rst @@ -0,0 +1,56 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../../disclaimer-zh_CN.rst + +:Original: Documentation/virt/acrn/cpuid.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 时奎亮 Alex Shi + +.. _cn_virt_acrn_cpuid: + +============== +ACRN CPUID位域 +============== + +在ACRN超级管理器上运行的客户虚拟机可以使用CPUID检查其一些功能。 + +ACRN的cpuid函数是: + +函数: 0x40000000 + +返回:: + + eax = 0x40000010 + ebx = 0x4e524341 + ecx = 0x4e524341 + edx = 0x4e524341 + +注意,ebx,ecx和edx中的这个值对应于字符串“ACRNACRNACRN”。eax中的值对应于这个叶子 +中存在的最大cpuid函数,如果将来有更多的函数加入,将被更新。 + +函数: define ACRN_CPUID_FEATURES (0x40000001) + +返回:: + + ebx, ecx, edx + eax = an OR'ed group of (1 << flag) + +其中 ``flag`` 的定义如下: + +================================= =========== ================================ +标志 值 描述 +================================= =========== ================================ +ACRN_FEATURE_PRIVILEGED_VM 0 客户虚拟机是一个有特权的虚拟机 +================================= =========== ================================ + +函数: 0x40000010 + +返回:: + + ebx, ecx, edx + eax = (Virtual) TSC frequency in kHz. diff --git a/Documentation/translations/zh_CN/virt/acrn/index.rst b/Documentation/translations/zh_CN/virt/acrn/index.rst index b53976e20a34..34605d87f103 100644 --- a/Documentation/translations/zh_CN/virt/acrn/index.rst +++ b/Documentation/translations/zh_CN/virt/acrn/index.rst @@ -22,9 +22,4 @@ ACRN超级管理器 introduction io-request - -TODOLIST: - - - cpuid -- cgit v1.2.3-70-g09d2 From f4e60d9f1ba5fa40544ab967513e450fa44656d0 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:48 +0800 Subject: docs/zh_CN: add infiniband index translation Translate Documentation/infiniband/index.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/e3bca9e59f410fe62489e36c5b9a3fab78bc1421.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/index.rst | 2 +- .../translations/zh_CN/infiniband/index.rst | 40 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/index.rst diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst index c311c8741e6f..1b6a07c04c79 100644 --- a/Documentation/translations/zh_CN/index.rst +++ b/Documentation/translations/zh_CN/index.rst @@ -103,6 +103,7 @@ TODOList: sound/index filesystems/index virt/index + infiniband/index TODOList: @@ -117,7 +118,6 @@ TODOList: * hid/index * i2c/index * isdn/index -* infiniband/index * leds/index * netlabel/index * networking/index diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst new file mode 100644 index 000000000000..ebb1e20b7df4 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -0,0 +1,40 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/index.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_index: + +========== +infiniband +========== + +.. toctree:: + :maxdepth: 1 + +TODOLIST: + + core_locking + ipoib + opa_vnic + sysfs + tag_matching + user_mad + user_verbs + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` -- cgit v1.2.3-70-g09d2 From 312356129e5836bb6ae4780340325e1f46fda1e7 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:49 +0800 Subject: docs/zh_CN: add infiniband core_locking translation Translate Documentation/infiniband/core_locking.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/d035d79b2936be762bc001b3a53831f34f72cbb7.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/core_locking.rst | 115 +++++++++++++++++++++ .../translations/zh_CN/infiniband/index.rst | 3 +- 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/core_locking.rst diff --git a/Documentation/translations/zh_CN/infiniband/core_locking.rst b/Documentation/translations/zh_CN/infiniband/core_locking.rst new file mode 100644 index 000000000000..42f08038d44b --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/core_locking.rst @@ -0,0 +1,115 @@ + +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/core_locking.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_core_locking: + +================== +infiniband中间层锁 +================== + + 本指南试图明确infiniband中间层的锁假设。它描述了对位于中间层以下的低 + 级驱动程序和使用中间层的上层协议的要求。 + +睡眠和中断环境 +============== + + 除了以下异常情况,ib_device结构体中所有方法的低级驱动实现都可以睡眠。 + 这些异常情况是列表中的任意的方法: + + - create_ah + - modify_ah + - query_ah + - destroy_ah + - post_send + - post_recv + - poll_cq + - req_notify_cq + + 他们可能不可以睡眠,而且必须可以从任何上下文中调用。 + + 向上层协议使用者输出的相应函数: + + - rdma_create_ah + - rdma_modify_ah + - rdma_query_ah + - rdma_destroy_ah + - ib_post_send + - ib_post_recv + - ib_req_notify_cq + + 因此,在任何情况下都可以安全调用(它们)。 + + 此外,该函数 + + - ib_dispatch_event + + 被底层驱动用来通过中间层调度异步事件的“A”,也可以从任何上下文中安全调 + 用。 + +可重入性 +-------- + + 由低级驱动程序导出的ib_device结构体中的所有方法必须是完全可重入的。 + 即使使用同一对象的多个函数调用被同时运行,低级驱动程序也需要执行所有 + 必要的同步以保持一致性。 + + IB中间层不执行任何函数调用的序列化。 + + 因为低级驱动程序是可重入的,所以不要求上层协议使用者任何顺序执行。然 + 而,为了得到合理的结果,可能需要一些顺序。例如,一个使用者可以在多个 + CPU上同时安全地调用ib_poll_cq()。然而,不同的ib_poll_cq()调用之间 + 的工作完成信息的顺序没有被定义。 + +回调 +---- + + 低级驱动程序不得直接从与ib_device方法调用相同的调用链中执行回调。例 + 如,低级驱动程序不允许从post_send方法直接调用使用者的完成事件处理程 + 序。相反,低级驱动程序应该推迟这个回调,例如,调度一个tasklet来执行 + 这个回调。 + + 低层驱动负责确保同一CQ的多个完成事件处理程序不被同时调用。驱动程序必 + 须保证一个给定的CQ的事件处理程序在同一时间只有一个在运行。换句话说, + 以下情况是不允许的:: + + CPU1 CPU2 + + low-level driver -> + consumer CQ event callback: + /* ... */ + ib_req_notify_cq(cq, ...); + low-level driver -> + /* ... */ consumer CQ event callback: + /* ... */ + return from CQ event handler + + 完成事件和异步事件回调的运行环境没有被定义。 根据低级别的驱动程序,它可能是 + 进程上下文、softirq上下文或中断上下文。上层协议使用者可能不会在回调中睡眠。 + +热插拔 +------ + + 当一个低级驱动程序调用ib_register_device()时,它宣布一个设备已经 + 准备好供使用者使用,所有的初始化必须在这个调用之前完成。设备必须保 + 持可用,直到驱动对ib_unregister_device()的调用返回。 + + 低级驱动程序必须从进程上下文调用ib_register_device()和 + ib_unregister_device()。如果使用者在这些调用中回调到驱动程序,它 + 不能持有任何可能导致死锁的semaphores。 + + 一旦其结构体ib_client的add方法被调用,上层协议使用者就可以开始使用 + 一个IB设备。使用者必须在从移除方法返回之前完成所有的清理工作并释放 + 与设备相关的所有资源。 + + 使用者被允许在其添加和删除方法中睡眠。 diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index ebb1e20b7df4..cc00f31c77d0 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -22,9 +22,10 @@ infiniband .. toctree:: :maxdepth: 1 + core_locking + TODOLIST: - core_locking ipoib opa_vnic sysfs -- cgit v1.2.3-70-g09d2 From 88e37e3d4443d56e674a97a2d717935c23767adf Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:50 +0800 Subject: docs/zh_CN: add infiniband ipoib translation Translate Documentation/infiniband/ipoib.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/2d71cfe6b11568d9d9c665e829eaf680c249c94a.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 2 +- .../translations/zh_CN/infiniband/ipoib.rst | 111 +++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/ipoib.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index cc00f31c77d0..da5e2821f767 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -23,10 +23,10 @@ infiniband :maxdepth: 1 core_locking + ipoib TODOLIST: - ipoib opa_vnic sysfs tag_matching diff --git a/Documentation/translations/zh_CN/infiniband/ipoib.rst b/Documentation/translations/zh_CN/infiniband/ipoib.rst new file mode 100644 index 000000000000..56517ea5fe9d --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/ipoib.rst @@ -0,0 +1,111 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/ipoib.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_ipoib: + +========================= +infiniband上的IP(IPoIB) +========================= + + ib_ipoib驱动是IETF ipoib工作组发布的RFC 4391和4392所规定的 + infiniband上IP协议的一个实现。它是一个“本地”实现,即把接口类型设置为 + ARPHRD_INFINIBAND,硬件地址长度为20(早期的专有实现向内核伪装为以太网 + 接口)。 + +分区和P_Keys +============ + + 当IPoIB驱动被加载时,它会使用索引为0的P_Key给每个端口创建一个接口。要用 + 不同的P_Key创建一个接口,将所需的P_Key写入主接口的 + /sys/class/net//create_child文件里面。比如说:: + + echo 0x8001 > /sys/class/net/ib0/create_child + + 这将用P_Key 0x8001创建一个名为ib0.8001的接口。要删除一个子接口,使用 + ``delete_child`` 文件:: + + echo 0x8001 > /sys/class/net/ib0/delete_child + + 任何接口的P_Key都由“pkey”文件给出,而子接口的主接口在“parent”中。 + + 子接口的创建/删除也可以使用IPoIB的rtnl_link_ops来完成,使用两种 + 方式创建的子接口的行为是一样的。 + +数据报与连接模式 +================ + + IPoIB驱动支持两种操作模式:数据报和连接。模式是通过接口的 + /sys/class/net//mode文件设置和读取的。 + + 在数据报模式下,使用IB UD(不可靠数据报)传输,因此接口MTU等于IB L2 MTU + 减去IPoIB封装头(4字节)。例如,在一个典型的具有2K MTU的IB结构中,IPoIB + MTU将是2048 - 4 = 2044字节。 + + 在连接模式下,使用IB RC(可靠的连接)传输。连接模式利用IB传输的连接特性, + 允许MTU达到最大的IP包大小64K,这减少了处理大型UDP数据包、TCP段等所需的 + IP包数量,提高了大型信息的性能。 + + 在连接模式下,接口的UD QP仍被用于组播和与不支持连接模式的对等体的通信。 + 在这种情况下,ICMP PMTU数据包的RX仿真被用来使网络堆栈对这些邻居使用较 + 小的UD MTU。 + +无状态卸载 +========== + + 如果IB HW支持IPoIB无状态卸载,IPoIB会向网络堆栈广播TCP/IP校验和/或大量 + 传送(LSO)负载转移能力。 + + 大量传送(LSO)负载转移也已实现,可以使用ethtool调用打开/关闭。目前,LRO + 只支持具有校验和卸载能力的设备。 + + 无状态卸载只在数据报模式下支持。 + +中断管理 +======== + + 如果底层IB设备支持CQ事件管理,可以使用ethtool来设置中断缓解参数,从而减少 + 处理中断产生的开销。IPoIB的主要代码路径不使用TX完成信号的事件,所以只支持 + RX管理。 + +调试信息 +======== + + 通过将CONFIG_INFINIBAND_IPOIB_DEBUG设置为“y”来编译IPoIB驱动,跟踪信 + 息被编译到驱动中。通过将模块参数debug_level和mcast_debug_level设置为1来 + 打开它们。这些参数可以在运行时通过/sys/module/ib_ipoib/的文件来控制。 + + CONFIG_INFINIBAND_IPOIB_DEBUG也启用debugfs虚拟文件系统中的文件。通过挂 + 载这个文件系统,例如用:: + + mount -t debugfs none /sys/kernel/debug + + 可以从/sys/kernel/debug/ipoib/ib0_mcg等文件中获得关于多播组的统计数据。 + + 这个选项对性能的影响可以忽略不计,所以在正常运行时,在debug_level设置为 + 0的情况下启用这个选项是安全的。 + + CONFIG_INFINIBAND_IPOIB_DEBUG_DATA当data_debug_level设置为1时,可以 + 在数据路径中启用更多的调试输出。 然而,即使禁用输出,启用这个配置选项也 + 会影响性能,因为它在快速路径中增加了测试。 + +引用 +==== + + 在InfiniBand上传输IP(IPoIB)(RFC 4391)。 + http://ietf.org/rfc/rfc4391.txt + + infiniband上的IP:上的IP架构(RFC 4392)。 + http://ietf.org/rfc/rfc4392.txt + + infiniband上的IP: 连接模式 (RFC 4755) + http://ietf.org/rfc/rfc4755.txt -- cgit v1.2.3-70-g09d2 From e7c640961a2efa93979128645172db7ce26a8d87 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:51 +0800 Subject: docs/zh_CN: add infiniband opa_vnic translation Translate Documentation/infiniband/opa_vnic.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/828550a6fb7fded8172c123c37d4c643d2593e53.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 2 +- .../translations/zh_CN/infiniband/opa_vnic.rst | 156 +++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/opa_vnic.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index da5e2821f767..a933e3c6981d 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -24,10 +24,10 @@ infiniband core_locking ipoib + opa_vnic TODOLIST: - opa_vnic sysfs tag_matching user_mad diff --git a/Documentation/translations/zh_CN/infiniband/opa_vnic.rst b/Documentation/translations/zh_CN/infiniband/opa_vnic.rst new file mode 100644 index 000000000000..12b147fbf792 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/opa_vnic.rst @@ -0,0 +1,156 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/opa_vnic.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_opa_vnic: + +============================================= +英特尔全路径(OPA)虚拟网络接口控制器(VNIC) +============================================= + +英特尔全路径(OPA)虚拟网络接口控制器(VNIC)功能通过封装HFI节点之间的以 +太网数据包,支持Omni-Path结构上的以太网功能。 + +体系结构 +======== + +Omni-Path封装的以太网数据包的交换模式涉及Omni-Path结构拓扑上覆盖的一个或 +多个虚拟以太网交换机。Omni-Path结构上的HFI节点的一个子集被允许在特定的虚 +拟以太网交换机上交换封装的以太网数据包。虚拟以太网交换机是通过配置结构上的 +HFI节点实现的逻辑抽象,用于生成和处理报头。在最简单的配置中,整个结构的所有 +HFI节点通过一个虚拟以太网交换机交换封装的以太网数据包。一个虚拟以太网交换机, +实际上是一个独立的以太网网络。该配置由以太网管理器(EM)执行,它是可信的结 +构管理器(FM)应用程序的一部分。HFI节点可以有多个VNIC,每个连接到不同的虚 +拟以太网交换机。下图介绍了两个虚拟以太网交换机与两个HFI节点的情况:: + + +-------------------+ + | 子网/ | + | 以太网 | + | 管理 | + +-------------------+ + / / + / / + / / + / / + +-----------------------------+ +------------------------------+ + | 虚拟以太网切换 | | 虚拟以太网切换 | + | +---------+ +---------+ | | +---------+ +---------+ | + | | VPORT | | VPORT | | | | VPORT | | VPORT | | + +--+---------+----+---------+-+ +-+---------+----+---------+---+ + | \ / | + | \ / | + | \/ | + | / \ | + | / \ | + +-----------+------------+ +-----------+------------+ + | VNIC | VNIC | | VNIC | VNIC | + +-----------+------------+ +-----------+------------+ + | HFI | | HFI | + +------------------------+ +------------------------+ + + +Omni-Path封装的以太网数据包格式如下所述。 + +==================== ================================ +位 域 +==================== ================================ +Quad Word 0: +0-19 SLID (低20位) +20-30 长度 (以四字为单位) +31 BECN 位 +32-51 DLID (低20位) +52-56 SC (服务级别) +57-59 RC (路由控制) +60 FECN 位 +61-62 L2 (=10, 16B 格式) +63 LT (=1, 链路传输头 Flit) + +Quad Word 1: +0-7 L4 type (=0x78 ETHERNET) +8-11 SLID[23:20] +12-15 DLID[23:20] +16-31 PKEY +32-47 熵 +48-63 保留 + +Quad Word 2: +0-15 保留 +16-31 L4 头 +32-63 以太网数据包 + +Quad Words 3 to N-1: +0-63 以太网数据包 (pad拓展) + +Quad Word N (last): +0-23 以太网数据包 (pad拓展) +24-55 ICRC +56-61 尾 +62-63 LT (=01, 链路传输尾 Flit) +==================== ================================ + +以太网数据包在传输端被填充,以确保VNIC OPA数据包是四字对齐的。“尾”字段 +包含填充的字节数。在接收端,“尾”字段被读取,在将数据包向上传递到网络堆 +栈之前,填充物被移除(与ICRC、尾和OPA头一起)。 + +L4头字段包含VNIC端口所属的虚拟以太网交换机ID。在接收端,该字段用于将收 +到的VNIC数据包去多路复用到不同的VNIC端口。 + +驱动设计 +======== + +英特尔OPA VNIC的软件设计如下图所示。OPA VNIC功能有一个依赖于硬件的部分 +和一个独立于硬件的部分。 + +对IB设备分配和释放RDMA netdev设备的支持已经被加入。RDMA netdev支持与 +网络堆栈的对接,从而创建标准的网络接口。OPA_VNIC是一个RDMA netdev设备 +类型。 + +依赖于HW的VNIC功能是HFI1驱动的一部分。它实现了分配和释放OPA_VNIC RDMA +netdev的动作。它涉及VNIC功能的HW资源分配/管理。它与网络堆栈接口并实现所 +需的net_device_ops功能。它在传输路径中期待Omni-Path封装的以太网数据包, +并提供对它们的HW访问。在将数据包向上传递到网络堆栈之前,它把Omni-Path头 +从接收的数据包中剥离。它还实现了RDMA netdev控制操作。 + +OPA VNIC模块实现了独立于硬件的VNIC功能。它由两部分组成。VNIC以太网管理 +代理(VEMA)作为一个IB客户端向IB核心注册,并与IB MAD栈接口。它与以太网 +管理器(EM)和VNIC netdev交换管理信息。VNIC netdev部分分配和释放OPA_VNIC +RDMA netdev设备。它在需要时覆盖由依赖HW的VNIC驱动设置的net_device_ops函数, +以适应任何控制操作。它还处理以太网数据包的封装,在传输路径中使用Omni-Path头。 +对于每个VNIC接口,封装所需的信息是由EM通过VEMA MAD接口配置的。它还通过调用 +RDMA netdev控制操作将任何控制信息传递给依赖于HW的驱动程序:: + + +-------------------+ +----------------------+ + | | | Linux | + | IB MAD | | 网络 | + | | | 栈 | + +-------------------+ +----------------------+ + | | | + | | | + +----------------------------+ | + | | | + | OPA VNIC 模块 | | + | (OPA VNIC RDMA Netdev | | + | & EMA 函数) | | + | | | + +----------------------------+ | + | | + | | + +------------------+ | + | IB 核心 | | + +------------------+ | + | | + | | + +--------------------------------------------+ + | | + | HFI1 驱动和 VNIC 支持 | + | | + +--------------------------------------------+ -- cgit v1.2.3-70-g09d2 From ccbad6a5216bd45a725feeafab4c05744538e0c9 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:52 +0800 Subject: docs/zh_CN: add infiniband sysfs translation Translate Documentation/infiniband/sysfs.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/dbd542628b71160f7bddd33a76cb77b127a9b826.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 2 +- .../translations/zh_CN/infiniband/sysfs.rst | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/sysfs.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index a933e3c6981d..1d208d50b0c2 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -25,10 +25,10 @@ infiniband core_locking ipoib opa_vnic + sysfs TODOLIST: - sysfs tag_matching user_mad user_verbs diff --git a/Documentation/translations/zh_CN/infiniband/sysfs.rst b/Documentation/translations/zh_CN/infiniband/sysfs.rst new file mode 100644 index 000000000000..e9a48b0b2ba6 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/sysfs.rst @@ -0,0 +1,21 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/sysfs.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_sysfs: + +========= +Sysfs文件 +========= + +sysfs接口已移至 +Documentation/ABI/stable/sysfs-class-infiniband. -- cgit v1.2.3-70-g09d2 From cc420b883b1fa69990d6b44ebc91831066eb6bf3 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:53 +0800 Subject: docs/zh_CN: add infiniband tag_matching translation Translate Documentation/infiniband/tag_matching.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/eaed122a0e5d0e3312cf5a495022a9d0be42a831.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 2 +- .../translations/zh_CN/infiniband/tag_matching.rst | 63 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/tag_matching.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index 1d208d50b0c2..c273088b8686 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -26,10 +26,10 @@ infiniband ipoib opa_vnic sysfs + tag_matching TODOLIST: - tag_matching user_mad user_verbs diff --git a/Documentation/translations/zh_CN/infiniband/tag_matching.rst b/Documentation/translations/zh_CN/infiniband/tag_matching.rst new file mode 100644 index 000000000000..19b99587b862 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/tag_matching.rst @@ -0,0 +1,63 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/tag_matching.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_tag_matching: + +============ +标签匹配逻辑 +============ + +MPI标准定义了一套规则,称为标签匹配,用于将源发送操作与目的接收匹配。以下参数必 +须与以下源和目的参数相匹配: + +* 沟通者 +* 用户标签--通配符(wild card)可由接收方指定 +* 来源等级--通配符可由接收方指定 +* 目的地等级 – wild + +排序规则要求,当一对以上的发送和接收消息信封可能匹配时,包括最早发布-发送和最早 +发布-接收的一对是必须用来满足匹配操作的一对。然而,这并不意味着标签是按照它们被 +创建的顺序消耗的,例如,如果早期的标签不能用来满足匹配规则,那么后来生成的标签 +可能被消耗。 + +当消息从发送方发送到接收方时,通信库可能试图在相应的匹配接收被发布之后或之前处 +理该操作。如果匹配的接收被发布,这就是一个预期的消息,否则就被称为一个意外的消 +息。实现时经常为这两种不同的匹配实例使用不同的匹配方案。 + +为了减少MPI库的内存占用,MPI实现通常使用两种不同的协议来实现这一目的: + +1. Eager协议--当发送方处理完发送时,完整的信息就会被发送。在send_cq中会收到 +一个完成发送的通知,通知缓冲区可以被重新使用。 + +2. Rendezvous协议--发送方在第一次通知接收方时发送标签匹配头,也许还有一部分 +数据。当相应的缓冲区被发布时,响应者将使用头中的信息,直接向匹配的缓冲区发起 +RDMA读取操作。为了使缓冲区得到重用,需要收到一个fin消息。 + +标签匹配的实现 +============== + +使用的匹配对象有两种类型,即发布的接收列表和意外消息列表。应用程序通过调用发布 +的接收列表中的MPI接收例程发布接收缓冲区,并使用MPI发送例程发布发送消息。发布的 +接收列表的头部可以由硬件来维护,而软件则要对这个列表进行跟踪。 + +当发送开始并到达接收端时,如果没有为这个到达的消息预先发布接收,它将被传递给软 +件并被放在意外(unexpect)消息列表中。否则,将对该匹配进行处理,包括交会处理, +如果合适的话,将数据传送到指定的接收缓冲区。这允许接收方MPI标签匹配与计算重叠。 + +当一个接收信息被发布时,通信库将首先检查软件的意外信息列表,以寻找一个匹配的接 +收信息。如果找到一个匹配的,数据就会被送到用户缓冲区,使用一个软件控制的协议。 +UCX的实现根据数据大小,使用急切或交会协议。如果没有找到匹配,整个预置的接收列 +表由硬件维护,并且有空间在这个列表中增加一个预置的接收,这个接收被传递给硬件。 +软件要对这个列表进行跟踪,以帮助处理MPI取消操作。此外,由于硬件和软件在标签匹 +配操作方面预计不会紧密同步,这个影子列表被用来检测预先发布的接收被传递到硬件的 +情况,因为匹配的意外消息正在从硬件传递到软件。 -- cgit v1.2.3-70-g09d2 From 0265e6ee2c5868a3efb7e9b49ccbdb51fd1c7f27 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:54 +0800 Subject: docs/zh_CN: add infiniband user_mad translation Translate Documentation/infiniband/user_mad.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/8859ef2b40b380d7db7548f2e6a2d6fd5397062d.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 2 +- .../translations/zh_CN/infiniband/user_mad.rst | 164 +++++++++++++++++++++ 2 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/infiniband/user_mad.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index c273088b8686..55645171a675 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -27,10 +27,10 @@ infiniband opa_vnic sysfs tag_matching + user_mad TODOLIST: - user_mad user_verbs .. only:: subproject and html diff --git a/Documentation/translations/zh_CN/infiniband/user_mad.rst b/Documentation/translations/zh_CN/infiniband/user_mad.rst new file mode 100644 index 000000000000..d9ab2edfb559 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/user_mad.rst @@ -0,0 +1,164 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/user_mad.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_user_mad: + +=============== +用户空间MAD访问 +=============== + +设备文件 +======== + + 每个InfiniBand设备的每个端口都有一个“umad”设备和一个“issm”设备连接。 + 例如,一个双端口的HCA将有两个umad设备和两个issm设备,而一个交换机将 + 有每个类型的一个设备(对于交换机端口0)。 + +创建MAD代理 +=========== + + 一个MAD代理可以通过填写一个结构体ib_user_mad_reg_req来创建,然后在 + 适当的设备文件的文件描述符上调用IB_USER_MAD_REGISTER_AGENT ioctl。 + 如果注册请求成功,结构体中会返回一个32位的ID。比如说:: + + struct ib_user_mad_reg_req req = { /* ... */ }; + ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req); + if (!ret) + my_agent = req.id; + else + perror("agent register"); + + 代理可以通过IB_USER_MAD_UNREGISTER_AGENT ioctl取消注册。另外,所有 + 通过文件描述符注册的代理在描述符关闭时将被取消注册。 + + 2014 + 现在提供了一个新的注册IOctl,允许在注册时提供额外的字段。这个注册 + 调用的用户隐含了对pkey_index的使用(见下文)。现在提供了一个新的 + 注册IOctl,允许在注册时提供额外的字段。这个注册调用的用户隐含了对 + pkey_index的使用(见下文)。 + +接收MADs +======== + + 使用read()接收MAD。现在接收端支持RMPP。传给read()的缓冲区必须至少是 + 一个struct ib_user_mad + 256字节。比如说: + + 如果传递的缓冲区不足以容纳收到的MAD(RMPP),errno被设置为ENOSPC,需 + 要的缓冲区长度被设置在mad.length中。 + + 正常MAD(非RMPP)的读取示例:: + + struct ib_user_mad *mad; + mad = malloc(sizeof *mad + 256); + ret = read(fd, mad, sizeof *mad + 256); + if (ret != sizeof mad + 256) { + perror("read"); + free(mad); + } + + RMPP读取示例:: + + struct ib_user_mad *mad; + mad = malloc(sizeof *mad + 256); + ret = read(fd, mad, sizeof *mad + 256); + if (ret == -ENOSPC)) { + length = mad.length; + free(mad); + mad = malloc(sizeof *mad + length); + ret = read(fd, mad, sizeof *mad + length); + } + if (ret < 0) { + perror("read"); + free(mad); + } + + 除了实际的MAD内容外,其他结构体ib_user_mad字段将被填入收到的MAD的信 + 息。例如,远程LID将在mad.lid中。 + + 如果发送超时,将产生一个接收,mad.status设置为ETIMEDOUT。否则,当一个 + MAD被成功接收后,mad.status将是0。 + + poll()/select()可以用来等待一个MAD可以被读取。 + + poll()/select()可以用来等待,直到可以读取一个MAD。 + +发送MADs +======== + + MADs是用write()发送的。发送的代理ID应该填入MAD的id字段,目的地LID应该 + 填入lid字段,以此类推。发送端确实支持RMPP,所以可以发送任意长度的MAD。 + 比如说:: + + struct ib_user_mad *mad; + + mad = malloc(sizeof *mad + mad_length); + + /* fill in mad->data */ + + mad->hdr.id = my_agent; /* req.id from agent registration */ + mad->hdr.lid = my_dest; /* in network byte order... */ + /* etc. */ + + ret = write(fd, &mad, sizeof *mad + mad_length); + if (ret != sizeof *mad + mad_length) + perror("write"); + +交换IDs +======= + + umad设备的用户可以在发送的MAD中使用交换ID字段的低32位(也就是网络字节顺序中 + 最小有效的一半字段)来匹配请求/响应对。上面的32位是保留给内核使用的,在发送 + MAD之前会被改写。 + +P_Key索引处理 +============= + + 旧的ib_umad接口不允许为发送的MAD设置P_Key索引,也没有提供获取接收的MAD的 + P_Key索引的方法。一个带有pkey_index成员的struct ib_user_mad_hdr的新布局已 + 经被定义;然而,为了保持与旧的应用程序的二进制兼容性,除非在文件描述符被用于 + 其他用途之前调用IB_USER_MAD_ENABLE_PKEY或IB_USER_MAD_REGISTER_AGENT2 ioctl + 之一,否则不会使用这种新布局。 + + 在2008年9月,IB_USER_MAD_ABI_VERSION将被增加到6,默认使用新的ib_user_mad_hdr + 结构布局,并且IB_USER_MAD_ENABLE_PKEY ioctl将被删除。 + +设置IsSM功能位 +============== + + 要为一个端口设置IsSM功能位,只需打开相应的issm设备文件。如果IsSM位已经被设置,那 + 么打开调用将阻塞,直到该位被清除(或者如果O_NONBLOCK标志被传递给open(),则立即返 + 回,errno设置为EAGAIN)。当issm文件被关闭时,IsSM位将被清除。在issm文件上不能进 + 行任何读、写或其他操作。 + +/dev文件 +======== + +为了用 udev自动创建相应的字符设备文件,一个类似:: + + KERNEL=="umad*", NAME="infiniband/%k" + KERNEL=="issm*", NAME="infiniband/%k" + + 的规则可以被使用。它将创建节点的名字:: + + /dev/infiniband/umad0 + /dev/infiniband/issm0 + + 为第一个端口,以此类推。与这些设备相关的infiniband设备和端口可以从以下文件中确定:: + + /sys/class/infiniband_mad/umad0/ibdev + /sys/class/infiniband_mad/umad0/port + + 和:: + + /sys/class/infiniband_mad/issm0/ibdev + /sys/class/infiniband_mad/issm0/port -- cgit v1.2.3-70-g09d2 From 4d488433dc4071fd55fa1d65f16f81dd149c9cda Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Fri, 6 Aug 2021 10:58:55 +0800 Subject: docs/zh_CN: add infiniband user_verbs translation Translate Documentation/infiniband/user_verbs.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Reviewed-by: Puyu Wang Link: https://lore.kernel.org/r/b7c1577cf9758943bff933c46200c7dff1e1c6e0.1628218477.git.siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/infiniband/index.rst | 3 +- .../translations/zh_CN/infiniband/user_verbs.rst | 72 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 Documentation/translations/zh_CN/infiniband/user_verbs.rst diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst index 55645171a675..5634cc48379f 100644 --- a/Documentation/translations/zh_CN/infiniband/index.rst +++ b/Documentation/translations/zh_CN/infiniband/index.rst @@ -28,10 +28,9 @@ infiniband sysfs tag_matching user_mad + user_verbs -TODOLIST: - user_verbs .. only:: subproject and html diff --git a/Documentation/translations/zh_CN/infiniband/user_verbs.rst b/Documentation/translations/zh_CN/infiniband/user_verbs.rst new file mode 100644 index 000000000000..970bc1a4e396 --- /dev/null +++ b/Documentation/translations/zh_CN/infiniband/user_verbs.rst @@ -0,0 +1,72 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/infiniband/user_verbs.rst + +:翻译: + + 司延腾 Yanteng Si + +:校译: + + 王普宇 Puyu Wang + 时奎亮 Alex Shi + +.. _cn_infiniband_user_verbs: + +================= +用户空间verbs访问 +================= + + ib_uverbs模块,通过启用CONFIG_INFINIBAND_USER_VERBS构建,使用户空间 + 通过“verbs”直接访问IB硬件,如InfiniBand架构规范第11章所述。 + + 要使用verbs,需要libibverbs库,可从https://github.com/linux-rdma/rdma-core。 + libibverbs包含一个独立于设备的API,用于使用ib_uverbs接口。libibverbs + 还需要为你的InfiniBand硬件提供适当的独立于设备的内核和用户空间驱动。例如, + 要使用Mellanox HCA,你需要安装ib_mthca内核模块和libmthca用户空间驱动。 + +用户-内核通信 +============= + + 用户空间通过/dev/infiniband/uverbsN字符设备与内核进行慢速路径、资源管理 + 操作的通信。快速路径操作通常是通过直接写入硬件寄存器mmap()到用户空间来完成 + 的,没有系统调用或上下文切换到内核。 + + 命令是通过在这些设备文件上的write()s发送给内核的。ABI在 + drivers/infiniband/include/ib_user_verbs.h中定义。需要内核响应的命令的结 + 构包含一个64位字段,用来传递一个指向输出缓冲区的指针。状态作为write()系统调 + 用的返回值被返回到用户空间。 + +资源管理 +======== + + 由于所有IB资源的创建和销毁都是通过文件描述符传递的命令完成的,所以内核可以跟 + 踪那些被附加到给定用户空间上下文的资源。ib_uverbs模块维护着idr表,用来在 + 内核指针和不透明的用户空间句柄之间进行转换,这样内核指针就不会暴露给用户空间, + 而用户空间也无法欺骗内核去跟踪一个假的指针。 + + 这也允许内核在一个进程退出时进行清理,并防止一个进程触及另一个进程的资源。 + +内存固定 +======== + + 直接的用户空间I/O要求与作为潜在I/O目标的内存区域保持在同一物理地址上。ib_uverbs + 模块通过get_user_pages()和put_page()调用来管理内存区域的固定和解除固定。它还核 + 算进程的pinned_vm中被固定的内存量,并检查非特权进程是否超过其RLIMIT_MEMLOCK限制。 + + 被多次固定的页面在每次被固定时都会被计数,所以pinned_vm的值可能会高估一个进程所 + 固定的页面数量。 + +/dev文件 +======== + + 要想用udev自动创建适当的字符设备文件,可以采用如下规则:: + + KERNEL=="uverbs*", NAME="infiniband/%k" + + 可以使用。 这将创建设备节点,名为:: + + /dev/infiniband/uverbs0 + + 等等。由于InfiniBand的用户空间verbs对于非特权进程来说应该是安全的,因此在udev规 + 则中加入适当的MODE或GROUP可能是有用的。 -- cgit v1.2.3-70-g09d2 From 27f373cb5c9805d1e921ec9c5faf738ecf3fd989 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 5 Aug 2021 00:27:39 +0800 Subject: Documentation/features/vm: riscv supports THP now After commit e88b333142e4 ("riscv: mm: add THP support on 64-bit"), riscv can support THP. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20210805002739.23f44d2d@xhacker Signed-off-by: Jonathan Corbet --- Documentation/features/vm/THP/arch-support.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/features/vm/THP/arch-support.txt b/Documentation/features/vm/THP/arch-support.txt index e8238cb2a4da..7dbd6967b37e 100644 --- a/Documentation/features/vm/THP/arch-support.txt +++ b/Documentation/features/vm/THP/arch-support.txt @@ -22,7 +22,7 @@ | openrisc: | .. | | parisc: | TODO | | powerpc: | ok | - | riscv: | TODO | + | riscv: | ok | | s390: | ok | | sh: | .. | | sparc: | ok | -- cgit v1.2.3-70-g09d2 From 191cf329f109df86d93f7782c3289b50bca15260 Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Sat, 31 Jul 2021 10:55:13 +0200 Subject: doc: align Italian translation Translation for the following patches commit 0ca0d55526d3 ("docs/core-api: Consistent code style") commit 9912d0bb9dee ("docs: process: submitting-patches.rst: avoid using ReST :doc:`foo` markup") commit 6349469a4f3c ("Documentation/submitting-patches: Document RESEND tag on patches") commit dbbe7c962c3a ("docs: networking: drop special stable handling") commit 7f3f7bfbbe02 ("docs: kernel-hacking: hacking.rst: avoid using ReST :doc:`foo` markup") commit 6ab0493dfc62 ("deprecated.rst: Include details on "no_hash_pointers" ") commit 77167b966b7e ("docs: submitting-patches: clarify the role of LKML ") Signed-off-by: Federico Vaga Link: https://lore.kernel.org/r/20210731085513.11820-1-federico.vaga@vaga.pv.it Signed-off-by: Jonathan Corbet --- .../it_IT/core-api/symbol-namespaces.rst | 26 +++++----- .../translations/it_IT/kernel-hacking/hacking.rst | 4 +- .../translations/it_IT/process/deprecated.rst | 8 +-- .../it_IT/process/stable-kernel-rules.rst | 6 --- .../it_IT/process/submitting-patches.rst | 57 ++++++++++++---------- 5 files changed, 51 insertions(+), 50 deletions(-) diff --git a/Documentation/translations/it_IT/core-api/symbol-namespaces.rst b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst index aa851a57a4b0..42f5d04e38ec 100644 --- a/Documentation/translations/it_IT/core-api/symbol-namespaces.rst +++ b/Documentation/translations/it_IT/core-api/symbol-namespaces.rst @@ -42,15 +42,15 @@ nomi: EXPORT_SYMBOL_NS() ed EXPORT_SYMBOL_NS_GPL(). Queste macro richiedono un argomento aggiuntivo: lo spazio dei nomi. Tenete presente che per via dell'espansione delle macro questo argomento deve essere un simbolo di preprocessore. Per esempio per esportare il -simbolo `usb_stor_suspend` nello spazio dei nomi `USB_STORAGE` usate:: +simbolo ``usb_stor_suspend`` nello spazio dei nomi ``USB_STORAGE`` usate:: EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce -rappresentata dalla struttura `kernel_symbol` che avrà il campo -`namespace` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio -dei nomi avrà questo campo impostato a `NULL`. Non esiste uno spazio dei nomi -di base. Il programma `modpost` e il codice in kernel/module.c usano lo spazio +rappresentata dalla struttura ``kernel_symbol`` che avrà il campo +``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio +dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi +di base. Il programma ``modpost`` e il codice in kernel/module.c usano lo spazio dei nomi, rispettivamente, durante la compilazione e durante il caricamento di un modulo. @@ -65,7 +65,7 @@ ed EXPORT_SYMBOL_GPL() che non specificano esplicitamente uno spazio dei nomi. Ci sono molti modi per specificare questo simbolo di preprocessore e il loro uso dipende dalle preferenze del manutentore di un sottosistema. La prima -possibilità è quella di definire il simbolo nel `Makefile` del sottosistema. +possibilità è quella di definire il simbolo nel ``Makefile`` del sottosistema. Per esempio per esportare tutti i simboli definiti in usb-common nello spazio dei nomi USB_COMMON, si può aggiungere la seguente linea in drivers/usb/common/Makefile:: @@ -97,7 +97,7 @@ USB_STORAGE usando la seguente dichiarazione:: MODULE_IMPORT_NS(USB_STORAGE); -Questo creerà un'etichetta `modinfo` per ogni spazio dei nomi +Questo creerà un'etichetta ``modinfo`` per ogni spazio dei nomi importato. Un risvolto di questo fatto è che gli spazi dei nomi importati da un modulo possono essere ispezionati tramite modinfo:: @@ -116,7 +116,7 @@ mancanti. 4. Caricare moduli che usano simboli provenienti da spazi dei nomi ================================================================== -Quando un modulo viene caricato (per esempio usando `insmod`), il kernel +Quando un modulo viene caricato (per esempio usando ``insmod``), il kernel verificherà la disponibilità di ogni simbolo usato e se lo spazio dei nomi che potrebbe contenerli è stato importato. Il comportamento di base del kernel è di rifiutarsi di caricare quei moduli che non importano tutti gli spazi dei @@ -144,22 +144,22 @@ Lo scenario tipico di chi scrive un modulo potrebbe essere:: - scrivere codice che dipende da un simbolo appartenente ad uno spazio dei nomi non importato - - eseguire `make` + - eseguire ``make`` - aver notato un avviso da modpost che parla di un'importazione mancante - - eseguire `make nsdeps` per aggiungere import nel posto giusto + - eseguire ``make nsdeps`` per aggiungere import nel posto giusto Per i manutentori di sottosistemi che vogliono aggiungere uno spazio dei nomi, -l'approccio è simile. Di nuovo, eseguendo `make nsdeps` aggiungerà le +l'approccio è simile. Di nuovo, eseguendo ``make nsdeps`` aggiungerà le importazioni mancanti nei moduli inclusi nel kernel:: - spostare o aggiungere simboli ad uno spazio dei nomi (per esempio usando EXPORT_SYMBOL_NS()) - - eseguire `make` (preferibilmente con allmodconfig per coprire tutti + - eseguire ``make`` (preferibilmente con allmodconfig per coprire tutti i moduli del kernel) - aver notato un avviso da modpost che parla di un'importazione mancante - - eseguire `make nsdeps` per aggiungere import nel posto giusto + - eseguire ``make nsdeps`` per aggiungere import nel posto giusto Potete anche eseguire nsdeps per moduli esterni. Solitamente si usa così:: diff --git a/Documentation/translations/it_IT/kernel-hacking/hacking.rst b/Documentation/translations/it_IT/kernel-hacking/hacking.rst index f6beb385b4ac..b4ea00f1b583 100644 --- a/Documentation/translations/it_IT/kernel-hacking/hacking.rst +++ b/Documentation/translations/it_IT/kernel-hacking/hacking.rst @@ -634,7 +634,7 @@ Definita in ``include/linux/export.h`` Questa è una variate di `EXPORT_SYMBOL()` che permette di specificare uno spazio dei nomi. Lo spazio dei nomi è documentato in -:doc:`../core-api/symbol-namespaces` +Documentation/translations/it_IT/core-api/symbol-namespaces.rst. :c:func:`EXPORT_SYMBOL_NS_GPL()` -------------------------------- @@ -643,7 +643,7 @@ Definita in ``include/linux/export.h`` Questa è una variate di `EXPORT_SYMBOL_GPL()` che permette di specificare uno spazio dei nomi. Lo spazio dei nomi è documentato in -:doc:`../core-api/symbol-namespaces` +Documentation/translations/it_IT/core-api/symbol-namespaces.rst. Procedure e convenzioni ======================= diff --git a/Documentation/translations/it_IT/process/deprecated.rst b/Documentation/translations/it_IT/process/deprecated.rst index 07c79d4bafca..987f45ee1804 100644 --- a/Documentation/translations/it_IT/process/deprecated.rst +++ b/Documentation/translations/it_IT/process/deprecated.rst @@ -183,9 +183,11 @@ di Linus: affrontare il giudizio di Linus, allora forse potrai usare "%px", assicurandosi anche di averne il permesso. -Infine, sappi che un cambio in favore di "%p" con hash `non verrà -accettato -`_. +Potete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa +funzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo +aggiungete l'opzione di debug "`no_hash_pointers +`_" alla +riga di comando del kernel. Vettori a dimensione variabile (VLA) ------------------------------------ diff --git a/Documentation/translations/it_IT/process/stable-kernel-rules.rst b/Documentation/translations/it_IT/process/stable-kernel-rules.rst index 283d62541c4f..83f48afe48b9 100644 --- a/Documentation/translations/it_IT/process/stable-kernel-rules.rst +++ b/Documentation/translations/it_IT/process/stable-kernel-rules.rst @@ -41,12 +41,6 @@ Regole sul tipo di patch che vengono o non vengono accettate nei sorgenti Procedura per sottomettere patch per i sorgenti -stable ------------------------------------------------------- - - Se la patch contiene modifiche a dei file nelle cartelle net/ o drivers/net, - allora seguite le linee guida descritte in - :ref:`Documentation/translations/it_IT/networking/netdev-FAQ.rst `; - ma solo dopo aver verificato al seguente indirizzo che la patch non sia - già in coda: - https://patchwork.kernel.org/bundle/netdev/stable/?state=* - Una patch di sicurezza non dovrebbero essere gestite (solamente) dal processo di revisione -stable, ma dovrebbe seguire le procedure descritte in :ref:`Documentation/translations/it_IT/admin-guide/security-bugs.rst `. diff --git a/Documentation/translations/it_IT/process/submitting-patches.rst b/Documentation/translations/it_IT/process/submitting-patches.rst index ded95048b9a8..458d9d24b9c0 100644 --- a/Documentation/translations/it_IT/process/submitting-patches.rst +++ b/Documentation/translations/it_IT/process/submitting-patches.rst @@ -14,14 +14,15 @@ una certa familiarità col "sistema". Questo testo è una raccolta di suggerimenti che aumenteranno significativamente le probabilità di vedere le vostre patch accettate. -Questo documento contiene un vasto numero di suggerimenti concisi. Per -maggiori dettagli su come funziona il processo di sviluppo del kernel leggete -:doc:`development-process`. -Leggete anche :doc:`submit-checklist` per una lista di punti da -verificare prima di inviare del codice. Se state inviando un driver, -allora leggete anche :doc:`submitting-drivers`; per delle patch +Questo documento contiene un vasto numero di suggerimenti concisi. Per maggiori +dettagli su come funziona il processo di sviluppo del kernel leggete +Documentation/translations/it_IT/process/development-process.rst. Leggete anche +Documentation/translations/it_IT/process/submit-checklist.rst per una lista di +punti da verificare prima di inviare del codice. Se state inviando un driver, +allora leggete anche +Documentation/translations/it_IT/process/submitting-drivers.rst; per delle patch relative alle associazioni per Device Tree leggete -:doc:`submitting-patches`. +Documentation/translations/it_IT/process/submitting-patches.rst. Questa documentazione assume che sappiate usare ``git`` per preparare le patch. Se non siete pratici di ``git``, allora è bene che lo impariate; @@ -193,7 +194,7 @@ ed integrate. --------------------------------------------- Controllate che la vostra patch non violi lo stile del codice, maggiori -dettagli sono disponibili in :ref:`Documentation/translations/it_IT/process/coding-style.rst `. +dettagli sono disponibili in Documentation/translations/it_IT/process/coding-style.rst. Non farlo porta semplicemente a una perdita di tempo da parte dei revisori e voi vedrete la vostra patch rifiutata, probabilmente senza nemmeno essere stata letta. @@ -230,13 +231,13 @@ scripts/get_maintainer.pl può esservi d'aiuto. Se non riuscite a trovare un manutentore per il sottosistema su cui state lavorando, allora Andrew Morton (akpm@linux-foundation.org) sarà la vostra ultima possibilità. -Normalmente, dovreste anche scegliere una lista di discussione a cui inviare -la vostra serie di patch. La lista di discussione linux-kernel@vger.kernel.org -è proprio l'ultima spiaggia, il volume di email su questa lista fa si che -diversi sviluppatori non la seguano. Guardate nel file MAINTAINERS per trovare -la lista di discussione dedicata ad un sottosistema; probabilmente lì la vostra -patch riceverà molta più attenzione. Tuttavia, per favore, non spammate le -liste di discussione che non sono interessate al vostro lavoro. +Normalmente, dovreste anche scegliere una lista di discussione a cui inviare la +vostra serie di patch. La lista di discussione linux-kernel@vger.kernel.org +dovrebbe essere usata per inviare tutte le patch, ma il traffico è tale per cui +diversi sviluppatori la trascurano. Guardate nel file MAINTAINERS per trovare la +lista di discussione dedicata ad un sottosistema; probabilmente lì la vostra +patch riceverà molta più attenzione. Tuttavia, per favore, non spammate le liste +di discussione che non sono interessate al vostro lavoro. Molte delle liste di discussione relative al kernel vengono ospitate su vger.kernel.org; potete trovare un loro elenco alla pagina @@ -257,7 +258,7 @@ embargo potrebbe essere preso in considerazione per dare il tempo alle distribuzioni di prendere la patch e renderla disponibile ai loro utenti; in questo caso, ovviamente, la patch non dovrebbe essere inviata su alcuna lista di discussione pubblica. Leggete anche -:doc:`/admin-guide/security-bugs`. +Documentation/admin-guide/security-bugs.rst. Patch che correggono bachi importanti su un kernel già rilasciato, dovrebbero essere inviate ai manutentori dei kernel stabili aggiungendo la seguente riga:: @@ -266,12 +267,7 @@ essere inviate ai manutentori dei kernel stabili aggiungendo la seguente riga:: nella vostra patch, nell'area dedicata alle firme (notate, NON come destinatario delle e-mail). In aggiunta a questo file, dovreste leggere anche -:ref:`Documentation/translations/it_IT/process/stable-kernel-rules.rst ` - -Tuttavia, notate, che alcuni manutentori di sottosistema preferiscono avere -l'ultima parola su quali patch dovrebbero essere aggiunte ai kernel stabili. -La rete di manutentori, in particolare, non vorrebbe vedere i singoli -sviluppatori aggiungere alle loro patch delle righe come quella sopracitata. +Documentation/translations/it_IT/process/stable-kernel-rules.rst. Se le modifiche hanno effetti sull'interfaccia con lo spazio utente, per favore inviate una patch per le pagine man ai manutentori di suddette pagine (elencati @@ -330,7 +326,7 @@ così la possibilità che il vostro allegato-MIME venga accettato. Eccezione: se il vostro servizio di posta storpia le patch, allora qualcuno potrebbe chiedervi di rinviarle come allegato MIME. -Leggete :doc:`/translations/it_IT/process/email-clients` +Leggete Documentation/translations/it_IT/process/email-clients.rst per dei suggerimenti sulla configurazione del programmi di posta elettronica per l'invio di patch intatte. @@ -351,7 +347,7 @@ richiede molto tempo, e a volte i revisori diventano burberi. Tuttavia, anche in questo caso, rispondete con educazione e concentratevi sul problema che hanno evidenziato. -Leggete :doc:`/translations/it_IT/process/email-clients` per +Leggete Documentation/translations/it_IT/process/email-clients.rst per le raccomandazioni sui programmi di posta elettronica e l'etichetta da usare sulle liste di discussione. @@ -369,6 +365,16 @@ aver inviato le patch correttamente. Aspettate almeno una settimana prima di rinviare le modifiche o sollecitare i revisori - probabilmente anche di più durante la finestra d'integrazione. +Potete anche rinviare la patch, o la serie di patch, dopo un paio di settimane +aggiungendo la parola "RESEND" nel titolo:: + + [PATCH Vx RESEND] sub/sys: Condensed patch summary + +Ma non aggiungete "RESEND" quando state sottomettendo una versione modificata +della vostra patch, o serie di patch - "RESEND" si applica solo alla +sottomissione di patch, o serie di patch, che non hanno subito modifiche +dall'ultima volta che sono state inviate. + Aggiungete PATCH nell'oggetto ----------------------------- @@ -795,8 +801,7 @@ Greg Kroah-Hartman, "Come scocciare un manutentore di un sottosistema" No!!!! Basta gigantesche bombe patch alle persone sulla lista linux-kernel@vger.kernel.org! -Kernel Documentation/translations/it_IT/process/coding-style.rst: - :ref:`Documentation/translations/it_IT/process/coding-style.rst ` +Kernel Documentation/translations/it_IT/process/coding-style.rst. E-mail di Linus Torvalds sul formato canonico di una patch: -- cgit v1.2.3-70-g09d2 From 6be70ccdd989e40af151ce52db5b2d93e97fc9fb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 12 Aug 2021 16:55:12 +0200 Subject: platform/x86: asus-nb-wmi: Allow configuring SW_TABLET_MODE method with a module option Unfortunately we have been unable to find a reliable way to detect if and how SW_TABLET_MODE reporting is supported, so we are relying on DMI quirks for this. Add a module-option to specify the SW_TABLET_MODE method so that this can be easily tested without needing to rebuild the kernel. BugLink: https://gitlab.freedesktop.org/libinput/libinput/-/issues/639 Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210812145513.39117-1-hdegoede@redhat.com --- drivers/platform/x86/asus-nb-wmi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 0cb927f0f301..9929eedf7dd8 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -41,6 +41,10 @@ static int wapf = -1; module_param(wapf, uint, 0444); MODULE_PARM_DESC(wapf, "WAPF value"); +static int tablet_mode_sw = -1; +module_param(tablet_mode_sw, uint, 0444); +MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip"); + static struct quirk_entry *quirks; static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str, @@ -477,6 +481,21 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) else wapf = quirks->wapf; + switch (tablet_mode_sw) { + case 0: + quirks->use_kbd_dock_devid = false; + quirks->use_lid_flip_devid = false; + break; + case 1: + quirks->use_kbd_dock_devid = true; + quirks->use_lid_flip_devid = false; + break; + case 2: + quirks->use_kbd_dock_devid = false; + quirks->use_lid_flip_devid = true; + break; + } + if (quirks->i8042_filter) { ret = i8042_install_filter(quirks->i8042_filter); if (ret) { -- cgit v1.2.3-70-g09d2 From 411f48bb58f49c40a627b052402a90e8301cd07e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 12 Aug 2021 16:55:13 +0200 Subject: platform/x86: asus-nb-wmi: Add tablet_mode_sw=lid-flip quirk for the TP200s The Asus TP200s / E205SA 360 degree hinges 2-in-1 supports reporting SW_TABLET_MODE info through the ASUS_WMI_DEVID_LID_FLIP WMI device-id. Add a quirk to enable this. BugLink: https://gitlab.freedesktop.org/libinput/libinput/-/issues/639 Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20210812145513.39117-2-hdegoede@redhat.com --- drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 9929eedf7dd8..a81dc4b191b7 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -462,6 +462,15 @@ static const struct dmi_system_id asus_quirks[] = { }, .driver_data = &quirk_asus_use_lid_flip_devid, }, + { + .callback = dmi_matched, + .ident = "ASUS TP200s / E205SA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "E205SA"), + }, + .driver_data = &quirk_asus_use_lid_flip_devid, + }, {}, }; -- cgit v1.2.3-70-g09d2 From 4f3791c3fe277446191f4d0857bd04baf5e6d9bd Mon Sep 17 00:00:00 2001 From: Yang Yang Date: Sat, 31 Jul 2021 01:45:03 -0700 Subject: docs/zh_CN: Add zh_CN/accounting/psi.rst Add translation zh_CN/accounting/psi.rst and zh_CN/accounting/index.rst. Signed-off-by: Yang Yang Reviewed-by: Yanteng Si Link: https://lore.kernel.org/r/20210731084502.571451-1-yang.yang29@zte.com.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/accounting/index.rst | 25 ++++ .../translations/zh_CN/accounting/psi.rst | 155 +++++++++++++++++++++ Documentation/translations/zh_CN/index.rst | 2 +- 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/accounting/index.rst create mode 100644 Documentation/translations/zh_CN/accounting/psi.rst diff --git a/Documentation/translations/zh_CN/accounting/index.rst b/Documentation/translations/zh_CN/accounting/index.rst new file mode 100644 index 000000000000..362e907b41f9 --- /dev/null +++ b/Documentation/translations/zh_CN/accounting/index.rst @@ -0,0 +1,25 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/accounting/index.rst +:Translator: Yang Yang + +.. _cn_accounting_index.rst: + + +==== +计数 +==== + +.. toctree:: + :maxdepth: 1 + + psi + +Todolist: + + cgroupstats + delay-accounting + taskstats + taskstats-struct diff --git a/Documentation/translations/zh_CN/accounting/psi.rst b/Documentation/translations/zh_CN/accounting/psi.rst new file mode 100644 index 000000000000..a0ddb7bd257c --- /dev/null +++ b/Documentation/translations/zh_CN/accounting/psi.rst @@ -0,0 +1,155 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/accounting/psi.rst +:Translator: Yang Yang + +.. _cn_psi.rst: + + +================= +PSI——压力阻塞信息 +================= + +:日期: April, 2018 +:作者: Johannes Weiner + +当CPU、memory或IO设备处于竞争状态,业务负载会遭受时延毛刺、吞吐量降低, +及面临OOM的风险。 + +如果没有一种准确的方法度量系统竞争程度,则有两种后果:一种是用户过于节制, +未充分利用系统资源;另一种是过度使用,经常性面临业务中断的风险。 + +psi特性能够识别和量化资源竞争导致的业务中断,及其对复杂负载乃至整个系统在 +时间上的影响。 + +准确度量因资源不足造成的生产力损失,有助于用户基于硬件调整业务负载,或基 +于业务负载配置硬件。 + +psi能够实时的提供相关信息,因此系统可基于psi实现动态的负载管理。如实施 +卸载、迁移、策略性的停止或杀死低优先级或可重启的批处理任务。 + +psi帮助用户实现硬件资源利用率的最大化。同时无需牺牲业务负载健康度,也无需 +面临OOM等造成业务中断的风险。 + +压力接口 +======== + +压力信息可通过/proc/pressure/ --cpu、memory、io文件分别获取。 + +CPU相关信息格式如下: + + some avg10=0.00 avg60=0.00 avg300=0.00 total=0 + +内存和IO相关信息如下: + + some avg10=0.00 avg60=0.00 avg300=0.00 total=0 + full avg10=0.00 avg60=0.00 avg300=0.00 total=0 + +some行代表至少有一个任务阻塞于特定资源的时间占比。 + +full行代表所有非idle任务同时阻塞于特定资源的时间占比。在这种状态下CPU资源 +完全被浪费,相对于正常运行,业务负载由于耗费更多时间等待而受到严重影响。 + +由于此情况严重影响系统性能,因此清楚的识别本情况并与some行所代表的情况区分开, +将有助于分析及提升系统性能。这就是full独立于some行的原因。 + +avg代表阻塞时间占比(百分比),为最近10秒、60秒、300秒内的均值。这样我们 +既可观察到短期事件的影响,也可看到中等及长时间内的趋势。total代表总阻塞 +时间(单位微秒),可用于观察时延毛刺,这种毛刺可能在均值中无法体现。 + +监控压力门限 +============ + +用户可注册触发器,通过poll()监控资源压力是否超过门限。 + +触发器定义:指定时间窗口期内累积阻塞时间的最大值。比如可定义500ms内积累 +100ms阻塞,即触发一次唤醒事件。 + +触发器注册方法:用户打开代表特定资源的psi接口文件,写入门限、时间窗口的值。 +所打开的文件描述符用于等待事件,可使用select()、poll()、epoll()。 +写入信息的格式如下: + +